blob: 3fc081bfb91ed6d435b7d4cccf6dc9bbde59045a [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"
67#include "net/third_party/quic/platform/api/quic_str_cat.h"
68#include "net/third_party/quic/platform/api/quic_string_piece.h"
69#include "net/third_party/quic/platform/api/quic_test.h"
70#include "net/third_party/quic/test_tools/crypto_test_utils.h"
71#include "net/third_party/quic/test_tools/mock_clock.h"
72#include "net/third_party/quic/test_tools/mock_random.h"
73#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
74#include "net/third_party/quic/test_tools/quic_test_utils.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2975#include "net/third_party/spdy/core/spdy_frame_builder.h"
76#include "net/third_party/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2977#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
allada71b2efb2016-09-09 04:57:4878#include "net/url_request/url_request.h"
79#include "net/url_request/url_request_job_factory_impl.h"
80#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0181#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0082#include "testing/gtest/include/gtest/gtest.h"
83#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4684#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0085
Reilly Grant89a7e512018-01-20 01:57:1686using ::testing::ElementsAre;
87using ::testing::Key;
88
bnc508835902015-05-12 20:10:2989namespace net {
90namespace test {
[email protected]61a527782013-02-21 03:58:0091
92namespace {
93
bnc359ed2a2016-04-29 20:43:4594enum DestinationType {
95 // In pooling tests with two requests for different origins to the same
96 // destination, the destination should be
97 SAME_AS_FIRST, // the same as the first origin,
98 SAME_AS_SECOND, // the same as the second origin, or
99 DIFFERENT, // different from both.
100};
101
rchf114d982015-10-21 01:34:56102static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52103 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12104static const char kQuicAlternativeServiceWithProbabilityHeader[] =
105 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56106static const char kQuicAlternativeServiceDifferentPortHeader[] =
107 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20108
rch9ae5b3b2016-02-11 00:36:29109const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45110const char kDifferentHostname[] = "different.example.com";
111
112// Run QuicNetworkTransactionWithDestinationTest instances with all value
113// combinations of version and destination_type.
114struct PoolingTestParams {
115 friend std::ostream& operator<<(std::ostream& os,
116 const PoolingTestParams& p) {
117 os << "{ version: " << QuicVersionToString(p.version)
118 << ", destination_type: ";
119 switch (p.destination_type) {
120 case SAME_AS_FIRST:
121 os << "SAME_AS_FIRST";
122 break;
123 case SAME_AS_SECOND:
124 os << "SAME_AS_SECOND";
125 break;
126 case DIFFERENT:
127 os << "DIFFERENT";
128 break;
129 }
Yixin Wang079ad542018-01-11 04:06:05130 os << ", client_headers_include_h2_stream_dependency: "
131 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45132 os << " }";
133 return os;
134 }
135
Ryan Hamilton8d9ee76e2018-05-29 23:52:52136 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45137 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05138 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45139};
140
zhongyie537a002017-06-27 16:48:21141std::string GenerateQuicVersionsListForAltSvcHeader(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52142 const quic::QuicTransportVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21143 std::string result = "";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52144 for (const quic::QuicTransportVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21145 if (!result.empty())
146 result.append(",");
147 result.append(base::IntToString(version));
148 }
149 return result;
150}
151
bnc359ed2a2016-04-29 20:43:45152std::vector<PoolingTestParams> GetPoolingTestParams() {
153 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52154 quic::QuicTransportVersionVector all_supported_versions =
155 quic::AllSupportedTransportVersions();
156 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05157 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
158 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
159 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
160 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
161 params.push_back(PoolingTestParams{version, DIFFERENT, false});
162 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45163 }
164 return params;
165}
bncb07c05532015-05-14 19:07:20166
[email protected]61a527782013-02-21 03:58:00167} // namespace
168
ryansturm49a8cb12016-06-15 16:51:09169class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12170 public:
ryansturm49a8cb12016-06-15 16:51:09171 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12172
ryansturm49a8cb12016-06-15 16:51:09173 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12174
ryansturm49a8cb12016-06-15 16:51:09175 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
176 HttpRequestHeaders* request_headers) {
177 if (!proxy_info.is_http() && !proxy_info.is_https() &&
178 !proxy_info.is_quic()) {
179 return;
180 }
181 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12182 }
183
184 private:
ryansturm49a8cb12016-06-15 16:51:09185 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12186};
187
tbansal0f56a39a2016-04-07 22:03:38188class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40189 public:
tbansal180587c2017-02-16 15:13:23190 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
191 bool* rtt_notification_received)
192 : should_notify_updated_rtt_(should_notify_updated_rtt),
193 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38194 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40195
tbansal180587c2017-02-16 15:13:23196 bool ShouldNotifyUpdatedRTT() const override {
197 return *should_notify_updated_rtt_;
198 }
tbansalfdf5665b2015-09-21 22:46:40199
tbansal0f56a39a2016-04-07 22:03:38200 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
201 *rtt_notification_received_ = true;
202 }
203
204 void OnConnectionChanged() override {}
205
206 private:
tbansal180587c2017-02-16 15:13:23207 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38208 bool* rtt_notification_received_;
209
210 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
211};
212
213class TestSocketPerformanceWatcherFactory
214 : public SocketPerformanceWatcherFactory {
215 public:
216 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23217 : watcher_count_(0u),
218 should_notify_updated_rtt_(true),
219 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38220 ~TestSocketPerformanceWatcherFactory() override {}
221
222 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42223 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41224 const Protocol protocol,
225 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51226 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38227 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51228 }
229 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42230 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23231 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
232 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40233 }
234
tbansalc8a94ea2015-11-02 23:58:51235 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40236
tbansalc8a94ea2015-11-02 23:58:51237 bool rtt_notification_received() const { return rtt_notification_received_; }
238
tbansal180587c2017-02-16 15:13:23239 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
240 should_notify_updated_rtt_ = should_notify_updated_rtt;
241 }
242
tbansalc8a94ea2015-11-02 23:58:51243 private:
tbansal0f56a39a2016-04-07 22:03:38244 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23245 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51246 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38247
248 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51249};
250
Ryan Hamilton8d9ee76e2018-05-29 23:52:52251class QuicNetworkTransactionTest
252 : public PlatformTest,
253 public ::testing::WithParamInterface<
254 std::tuple<quic::QuicTransportVersion, bool>>,
255 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00256 protected:
[email protected]1c04f9522013-02-21 20:32:43257 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05258 : version_(std::get<0>(GetParam())),
259 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52260 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc90be5dd782016-11-09 16:28:44261 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58262 0,
rchbf4c26d2017-04-16 23:17:55263 &clock_,
alyssar2adf3ac2016-05-03 17:12:58264 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52265 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05266 client_headers_include_h2_stream_dependency_),
bnc90be5dd782016-11-09 16:28:44267 server_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58268 0,
rchbf4c26d2017-04-16 23:17:55269 &clock_,
alyssar2adf3ac2016-05-03 17:12:58270 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52271 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05272 false),
rtenneti052774e2015-11-24 21:00:12273 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43274 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59275 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
[email protected]1c04f9522013-02-21 20:32:43276 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30277 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
[email protected]457d6952013-12-13 09:24:58278 random_generator_(0),
rchf114d982015-10-21 01:34:56279 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19280 request_.method = "GET";
rchf114d982015-10-21 01:34:56281 std::string url("https://");
bncb07c05532015-05-14 19:07:20282 url.append(kDefaultServerHostName);
283 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19284 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10285 request_.traffic_annotation =
286 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52287 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56288
289 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29290 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56291 verify_details_.cert_verify_result.verified_cert = cert;
292 verify_details_.cert_verify_result.is_issued_by_known_root = true;
293 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43294 }
[email protected]61a527782013-02-21 03:58:00295
dcheng67be2b1f2014-10-27 21:47:29296 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00297 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55298 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00299 }
300
dcheng67be2b1f2014-10-27 21:47:29301 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00302 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
303 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55304 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00305 PlatformTest::TearDown();
306 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55307 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40308 session_.reset();
[email protected]61a527782013-02-21 03:58:00309 }
310
Ryan Hamilton8d9ee76e2018-05-29 23:52:52311 std::unique_ptr<quic::QuicEncryptedPacket>
312 ConstructClientConnectionClosePacket(quic::QuicPacketNumber num) {
Bin Wu5311aca2018-01-22 01:19:03313 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52314 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30315 }
316
Ryan Hamilton8d9ee76e2018-05-29 23:52:52317 std::unique_ptr<quic::QuicEncryptedPacket>
318 ConstructServerConnectionClosePacket(quic::QuicPacketNumber num) {
Bin Wu5311aca2018-01-22 01:19:03319 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52320 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58321 }
322
Ryan Hamilton8d9ee76e2018-05-29 23:52:52323 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
324 quic::QuicPacketNumber num,
325 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20326 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58327 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20328 }
329
Ryan Hamilton8d9ee76e2018-05-29 23:52:52330 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
331 quic::QuicPacketNumber packet_number,
332 quic::QuicPacketNumber largest_received,
333 quic::QuicPacketNumber smallest_received,
334 quic::QuicPacketNumber least_unacked) {
fayang3bcb8b502016-12-07 21:44:37335 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49336 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37337 }
338
Ryan Hamilton8d9ee76e2018-05-29 23:52:52339 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
340 quic::QuicPacketNumber packet_number,
341 quic::QuicPacketNumber largest_received,
342 quic::QuicPacketNumber smallest_received,
343 quic::QuicPacketNumber least_unacked,
344 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23345 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49346 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23347 ack_delay_time);
348 }
349
Ryan Hamilton8d9ee76e2018-05-29 23:52:52350 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
351 quic::QuicPacketNumber num,
352 quic::QuicStreamId stream_id,
353 quic::QuicRstStreamErrorCode error_code,
354 quic::QuicPacketNumber largest_received,
355 quic::QuicPacketNumber smallest_received,
356 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58357 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49358 num, false, stream_id, error_code, largest_received, smallest_received,
359 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20360 }
361
Ryan Hamilton8d9ee76e2018-05-29 23:52:52362 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
363 quic::QuicPacketNumber num,
364 quic::QuicStreamId stream_id,
365 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56366 size_t bytes_written) {
367 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
368 bytes_written);
369 }
370
Ryan Hamilton8d9ee76e2018-05-29 23:52:52371 std::unique_ptr<quic::QuicEncryptedPacket>
372 ConstructClientAckAndConnectionClosePacket(
373 quic::QuicPacketNumber packet_number,
374 quic::QuicPacketNumber largest_received,
375 quic::QuicPacketNumber smallest_received,
376 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58377 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49378 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20379 }
[email protected]61a527782013-02-21 03:58:00380
Ryan Hamilton8d9ee76e2018-05-29 23:52:52381 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58382 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52383 quic::QuicPacketNumber num,
384 quic::QuicTime::Delta delta_time_largest_observed,
385 quic::QuicPacketNumber largest_received,
386 quic::QuicPacketNumber smallest_received,
387 quic::QuicPacketNumber least_unacked,
388 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50389 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58390 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12391 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49392 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12393 }
394
Ryan Hamilton8d9ee76e2018-05-29 23:52:52395 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
396 quic::QuicPacketNumber num,
zhongyica364fbb2015-12-12 03:39:12397 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52398 quic::QuicStreamId stream_id,
399 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58400 return server_maker_.MakeRstPacket(num, include_version, stream_id,
401 error_code);
zhongyica364fbb2015-12-12 03:39:12402 }
403
Ryan Hamilton8d9ee76e2018-05-29 23:52:52404 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
405 quic::QuicPacketNumber packet_number,
406 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36407 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37408 }
409
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
411 quic::QuicPacketNumber packet_number,
412 quic::QuicPacketNumber largest_received,
413 quic::QuicPacketNumber smallest_received,
414 quic::QuicPacketNumber least_unacked) {
fayang3bcb8b502016-12-07 21:44:37415 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49416 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37417 }
418
Ryan Hamilton8d9ee76e2018-05-29 23:52:52419 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
420 quic::QuicPacketNumber packet_number,
Yixin Wangb470bc882018-02-15 18:43:57421 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52422 quic::QuicStreamId id,
423 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57424 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52425 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57426 return client_maker_.MakePriorityPacket(
427 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23428 ConvertRequestPriorityToQuicPriority(request_priority), offset);
429 }
430
Ryan Hamilton8d9ee76e2018-05-29 23:52:52431 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25432 ConstructClientAckAndPriorityFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52433 quic::QuicPacketNumber packet_number,
Yixin Wang385652a2018-02-16 02:37:23434 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 quic::QuicPacketNumber largest_received,
436 quic::QuicPacketNumber smallest_received,
437 quic::QuicPacketNumber least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25438 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
439 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52440 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25441 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23442 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25443 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57444 }
445
zhongyi32569c62016-01-08 02:54:30446 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13447 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
448 const std::string& scheme,
449 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58450 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30451 }
452
453 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13454 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
455 const std::string& scheme,
456 const std::string& path,
457 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50458 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00459 }
460
Ryan Hamilton0239aac2018-05-19 00:03:13461 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56462 return client_maker_.ConnectRequestHeaders(host_port);
463 }
464
Ryan Hamilton0239aac2018-05-19 00:03:13465 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58466 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00467 }
468
zhongyi32569c62016-01-08 02:54:30469 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13470 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
471 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58472 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30473 }
474
Ryan Hamilton8d9ee76e2018-05-29 23:52:52475 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
476 quic::QuicPacketNumber packet_number,
477 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05478 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00479 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52480 quic::QuicStreamOffset offset,
481 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58482 return server_maker_.MakeDataPacket(
483 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00484 }
485
Ryan Hamilton8d9ee76e2018-05-29 23:52:52486 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
487 quic::QuicPacketNumber packet_number,
488 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36489 bool should_include_version,
490 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 quic::QuicStreamOffset offset,
492 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36493 return client_maker_.MakeDataPacket(
494 packet_number, stream_id, should_include_version, fin, offset, data);
495 }
496
Ryan Hamilton8d9ee76e2018-05-29 23:52:52497 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
498 quic::QuicPacketNumber packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56499 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52500 quic::QuicStreamId stream_id,
501 quic::QuicPacketNumber largest_received,
502 quic::QuicPacketNumber smallest_received,
503 quic::QuicPacketNumber least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56504 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52505 quic::QuicStreamOffset offset,
506 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56507 return client_maker_.MakeAckAndDataPacket(
508 packet_number, include_version, stream_id, largest_received,
509 smallest_received, least_unacked, fin, offset, data);
510 }
511
Ryan Hamilton8d9ee76e2018-05-29 23:52:52512 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
513 quic::QuicPacketNumber packet_number,
514 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36515 bool should_include_version,
516 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 quic::QuicStreamOffset* offset,
518 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36519 return client_maker_.MakeForceHolDataPacket(
520 packet_number, stream_id, should_include_version, fin, offset, data);
521 }
522
Ryan Hamilton8d9ee76e2018-05-29 23:52:52523 std::unique_ptr<quic::QuicEncryptedPacket>
524 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
525 quic::QuicStreamId stream_id,
526 bool should_include_version,
527 bool fin,
528 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56529 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
530 should_include_version, fin,
531 std::move(headers), nullptr);
532 }
533
Ryan Hamilton8d9ee76e2018-05-29 23:52:52534 std::unique_ptr<quic::QuicEncryptedPacket>
535 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
536 quic::QuicStreamId stream_id,
537 bool should_include_version,
538 bool fin,
539 spdy::SpdyHeaderBlock headers,
540 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48541 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
542 should_include_version, fin,
543 std::move(headers), 0, offset);
544 }
545
Ryan Hamilton8d9ee76e2018-05-29 23:52:52546 std::unique_ptr<quic::QuicEncryptedPacket>
547 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
548 quic::QuicStreamId stream_id,
549 bool should_include_version,
550 bool fin,
551 spdy::SpdyHeaderBlock headers,
552 quic::QuicStreamId parent_stream_id,
553 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56554 return ConstructClientRequestHeadersPacket(
555 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48556 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30557 }
558
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 std::unique_ptr<quic::QuicEncryptedPacket>
560 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
561 quic::QuicStreamId stream_id,
562 bool should_include_version,
563 bool fin,
564 RequestPriority request_priority,
565 spdy::SpdyHeaderBlock headers,
566 quic::QuicStreamId parent_stream_id,
567 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13568 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56569 ConvertRequestPriorityToQuicPriority(request_priority);
570 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
571 packet_number, stream_id, should_include_version, fin, priority,
572 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00573 }
574
Ryan Hamilton8d9ee76e2018-05-29 23:52:52575 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25576 ConstructClientRequestHeadersAndDataFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52577 quic::QuicPacketNumber packet_number,
578 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25579 bool should_include_version,
580 bool fin,
581 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13582 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52583 quic::QuicStreamId parent_stream_id,
584 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25585 size_t* spdy_headers_frame_length,
586 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13587 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25588 ConvertRequestPriorityToQuicPriority(request_priority);
589 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
590 packet_number, stream_id, should_include_version, fin, priority,
591 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
592 data_writes);
593 }
594
Ryan Hamilton8d9ee76e2018-05-29 23:52:52595 std::unique_ptr<quic::QuicEncryptedPacket>
596 ConstructClientMultipleDataFramesPacket(quic::QuicPacketNumber packet_number,
597 quic::QuicStreamId stream_id,
598 bool should_include_version,
599 bool fin,
600 const std::vector<std::string>& data,
601 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27602 return client_maker_.MakeMultipleDataFramesPacket(
603 packet_number, stream_id, should_include_version, fin, offset, data);
604 }
605
Ryan Hamilton8d9ee76e2018-05-29 23:52:52606 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
607 quic::QuicPacketNumber packet_number,
608 quic::QuicStreamId stream_id,
609 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13610 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13611 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52612 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13613 QuicTestPacketMaker* maker) {
614 return maker->MakePushPromisePacket(
615 packet_number, stream_id, promised_stream_id, should_include_version,
616 false, std::move(headers), nullptr, offset);
617 }
618
Ryan Hamilton8d9ee76e2018-05-29 23:52:52619 std::unique_ptr<quic::QuicEncryptedPacket>
620 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
621 quic::QuicStreamId stream_id,
622 bool should_include_version,
623 bool fin,
624 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27625 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
626 should_include_version, fin,
627 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30628 }
629
Ryan Hamilton8d9ee76e2018-05-29 23:52:52630 std::unique_ptr<quic::QuicEncryptedPacket>
631 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
632 quic::QuicStreamId stream_id,
633 bool should_include_version,
634 bool fin,
635 spdy::SpdyHeaderBlock headers,
636 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58637 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25638 packet_number, stream_id, should_include_version, fin,
639 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30640 }
641
Ryan Hamilton8d9ee76e2018-05-29 23:52:52642 void CreateSession(
643 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41644 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21645 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05646 session_params_.quic_headers_include_h2_stream_dependency =
647 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00648
mmenke6ddfbea2017-05-31 21:48:41649 session_context_.quic_clock = &clock_;
650 session_context_.quic_random = &random_generator_;
651 session_context_.client_socket_factory = &socket_factory_;
652 session_context_.quic_crypto_client_stream_factory =
653 &crypto_client_stream_factory_;
654 session_context_.host_resolver = &host_resolver_;
655 session_context_.cert_verifier = &cert_verifier_;
656 session_context_.transport_security_state = &transport_security_state_;
657 session_context_.cert_transparency_verifier =
658 cert_transparency_verifier_.get();
659 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
660 session_context_.socket_performance_watcher_factory =
661 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59662 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41663 session_context_.ssl_config_service = ssl_config_service_.get();
664 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
665 session_context_.http_server_properties = &http_server_properties_;
666 session_context_.net_log = net_log_.bound().net_log();
667
668 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12669 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56670 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
671 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00672 }
673
zhongyi86838d52017-06-30 01:19:44674 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21675
bnc691fda62016-08-12 00:43:16676 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19677 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42678 ASSERT_TRUE(response != nullptr);
679 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19680 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
681 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52682 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44683 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19684 response->connection_info);
685 }
686
bnc691fda62016-08-12 00:43:16687 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41688 const HttpResponseInfo* response = trans->GetResponseInfo();
689 ASSERT_TRUE(response != nullptr);
690 EXPECT_EQ(port, response->socket_address.port());
691 }
692
bnc691fda62016-08-12 00:43:16693 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19694 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42695 ASSERT_TRUE(response != nullptr);
696 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19697 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
698 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52699 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52700 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19701 response->connection_info);
702 }
703
Yixin Wang46a273ec302018-01-23 17:59:56704 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
705 const HttpResponseInfo* response = trans->GetResponseInfo();
706 ASSERT_TRUE(response != nullptr);
707 ASSERT_TRUE(response->headers.get() != nullptr);
708 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
709 EXPECT_TRUE(response->was_fetched_via_spdy);
710 EXPECT_TRUE(response->was_alpn_negotiated);
711 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
712 response->connection_info);
713 }
714
bnc691fda62016-08-12 00:43:16715 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19716 const std::string& expected) {
717 std::string response_data;
bnc691fda62016-08-12 00:43:16718 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19719 EXPECT_EQ(expected, response_data);
720 }
721
bnc691fda62016-08-12 00:43:16722 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19723 TestCompletionCallback callback;
724 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
726 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19727 }
728
729 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
731 RunTransaction(&trans);
732 CheckWasHttpResponse(&trans);
733 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19734 }
735
tbansalc3308d72016-08-27 10:25:04736 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
737 bool used_proxy,
738 uint16_t port) {
739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
740 HeadersHandler headers_handler;
741 trans.SetBeforeHeadersSentCallback(
742 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
743 base::Unretained(&headers_handler)));
744 RunTransaction(&trans);
745 CheckWasHttpResponse(&trans);
746 CheckResponsePort(&trans, port);
747 CheckResponseData(&trans, expected);
748 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47749 if (used_proxy) {
750 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
751 } else {
752 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
753 }
tbansalc3308d72016-08-27 10:25:04754 }
755
[email protected]aa9b14d2013-05-10 23:45:19756 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56757 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12758 }
759
bnc62a44f022015-04-02 15:59:41760 void SendRequestAndExpectQuicResponseFromProxyOnPort(
761 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46762 uint16_t port) {
bnc62a44f022015-04-02 15:59:41763 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19764 }
765
766 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27767 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19768 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46769 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21770 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12771 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21772 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44773 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19774 }
775
rchbe69cb902016-02-11 01:10:48776 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27777 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48778 const HostPortPair& alternative) {
779 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46780 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21781 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48782 alternative.port());
783 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21784 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44785 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48786 }
787
[email protected]aa9b14d2013-05-10 23:45:19788 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46789 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34790 const AlternativeServiceInfoVector alternative_service_info_vector =
791 http_server_properties_.GetAlternativeServiceInfos(server);
792 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07793 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54794 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19795 }
796
[email protected]4d590c9c2014-05-02 05:14:33797 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46798 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34799 const AlternativeServiceInfoVector alternative_service_info_vector =
800 http_server_properties_.GetAlternativeServiceInfos(server);
801 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54802 EXPECT_EQ(
803 kProtoQUIC,
804 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23805 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54806 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33807 }
808
[email protected]aa9b14d2013-05-10 23:45:19809 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42810 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30811 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30812 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30813 hanging_data->set_connect_data(hanging_connect);
814 hanging_data_.push_back(std::move(hanging_data));
815 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56816 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19817 }
818
tbansalc3308d72016-08-27 10:25:04819 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
820 // alternative proxy. Verifies that if the alternative proxy job returns
821 // |error_code|, the request is fetched successfully by the main job.
822 void TestAlternativeProxy(int error_code) {
823 // Use a non-cryptographic scheme for the request URL since this request
824 // will be fetched via proxy with QUIC as the alternative service.
825 request_.url = GURL("http://example.org/");
826 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27827 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04828 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27829 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04830 };
831
Ryan Sleevib8d7ea02018-05-07 20:01:01832 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04833 socket_factory_.AddSocketDataProvider(&quic_data);
834
835 // Main job succeeds and the alternative job fails.
836 // Add data for two requests that will be read by the main job.
837 MockRead http_reads_1[] = {
838 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
839 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
840 MockRead(ASYNC, OK)};
841
842 MockRead http_reads_2[] = {
843 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
844 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
845 MockRead(ASYNC, OK)};
846
Ryan Sleevib8d7ea02018-05-07 20:01:01847 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
848 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04849 socket_factory_.AddSocketDataProvider(&http_data_1);
850 socket_factory_.AddSocketDataProvider(&http_data_2);
851 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
852 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
853
854 TestProxyDelegate test_proxy_delegate;
855 // Proxy URL is different from the request URL.
856 test_proxy_delegate.set_alternative_proxy_server(
857 ProxyServer::FromPacString("QUIC myproxy.org:443"));
858
mmenke6ddfbea2017-05-31 21:48:41859 session_context_.proxy_delegate = &test_proxy_delegate;
Lily Houghton8c2f97d2018-01-22 05:06:59860 proxy_resolution_service_ =
861 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49862 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:04863
864 CreateSession();
865 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
866
867 // The first request should be fetched via the HTTPS proxy.
868 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
869
Reilly Grant89a7e512018-01-20 01:57:16870 // Since the main job succeeded only the alternative proxy server should be
871 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59872 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16873 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04874
875 // Verify that the second request completes successfully, and the
876 // alternative proxy server job is not started.
877 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
878 }
879
Ryan Hamilton8d9ee76e2018-05-29 23:52:52880 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
881 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36882 }
883
Ryan Hamilton8d9ee76e2018-05-29 23:52:52884 quic::QuicStreamId GetNthServerInitiatedStreamId(int n) {
885 return quic::test::GetNthServerInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36886 }
887
Bence Béky230ac612017-08-30 19:17:08888 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49889 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08890 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49891 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08892 }
893
Ryan Hamilton8d9ee76e2018-05-29 23:52:52894 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05895 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52896 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01897 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52898 quic::MockClock clock_;
alyssar2adf3ac2016-05-03 17:12:58899 QuicTestPacketMaker client_maker_;
900 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42901 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00902 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56903 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05904 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43905 MockHostResolver host_resolver_;
906 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11907 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42908 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23909 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38910 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07911 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59912 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42913 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52914 quic::test::MockRandom random_generator_;
bnc6be245c12015-05-15 11:24:07915 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41916 HttpNetworkSession::Params session_params_;
917 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19918 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51919 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42920 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56921 SSLSocketDataProvider ssl_data_;
tbansal7cec3812015-02-05 21:25:12922
923 private:
924 void SendRequestAndExpectQuicResponseMaybeFromProxy(
925 const std::string& expected,
bnc62a44f022015-04-02 15:59:41926 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46927 uint16_t port) {
bnc691fda62016-08-12 00:43:16928 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09929 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16930 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09931 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
932 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16933 RunTransaction(&trans);
934 CheckWasQuicResponse(&trans);
935 CheckResponsePort(&trans, port);
936 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09937 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47938 if (used_proxy) {
939 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
940 } else {
941 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
942 }
tbansal7cec3812015-02-05 21:25:12943 }
[email protected]61a527782013-02-21 03:58:00944};
945
Yixin Wang079ad542018-01-11 04:06:05946INSTANTIATE_TEST_CASE_P(
Yixin Wang385652a2018-02-16 02:37:23947 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05948 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52949 ::testing::Combine(
950 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
951 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20952
Ryan Hamiltona64a5bcf2017-11-30 07:35:28953TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:48954 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28955 base::HistogramTester histograms;
956 session_params_.origins_to_force_quic_on.insert(
957 HostPortPair::FromString("mail.example.org:443"));
958 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27959 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:28960
961 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52962 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28963 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43964 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:28965 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
966 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
967 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
968
969 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
970
971 CreateSession();
972
973 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
974 TestCompletionCallback callback;
975 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
977 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
978
979 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
980 -ERR_INTERNET_DISCONNECTED, 1);
981 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
982 -ERR_INTERNET_DISCONNECTED, 1);
983}
984
985TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:48986 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28987 base::HistogramTester histograms;
988 session_params_.origins_to_force_quic_on.insert(
989 HostPortPair::FromString("mail.example.org:443"));
990 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27991 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:28992
993 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52994 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28995 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43996 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:28997 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
998 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
999 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1000
1001 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1002
1003 CreateSession();
1004
1005 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1006 TestCompletionCallback callback;
1007 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1009 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1010
1011 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1012 -ERR_INTERNET_DISCONNECTED, 1);
1013 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1014 -ERR_INTERNET_DISCONNECTED, 1);
1015}
1016
tbansal180587c2017-02-16 15:13:231017TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411018 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231019 HostPortPair::FromString("mail.example.org:443"));
1020
1021 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521022 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361023 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431024 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1025 mock_quic_data.AddWrite(
1026 SYNCHRONOUS,
1027 ConstructClientRequestHeadersPacket(
1028 2, GetNthClientInitiatedStreamId(0), true, true,
1029 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1030 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1031 1, GetNthClientInitiatedStreamId(0), false,
1032 false, GetResponseHeaders("200 OK")));
1033 mock_quic_data.AddRead(
1034 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1035 false, true, 0, "hello!"));
1036 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231037 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1038
1039 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1040
1041 CreateSession();
1042 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1043
1044 EXPECT_FALSE(
1045 test_socket_performance_watcher_factory_.rtt_notification_received());
1046 SendRequestAndExpectQuicResponse("hello!");
1047 EXPECT_TRUE(
1048 test_socket_performance_watcher_factory_.rtt_notification_received());
1049}
1050
1051TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411052 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231053 HostPortPair::FromString("mail.example.org:443"));
1054
1055 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521056 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361057 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431058 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1059 mock_quic_data.AddWrite(
1060 SYNCHRONOUS,
1061 ConstructClientRequestHeadersPacket(
1062 2, GetNthClientInitiatedStreamId(0), true, true,
1063 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1064 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1065 1, GetNthClientInitiatedStreamId(0), false,
1066 false, GetResponseHeaders("200 OK")));
1067 mock_quic_data.AddRead(
1068 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1069 false, true, 0, "hello!"));
1070 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231071 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1072
1073 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1074
1075 CreateSession();
1076 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1077
1078 EXPECT_FALSE(
1079 test_socket_performance_watcher_factory_.rtt_notification_received());
1080 SendRequestAndExpectQuicResponse("hello!");
1081 EXPECT_FALSE(
1082 test_socket_performance_watcher_factory_.rtt_notification_received());
1083}
1084
[email protected]1e960032013-12-20 19:00:201085TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411086 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571087 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471088
[email protected]1e960032013-12-20 19:00:201089 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521090 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361091 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431092 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1093 mock_quic_data.AddWrite(
1094 SYNCHRONOUS,
1095 ConstructClientRequestHeadersPacket(
1096 2, GetNthClientInitiatedStreamId(0), true, true,
1097 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1098 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1099 1, GetNthClientInitiatedStreamId(0), false,
1100 false, GetResponseHeaders("200 OK")));
1101 mock_quic_data.AddRead(
1102 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1103 false, true, 0, "hello!"));
1104 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591105 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471106
rcha5399e02015-04-21 19:32:041107 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471108
[email protected]4dca587c2013-03-07 16:54:471109 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471110
[email protected]aa9b14d2013-05-10 23:45:191111 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471112
[email protected]98b20ce2013-05-10 05:55:261113 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461114 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191115 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261116 EXPECT_LT(0u, entries.size());
1117
1118 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291119 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001120 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1121 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261122 EXPECT_LT(0, pos);
1123
rchfd527212015-08-25 00:41:261124 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291125 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261126 entries, 0,
mikecirone8b85c432016-09-08 19:11:001127 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1128 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261129 EXPECT_LT(0, pos);
1130
rtennetia004d332015-08-28 06:44:571131 std::string packet_number;
1132 ASSERT_TRUE(entries[pos].GetStringValue("packet_number", &packet_number));
1133 EXPECT_EQ("1", packet_number);
[email protected]98b20ce2013-05-10 05:55:261134
rchfd527212015-08-25 00:41:261135 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1136 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001137 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1138 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261139 EXPECT_LT(0, pos);
1140
[email protected]98b20ce2013-05-10 05:55:261141 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291142 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001143 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1144 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261145 EXPECT_LT(0, pos);
1146
1147 int log_stream_id;
1148 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
[email protected]1e960032013-12-20 19:00:201149 EXPECT_EQ(3, log_stream_id);
[email protected]4dca587c2013-03-07 16:54:471150}
1151
rchbd089ab2017-05-26 23:05:041152TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411153 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041154 HostPortPair::FromString("mail.example.org:443"));
1155
1156 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521157 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041158 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431159 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1160 mock_quic_data.AddWrite(
1161 SYNCHRONOUS,
1162 ConstructClientRequestHeadersPacket(
1163 2, GetNthClientInitiatedStreamId(0), true, true,
1164 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131165 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041166 response_headers["key1"] = std::string(30000, 'A');
1167 response_headers["key2"] = std::string(30000, 'A');
1168 response_headers["key3"] = std::string(30000, 'A');
1169 response_headers["key4"] = std::string(30000, 'A');
1170 response_headers["key5"] = std::string(30000, 'A');
1171 response_headers["key6"] = std::string(30000, 'A');
1172 response_headers["key7"] = std::string(30000, 'A');
1173 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamilton0239aac2018-05-19 00:03:131174 spdy::SpdyHeadersIR headers_frame(GetNthClientInitiatedStreamId(0),
1175 std::move(response_headers));
1176 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1177 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041178 response_framer.SerializeFrame(headers_frame);
1179
Ryan Hamilton8d9ee76e2018-05-29 23:52:521180 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041181 size_t chunk_size = 1200;
1182 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1183 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431184 mock_quic_data.AddRead(
1185 ASYNC, ConstructServerDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521186 packet_number++, quic::kHeadersStreamId, false, false,
1187 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041188 }
1189
1190 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:431191 ASYNC,
rchbd089ab2017-05-26 23:05:041192 ConstructServerDataPacket(packet_number, GetNthClientInitiatedStreamId(0),
1193 false, true, 0, "hello!"));
1194 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431195 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1196 mock_quic_data.AddWrite(ASYNC,
1197 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041198
1199 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1200
1201 CreateSession();
1202
1203 SendRequestAndExpectQuicResponse("hello!");
1204}
1205
1206TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481207 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411208 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041209 HostPortPair::FromString("mail.example.org:443"));
1210
1211 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521212 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041213 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431214 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1215 mock_quic_data.AddWrite(
1216 SYNCHRONOUS,
1217 ConstructClientRequestHeadersPacket(
1218 2, GetNthClientInitiatedStreamId(0), true, true,
1219 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131220 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041221 response_headers["key1"] = std::string(30000, 'A');
1222 response_headers["key2"] = std::string(30000, 'A');
1223 response_headers["key3"] = std::string(30000, 'A');
1224 response_headers["key4"] = std::string(30000, 'A');
1225 response_headers["key5"] = std::string(30000, 'A');
1226 response_headers["key6"] = std::string(30000, 'A');
1227 response_headers["key7"] = std::string(30000, 'A');
1228 response_headers["key8"] = std::string(30000, 'A');
1229 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamilton0239aac2018-05-19 00:03:131230 spdy::SpdyHeadersIR headers_frame(GetNthClientInitiatedStreamId(0),
1231 std::move(response_headers));
1232 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1233 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041234 response_framer.SerializeFrame(headers_frame);
1235
Ryan Hamilton8d9ee76e2018-05-29 23:52:521236 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041237 size_t chunk_size = 1200;
1238 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1239 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431240 mock_quic_data.AddRead(
1241 ASYNC, ConstructServerDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521242 packet_number++, quic::kHeadersStreamId, false, false,
1243 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041244 }
1245
1246 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:431247 ASYNC,
rchbd089ab2017-05-26 23:05:041248 ConstructServerDataPacket(packet_number, GetNthClientInitiatedStreamId(0),
1249 false, true, 0, "hello!"));
1250 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431251 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1252 mock_quic_data.AddWrite(
1253 ASYNC, ConstructClientAckAndRstPacket(4, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:521254 quic::QUIC_HEADERS_TOO_LARGE,
Zhongyi Shi32f2fd02018-04-16 18:23:431255 packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041256
1257 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1258
1259 CreateSession();
1260
1261 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1262 TestCompletionCallback callback;
1263 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1265 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1266}
1267
rcha2bd44b2016-07-02 00:42:551268TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411269 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551270
Ryan Hamilton9835e662018-08-02 05:36:271271 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551272
1273 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521274 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361275 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431276 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1277 mock_quic_data.AddWrite(
1278 SYNCHRONOUS,
1279 ConstructClientRequestHeadersPacket(
1280 2, GetNthClientInitiatedStreamId(0), true, true,
1281 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1282 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1283 1, GetNthClientInitiatedStreamId(0), false,
1284 false, GetResponseHeaders("200 OK")));
1285 mock_quic_data.AddRead(
1286 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1287 false, true, 0, "hello!"));
1288 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551289 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1290
1291 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1292
1293 CreateSession();
1294
1295 SendRequestAndExpectQuicResponse("hello!");
1296 EXPECT_TRUE(
1297 test_socket_performance_watcher_factory_.rtt_notification_received());
1298}
1299
[email protected]cf3e3cd62014-02-05 16:16:161300TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411301 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591302 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491303 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161304
[email protected]cf3e3cd62014-02-05 16:16:161305 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521306 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361307 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431308 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1309 mock_quic_data.AddWrite(
1310 SYNCHRONOUS,
1311 ConstructClientRequestHeadersPacket(
1312 2, GetNthClientInitiatedStreamId(0), true, true,
1313 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
1314 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1315 1, GetNthClientInitiatedStreamId(0), false,
1316 false, GetResponseHeaders("200 OK")));
1317 mock_quic_data.AddRead(
1318 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1319 false, true, 0, "hello!"));
1320 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501321 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591322 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161323
rcha5399e02015-04-21 19:32:041324 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161325
tbansal0f56a39a2016-04-07 22:03:381326 EXPECT_FALSE(
1327 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161328 // There is no need to set up an alternate protocol job, because
1329 // no attempt will be made to speak to the proxy over TCP.
1330
rch9ae5b3b2016-02-11 00:36:291331 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161332 CreateSession();
1333
bnc62a44f022015-04-02 15:59:411334 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381335 EXPECT_TRUE(
1336 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161337}
1338
bnc313ba9c2015-06-11 15:42:311339// Regression test for https://crbug.com/492458. Test that for an HTTP
1340// connection through a QUIC proxy, the certificate exhibited by the proxy is
1341// checked against the proxy hostname, not the origin hostname.
1342TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291343 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311344 const std::string proxy_host = "www.example.org";
1345
mmenke6ddfbea2017-05-31 21:48:411346 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591347 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491348 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311349
alyssar2adf3ac2016-05-03 17:12:581350 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311351 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521352 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361353 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431354 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1355 mock_quic_data.AddWrite(
1356 SYNCHRONOUS,
1357 ConstructClientRequestHeadersPacket(
1358 2, GetNthClientInitiatedStreamId(0), true, true,
1359 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
1360 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1361 1, GetNthClientInitiatedStreamId(0), false,
1362 false, GetResponseHeaders("200 OK")));
1363 mock_quic_data.AddRead(
1364 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1365 false, true, 0, "hello!"));
1366 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501367 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591368 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311369 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1370
1371 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291372 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311373 ASSERT_TRUE(cert.get());
1374 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241375 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1376 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311377 ProofVerifyDetailsChromium verify_details;
1378 verify_details.cert_verify_result.verified_cert = cert;
1379 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561380 ProofVerifyDetailsChromium verify_details2;
1381 verify_details2.cert_verify_result.verified_cert = cert;
1382 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311383
1384 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091385 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321386 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271387 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311388 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1389}
1390
rchbe69cb902016-02-11 01:10:481391TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341392 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481393 HostPortPair origin("www.example.org", 443);
1394 HostPortPair alternative("mail.example.org", 443);
1395
1396 base::FilePath certs_dir = GetTestCertsDirectory();
1397 scoped_refptr<X509Certificate> cert(
1398 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1399 ASSERT_TRUE(cert.get());
1400 // TODO(rch): the connection should be "to" the origin, so if the cert is
1401 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241402 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1403 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481404 ProofVerifyDetailsChromium verify_details;
1405 verify_details.cert_verify_result.verified_cert = cert;
1406 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1407
alyssar2adf3ac2016-05-03 17:12:581408 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481409 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521410 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361411 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431412 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1413 mock_quic_data.AddWrite(
1414 SYNCHRONOUS,
1415 ConstructClientRequestHeadersPacket(
1416 2, GetNthClientInitiatedStreamId(0), true, true,
1417 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1418 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1419 1, GetNthClientInitiatedStreamId(0), false,
1420 false, GetResponseHeaders("200 OK")));
1421 mock_quic_data.AddRead(
1422 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1423 false, true, 0, "hello!"));
1424 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481425 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1426 mock_quic_data.AddRead(ASYNC, 0);
1427 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1428
1429 request_.url = GURL("https://" + origin.host());
1430 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271431 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091432 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321433 CreateSession();
rchbe69cb902016-02-11 01:10:481434
1435 SendRequestAndExpectQuicResponse("hello!");
1436}
1437
zhongyief3f4ce52017-07-05 23:53:281438TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521439 quic::QuicTransportVersion unsupported_version =
1440 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281441 // Add support for another QUIC version besides |version_|. Also find a
1442 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521443 for (const quic::QuicTransportVersion& version :
1444 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281445 if (version == version_)
1446 continue;
1447 if (supported_versions_.size() != 2) {
1448 supported_versions_.push_back(version);
1449 continue;
1450 }
1451 unsupported_version = version;
1452 break;
1453 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521454 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281455
1456 // Set up alternative service to use QUIC with a version that is not
1457 // supported.
1458 url::SchemeHostPort server(request_.url);
1459 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1460 443);
1461 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1462 http_server_properties_.SetQuicAlternativeService(
1463 server, alternative_service, expiration, {unsupported_version});
1464
1465 AlternativeServiceInfoVector alt_svc_info_vector =
1466 http_server_properties_.GetAlternativeServiceInfos(server);
1467 EXPECT_EQ(1u, alt_svc_info_vector.size());
1468 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1469 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1470 EXPECT_EQ(unsupported_version,
1471 alt_svc_info_vector[0].advertised_versions()[0]);
1472
1473 // First request should still be sent via TCP as the QUIC version advertised
1474 // in the stored AlternativeService is not supported by the client. However,
1475 // the response from the server will advertise new Alt-Svc with supported
1476 // versions.
1477 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521478 GenerateQuicVersionsListForAltSvcHeader(
1479 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281480 std::string altsvc_header =
1481 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1482 advertised_versions_list_str.c_str());
1483 MockRead http_reads[] = {
1484 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1485 MockRead("hello world"),
1486 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1487 MockRead(ASYNC, OK)};
1488
Ryan Sleevib8d7ea02018-05-07 20:01:011489 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281490 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081491 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281492 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1493
1494 // Second request should be sent via QUIC as a new list of verions supported
1495 // by the client has been advertised by the server.
1496 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521497 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281498 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431499 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1500 mock_quic_data.AddWrite(
1501 SYNCHRONOUS,
1502 ConstructClientRequestHeadersPacket(
1503 2, GetNthClientInitiatedStreamId(0), true, true,
1504 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1505 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1506 1, GetNthClientInitiatedStreamId(0), false,
1507 false, GetResponseHeaders("200 OK")));
1508 mock_quic_data.AddRead(
1509 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1510 false, true, 0, "hello!"));
1511 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281512 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1513 mock_quic_data.AddRead(ASYNC, 0); // EOF
1514
1515 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1516
1517 AddHangingNonAlternateProtocolSocketData();
1518
1519 CreateSession(supported_versions_);
1520
1521 SendRequestAndExpectHttpResponse("hello world");
1522 SendRequestAndExpectQuicResponse("hello!");
1523
1524 // Check alternative service list is updated with new versions.
1525 alt_svc_info_vector =
1526 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1527 EXPECT_EQ(1u, alt_svc_info_vector.size());
1528 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1529 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1530 // Advertised versions will be lised in a sorted order.
1531 std::sort(supported_versions_.begin(), supported_versions_.end());
1532 EXPECT_EQ(supported_versions_[0],
1533 alt_svc_info_vector[0].advertised_versions()[0]);
1534 EXPECT_EQ(supported_versions_[1],
1535 alt_svc_info_vector[0].advertised_versions()[1]);
1536}
1537
bncaccd4962017-04-06 21:00:261538// Regression test for https://crbug.com/546991.
1539// The server might not be able to serve a request on an alternative connection,
1540// and might send a 421 Misdirected Request response status to indicate this.
1541// HttpNetworkTransaction should reset the request and retry without using
1542// alternative services.
1543TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1544 // Set up alternative service to use QUIC.
1545 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1546 // that overrides |enable_alternative_services|.
1547 url::SchemeHostPort server(request_.url);
1548 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1549 443);
1550 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211551 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441552 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261553
davidbena4449722017-05-05 23:30:531554 // First try: The alternative job uses QUIC and reports an HTTP 421
1555 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1556 // paused at Connect(), so it will never exit the socket pool. This ensures
1557 // that the alternate job always wins the race and keeps whether the
1558 // |http_data| exits the socket pool before the main job is aborted
1559 // deterministic. The first main job gets aborted without the socket pool ever
1560 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261561 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521562 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361563 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431564 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1565 mock_quic_data.AddWrite(
1566 SYNCHRONOUS,
1567 ConstructClientRequestHeadersPacket(
1568 2, GetNthClientInitiatedStreamId(0), true, true,
1569 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
1570 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1571 1, GetNthClientInitiatedStreamId(0), false,
1572 true, GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261573 mock_quic_data.AddRead(ASYNC, OK);
1574 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1575
davidbena4449722017-05-05 23:30:531576 // Second try: The main job uses TCP, and there is no alternate job. Once the
1577 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1578 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261579 // Note that if there was an alternative QUIC Job created for the second try,
1580 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1581 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531582 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1583 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1584 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1585 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1586 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1587 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011588 reads, writes);
bncaccd4962017-04-06 21:00:261589 socket_factory_.AddSocketDataProvider(&http_data);
1590 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1591
bncaccd4962017-04-06 21:00:261592 CreateSession();
1593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531594
1595 // Run until |mock_quic_data| has failed and |http_data| has paused.
1596 TestCompletionCallback callback;
1597 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1598 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1599 base::RunLoop().RunUntilIdle();
1600
1601 // |mock_quic_data| must have run to completion.
1602 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1603 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1604
1605 // Now that the QUIC data has been consumed, unblock |http_data|.
1606 http_data.socket()->OnConnectComplete(MockConnect());
1607
1608 // The retry logic must hide the 421 status. The transaction succeeds on
1609 // |http_data|.
1610 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261611 CheckWasHttpResponse(&trans);
1612 CheckResponsePort(&trans, 443);
1613 CheckResponseData(&trans, "hello!");
1614}
1615
[email protected]1e960032013-12-20 19:00:201616TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411617 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571618 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301619
tbansalfdf5665b2015-09-21 22:46:401620 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521621 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361622 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431623 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401624 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401625 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371626 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361627 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431628 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301629 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401630 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431631 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401632
1633 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1634 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301635
1636 CreateSession();
1637
tbansal0f56a39a2016-04-07 22:03:381638 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401639 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401641 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161642 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1644 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381645 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531646
1647 NetErrorDetails details;
1648 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521649 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401650 }
[email protected]cebe3282013-05-22 23:49:301651}
1652
tbansalc8a94ea2015-11-02 23:58:511653TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1654 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411655 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571656 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511657
1658 MockRead http_reads[] = {
1659 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1660 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1661 MockRead(ASYNC, OK)};
1662
Ryan Sleevib8d7ea02018-05-07 20:01:011663 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511664 socket_factory_.AddSocketDataProvider(&data);
1665 SSLSocketDataProvider ssl(ASYNC, OK);
1666 socket_factory_.AddSSLSocketDataProvider(&ssl);
1667
1668 CreateSession();
1669
1670 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381671 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511672}
1673
bncc958faa2015-07-31 18:14:521674TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521675 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561676 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1677 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521678 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1679 MockRead(ASYNC, OK)};
1680
Ryan Sleevib8d7ea02018-05-07 20:01:011681 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521682 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081683 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561684 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521685
1686 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521687 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361688 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431689 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1690 mock_quic_data.AddWrite(
1691 SYNCHRONOUS,
1692 ConstructClientRequestHeadersPacket(
1693 2, GetNthClientInitiatedStreamId(0), true, true,
1694 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1695 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1696 1, GetNthClientInitiatedStreamId(0), false,
1697 false, GetResponseHeaders("200 OK")));
1698 mock_quic_data.AddRead(
1699 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1700 false, true, 0, "hello!"));
1701 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521702 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591703 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521704
1705 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1706
rtennetib8e80fb2016-05-16 00:12:091707 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321708 CreateSession();
bncc958faa2015-07-31 18:14:521709
1710 SendRequestAndExpectHttpResponse("hello world");
1711 SendRequestAndExpectQuicResponse("hello!");
1712}
1713
zhongyia00ca012017-07-06 23:36:391714TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1715 // Both server advertises and client supports two QUIC versions.
1716 // Only |version_| is advertised and supported.
1717 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1718 // PacketMakers are using |version_|.
1719
1720 // Add support for another QUIC version besides |version_| on the client side.
1721 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521722 quic::QuicTransportVersion advertised_version_2 =
1723 quic::QUIC_VERSION_UNSUPPORTED;
1724 for (const quic::QuicTransportVersion& version :
1725 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391726 if (version == version_)
1727 continue;
1728 if (supported_versions_.size() != 2) {
1729 supported_versions_.push_back(version);
1730 continue;
1731 }
1732 advertised_version_2 = version;
1733 break;
1734 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521735 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391736
1737 std::string QuicAltSvcWithVersionHeader =
1738 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1739 advertised_version_2, version_);
1740
1741 MockRead http_reads[] = {
1742 MockRead("HTTP/1.1 200 OK\r\n"),
1743 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1744 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1745 MockRead(ASYNC, OK)};
1746
Ryan Sleevib8d7ea02018-05-07 20:01:011747 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391748 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081749 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391750 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1751
1752 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521753 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391754 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431755 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1756 mock_quic_data.AddWrite(
1757 SYNCHRONOUS,
1758 ConstructClientRequestHeadersPacket(
1759 2, GetNthClientInitiatedStreamId(0), true, true,
1760 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1761 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1762 1, GetNthClientInitiatedStreamId(0), false,
1763 false, GetResponseHeaders("200 OK")));
1764 mock_quic_data.AddRead(
1765 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1766 false, true, 0, "hello!"));
1767 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391768 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1769 mock_quic_data.AddRead(ASYNC, 0); // EOF
1770
1771 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1772
1773 AddHangingNonAlternateProtocolSocketData();
1774 CreateSession(supported_versions_);
1775
1776 SendRequestAndExpectHttpResponse("hello world");
1777 SendRequestAndExpectQuicResponse("hello!");
1778}
1779
1780TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1781 // Client and server mutually support more than one QUIC_VERSION.
1782 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1783 // which is verified as the PacketMakers are using |version_|.
1784
Ryan Hamilton8d9ee76e2018-05-29 23:52:521785 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1786 for (const quic::QuicTransportVersion& version :
1787 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391788 if (version == version_)
1789 continue;
1790 common_version_2 = version;
1791 break;
1792 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521793 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391794
1795 supported_versions_.push_back(
1796 common_version_2); // Supported but unpreferred.
1797
1798 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1799 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1800
1801 MockRead http_reads[] = {
1802 MockRead("HTTP/1.1 200 OK\r\n"),
1803 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1804 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1805 MockRead(ASYNC, OK)};
1806
Ryan Sleevib8d7ea02018-05-07 20:01:011807 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391808 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081809 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391810 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1811
1812 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521813 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391814 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431815 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1816 mock_quic_data.AddWrite(
1817 SYNCHRONOUS,
1818 ConstructClientRequestHeadersPacket(
1819 2, GetNthClientInitiatedStreamId(0), true, true,
1820 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1821 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1822 1, GetNthClientInitiatedStreamId(0), false,
1823 false, GetResponseHeaders("200 OK")));
1824 mock_quic_data.AddRead(
1825 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1826 false, true, 0, "hello!"));
1827 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391828 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1829 mock_quic_data.AddRead(ASYNC, 0); // EOF
1830
1831 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1832
1833 AddHangingNonAlternateProtocolSocketData();
1834 CreateSession(supported_versions_);
1835
1836 SendRequestAndExpectHttpResponse("hello world");
1837 SendRequestAndExpectQuicResponse("hello!");
1838}
1839
rchf47265dc2016-03-21 21:33:121840TEST_P(QuicNetworkTransactionTest,
1841 UseAlternativeServiceWithProbabilityForQuic) {
1842 MockRead http_reads[] = {
1843 MockRead("HTTP/1.1 200 OK\r\n"),
1844 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1845 MockRead("hello world"),
1846 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1847 MockRead(ASYNC, OK)};
1848
Ryan Sleevib8d7ea02018-05-07 20:01:011849 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121850 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081851 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121852 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1853
1854 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521855 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361856 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431857 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1858 mock_quic_data.AddWrite(
1859 SYNCHRONOUS,
1860 ConstructClientRequestHeadersPacket(
1861 2, GetNthClientInitiatedStreamId(0), true, true,
1862 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1863 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1864 1, GetNthClientInitiatedStreamId(0), false,
1865 false, GetResponseHeaders("200 OK")));
1866 mock_quic_data.AddRead(
1867 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1868 false, true, 0, "hello!"));
1869 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121870 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
rtennetib8e80fb2016-05-16 00:12:091875 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121876 CreateSession();
1877
1878 SendRequestAndExpectHttpResponse("hello world");
1879 SendRequestAndExpectQuicResponse("hello!");
1880}
1881
zhongyi3d4a55e72016-04-22 20:36:461882TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1883 MockRead http_reads[] = {
1884 MockRead("HTTP/1.1 200 OK\r\n"),
1885 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1886 MockRead("hello world"),
1887 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1888 MockRead(ASYNC, OK)};
1889
Ryan Sleevib8d7ea02018-05-07 20:01:011890 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461891 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081892 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461893 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1894
1895 CreateSession();
bncb26024382016-06-29 02:39:451896 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461897 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:451898 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:461899 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401900 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461901 session_->http_server_properties();
1902 url::SchemeHostPort http_server("http", "mail.example.org", 443);
1903 url::SchemeHostPort https_server("https", "mail.example.org", 443);
1904 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:461905 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:341906 2u,
1907 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:451908 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:341909 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:461910}
1911
1912TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
1913 MockRead http_reads[] = {
1914 MockRead("HTTP/1.1 200 OK\r\n"),
1915 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1916 MockRead("hello world"),
1917 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1918 MockRead(ASYNC, OK)};
1919
Ryan Sleevib8d7ea02018-05-07 20:01:011920 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:081921 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461922
1923 socket_factory_.AddSocketDataProvider(&http_data);
1924 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1925 socket_factory_.AddSocketDataProvider(&http_data);
1926 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1927
1928 CreateSession();
1929
1930 // Send https request and set alternative services if response header
1931 // advertises alternative service for mail.example.org.
1932 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401933 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461934 session_->http_server_properties();
1935
1936 const url::SchemeHostPort https_server(request_.url);
1937 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:341938 EXPECT_EQ(
1939 2u,
1940 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:461941
1942 // Send http request to the same origin but with diffrent scheme, should not
1943 // use QUIC.
1944 request_.url = GURL("http://mail.example.org:443");
1945 SendRequestAndExpectHttpResponse("hello world");
1946}
1947
zhongyie537a002017-06-27 16:48:211948TEST_P(QuicNetworkTransactionTest,
1949 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:441950 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521951 for (const quic::QuicTransportVersion& version :
1952 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:441953 if (version == version_)
1954 continue;
1955 supported_versions_.push_back(version);
1956 break;
1957 }
1958
zhongyie537a002017-06-27 16:48:211959 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521960 GenerateQuicVersionsListForAltSvcHeader(
1961 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:211962 std::string altsvc_header =
1963 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1964 advertised_versions_list_str.c_str());
1965 MockRead http_reads[] = {
1966 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1967 MockRead("hello world"),
1968 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1969 MockRead(ASYNC, OK)};
1970
Ryan Sleevib8d7ea02018-05-07 20:01:011971 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:211972 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081973 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:211974 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1975
1976 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521977 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:211978 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431979 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1980 mock_quic_data.AddWrite(
1981 SYNCHRONOUS,
1982 ConstructClientRequestHeadersPacket(
1983 2, GetNthClientInitiatedStreamId(0), true, true,
1984 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1985 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1986 1, GetNthClientInitiatedStreamId(0), false,
1987 false, GetResponseHeaders("200 OK")));
1988 mock_quic_data.AddRead(
1989 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1990 false, true, 0, "hello!"));
1991 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:211992 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1993 mock_quic_data.AddRead(ASYNC, 0); // EOF
1994
1995 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1996
1997 AddHangingNonAlternateProtocolSocketData();
1998
zhongyi86838d52017-06-30 01:19:441999 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212000
2001 SendRequestAndExpectHttpResponse("hello world");
2002 SendRequestAndExpectQuicResponse("hello!");
2003
2004 // Check alternative service is set with only mutually supported versions.
2005 const url::SchemeHostPort https_server(request_.url);
2006 const AlternativeServiceInfoVector alt_svc_info_vector =
2007 session_->http_server_properties()->GetAlternativeServiceInfos(
2008 https_server);
2009 EXPECT_EQ(1u, alt_svc_info_vector.size());
2010 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2011 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2012 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442013 std::sort(supported_versions_.begin(), supported_versions_.end());
2014 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212015 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442016 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212017 alt_svc_info_vector[0].advertised_versions()[1]);
2018}
2019
danzh3134c2562016-08-12 14:07:522020TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442021 std::string altsvc_header =
2022 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072023 MockRead http_reads[] = {
2024 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2025 MockRead("hello world"),
2026 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2027 MockRead(ASYNC, OK)};
2028
Ryan Sleevib8d7ea02018-05-07 20:01:012029 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072030 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082031 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072032 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2033
2034 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522035 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362036 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432037 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2038 mock_quic_data.AddWrite(
2039 SYNCHRONOUS,
2040 ConstructClientRequestHeadersPacket(
2041 2, GetNthClientInitiatedStreamId(0), true, true,
2042 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2043 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2044 1, GetNthClientInitiatedStreamId(0), false,
2045 false, GetResponseHeaders("200 OK")));
2046 mock_quic_data.AddRead(
2047 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
2048 false, true, 0, "hello!"));
2049 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072050 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592051 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072052
2053 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2054
rtennetib8e80fb2016-05-16 00:12:092055 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322056 CreateSession();
bnc8be55ebb2015-10-30 14:12:072057
2058 SendRequestAndExpectHttpResponse("hello world");
2059 SendRequestAndExpectQuicResponse("hello!");
2060}
2061
zhongyi6b5a3892016-03-12 04:46:202062TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092063 if (version_ == quic::QUIC_VERSION_99) {
2064 // Not available under version 99
2065 return;
2066 }
zhongyi6b5a3892016-03-12 04:46:202067 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522068 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362069 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432070 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2071 mock_quic_data.AddWrite(
2072 SYNCHRONOUS,
2073 ConstructClientRequestHeadersPacket(
2074 2, GetNthClientInitiatedStreamId(0), true, true,
2075 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2076 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2077 1, GetNthClientInitiatedStreamId(0), false,
2078 false, GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202079 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522080 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432081 mock_quic_data.AddRead(SYNCHRONOUS,
2082 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522083 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432084 "connection migration with port change only"));
2085 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
2086 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
2087 3, GetNthClientInitiatedStreamId(0),
2088 false, true, 0, "hello!"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522089 mock_quic_data.AddWrite(
2090 SYNCHRONOUS,
2091 ConstructClientAckAndRstPacket(4, GetNthClientInitiatedStreamId(0),
2092 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202093 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2094 mock_quic_data.AddRead(ASYNC, 0); // EOF
2095
2096 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2097
2098 // The non-alternate protocol job needs to hang in order to guarantee that
2099 // the alternate-protocol job will "win".
2100 AddHangingNonAlternateProtocolSocketData();
2101
2102 // In order for a new QUIC session to be established via alternate-protocol
2103 // without racing an HTTP connection, we need the host resolution to happen
2104 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2105 // connection to the the server, in this test we require confirmation
2106 // before encrypting so the HTTP job will still start.
2107 host_resolver_.set_synchronous_mode(true);
2108 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2109 "");
2110 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2111 AddressList address;
maksim.sisov31452af2016-07-27 06:38:102112 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582113 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2114 CompletionOnceCallback(), &request,
2115 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412116 EXPECT_THAT(rv, IsOk());
zhongyi6b5a3892016-03-12 04:46:202117
2118 CreateSession();
2119 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272120 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202121
bnc691fda62016-08-12 00:43:162122 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202123 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412124 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012125 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202126
2127 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522128 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012129 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202130
2131 // Check whether this transaction is correctly marked as received a go-away
2132 // because of migrating port.
2133 NetErrorDetails details;
2134 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162135 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202136 EXPECT_TRUE(details.quic_port_migration_detected);
2137}
2138
rch9ecde09b2017-04-08 00:18:232139// Verify that if a QUIC connection times out, the QuicHttpStream will
2140// return QUIC_PROTOCOL_ERROR.
2141TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482142 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412143 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232144
2145 // The request will initially go out over QUIC.
2146 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522147 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132148 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232149 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2150
2151 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522152 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2153 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432154 quic_data.AddWrite(SYNCHRONOUS,
2155 client_maker_.MakeRequestHeadersPacketAndSaveData(
2156 1, GetNthClientInitiatedStreamId(0), true, true,
2157 priority, GetRequestHeaders("GET", "https", "/"), 0,
2158 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232159
2160 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522161 quic::QuicStreamOffset settings_offset = header_stream_offset;
2162 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432163 quic_data.AddWrite(SYNCHRONOUS,
2164 client_maker_.MakeInitialSettingsPacketAndSaveData(
2165 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232166 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522167 quic_data.AddWrite(
2168 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
2169 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232170 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:432171 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522172 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432173 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232174 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522175 quic_data.AddWrite(
2176 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
2177 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432178 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522179 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432180 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232181 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:522182 quic_data.AddWrite(
2183 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
2184 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432185 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522186 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432187 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232188 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522189 quic_data.AddWrite(
2190 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
2191 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432192 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522193 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432194 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232195
Zhongyi Shi32f2fd02018-04-16 18:23:432196 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522197 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432198 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222199
rch9ecde09b2017-04-08 00:18:232200 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2201 quic_data.AddRead(ASYNC, OK);
2202 quic_data.AddSocketDataToFactory(&socket_factory_);
2203
2204 // In order for a new QUIC session to be established via alternate-protocol
2205 // without racing an HTTP connection, we need the host resolution to happen
2206 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2207 // connection to the the server, in this test we require confirmation
2208 // before encrypting so the HTTP job will still start.
2209 host_resolver_.set_synchronous_mode(true);
2210 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2211 "");
2212 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2213 AddressList address;
2214 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582215 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2216 CompletionOnceCallback(), &request,
2217 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412218 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232219
2220 CreateSession();
2221 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552222 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232223 QuicStreamFactoryPeer::SetAlarmFactory(
2224 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192225 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552226 &clock_));
rch9ecde09b2017-04-08 00:18:232227
Ryan Hamilton9835e662018-08-02 05:36:272228 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232229
2230 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2231 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412232 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2234
2235 // Pump the message loop to get the request started.
2236 base::RunLoop().RunUntilIdle();
2237 // Explicitly confirm the handshake.
2238 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522239 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232240
2241 // Run the QUIC session to completion.
2242 quic_task_runner_->RunUntilIdle();
2243
2244 ExpectQuicAlternateProtocolMapping();
2245 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2246 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2247}
2248
2249// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2250// return QUIC_PROTOCOL_ERROR.
2251TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482252 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522253 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232254
2255 // The request will initially go out over QUIC.
2256 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522257 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132258 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232259 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2260
2261 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522262 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2263 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432264 quic_data.AddWrite(SYNCHRONOUS,
2265 client_maker_.MakeRequestHeadersPacketAndSaveData(
2266 1, GetNthClientInitiatedStreamId(0), true, true,
2267 priority, GetRequestHeaders("GET", "https", "/"), 0,
2268 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232269
2270 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522271 quic::QuicStreamOffset settings_offset = header_stream_offset;
2272 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432273 quic_data.AddWrite(SYNCHRONOUS,
2274 client_maker_.MakeInitialSettingsPacketAndSaveData(
2275 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232276 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522277 quic_data.AddWrite(
2278 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
2279 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232280 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:432281 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522282 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432283 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232284 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522285 quic_data.AddWrite(
2286 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
2287 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432288 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522289 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432290 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232291 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:522292 quic_data.AddWrite(
2293 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
2294 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432295 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522296 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432297 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232298 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522299 quic_data.AddWrite(
2300 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
2301 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432302 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522303 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432304 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232305 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522306 quic_data.AddWrite(
2307 SYNCHRONOUS, client_maker_.MakeDataPacket(11, quic::kHeadersStreamId,
2308 true, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432309 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522310 12, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432311 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232312 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432313 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522314 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432315 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232316
2317 quic_data.AddRead(ASYNC, OK);
2318 quic_data.AddSocketDataToFactory(&socket_factory_);
2319
2320 // In order for a new QUIC session to be established via alternate-protocol
2321 // without racing an HTTP connection, we need the host resolution to happen
2322 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2323 // connection to the the server, in this test we require confirmation
2324 // before encrypting so the HTTP job will still start.
2325 host_resolver_.set_synchronous_mode(true);
2326 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2327 "");
2328 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2329 AddressList address;
2330 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582331 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2332 CompletionOnceCallback(), &request,
2333 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412334 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232335
2336 CreateSession();
2337 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552338 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232339 QuicStreamFactoryPeer::SetAlarmFactory(
2340 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192341 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552342 &clock_));
rch9ecde09b2017-04-08 00:18:232343
Ryan Hamilton9835e662018-08-02 05:36:272344 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232345
2346 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2347 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412348 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2350
2351 // Pump the message loop to get the request started.
2352 base::RunLoop().RunUntilIdle();
2353 // Explicitly confirm the handshake.
2354 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522355 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232356
2357 // Run the QUIC session to completion.
2358 quic_task_runner_->RunUntilIdle();
2359
2360 ExpectQuicAlternateProtocolMapping();
2361 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2362 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2363}
2364
2365// Verify that if a QUIC connection RTOs, while there are no active streams
2366// QUIC will not be marked as broken.
2367TEST_P(QuicNetworkTransactionTest,
2368 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522369 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232370
2371 // The request will initially go out over QUIC.
2372 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522373 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132374 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232375 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2376
2377 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522378 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2379 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432380 quic_data.AddWrite(SYNCHRONOUS,
2381 client_maker_.MakeRequestHeadersPacketAndSaveData(
2382 1, GetNthClientInitiatedStreamId(0), true, true,
2383 priority, GetRequestHeaders("GET", "https", "/"), 0,
2384 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232385
2386 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522387 quic::QuicStreamOffset settings_offset = header_stream_offset;
2388 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432389 quic_data.AddWrite(SYNCHRONOUS,
2390 client_maker_.MakeInitialSettingsPacketAndSaveData(
2391 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232392
Zhongyi Shi32f2fd02018-04-16 18:23:432393 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
2394 3, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522395 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232396 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522397 quic_data.AddWrite(
2398 SYNCHRONOUS, client_maker_.MakeDataPacket(4, quic::kHeadersStreamId, true,
2399 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232400 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:432401 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522402 5, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432403 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232404 // RTO 1
Zhongyi Shi32f2fd02018-04-16 18:23:432405 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
2406 6, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522407 quic::QUIC_STREAM_CANCELLED));
2408 quic_data.AddWrite(
2409 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
2410 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232411 // RTO 2
Zhongyi Shi32f2fd02018-04-16 18:23:432412 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522413 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432414 settings_offset, settings_data));
2415 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
2416 9, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522417 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232418 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522419 quic_data.AddWrite(
2420 SYNCHRONOUS, client_maker_.MakeDataPacket(10, quic::kHeadersStreamId,
2421 true, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432422 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522423 11, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432424 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232425 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432426 quic_data.AddWrite(
2427 SYNCHRONOUS,
2428 client_maker_.MakeRstPacket(12, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522429 quic::QUIC_STREAM_CANCELLED));
2430 quic_data.AddWrite(
2431 SYNCHRONOUS, client_maker_.MakeDataPacket(13, quic::kHeadersStreamId,
2432 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232433 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432434 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522435 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432436 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232437
2438 quic_data.AddRead(ASYNC, OK);
2439 quic_data.AddSocketDataToFactory(&socket_factory_);
2440
2441 // In order for a new QUIC session to be established via alternate-protocol
2442 // without racing an HTTP connection, we need the host resolution to happen
2443 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2444 // connection to the the server, in this test we require confirmation
2445 // before encrypting so the HTTP job will still start.
2446 host_resolver_.set_synchronous_mode(true);
2447 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2448 "");
2449 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2450 AddressList address;
2451 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582452 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2453 CompletionOnceCallback(), &request,
2454 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412455 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232456
2457 CreateSession();
2458 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552459 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232460 QuicStreamFactoryPeer::SetAlarmFactory(
2461 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192462 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552463 &clock_));
rch9ecde09b2017-04-08 00:18:232464
Ryan Hamilton9835e662018-08-02 05:36:272465 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232466
Jeremy Roman0579ed62017-08-29 15:56:192467 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232468 session_.get());
2469 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412470 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2472
2473 // Pump the message loop to get the request started.
2474 base::RunLoop().RunUntilIdle();
2475 // Explicitly confirm the handshake.
2476 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522477 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232478
2479 // Now cancel the request.
2480 trans.reset();
2481
2482 // Run the QUIC session to completion.
2483 quic_task_runner_->RunUntilIdle();
2484
2485 ExpectQuicAlternateProtocolMapping();
2486
2487 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2488}
2489
rch2f2991c2017-04-13 19:28:172490// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2491// the request fails with QUIC_PROTOCOL_ERROR.
2492TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482493 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172494 // The request will initially go out over QUIC.
2495 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522496 quic::QuicStreamOffset header_stream_offset = 0;
2497 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2498 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432499 quic_data.AddWrite(
2500 SYNCHRONOUS,
2501 ConstructClientRequestHeadersPacket(
2502 1, GetNthClientInitiatedStreamId(0), true, true,
2503 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522504 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432505 quic_data.AddWrite(SYNCHRONOUS,
2506 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:172507 // Peer sending data from an non-existing stream causes this end to raise
2508 // error and close connection.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522509 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
2510 1, false, 99, quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:172511 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:432512 quic_data.AddWrite(SYNCHRONOUS,
2513 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522514 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
2515 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:172516 quic_data.AddSocketDataToFactory(&socket_factory_);
2517
2518 // In order for a new QUIC session to be established via alternate-protocol
2519 // without racing an HTTP connection, we need the host resolution to happen
2520 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2521 // connection to the the server, in this test we require confirmation
2522 // before encrypting so the HTTP job will still start.
2523 host_resolver_.set_synchronous_mode(true);
2524 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2525 "");
2526 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2527 AddressList address;
2528 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582529 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2530 CompletionOnceCallback(), &request,
2531 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412532 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:172533
2534 CreateSession();
2535
Ryan Hamilton9835e662018-08-02 05:36:272536 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172537
2538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2539 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412540 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:172541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2542
2543 // Pump the message loop to get the request started.
2544 base::RunLoop().RunUntilIdle();
2545 // Explicitly confirm the handshake.
2546 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522547 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:172548
2549 ASSERT_FALSE(quic_data.AllReadDataConsumed());
2550
2551 // Run the QUIC session to completion.
2552 base::RunLoop().RunUntilIdle();
2553 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2554 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2555
2556 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2557 ExpectQuicAlternateProtocolMapping();
2558 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2559}
2560
rch9ecde09b2017-04-08 00:18:232561// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
2562// connection times out, then QUIC will be marked as broken and the request
2563// retried over TCP.
2564TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:412565 session_params_.mark_quic_broken_when_network_blackholes = true;
2566 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232567
2568 // The request will initially go out over QUIC.
2569 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522570 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132571 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232572 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2573
2574 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522575 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2576 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432577 quic_data.AddWrite(SYNCHRONOUS,
2578 client_maker_.MakeRequestHeadersPacketAndSaveData(
2579 1, GetNthClientInitiatedStreamId(0), true, true,
2580 priority, GetRequestHeaders("GET", "https", "/"), 0,
2581 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232582
2583 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522584 quic::QuicStreamOffset settings_offset = header_stream_offset;
2585 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432586 quic_data.AddWrite(SYNCHRONOUS,
2587 client_maker_.MakeInitialSettingsPacketAndSaveData(
2588 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232589 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522590 quic_data.AddWrite(
2591 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
2592 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232593 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:432594 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522595 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432596 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232597 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522598 quic_data.AddWrite(
2599 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
2600 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432601 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522602 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432603 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232604 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:522605 quic_data.AddWrite(
2606 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
2607 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432608 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522609 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432610 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232611 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522612 quic_data.AddWrite(
2613 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
2614 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432615 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522616 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432617 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232618
Zhongyi Shi32f2fd02018-04-16 18:23:432619 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522620 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432621 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222622
rch9ecde09b2017-04-08 00:18:232623 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2624 quic_data.AddRead(ASYNC, OK);
2625 quic_data.AddSocketDataToFactory(&socket_factory_);
2626
2627 // After that fails, it will be resent via TCP.
2628 MockWrite http_writes[] = {
2629 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2630 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2631 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2632
2633 MockRead http_reads[] = {
2634 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2635 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2636 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:012637 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:232638 socket_factory_.AddSocketDataProvider(&http_data);
2639 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2640
2641 // In order for a new QUIC session to be established via alternate-protocol
2642 // without racing an HTTP connection, we need the host resolution to happen
2643 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2644 // connection to the the server, in this test we require confirmation
2645 // before encrypting so the HTTP job will still start.
2646 host_resolver_.set_synchronous_mode(true);
2647 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2648 "");
2649 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2650 AddressList address;
2651 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582652 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2653 CompletionOnceCallback(), &request,
2654 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412655 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232656
2657 CreateSession();
2658 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552659 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232660 QuicStreamFactoryPeer::SetAlarmFactory(
2661 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192662 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552663 &clock_));
rch9ecde09b2017-04-08 00:18:232664
Ryan Hamilton9835e662018-08-02 05:36:272665 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232666
2667 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2668 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412669 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2671
2672 // Pump the message loop to get the request started.
2673 base::RunLoop().RunUntilIdle();
2674 // Explicitly confirm the handshake.
2675 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522676 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232677
2678 // Run the QUIC session to completion.
2679 quic_task_runner_->RunUntilIdle();
2680 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2681
2682 // Let the transaction proceed which will result in QUIC being marked
2683 // as broken and the request falling back to TCP.
2684 EXPECT_THAT(callback.WaitForResult(), IsOk());
2685
2686 ExpectBrokenAlternateProtocolMapping();
2687 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2688 ASSERT_FALSE(http_data.AllReadDataConsumed());
2689
2690 // Read the response body over TCP.
2691 CheckResponseData(&trans, "hello world");
2692 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2693 ASSERT_TRUE(http_data.AllReadDataConsumed());
2694}
2695
rch2f2991c2017-04-13 19:28:172696// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
2697// connection times out, then QUIC will be marked as broken and the request
2698// retried over TCP.
2699TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:412700 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:172701
2702 // The request will initially go out over QUIC.
2703 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522704 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132705 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:172706 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2707
2708 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522709 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2710 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432711 quic_data.AddWrite(SYNCHRONOUS,
2712 client_maker_.MakeRequestHeadersPacketAndSaveData(
2713 1, GetNthClientInitiatedStreamId(0), true, true,
2714 priority, GetRequestHeaders("GET", "https", "/"), 0,
2715 nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:172716
2717 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522718 quic::QuicStreamOffset settings_offset = header_stream_offset;
2719 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432720 quic_data.AddWrite(SYNCHRONOUS,
2721 client_maker_.MakeInitialSettingsPacketAndSaveData(
2722 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:172723 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522724 quic_data.AddWrite(
2725 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
2726 false, 0, request_data));
rch2f2991c2017-04-13 19:28:172727 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:432728 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522729 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432730 settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:172731 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522732 quic_data.AddWrite(
2733 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
2734 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432735 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522736 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432737 settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:172738 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:522739 quic_data.AddWrite(
2740 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
2741 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432742 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522743 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432744 settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:172745 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522746 quic_data.AddWrite(
2747 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
2748 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432749 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522750 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432751 settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:172752
Zhongyi Shi32f2fd02018-04-16 18:23:432753 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522754 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432755 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222756
rch2f2991c2017-04-13 19:28:172757 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2758 quic_data.AddRead(ASYNC, OK);
2759 quic_data.AddSocketDataToFactory(&socket_factory_);
2760
2761 // After that fails, it will be resent via TCP.
2762 MockWrite http_writes[] = {
2763 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2764 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2765 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2766
2767 MockRead http_reads[] = {
2768 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2769 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2770 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:012771 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:172772 socket_factory_.AddSocketDataProvider(&http_data);
2773 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2774
2775 // In order for a new QUIC session to be established via alternate-protocol
2776 // without racing an HTTP connection, we need the host resolution to happen
2777 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2778 // connection to the the server, in this test we require confirmation
2779 // before encrypting so the HTTP job will still start.
2780 host_resolver_.set_synchronous_mode(true);
2781 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2782 "");
2783 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2784 AddressList address;
2785 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582786 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2787 CompletionOnceCallback(), &request,
2788 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412789 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:172790
2791 CreateSession();
2792 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552793 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:172794 QuicStreamFactoryPeer::SetAlarmFactory(
2795 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192796 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552797 &clock_));
rch2f2991c2017-04-13 19:28:172798
Ryan Hamilton9835e662018-08-02 05:36:272799 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172800
2801 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2802 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412803 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:172804 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2805
2806 // Pump the message loop to get the request started.
2807 base::RunLoop().RunUntilIdle();
2808 // Explicitly confirm the handshake.
2809 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522810 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:172811
2812 // Run the QUIC session to completion.
2813 quic_task_runner_->RunUntilIdle();
2814 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2815
2816 ExpectQuicAlternateProtocolMapping();
2817
2818 // Let the transaction proceed which will result in QUIC being marked
2819 // as broken and the request falling back to TCP.
2820 EXPECT_THAT(callback.WaitForResult(), IsOk());
2821
2822 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2823 ASSERT_FALSE(http_data.AllReadDataConsumed());
2824
2825 // Read the response body over TCP.
2826 CheckResponseData(&trans, "hello world");
2827 ExpectBrokenAlternateProtocolMapping();
2828 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2829 ASSERT_TRUE(http_data.AllReadDataConsumed());
2830}
2831
rch9ecde09b2017-04-08 00:18:232832// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
2833// connection times out, then QUIC will be marked as broken but the request
2834// will not be retried over TCP.
2835TEST_P(QuicNetworkTransactionTest,
2836 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:412837 session_params_.mark_quic_broken_when_network_blackholes = true;
2838 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232839
2840 // The request will initially go out over QUIC.
2841 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522842 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132843 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232844 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2845
2846 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522847 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2848 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432849 quic_data.AddWrite(SYNCHRONOUS,
2850 client_maker_.MakeRequestHeadersPacketAndSaveData(
2851 1, GetNthClientInitiatedStreamId(0), true, true,
2852 priority, GetRequestHeaders("GET", "https", "/"), 0,
2853 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232854
2855 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522856 quic::QuicStreamOffset settings_offset = header_stream_offset;
2857 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432858 quic_data.AddWrite(SYNCHRONOUS,
2859 client_maker_.MakeInitialSettingsPacketAndSaveData(
2860 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232861
Zhongyi Shi32f2fd02018-04-16 18:23:432862 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2863 1, GetNthClientInitiatedStreamId(0), false,
2864 false, GetResponseHeaders("200 OK")));
2865 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522866 quic_data.AddWrite(
2867 SYNCHRONOUS,
2868 ConstructClientAckPacket(3, 1, 1, 1,
2869 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:232870
2871 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522872 quic_data.AddWrite(
2873 SYNCHRONOUS, client_maker_.MakeDataPacket(4, quic::kHeadersStreamId,
2874 false, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232875 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:432876 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522877 5, quic::kHeadersStreamId, false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432878 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232879 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522880 quic_data.AddWrite(
2881 SYNCHRONOUS, client_maker_.MakeDataPacket(6, quic::kHeadersStreamId,
2882 false, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432883 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522884 7, quic::kHeadersStreamId, false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432885 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232886 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:522887 quic_data.AddWrite(
2888 SYNCHRONOUS, client_maker_.MakeDataPacket(8, quic::kHeadersStreamId,
2889 false, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432890 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522891 9, quic::kHeadersStreamId, false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432892 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232893 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522894 quic_data.AddWrite(
2895 SYNCHRONOUS, client_maker_.MakeDataPacket(10, quic::kHeadersStreamId,
2896 false, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432897 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522898 11, quic::kHeadersStreamId, false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432899 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232900
Zhongyi Shi32f2fd02018-04-16 18:23:432901 quic_data.AddWrite(
2902 SYNCHRONOUS,
2903 client_maker_.MakeAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522904 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
2905 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222906
rch9ecde09b2017-04-08 00:18:232907 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2908 quic_data.AddRead(ASYNC, OK);
2909 quic_data.AddSocketDataToFactory(&socket_factory_);
2910
2911 // In order for a new QUIC session to be established via alternate-protocol
2912 // without racing an HTTP connection, we need the host resolution to happen
2913 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2914 // connection to the the server, in this test we require confirmation
2915 // before encrypting so the HTTP job will still start.
2916 host_resolver_.set_synchronous_mode(true);
2917 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2918 "");
2919 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2920 AddressList address;
2921 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582922 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2923 CompletionOnceCallback(), &request,
2924 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412925 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232926
2927 CreateSession();
2928 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552929 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232930 QuicStreamFactoryPeer::SetAlarmFactory(
2931 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192932 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552933 &clock_));
rch9ecde09b2017-04-08 00:18:232934
Ryan Hamilton9835e662018-08-02 05:36:272935 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232936
2937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2938 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412939 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2941
2942 // Pump the message loop to get the request started.
2943 base::RunLoop().RunUntilIdle();
2944 // Explicitly confirm the handshake.
2945 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522946 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232947
2948 // Pump the message loop to get the request started.
2949 base::RunLoop().RunUntilIdle();
2950
2951 // Run the QUIC session to completion.
2952 quic_task_runner_->RunUntilIdle();
2953 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2954
2955 // Let the transaction proceed which will result in QUIC being marked
2956 // as broken and the request falling back to TCP.
2957 EXPECT_THAT(callback.WaitForResult(), IsOk());
2958
2959 ExpectBrokenAlternateProtocolMapping();
2960 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2961
2962 std::string response_data;
2963 ASSERT_THAT(ReadTransaction(&trans, &response_data),
2964 IsError(ERR_QUIC_PROTOCOL_ERROR));
2965}
2966
2967// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
2968// connection RTOs, then QUIC will be marked as broken and the request retried
2969// over TCP.
2970TEST_P(QuicNetworkTransactionTest,
2971 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:412972 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522973 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232974
2975 // The request will initially go out over QUIC.
2976 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522977 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132978 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232979 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2980
2981 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522982 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2983 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432984 quic_data.AddWrite(SYNCHRONOUS,
2985 client_maker_.MakeRequestHeadersPacketAndSaveData(
2986 1, GetNthClientInitiatedStreamId(0), true, true,
2987 priority, GetRequestHeaders("GET", "https", "/"), 0,
2988 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232989
2990 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522991 quic::QuicStreamOffset settings_offset = header_stream_offset;
2992 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432993 quic_data.AddWrite(SYNCHRONOUS,
2994 client_maker_.MakeInitialSettingsPacketAndSaveData(
2995 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232996 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522997 quic_data.AddWrite(
2998 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
2999 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233000 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:433001 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523002 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433003 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233004 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523005 quic_data.AddWrite(
3006 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
3007 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433008 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523009 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433010 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233011 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523012 quic_data.AddWrite(
3013 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
3014 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433015 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523016 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433017 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233018 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523019 quic_data.AddWrite(
3020 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
3021 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433022 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523023 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433024 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233025 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523026 quic_data.AddWrite(
3027 SYNCHRONOUS, client_maker_.MakeDataPacket(11, quic::kHeadersStreamId,
3028 true, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433029 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523030 12, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433031 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233032
Zhongyi Shi32f2fd02018-04-16 18:23:433033 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523034 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433035 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233036
3037 quic_data.AddRead(ASYNC, OK);
3038 quic_data.AddSocketDataToFactory(&socket_factory_);
3039
3040 // After that fails, it will be resent via TCP.
3041 MockWrite http_writes[] = {
3042 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3043 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3044 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3045
3046 MockRead http_reads[] = {
3047 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3048 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3049 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013050 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233051 socket_factory_.AddSocketDataProvider(&http_data);
3052 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3053
3054 // In order for a new QUIC session to be established via alternate-protocol
3055 // without racing an HTTP connection, we need the host resolution to happen
3056 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3057 // connection to the the server, in this test we require confirmation
3058 // before encrypting so the HTTP job will still start.
3059 host_resolver_.set_synchronous_mode(true);
3060 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3061 "");
3062 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3063 AddressList address;
3064 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583065 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3066 CompletionOnceCallback(), &request,
3067 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413068 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233069
3070 CreateSession();
3071 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553072 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233073 QuicStreamFactoryPeer::SetAlarmFactory(
3074 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193075 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553076 &clock_));
rch9ecde09b2017-04-08 00:18:233077
Ryan Hamilton9835e662018-08-02 05:36:273078 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233079
3080 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3081 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413082 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233083 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3084
3085 // Pump the message loop to get the request started.
3086 base::RunLoop().RunUntilIdle();
3087 // Explicitly confirm the handshake.
3088 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523089 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233090
3091 // Run the QUIC session to completion.
3092 quic_task_runner_->RunUntilIdle();
3093 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3094
3095 // Let the transaction proceed which will result in QUIC being marked
3096 // as broken and the request falling back to TCP.
3097 EXPECT_THAT(callback.WaitForResult(), IsOk());
3098
3099 ExpectBrokenAlternateProtocolMapping();
3100 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3101 ASSERT_FALSE(http_data.AllReadDataConsumed());
3102
3103 // Read the response body over TCP.
3104 CheckResponseData(&trans, "hello world");
3105 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3106 ASSERT_TRUE(http_data.AllReadDataConsumed());
3107}
3108
3109// Verify that if a QUIC connection RTOs, while there are no active streams
3110// QUIC will be marked as broken.
3111TEST_P(QuicNetworkTransactionTest,
3112 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413113 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523114 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233115
3116 // The request will initially go out over QUIC.
3117 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523118 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133119 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233120 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3121
3122 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523123 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3124 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433125 quic_data.AddWrite(SYNCHRONOUS,
3126 client_maker_.MakeRequestHeadersPacketAndSaveData(
3127 1, GetNthClientInitiatedStreamId(0), true, true,
3128 priority, GetRequestHeaders("GET", "https", "/"), 0,
3129 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233130
3131 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523132 quic::QuicStreamOffset settings_offset = header_stream_offset;
3133 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433134 quic_data.AddWrite(SYNCHRONOUS,
3135 client_maker_.MakeInitialSettingsPacketAndSaveData(
3136 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233137
Zhongyi Shi32f2fd02018-04-16 18:23:433138 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
3139 3, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523140 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233141 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523142 quic_data.AddWrite(
3143 SYNCHRONOUS, client_maker_.MakeDataPacket(4, quic::kHeadersStreamId, true,
3144 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233145 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:433146 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523147 5, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433148 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233149 // RTO 1
Zhongyi Shi32f2fd02018-04-16 18:23:433150 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
3151 6, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523152 quic::QUIC_STREAM_CANCELLED));
3153 quic_data.AddWrite(
3154 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
3155 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233156 // RTO 2
Zhongyi Shi32f2fd02018-04-16 18:23:433157 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523158 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433159 settings_offset, settings_data));
3160 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
3161 9, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523162 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233163 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523164 quic_data.AddWrite(
3165 SYNCHRONOUS, client_maker_.MakeDataPacket(10, quic::kHeadersStreamId,
3166 true, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433167 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523168 11, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433169 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233170 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433171 quic_data.AddWrite(
3172 SYNCHRONOUS,
3173 client_maker_.MakeRstPacket(12, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523174 quic::QUIC_STREAM_CANCELLED));
3175 quic_data.AddWrite(
3176 SYNCHRONOUS, client_maker_.MakeDataPacket(13, quic::kHeadersStreamId,
3177 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233178 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433179 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523180 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433181 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233182
3183 quic_data.AddRead(ASYNC, OK);
3184 quic_data.AddSocketDataToFactory(&socket_factory_);
3185
3186 // In order for a new QUIC session to be established via alternate-protocol
3187 // without racing an HTTP connection, we need the host resolution to happen
3188 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3189 // connection to the the server, in this test we require confirmation
3190 // before encrypting so the HTTP job will still start.
3191 host_resolver_.set_synchronous_mode(true);
3192 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3193 "");
3194 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3195 AddressList address;
3196 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583197 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3198 CompletionOnceCallback(), &request,
3199 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413200 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233201
3202 CreateSession();
3203 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553204 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233205 QuicStreamFactoryPeer::SetAlarmFactory(
3206 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193207 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553208 &clock_));
rch9ecde09b2017-04-08 00:18:233209
Ryan Hamilton9835e662018-08-02 05:36:273210 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233211
Jeremy Roman0579ed62017-08-29 15:56:193212 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233213 session_.get());
3214 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413215 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3217
3218 // Pump the message loop to get the request started.
3219 base::RunLoop().RunUntilIdle();
3220 // Explicitly confirm the handshake.
3221 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523222 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233223
3224 // Now cancel the request.
3225 trans.reset();
3226
3227 // Run the QUIC session to completion.
3228 quic_task_runner_->RunUntilIdle();
3229
3230 ExpectBrokenAlternateProtocolMapping();
3231
3232 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3233}
3234
rch2f2991c2017-04-13 19:28:173235// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3236// protocol error occurs after the handshake is confirmed, the request
3237// retried over TCP and the QUIC will be marked as broken.
3238TEST_P(QuicNetworkTransactionTest,
3239 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413240 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173241
3242 // The request will initially go out over QUIC.
3243 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523244 quic::QuicStreamOffset header_stream_offset = 0;
3245 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3246 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433247 quic_data.AddWrite(
3248 SYNCHRONOUS,
3249 ConstructClientRequestHeadersPacket(
3250 1, GetNthClientInitiatedStreamId(0), true, true,
3251 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523252 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433253 quic_data.AddWrite(SYNCHRONOUS,
3254 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173255 // Peer sending data from an non-existing stream causes this end to raise
3256 // error and close connection.
Ryan Hamilton8d9ee76e2018-05-29 23:52:523257 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
3258 1, false, 99, quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173259 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433260 quic_data.AddWrite(SYNCHRONOUS,
3261 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523262 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3263 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173264 quic_data.AddSocketDataToFactory(&socket_factory_);
3265
3266 // After that fails, it will be resent via TCP.
3267 MockWrite http_writes[] = {
3268 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3269 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3270 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3271
3272 MockRead http_reads[] = {
3273 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3274 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3275 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013276 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173277 socket_factory_.AddSocketDataProvider(&http_data);
3278 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3279
3280 // In order for a new QUIC session to be established via alternate-protocol
3281 // without racing an HTTP connection, we need the host resolution to happen
3282 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3283 // connection to the the server, in this test we require confirmation
3284 // before encrypting so the HTTP job will still start.
3285 host_resolver_.set_synchronous_mode(true);
3286 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3287 "");
3288 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3289 AddressList address;
3290 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583291 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3292 CompletionOnceCallback(), &request,
3293 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413294 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173295
3296 CreateSession();
3297
Ryan Hamilton9835e662018-08-02 05:36:273298 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173299
3300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3301 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413302 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173303 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3304
3305 // Pump the message loop to get the request started.
3306 base::RunLoop().RunUntilIdle();
3307 // Explicitly confirm the handshake.
3308 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523309 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173310
3311 // Run the QUIC session to completion.
3312 base::RunLoop().RunUntilIdle();
3313 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3314
3315 ExpectQuicAlternateProtocolMapping();
3316
3317 // Let the transaction proceed which will result in QUIC being marked
3318 // as broken and the request falling back to TCP.
3319 EXPECT_THAT(callback.WaitForResult(), IsOk());
3320
3321 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3322 ASSERT_FALSE(http_data.AllReadDataConsumed());
3323
3324 // Read the response body over TCP.
3325 CheckResponseData(&trans, "hello world");
3326 ExpectBrokenAlternateProtocolMapping();
3327 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3328 ASSERT_TRUE(http_data.AllReadDataConsumed());
3329}
3330
rch30943ee2017-06-12 21:28:443331// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3332// request is reset from, then QUIC will be marked as broken and the request
3333// retried over TCP.
3334TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443335 // The request will initially go out over QUIC.
3336 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523337 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133338 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443339 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3340
3341 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523342 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3343 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433344 quic_data.AddWrite(SYNCHRONOUS,
3345 client_maker_.MakeRequestHeadersPacketAndSaveData(
3346 1, GetNthClientInitiatedStreamId(0), true, true,
3347 priority, GetRequestHeaders("GET", "https", "/"), 0,
3348 nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443349
3350 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523351 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3352 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433353 quic_data.AddWrite(SYNCHRONOUS,
3354 client_maker_.MakeInitialSettingsPacketAndSaveData(
3355 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443356
Zhongyi Shi32f2fd02018-04-16 18:23:433357 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
3358 1, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523359 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443360
3361 quic_data.AddRead(ASYNC, OK);
3362 quic_data.AddSocketDataToFactory(&socket_factory_);
3363
3364 // After that fails, it will be resent via TCP.
3365 MockWrite http_writes[] = {
3366 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3367 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3368 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3369
3370 MockRead http_reads[] = {
3371 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3372 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3373 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013374 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443375 socket_factory_.AddSocketDataProvider(&http_data);
3376 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3377
3378 // In order for a new QUIC session to be established via alternate-protocol
3379 // without racing an HTTP connection, we need the host resolution to happen
3380 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3381 // connection to the the server, in this test we require confirmation
3382 // before encrypting so the HTTP job will still start.
3383 host_resolver_.set_synchronous_mode(true);
3384 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3385 "");
3386 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3387 AddressList address;
3388 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583389 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3390 CompletionOnceCallback(), &request,
3391 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413392 EXPECT_THAT(rv, IsOk());
rch30943ee2017-06-12 21:28:443393
3394 CreateSession();
3395
Ryan Hamilton9835e662018-08-02 05:36:273396 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443397
3398 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3399 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413400 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443401 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3402
3403 // Pump the message loop to get the request started.
3404 base::RunLoop().RunUntilIdle();
3405 // Explicitly confirm the handshake.
3406 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523407 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443408
3409 // Run the QUIC session to completion.
3410 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3411
3412 ExpectQuicAlternateProtocolMapping();
3413
3414 // Let the transaction proceed which will result in QUIC being marked
3415 // as broken and the request falling back to TCP.
3416 EXPECT_THAT(callback.WaitForResult(), IsOk());
3417
3418 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3419 ASSERT_FALSE(http_data.AllReadDataConsumed());
3420
3421 // Read the response body over TCP.
3422 CheckResponseData(&trans, "hello world");
3423 ExpectBrokenAlternateProtocolMapping();
3424 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3425 ASSERT_TRUE(http_data.AllReadDataConsumed());
3426}
3427
Ryan Hamilton6c2a2a82017-12-15 02:06:283428// Verify that when an origin has two alt-svc advertisements, one local and one
3429// remote, that when the local is broken the request will go over QUIC via
3430// the remote Alt-Svc.
3431// This is a regression test for crbug/825646.
3432TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3433 session_params_.quic_allow_remote_alt_svc = true;
3434
3435 GURL origin1 = request_.url; // mail.example.org
3436 GURL origin2("https://www.example.org/");
3437 ASSERT_NE(origin1.host(), origin2.host());
3438
3439 scoped_refptr<X509Certificate> cert(
3440 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243441 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3442 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283443
3444 ProofVerifyDetailsChromium verify_details;
3445 verify_details.cert_verify_result.verified_cert = cert;
3446 verify_details.cert_verify_result.is_issued_by_known_root = true;
3447 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3448
3449 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523450 quic::QuicStreamOffset request_header_offset(0);
3451 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283452 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433453 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3454 mock_quic_data.AddWrite(
3455 SYNCHRONOUS,
3456 ConstructClientRequestHeadersPacket(
3457 2, GetNthClientInitiatedStreamId(0), true, true,
3458 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3459 mock_quic_data.AddRead(
3460 ASYNC, ConstructServerResponseHeadersPacket(
3461 1, GetNthClientInitiatedStreamId(0), false, false,
3462 GetResponseHeaders("200 OK"), &response_header_offset));
3463 mock_quic_data.AddRead(
3464 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
3465 false, true, 0, "hello!"));
3466 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283467 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3468 mock_quic_data.AddRead(ASYNC, 0); // EOF
3469
3470 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3471 MockQuicData mock_quic_data2;
3472 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3473 AddHangingNonAlternateProtocolSocketData();
3474
3475 CreateSession();
3476
3477 // Set up alternative service for |origin1|.
3478 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3479 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3480 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3481 AlternativeServiceInfoVector alternative_services;
3482 alternative_services.push_back(
3483 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3484 local_alternative, expiration,
3485 session_->params().quic_supported_versions));
3486 alternative_services.push_back(
3487 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3488 remote_alternative, expiration,
3489 session_->params().quic_supported_versions));
3490 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
3491 alternative_services);
3492
3493 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
3494
3495 SendRequestAndExpectQuicResponse("hello!");
3496}
3497
rch30943ee2017-06-12 21:28:443498// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3499// request is reset from, then QUIC will be marked as broken and the request
3500// retried over TCP. Then, subsequent requests will go over a new QUIC
3501// connection instead of going back to the broken QUIC connection.
3502// This is a regression tests for crbug/731303.
3503TEST_P(QuicNetworkTransactionTest,
3504 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:343505 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443506
3507 GURL origin1 = request_.url;
3508 GURL origin2("https://www.example.org/");
3509 ASSERT_NE(origin1.host(), origin2.host());
3510
3511 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523512 quic::QuicStreamOffset request_header_offset(0);
3513 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:443514
3515 scoped_refptr<X509Certificate> cert(
3516 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243517 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3518 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:443519
3520 ProofVerifyDetailsChromium verify_details;
3521 verify_details.cert_verify_result.verified_cert = cert;
3522 verify_details.cert_verify_result.is_issued_by_known_root = true;
3523 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3524
3525 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433526 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:443527 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433528 mock_quic_data.AddWrite(
3529 SYNCHRONOUS,
3530 ConstructClientRequestHeadersPacket(
3531 2, GetNthClientInitiatedStreamId(0), true, true,
3532 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3533 mock_quic_data.AddRead(
3534 ASYNC, ConstructServerResponseHeadersPacket(
3535 1, GetNthClientInitiatedStreamId(0), false, false,
3536 GetResponseHeaders("200 OK"), &response_header_offset));
3537 mock_quic_data.AddRead(
3538 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
3539 false, true, 0, "hello!"));
3540 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:443541
3542 // Second request will go over the pooled QUIC connection, but will be
3543 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:053544 QuicTestPacketMaker client_maker2(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523545 version_, 0, &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:053546 client_headers_include_h2_stream_dependency_);
rch30943ee2017-06-12 21:28:443547 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523548 quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:433549 mock_quic_data.AddWrite(
3550 SYNCHRONOUS,
3551 ConstructClientRequestHeadersPacket(
3552 4, GetNthClientInitiatedStreamId(1), false, true,
3553 GetRequestHeaders("GET", "https", "/", &client_maker2),
3554 GetNthClientInitiatedStreamId(0), &request_header_offset));
3555 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
3556 3, false, GetNthClientInitiatedStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523557 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443558 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3559 mock_quic_data.AddRead(ASYNC, 0); // EOF
3560
3561 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3562
3563 // After that fails, it will be resent via TCP.
3564 MockWrite http_writes[] = {
3565 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3566 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
3567 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3568
3569 MockRead http_reads[] = {
3570 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3571 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3572 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013573 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443574 socket_factory_.AddSocketDataProvider(&http_data);
3575 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3576
Ryan Hamilton6c2a2a82017-12-15 02:06:283577 // Then the next request to the second origin will be sent over TCP.
3578 socket_factory_.AddSocketDataProvider(&http_data);
3579 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:443580
3581 CreateSession();
3582
3583 // Set up alternative service for |origin1|.
3584 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:243585 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:213586 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:243587 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:443588 supported_versions_);
rch30943ee2017-06-12 21:28:443589
3590 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:243591 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:213592 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:243593 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:443594 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:343595
rch30943ee2017-06-12 21:28:443596 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523597 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:443598 SendRequestAndExpectQuicResponse("hello!");
3599
3600 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:523601 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:443602 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
3603 request_.url = origin2;
3604 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:283605 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:243606 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:283607 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:243608 << alternative2.ToString();
rch30943ee2017-06-12 21:28:443609
3610 // The third request should use a new QUIC connection, not the broken
3611 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:283612 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:443613}
3614
bnc8be55ebb2015-10-30 14:12:073615TEST_P(QuicNetworkTransactionTest,
3616 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
3617 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:443618 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:073619 MockRead http_reads[] = {
3620 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
3621 MockRead("hello world"),
3622 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3623 MockRead(ASYNC, OK)};
3624
Ryan Sleevib8d7ea02018-05-07 20:01:013625 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:073626 socket_factory_.AddSocketDataProvider(&http_data);
3627 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3628 socket_factory_.AddSocketDataProvider(&http_data);
3629 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3630
rch3f4b8452016-02-23 16:59:323631 CreateSession();
bnc8be55ebb2015-10-30 14:12:073632
3633 SendRequestAndExpectHttpResponse("hello world");
3634 SendRequestAndExpectHttpResponse("hello world");
3635}
3636
Xida Chen9bfe0b62018-04-24 19:52:213637// When multiple alternative services are advertised, HttpStreamFactory should
3638// select the alternative service which uses existing QUIC session if available.
3639// If no existing QUIC session can be used, use the first alternative service
3640// from the list.
zhongyi32569c62016-01-08 02:54:303641TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:343642 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:523643 MockRead http_reads[] = {
3644 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:293645 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:523646 MockRead("hello world"),
3647 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3648 MockRead(ASYNC, OK)};
3649
Ryan Sleevib8d7ea02018-05-07 20:01:013650 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:523651 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083652 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:563653 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:523654
Ryan Hamilton8d9ee76e2018-05-29 23:52:523655 quic::QuicStreamOffset request_header_offset = 0;
3656 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:303657 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:293658 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:303659 // alternative service list.
bncc958faa2015-07-31 18:14:523660 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:363661 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433662 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3663 mock_quic_data.AddWrite(
3664 SYNCHRONOUS,
3665 ConstructClientRequestHeadersPacket(
3666 2, GetNthClientInitiatedStreamId(0), true, true,
3667 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:303668
3669 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:293670 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
3671 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:433672 mock_quic_data.AddRead(
3673 ASYNC,
3674 ConstructServerResponseHeadersPacket(
3675 1, GetNthClientInitiatedStreamId(0), false, false,
3676 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
3677 mock_quic_data.AddRead(
3678 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
3679 false, true, 0, "hello!"));
3680 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:303681
3682 // Second QUIC request data.
3683 // Connection pooling, using existing session, no need to include version
3684 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:583685 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433686 SYNCHRONOUS,
3687 ConstructClientRequestHeadersPacket(
3688 4, GetNthClientInitiatedStreamId(1), false, true,
3689 GetRequestHeaders("GET", "https", "/"),
3690 GetNthClientInitiatedStreamId(0), &request_header_offset));
3691 mock_quic_data.AddRead(
3692 ASYNC, ConstructServerResponseHeadersPacket(
3693 3, GetNthClientInitiatedStreamId(1), false, false,
3694 GetResponseHeaders("200 OK"), &response_header_offset));
3695 mock_quic_data.AddRead(
3696 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
3697 false, true, 0, "hello!"));
3698 mock_quic_data.AddWrite(
3699 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:523700 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:593701 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:523702
3703 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3704
rtennetib8e80fb2016-05-16 00:12:093705 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323706 CreateSession();
bncc958faa2015-07-31 18:14:523707
3708 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:303709
bnc359ed2a2016-04-29 20:43:453710 SendRequestAndExpectQuicResponse("hello!");
3711 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:303712}
3713
tbansal6490783c2016-09-20 17:55:273714// Check that an existing QUIC connection to an alternative proxy server is
3715// used.
3716TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
3717 base::HistogramTester histogram_tester;
3718
Ryan Hamilton8d9ee76e2018-05-29 23:52:523719 quic::QuicStreamOffset request_header_offset = 0;
3720 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:273721 // First QUIC request data.
3722 // Open a session to foo.example.org:443 using the first entry of the
3723 // alternative service list.
3724 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:363725 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433726 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3727 mock_quic_data.AddWrite(
3728 SYNCHRONOUS,
3729 ConstructClientRequestHeadersPacket(
3730 2, GetNthClientInitiatedStreamId(0), true, true,
3731 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:273732
3733 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:433734 mock_quic_data.AddRead(
3735 ASYNC,
3736 ConstructServerResponseHeadersPacket(
3737 1, GetNthClientInitiatedStreamId(0), false, false,
3738 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
3739 mock_quic_data.AddRead(
3740 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
3741 false, true, 0, "hello!"));
3742 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:273743
3744 // Second QUIC request data.
3745 // Connection pooling, using existing session, no need to include version
3746 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:273747 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433748 SYNCHRONOUS,
3749 ConstructClientRequestHeadersPacket(
3750 4, GetNthClientInitiatedStreamId(1), false, true,
3751 GetRequestHeaders("GET", "http", "/"),
3752 GetNthClientInitiatedStreamId(0), &request_header_offset));
3753 mock_quic_data.AddRead(
3754 ASYNC, ConstructServerResponseHeadersPacket(
3755 3, GetNthClientInitiatedStreamId(1), false, false,
3756 GetResponseHeaders("200 OK"), &response_header_offset));
3757 mock_quic_data.AddRead(
3758 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
3759 false, true, 0, "hello!"));
3760 mock_quic_data.AddWrite(
3761 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:273762 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3763 mock_quic_data.AddRead(ASYNC, 0); // EOF
3764
3765 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3766
3767 AddHangingNonAlternateProtocolSocketData();
3768
3769 TestProxyDelegate test_proxy_delegate;
3770
Lily Houghton8c2f97d2018-01-22 05:06:593771 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:493772 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:273773
3774 test_proxy_delegate.set_alternative_proxy_server(
3775 ProxyServer::FromPacString("QUIC mail.example.org:443"));
mmenke6ddfbea2017-05-31 21:48:413776 session_context_.proxy_delegate = &test_proxy_delegate;
tbansal6490783c2016-09-20 17:55:273777
3778 request_.url = GURL("http://mail.example.org/");
3779
3780 CreateSession();
3781
3782 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
3783 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
3784 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
3785 1);
3786
3787 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
3788 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
3789 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
3790 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
3791 1);
3792}
3793
Ryan Hamilton8d9ee76e2018-05-29 23:52:523794// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:453795// even if alternative service destination is different.
3796TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:343797 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:303798 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523799 quic::QuicStreamOffset request_header_offset(0);
3800 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:453801
rch5cb522462017-04-25 20:18:363802 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433803 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:453804 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433805 mock_quic_data.AddWrite(
3806 SYNCHRONOUS,
3807 ConstructClientRequestHeadersPacket(
3808 2, GetNthClientInitiatedStreamId(0), true, true,
3809 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3810 mock_quic_data.AddRead(
3811 ASYNC, ConstructServerResponseHeadersPacket(
3812 1, GetNthClientInitiatedStreamId(0), false, false,
3813 GetResponseHeaders("200 OK"), &response_header_offset));
3814 mock_quic_data.AddRead(
3815 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
3816 false, true, 0, "hello!"));
3817 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:303818
bnc359ed2a2016-04-29 20:43:453819 // Second request.
alyssar2adf3ac2016-05-03 17:12:583820 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433821 SYNCHRONOUS,
3822 ConstructClientRequestHeadersPacket(
3823 4, GetNthClientInitiatedStreamId(1), false, true,
3824 GetRequestHeaders("GET", "https", "/"),
3825 GetNthClientInitiatedStreamId(0), &request_header_offset));
3826 mock_quic_data.AddRead(
3827 ASYNC, ConstructServerResponseHeadersPacket(
3828 3, GetNthClientInitiatedStreamId(1), false, false,
3829 GetResponseHeaders("200 OK"), &response_header_offset));
3830 mock_quic_data.AddRead(
3831 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
3832 false, true, 0, "hello!"));
3833 mock_quic_data.AddWrite(
3834 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:303835 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3836 mock_quic_data.AddRead(ASYNC, 0); // EOF
3837
3838 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:453839
3840 AddHangingNonAlternateProtocolSocketData();
3841 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:303842
rch3f4b8452016-02-23 16:59:323843 CreateSession();
zhongyi32569c62016-01-08 02:54:303844
bnc359ed2a2016-04-29 20:43:453845 const char destination1[] = "first.example.com";
3846 const char destination2[] = "second.example.com";
3847
3848 // Set up alternative service entry to destination1.
3849 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:213850 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:453851 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:213852 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:443853 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:453854 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523855 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:453856 SendRequestAndExpectQuicResponse("hello!");
3857
3858 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:213859 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:213860 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:443861 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523862 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:453863 // even though alternative service destination is different.
3864 SendRequestAndExpectQuicResponse("hello!");
3865}
3866
3867// Pool to existing session with matching destination and matching certificate
3868// even if origin is different, and even if the alternative service with
3869// matching destination is not the first one on the list.
3870TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:343871 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:453872 GURL origin1 = request_.url;
3873 GURL origin2("https://www.example.org/");
3874 ASSERT_NE(origin1.host(), origin2.host());
3875
3876 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523877 quic::QuicStreamOffset request_header_offset(0);
3878 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:453879
rch5cb522462017-04-25 20:18:363880 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433881 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:453882 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433883 mock_quic_data.AddWrite(
3884 SYNCHRONOUS,
3885 ConstructClientRequestHeadersPacket(
3886 2, GetNthClientInitiatedStreamId(0), true, true,
3887 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3888 mock_quic_data.AddRead(
3889 ASYNC, ConstructServerResponseHeadersPacket(
3890 1, GetNthClientInitiatedStreamId(0), false, false,
3891 GetResponseHeaders("200 OK"), &response_header_offset));
3892 mock_quic_data.AddRead(
3893 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
3894 false, true, 0, "hello!"));
3895 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:453896
3897 // Second request.
Yixin Wang079ad542018-01-11 04:06:053898 QuicTestPacketMaker client_maker2(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523899 version_, 0, &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:053900 client_headers_include_h2_stream_dependency_);
rchbf4c26d2017-04-16 23:17:553901 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523902 quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:583903 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433904 SYNCHRONOUS,
3905 ConstructClientRequestHeadersPacket(
3906 4, GetNthClientInitiatedStreamId(1), false, true,
3907 GetRequestHeaders("GET", "https", "/", &client_maker2),
3908 GetNthClientInitiatedStreamId(0), &request_header_offset));
3909 mock_quic_data.AddRead(
3910 ASYNC, ConstructServerResponseHeadersPacket(
3911 3, GetNthClientInitiatedStreamId(1), false, false,
3912 GetResponseHeaders("200 OK"), &response_header_offset));
3913 mock_quic_data.AddRead(
3914 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
3915 false, true, 0, "hello!"));
3916 mock_quic_data.AddWrite(
3917 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:453918 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3919 mock_quic_data.AddRead(ASYNC, 0); // EOF
3920
3921 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3922
3923 AddHangingNonAlternateProtocolSocketData();
3924 AddHangingNonAlternateProtocolSocketData();
3925
3926 CreateSession();
3927
3928 const char destination1[] = "first.example.com";
3929 const char destination2[] = "second.example.com";
3930
3931 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:213932 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:453933 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:213934 http_server_properties_.SetQuicAlternativeService(
3935 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:443936 supported_versions_);
bnc359ed2a2016-04-29 20:43:453937
3938 // Set up multiple alternative service entries for |origin2|,
3939 // the first one with a different destination as for |origin1|,
3940 // the second one with the same. The second one should be used,
3941 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:213942 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:453943 AlternativeServiceInfoVector alternative_services;
3944 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:213945 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3946 alternative_service2, expiration,
3947 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:453948 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:213949 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3950 alternative_service1, expiration,
3951 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:453952 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
3953 alternative_services);
bnc359ed2a2016-04-29 20:43:453954 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523955 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:453956 SendRequestAndExpectQuicResponse("hello!");
3957
3958 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:523959 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:453960 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:583961
bnc359ed2a2016-04-29 20:43:453962 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:303963}
3964
3965// Multiple origins have listed the same alternative services. When there's a
3966// existing QUIC session opened by a request to other origin,
3967// if the cert is valid, should select this QUIC session to make the request
3968// if this is also the first existing QUIC session.
3969TEST_P(QuicNetworkTransactionTest,
3970 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:343971 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:293972 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:303973
rch9ae5b3b2016-02-11 00:36:293974 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:303975 MockRead http_reads[] = {
3976 MockRead("HTTP/1.1 200 OK\r\n"),
3977 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:293978 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:303979 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3980 MockRead(ASYNC, OK)};
3981
Ryan Sleevib8d7ea02018-05-07 20:01:013982 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:303983 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083984 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:303985 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3986
3987 // HTTP data for request to mail.example.org.
3988 MockRead http_reads2[] = {
3989 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:293990 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:303991 MockRead("hello world from mail.example.org"),
3992 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3993 MockRead(ASYNC, OK)};
3994
Ryan Sleevib8d7ea02018-05-07 20:01:013995 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:303996 socket_factory_.AddSocketDataProvider(&http_data2);
3997 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3998
Ryan Hamilton8d9ee76e2018-05-29 23:52:523999 quic::QuicStreamOffset request_header_offset = 0;
4000 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304001
Yixin Wang079ad542018-01-11 04:06:054002 QuicTestPacketMaker client_maker(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524003 version_, 0, &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054004 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584005 server_maker_.set_hostname("www.example.org");
4006 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304007 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364008 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434009 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304010 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584011 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434012 SYNCHRONOUS,
4013 ConstructClientRequestHeadersPacket(
4014 2, GetNthClientInitiatedStreamId(0), true, true,
4015 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4016
4017 mock_quic_data.AddRead(
4018 ASYNC, ConstructServerResponseHeadersPacket(
4019 1, GetNthClientInitiatedStreamId(0), false, false,
4020 GetResponseHeaders("200 OK"), &response_header_offset));
4021 mock_quic_data.AddRead(ASYNC, ConstructServerDataPacket(
4022 2, GetNthClientInitiatedStreamId(0), false,
4023 true, 0, "hello from mail QUIC!"));
4024 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4025 // Second QUIC request data.
4026 mock_quic_data.AddWrite(
4027 SYNCHRONOUS,
4028 ConstructClientRequestHeadersPacket(
4029 4, GetNthClientInitiatedStreamId(1), false, true,
4030 GetRequestHeaders("GET", "https", "/", &client_maker),
4031 GetNthClientInitiatedStreamId(0), &request_header_offset));
4032 mock_quic_data.AddRead(
4033 ASYNC, ConstructServerResponseHeadersPacket(
4034 3, GetNthClientInitiatedStreamId(1), false, false,
4035 GetResponseHeaders("200 OK"), &response_header_offset));
4036 mock_quic_data.AddRead(ASYNC, ConstructServerDataPacket(
4037 4, GetNthClientInitiatedStreamId(1), false,
4038 true, 0, "hello from mail QUIC!"));
4039 mock_quic_data.AddWrite(
4040 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304041 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4042 mock_quic_data.AddRead(ASYNC, 0); // EOF
4043
4044 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304045
rtennetib8e80fb2016-05-16 00:12:094046 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324047 CreateSession();
zhongyi32569c62016-01-08 02:54:304048
4049 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294050 request_.url = GURL("https://www.example.org/");
4051 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304052 request_.url = GURL("https://mail.example.org/");
4053 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4054
rch9ae5b3b2016-02-11 00:36:294055 // Open a QUIC session to mail.example.org:443 when making request
4056 // to mail.example.org.
4057 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454058 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304059
rch9ae5b3b2016-02-11 00:36:294060 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304061 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454062 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524063}
4064
4065TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524066 MockRead http_reads[] = {
4067 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564068 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524069 MockRead("hello world"),
4070 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4071 MockRead(ASYNC, OK)};
4072
Ryan Sleevib8d7ea02018-05-07 20:01:014073 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524074 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084075 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564076 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524077
rtennetib8e80fb2016-05-16 00:12:094078 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324079 CreateSession();
bncc958faa2015-07-31 18:14:524080
4081 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454082
4083 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344084 AlternativeServiceInfoVector alternative_service_info_vector =
4085 http_server_properties_.GetAlternativeServiceInfos(http_server);
4086 ASSERT_EQ(1u, alternative_service_info_vector.size());
4087 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544088 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344089 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4090 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4091 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524092}
4093
4094TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524095 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564096 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4097 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524098 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4099 MockRead(ASYNC, OK)};
4100
Ryan Sleevib8d7ea02018-05-07 20:01:014101 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524102 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084103 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564104 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524105
4106 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524107 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364108 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434109 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4110 mock_quic_data.AddWrite(
4111 SYNCHRONOUS,
4112 ConstructClientRequestHeadersPacket(
4113 2, GetNthClientInitiatedStreamId(0), true, true,
4114 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4115 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4116 1, GetNthClientInitiatedStreamId(0), false,
4117 false, GetResponseHeaders("200 OK")));
4118 mock_quic_data.AddRead(
4119 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4120 false, true, 0, "hello!"));
4121 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524122 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4123 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524124
4125 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4126
rtennetib8e80fb2016-05-16 00:12:094127 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324128 CreateSession();
bncc958faa2015-07-31 18:14:524129
bnc3472afd2016-11-17 15:27:214130 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524131 HostPortPair::FromURL(request_.url));
4132 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4133 alternative_service);
4134 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4135 alternative_service));
4136
4137 SendRequestAndExpectHttpResponse("hello world");
4138 SendRequestAndExpectQuicResponse("hello!");
4139
mmenkee24011922015-12-17 22:12:594140 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524141
4142 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4143 alternative_service));
rchac7f35e2017-03-15 20:42:304144 EXPECT_NE(nullptr,
4145 http_server_properties_.GetServerNetworkStats(
4146 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524147}
4148
bncc958faa2015-07-31 18:14:524149TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524150 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564151 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4152 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524153 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4154 MockRead(ASYNC, OK)};
4155
Ryan Sleevib8d7ea02018-05-07 20:01:014156 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524157 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564158 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524159
4160 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524161 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364162 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434163 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4164 mock_quic_data.AddWrite(
4165 SYNCHRONOUS,
4166 ConstructClientRequestHeadersPacket(
4167 2, GetNthClientInitiatedStreamId(0), true, true,
4168 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4169 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4170 1, GetNthClientInitiatedStreamId(0), false,
4171 false, GetResponseHeaders("200 OK")));
4172 mock_quic_data.AddRead(
4173 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4174 false, true, 0, "hello!"));
4175 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524176 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4177
4178 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4179
4180 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324181 CreateSession();
bncc958faa2015-07-31 18:14:524182
4183 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4184 SendRequestAndExpectHttpResponse("hello world");
4185}
4186
tbansalc3308d72016-08-27 10:25:044187// Tests that the connection to an HTTPS proxy is raced with an available
4188// alternative proxy server.
4189TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274190 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594191 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494192 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044193
4194 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524195 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364196 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434197 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4198 mock_quic_data.AddWrite(
4199 SYNCHRONOUS,
4200 ConstructClientRequestHeadersPacket(
4201 2, GetNthClientInitiatedStreamId(0), true, true,
4202 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
4203 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4204 1, GetNthClientInitiatedStreamId(0), false,
4205 false, GetResponseHeaders("200 OK")));
4206 mock_quic_data.AddRead(
4207 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4208 false, true, 0, "hello!"));
4209 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044210 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4211 mock_quic_data.AddRead(ASYNC, 0); // EOF
4212
4213 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4214
4215 // There is no need to set up main job, because no attempt will be made to
4216 // speak to the proxy over TCP.
4217 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044218 TestProxyDelegate test_proxy_delegate;
4219 const HostPortPair host_port_pair("mail.example.org", 443);
4220
4221 test_proxy_delegate.set_alternative_proxy_server(
4222 ProxyServer::FromPacString("QUIC mail.example.org:443"));
mmenke6ddfbea2017-05-31 21:48:414223 session_context_.proxy_delegate = &test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:044224 CreateSession();
4225 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4226
4227 // The main job needs to hang in order to guarantee that the alternative
4228 // proxy server job will "win".
4229 AddHangingNonAlternateProtocolSocketData();
4230
4231 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4232
4233 // Verify that the alternative proxy server is not marked as broken.
4234 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4235
4236 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594237 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274238
4239 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4240 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4241 1);
tbansalc3308d72016-08-27 10:25:044242}
4243
bnc1c196c6e2016-05-28 13:51:484244TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304245 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274246 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304247
4248 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564249 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294250 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564251 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304252
4253 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564254 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484255 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564256 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304257
Ryan Sleevib8d7ea02018-05-07 20:01:014258 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504259 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084260 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504261 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304262
4263 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454264 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304265 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454266 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304267 };
Ryan Sleevib8d7ea02018-05-07 20:01:014268 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504269 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304270
4271 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014272 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504273 socket_factory_.AddSocketDataProvider(&http_data2);
4274 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304275
bnc912a04b2016-04-20 14:19:504276 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304277
4278 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304279 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174280 ASSERT_TRUE(http_data.AllReadDataConsumed());
4281 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304282
4283 // Now run the second request in which the QUIC socket hangs,
4284 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304285 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454286 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304287
rch37de576c2015-05-17 20:28:174288 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4289 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454290 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304291}
4292
[email protected]1e960032013-12-20 19:00:204293TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204294 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524295 quic::QuicStreamOffset header_stream_offset = 0;
4296 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4297 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434298 mock_quic_data.AddWrite(
4299 SYNCHRONOUS,
4300 ConstructClientRequestHeadersPacket(
4301 1, GetNthClientInitiatedStreamId(0), true, true,
4302 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4303 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4304 1, GetNthClientInitiatedStreamId(0), false,
4305 false, GetResponseHeaders("200 OK")));
4306 mock_quic_data.AddRead(
4307 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4308 false, true, 0, "hello!"));
4309 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504310 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594311 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484312
rcha5399e02015-04-21 19:32:044313 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484314
rtennetib8e80fb2016-05-16 00:12:094315 // The non-alternate protocol job needs to hang in order to guarantee that
4316 // the alternate-protocol job will "win".
4317 AddHangingNonAlternateProtocolSocketData();
4318
rch3f4b8452016-02-23 16:59:324319 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274320 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194321 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304322
4323 EXPECT_EQ(nullptr,
4324 http_server_properties_.GetServerNetworkStats(
4325 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484326}
4327
[email protected]1e960032013-12-20 19:00:204328TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204329 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524330 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4331 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434332 mock_quic_data.AddWrite(SYNCHRONOUS,
4333 ConstructClientRequestHeadersPacket(
4334 1, GetNthClientInitiatedStreamId(0), true, true,
4335 GetRequestHeaders("GET", "https", "/")));
4336 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4337 1, GetNthClientInitiatedStreamId(0), false,
4338 false, GetResponseHeaders("200 OK")));
4339 mock_quic_data.AddRead(
4340 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4341 false, true, 0, "hello!"));
4342 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504343 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594344 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044345 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274346
4347 // In order for a new QUIC session to be established via alternate-protocol
4348 // without racing an HTTP connection, we need the host resolution to happen
4349 // synchronously.
4350 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294351 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564352 "");
rch9ae5b3b2016-02-11 00:36:294353 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]3a120a6b2013-06-25 01:08:274354 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104355 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584356 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4357 CompletionOnceCallback(), &request,
4358 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414359 EXPECT_THAT(rv, IsOk());
[email protected]3a120a6b2013-06-25 01:08:274360
rtennetib8e80fb2016-05-16 00:12:094361 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324362 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274363 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274364 SendRequestAndExpectQuicResponse("hello!");
4365}
4366
[email protected]0fc924b2014-03-31 04:34:154367TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494368 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4369 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154370
4371 // Since we are using a proxy, the QUIC job will not succeed.
4372 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294373 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4374 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564375 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154376
4377 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564378 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484379 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564380 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154381
Ryan Sleevib8d7ea02018-05-07 20:01:014382 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154383 socket_factory_.AddSocketDataProvider(&http_data);
4384
4385 // In order for a new QUIC session to be established via alternate-protocol
4386 // without racing an HTTP connection, we need the host resolution to happen
4387 // synchronously.
4388 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294389 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564390 "");
rch9ae5b3b2016-02-11 00:36:294391 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]0fc924b2014-03-31 04:34:154392 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104393 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584394 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4395 CompletionOnceCallback(), &request,
4396 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414397 EXPECT_THAT(rv, IsOk());
[email protected]0fc924b2014-03-31 04:34:154398
rch9ae5b3b2016-02-11 00:36:294399 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324400 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274401 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154402 SendRequestAndExpectHttpResponse("hello world");
4403}
4404
[email protected]1e960032013-12-20 19:00:204405TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:204406 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524407 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364408 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434409 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4410 mock_quic_data.AddWrite(
4411 SYNCHRONOUS,
4412 ConstructClientRequestHeadersPacket(
4413 2, GetNthClientInitiatedStreamId(0), true, true,
4414 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4415 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4416 1, GetNthClientInitiatedStreamId(0), false,
4417 false, GetResponseHeaders("200 OK")));
4418 mock_quic_data.AddRead(
4419 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4420 false, true, 0, "hello!"));
4421 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594422 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044423 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124424
rtennetib8e80fb2016-05-16 00:12:094425 // The non-alternate protocol job needs to hang in order to guarantee that
4426 // the alternate-protocol job will "win".
4427 AddHangingNonAlternateProtocolSocketData();
4428
[email protected]11c05872013-08-20 02:04:124429 // In order for a new QUIC session to be established via alternate-protocol
4430 // without racing an HTTP connection, we need the host resolution to happen
4431 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4432 // connection to the the server, in this test we require confirmation
4433 // before encrypting so the HTTP job will still start.
4434 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294435 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564436 "");
rch9ae5b3b2016-02-11 00:36:294437 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]11c05872013-08-20 02:04:124438 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104439 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584440 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4441 CompletionOnceCallback(), &request,
4442 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414443 EXPECT_THAT(rv, IsOk());
[email protected]11c05872013-08-20 02:04:124444
rch3f4b8452016-02-23 16:59:324445 CreateSession();
[email protected]11c05872013-08-20 02:04:124446 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274447 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124448
bnc691fda62016-08-12 00:43:164449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124450 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:414451 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014452 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124453
4454 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524455 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014456 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504457
bnc691fda62016-08-12 00:43:164458 CheckWasQuicResponse(&trans);
4459 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:124460}
4461
Steven Valdez58097ec32018-07-16 18:29:044462TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
4463 MockQuicData mock_quic_data;
4464 quic::QuicStreamOffset client_header_stream_offset = 0;
4465 quic::QuicStreamOffset server_header_stream_offset = 0;
4466 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4467 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
4468 mock_quic_data.AddWrite(SYNCHRONOUS,
4469 ConstructClientRequestHeadersPacket(
4470 1, GetNthClientInitiatedStreamId(0), true, true,
4471 GetRequestHeaders("GET", "https", "/"),
4472 &client_header_stream_offset));
4473 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4474 1, GetNthClientInitiatedStreamId(0), false,
4475 false, GetResponseHeaders("425 TOO_EARLY"),
4476 &server_header_stream_offset));
4477 mock_quic_data.AddWrite(
4478 SYNCHRONOUS,
4479 ConstructClientAckAndRstPacket(2, GetNthClientInitiatedStreamId(0),
4480 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
4481
4482 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4483
4484 spdy::SpdySettingsIR settings_frame;
4485 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
4486 quic::kDefaultMaxUncompressedHeaderSize);
4487 spdy::SpdySerializedFrame spdy_frame(
4488 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
4489 mock_quic_data.AddWrite(
4490 SYNCHRONOUS,
4491 client_maker_.MakeDataPacket(
4492 3, 3, false, false, client_header_stream_offset,
4493 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
4494 client_header_stream_offset += spdy_frame.size();
4495
4496 mock_quic_data.AddWrite(
4497 SYNCHRONOUS,
4498 ConstructClientRequestHeadersPacket(
4499 4, GetNthClientInitiatedStreamId(1), false, true,
4500 GetRequestHeaders("GET", "https", "/"),
4501 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
4502 mock_quic_data.AddRead(
4503 ASYNC, ConstructServerResponseHeadersPacket(
4504 2, GetNthClientInitiatedStreamId(1), false, false,
4505 GetResponseHeaders("200 OK"), &server_header_stream_offset));
4506 mock_quic_data.AddRead(
4507 ASYNC, ConstructServerDataPacket(3, GetNthClientInitiatedStreamId(1),
4508 false, true, 0, "hello!"));
4509 mock_quic_data.AddWrite(
4510 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
4511 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4512 mock_quic_data.AddRead(ASYNC, 0); // EOF
4513
4514 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4515
4516 // In order for a new QUIC session to be established via alternate-protocol
4517 // without racing an HTTP connection, we need the host resolution to happen
4518 // synchronously.
4519 host_resolver_.set_synchronous_mode(true);
4520 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4521 "");
4522 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
4523 AddressList address;
4524 std::unique_ptr<HostResolver::Request> request;
4525 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4526 CompletionOnceCallback(), &request, net_log_.bound());
4527
4528 AddHangingNonAlternateProtocolSocketData();
4529 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274530 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:044531
4532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4533 TestCompletionCallback callback;
4534 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
4535 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4536
4537 // Confirm the handshake after the 425 Too Early.
4538 base::RunLoop().RunUntilIdle();
4539
4540 // The handshake hasn't been confirmed yet, so the retry should not have
4541 // succeeded.
4542 EXPECT_FALSE(callback.have_result());
4543
4544 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
4545 quic::QuicSession::HANDSHAKE_CONFIRMED);
4546
4547 EXPECT_THAT(callback.WaitForResult(), IsOk());
4548 CheckWasQuicResponse(&trans);
4549 CheckResponseData(&trans, "hello!");
4550}
4551
4552TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
4553 MockQuicData mock_quic_data;
4554 quic::QuicStreamOffset client_header_stream_offset = 0;
4555 quic::QuicStreamOffset server_header_stream_offset = 0;
4556 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4557 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
4558 mock_quic_data.AddWrite(SYNCHRONOUS,
4559 ConstructClientRequestHeadersPacket(
4560 1, GetNthClientInitiatedStreamId(0), true, true,
4561 GetRequestHeaders("GET", "https", "/"),
4562 &client_header_stream_offset));
4563 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4564 1, GetNthClientInitiatedStreamId(0), false,
4565 false, GetResponseHeaders("425 TOO_EARLY"),
4566 &server_header_stream_offset));
4567 mock_quic_data.AddWrite(
4568 SYNCHRONOUS,
4569 ConstructClientAckAndRstPacket(2, GetNthClientInitiatedStreamId(0),
4570 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
4571
4572 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4573
4574 spdy::SpdySettingsIR settings_frame;
4575 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
4576 quic::kDefaultMaxUncompressedHeaderSize);
4577 spdy::SpdySerializedFrame spdy_frame(
4578 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
4579 mock_quic_data.AddWrite(
4580 SYNCHRONOUS,
4581 client_maker_.MakeDataPacket(
4582 3, 3, false, false, client_header_stream_offset,
4583 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
4584 client_header_stream_offset += spdy_frame.size();
4585
4586 mock_quic_data.AddWrite(
4587 SYNCHRONOUS,
4588 ConstructClientRequestHeadersPacket(
4589 4, GetNthClientInitiatedStreamId(1), false, true,
4590 GetRequestHeaders("GET", "https", "/"),
4591 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
4592 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4593 2, GetNthClientInitiatedStreamId(1), false,
4594 false, GetResponseHeaders("425 TOO_EARLY"),
4595 &server_header_stream_offset));
4596 mock_quic_data.AddWrite(
4597 SYNCHRONOUS,
4598 ConstructClientAckAndRstPacket(5, GetNthClientInitiatedStreamId(1),
4599 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
4600 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4601 mock_quic_data.AddRead(ASYNC, 0); // EOF
4602
4603 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4604
4605 // In order for a new QUIC session to be established via alternate-protocol
4606 // without racing an HTTP connection, we need the host resolution to happen
4607 // synchronously.
4608 host_resolver_.set_synchronous_mode(true);
4609 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4610 "");
4611 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
4612 AddressList address;
4613 std::unique_ptr<HostResolver::Request> request;
4614 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4615 CompletionOnceCallback(), &request, net_log_.bound());
4616
4617 AddHangingNonAlternateProtocolSocketData();
4618 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274619 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:044620
4621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4622 TestCompletionCallback callback;
4623 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
4624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4625
4626 // Confirm the handshake after the 425 Too Early.
4627 base::RunLoop().RunUntilIdle();
4628
4629 // The handshake hasn't been confirmed yet, so the retry should not have
4630 // succeeded.
4631 EXPECT_FALSE(callback.have_result());
4632
4633 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
4634 quic::QuicSession::HANDSHAKE_CONFIRMED);
4635
4636 EXPECT_THAT(callback.WaitForResult(), IsOk());
4637 const HttpResponseInfo* response = trans.GetResponseInfo();
4638 ASSERT_TRUE(response != nullptr);
4639 ASSERT_TRUE(response->headers.get() != nullptr);
4640 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
4641 EXPECT_TRUE(response->was_fetched_via_spdy);
4642 EXPECT_TRUE(response->was_alpn_negotiated);
4643 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
4644 response->connection_info);
4645}
4646
zhongyica364fbb2015-12-12 03:39:124647TEST_P(QuicNetworkTransactionTest,
4648 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:484649 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:124650 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524651 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364652 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434653 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4654 mock_quic_data.AddWrite(
4655 SYNCHRONOUS,
4656 ConstructClientRequestHeadersPacket(
4657 2, GetNthClientInitiatedStreamId(0), true, true,
4658 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:124659 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:524660 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:434661 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:124662 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4663
4664 // The non-alternate protocol job needs to hang in order to guarantee that
4665 // the alternate-protocol job will "win".
4666 AddHangingNonAlternateProtocolSocketData();
4667
4668 // In order for a new QUIC session to be established via alternate-protocol
4669 // without racing an HTTP connection, we need the host resolution to happen
4670 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4671 // connection to the the server, in this test we require confirmation
4672 // before encrypting so the HTTP job will still start.
4673 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294674 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124675 "");
rch9ae5b3b2016-02-11 00:36:294676 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:124677 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104678 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584679 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4680 CompletionOnceCallback(), &request,
4681 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414682 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:124683
rch3f4b8452016-02-23 16:59:324684 CreateSession();
zhongyica364fbb2015-12-12 03:39:124685 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274686 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124687
bnc691fda62016-08-12 00:43:164688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124689 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:414690 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014691 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:124692
4693 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524694 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014695 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124696
4697 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524698 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124699
bnc691fda62016-08-12 00:43:164700 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:124701 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524702 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
4703 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124704}
4705
4706TEST_P(QuicNetworkTransactionTest,
4707 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:484708 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:124709 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524710 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364711 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434712 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4713 mock_quic_data.AddWrite(
4714 SYNCHRONOUS,
4715 ConstructClientRequestHeadersPacket(
4716 2, GetNthClientInitiatedStreamId(0), true, true,
4717 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:214718 // Peer sending data from an non-existing stream causes this end to raise
4719 // error and close connection.
4720 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524721 ASYNC,
4722 ConstructServerRstPacket(1, false, 99, quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:214723 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:524724 mock_quic_data.AddWrite(
4725 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
4726 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
4727 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:124728 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4729
4730 // The non-alternate protocol job needs to hang in order to guarantee that
4731 // the alternate-protocol job will "win".
4732 AddHangingNonAlternateProtocolSocketData();
4733
4734 // In order for a new QUIC session to be established via alternate-protocol
4735 // without racing an HTTP connection, we need the host resolution to happen
4736 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4737 // connection to the the server, in this test we require confirmation
4738 // before encrypting so the HTTP job will still start.
4739 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294740 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124741 "");
rch9ae5b3b2016-02-11 00:36:294742 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:124743 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104744 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584745 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4746 CompletionOnceCallback(), &request,
4747 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414748 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:124749
rch3f4b8452016-02-23 16:59:324750 CreateSession();
zhongyica364fbb2015-12-12 03:39:124751 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274752 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124753
bnc691fda62016-08-12 00:43:164754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124755 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:414756 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:124758
4759 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524760 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014761 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124762 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524763 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124764
bnc691fda62016-08-12 00:43:164765 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524766 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124767}
4768
rchcd5f1c62016-06-23 02:43:484769TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
4770 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524771 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364772 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434773 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4774 mock_quic_data.AddWrite(
4775 SYNCHRONOUS,
4776 ConstructClientRequestHeadersPacket(
4777 2, GetNthClientInitiatedStreamId(0), true, true,
4778 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:484779 // Read the response headers, then a RST_STREAM frame.
Zhongyi Shi32f2fd02018-04-16 18:23:434780 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4781 1, GetNthClientInitiatedStreamId(0), false,
4782 false, GetResponseHeaders("200 OK")));
4783 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
4784 2, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524785 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:434786 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:484787 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
4788 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4789
4790 // The non-alternate protocol job needs to hang in order to guarantee that
4791 // the alternate-protocol job will "win".
4792 AddHangingNonAlternateProtocolSocketData();
4793
4794 // In order for a new QUIC session to be established via alternate-protocol
4795 // without racing an HTTP connection, we need the host resolution to happen
4796 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4797 // connection to the the server, in this test we require confirmation
4798 // before encrypting so the HTTP job will still start.
4799 host_resolver_.set_synchronous_mode(true);
4800 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4801 "");
4802 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
4803 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104804 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584805 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4806 CompletionOnceCallback(), &request,
4807 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414808 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:484809
4810 CreateSession();
4811 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274812 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:484813
bnc691fda62016-08-12 00:43:164814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:484815 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:414816 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:484818
4819 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524820 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:484821 // Read the headers.
robpercival214763f2016-07-01 23:27:014822 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:484823
bnc691fda62016-08-12 00:43:164824 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:484825 ASSERT_TRUE(response != nullptr);
4826 ASSERT_TRUE(response->headers.get() != nullptr);
4827 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4828 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:524829 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:444830 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
4831 response->connection_info);
rchcd5f1c62016-06-23 02:43:484832
4833 std::string response_data;
bnc691fda62016-08-12 00:43:164834 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:484835}
4836
4837TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:484838 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:484839 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524840 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364841 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434842 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4843 mock_quic_data.AddWrite(
4844 SYNCHRONOUS,
4845 ConstructClientRequestHeadersPacket(
4846 2, GetNthClientInitiatedStreamId(0), true, true,
4847 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4848 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
4849 1, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524850 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:484851 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
4852 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4853
4854 // The non-alternate protocol job needs to hang in order to guarantee that
4855 // the alternate-protocol job will "win".
4856 AddHangingNonAlternateProtocolSocketData();
4857
4858 // In order for a new QUIC session to be established via alternate-protocol
4859 // without racing an HTTP connection, we need the host resolution to happen
4860 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4861 // connection to the the server, in this test we require confirmation
4862 // before encrypting so the HTTP job will still start.
4863 host_resolver_.set_synchronous_mode(true);
4864 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4865 "");
4866 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
4867 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104868 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584869 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4870 CompletionOnceCallback(), &request,
4871 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414872 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:484873
4874 CreateSession();
4875 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274876 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:484877
bnc691fda62016-08-12 00:43:164878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:484879 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:414880 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:484882
4883 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524884 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:484885 // Read the headers.
robpercival214763f2016-07-01 23:27:014886 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:484887}
4888
[email protected]1e960032013-12-20 19:00:204889TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:304890 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:524891 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:584892 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:304893 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:504894 MockRead(ASYNC, close->data(), close->length()),
4895 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
4896 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:304897 };
Ryan Sleevib8d7ea02018-05-07 20:01:014898 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:304899 socket_factory_.AddSocketDataProvider(&quic_data);
4900
4901 // Main job which will succeed even though the alternate job fails.
4902 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024903 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4904 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4905 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:304906
Ryan Sleevib8d7ea02018-05-07 20:01:014907 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:304908 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564909 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:304910
rch3f4b8452016-02-23 16:59:324911 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274912 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:194913 SendRequestAndExpectHttpResponse("hello from http");
4914 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:304915}
4916
[email protected]1e960032013-12-20 19:00:204917TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:594918 // Alternate-protocol job
4919 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:024920 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:594921 };
Ryan Sleevib8d7ea02018-05-07 20:01:014922 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:594923 socket_factory_.AddSocketDataProvider(&quic_data);
4924
4925 // Main job which will succeed even though the alternate job fails.
4926 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024927 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4928 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4929 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:594930
Ryan Sleevib8d7ea02018-05-07 20:01:014931 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:594932 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564933 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:594934
rch3f4b8452016-02-23 16:59:324935 CreateSession();
[email protected]d03a66d2013-05-06 12:55:594936
Ryan Hamilton9835e662018-08-02 05:36:274937 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:194938 SendRequestAndExpectHttpResponse("hello from http");
4939 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:594940}
4941
[email protected]00c159f2014-05-21 22:38:164942TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:534943 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:164944 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:024945 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:164946 };
Ryan Sleevib8d7ea02018-05-07 20:01:014947 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:164948 socket_factory_.AddSocketDataProvider(&quic_data);
4949
[email protected]eb71ab62014-05-23 07:57:534950 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:164951 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024952 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:164953 };
4954
Ryan Sleevib8d7ea02018-05-07 20:01:014955 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:164956 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
4957 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564958 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:164959
rtennetib8e80fb2016-05-16 00:12:094960 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324961 CreateSession();
[email protected]00c159f2014-05-21 22:38:164962
Ryan Hamilton9835e662018-08-02 05:36:274963 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:164964 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:164965 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:164966 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014967 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4968 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:164969 ExpectQuicAlternateProtocolMapping();
4970}
4971
Zhongyi Shia0cef1082017-08-25 01:49:504972TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
4973 // Tests that TCP job is delayed and QUIC job does not require confirmation
4974 // if QUIC was recently supported on the same IP on start.
4975
4976 // Set QUIC support on the last IP address, which is same with the local IP
4977 // address. Require confirmation mode will be turned off immediately when
4978 // local IP address is sorted out after we configure the UDP socket.
4979 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
4980
4981 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524982 quic::QuicStreamOffset header_stream_offset = 0;
4983 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4984 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434985 mock_quic_data.AddWrite(
4986 SYNCHRONOUS,
4987 ConstructClientRequestHeadersPacket(
4988 1, GetNthClientInitiatedStreamId(0), true, true,
4989 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4990 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4991 1, GetNthClientInitiatedStreamId(0), false,
4992 false, GetResponseHeaders("200 OK")));
4993 mock_quic_data.AddRead(
4994 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4995 false, true, 0, "hello!"));
4996 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:504997 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4998 mock_quic_data.AddRead(ASYNC, 0); // EOF
4999
5000 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5001 // No HTTP data is mocked as TCP job never starts in this case.
5002
5003 CreateSession();
5004 // QuicStreamFactory by default requires confirmation on construction.
5005 session_->quic_stream_factory()->set_require_confirmation(true);
5006
Ryan Hamilton9835e662018-08-02 05:36:275007 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505008
5009 // Stall host resolution so that QUIC job will not succeed synchronously.
5010 // Socket will not be configured immediately and QUIC support is not sorted
5011 // out, TCP job will still be delayed as server properties indicates QUIC
5012 // support on last IP address.
5013 host_resolver_.set_synchronous_mode(false);
5014
5015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5016 TestCompletionCallback callback;
5017 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5018 IsError(ERR_IO_PENDING));
5019 // Complete host resolution in next message loop so that QUIC job could
5020 // proceed.
5021 base::RunLoop().RunUntilIdle();
5022 EXPECT_THAT(callback.WaitForResult(), IsOk());
5023
5024 CheckWasQuicResponse(&trans);
5025 CheckResponseData(&trans, "hello!");
5026}
5027
5028TEST_P(QuicNetworkTransactionTest,
5029 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5030 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5031 // was recently supported on a different IP address on start.
5032
5033 // Set QUIC support on the last IP address, which is different with the local
5034 // IP address. Require confirmation mode will remain when local IP address is
5035 // sorted out after we configure the UDP socket.
5036 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5037
5038 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525039 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505040 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435041 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5042 mock_quic_data.AddWrite(
5043 SYNCHRONOUS,
5044 ConstructClientRequestHeadersPacket(
5045 2, GetNthClientInitiatedStreamId(0), true, true,
5046 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5047 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5048 1, GetNthClientInitiatedStreamId(0), false,
5049 false, GetResponseHeaders("200 OK")));
5050 mock_quic_data.AddRead(
5051 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5052 false, true, 0, "hello!"));
5053 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505054 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5055 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5056 // No HTTP data is mocked as TCP job will be delayed and never starts.
5057
5058 CreateSession();
5059 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275060 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505061
5062 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5063 // Socket will not be configured immediately and QUIC support is not sorted
5064 // out, TCP job will still be delayed as server properties indicates QUIC
5065 // support on last IP address.
5066 host_resolver_.set_synchronous_mode(false);
5067
5068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5069 TestCompletionCallback callback;
5070 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5071 IsError(ERR_IO_PENDING));
5072
5073 // Complete host resolution in next message loop so that QUIC job could
5074 // proceed.
5075 base::RunLoop().RunUntilIdle();
5076 // Explicitly confirm the handshake so that QUIC job could succeed.
5077 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525078 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505079 EXPECT_THAT(callback.WaitForResult(), IsOk());
5080
5081 CheckWasQuicResponse(&trans);
5082 CheckResponseData(&trans, "hello!");
5083}
5084
Ryan Hamilton75f197262017-08-17 14:00:075085TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5086 // Test that NetErrorDetails is correctly populated, even if the
5087 // handshake has not yet been confirmed and no stream has been created.
5088
5089 // QUIC job will pause. When resumed, it will fail.
5090 MockQuicData mock_quic_data;
5091 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5092 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5093 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5094
5095 // Main job will also fail.
5096 MockRead http_reads[] = {
5097 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5098 };
5099
Ryan Sleevib8d7ea02018-05-07 20:01:015100 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075101 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5102 socket_factory_.AddSocketDataProvider(&http_data);
5103 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5104
5105 AddHangingNonAlternateProtocolSocketData();
5106 CreateSession();
5107 // Require handshake confirmation to ensure that no QUIC streams are
5108 // created, and to ensure that the TCP job does not wait for the QUIC
5109 // job to fail before it starts.
5110 session_->quic_stream_factory()->set_require_confirmation(true);
5111
Ryan Hamilton9835e662018-08-02 05:36:275112 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075113 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5114 TestCompletionCallback callback;
5115 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5117 // Allow the TCP job to fail.
5118 base::RunLoop().RunUntilIdle();
5119 // Now let the QUIC job fail.
5120 mock_quic_data.Resume();
5121 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5122 ExpectQuicAlternateProtocolMapping();
5123 NetErrorDetails details;
5124 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525125 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075126}
5127
[email protected]1e960032013-12-20 19:00:205128TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455129 // Alternate-protocol job
5130 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025131 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455132 };
Ryan Sleevib8d7ea02018-05-07 20:01:015133 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455134 socket_factory_.AddSocketDataProvider(&quic_data);
5135
[email protected]c92c1b52014-05-31 04:16:065136 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015137 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065138 socket_factory_.AddSocketDataProvider(&quic_data2);
5139
[email protected]4d283b32013-10-17 12:57:275140 // Final job that will proceed when the QUIC job fails.
5141 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025142 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5143 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5144 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275145
Ryan Sleevib8d7ea02018-05-07 20:01:015146 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275147 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565148 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275149
rtennetiafccbc062016-05-16 18:21:145150 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325151 CreateSession();
[email protected]77c6c162013-08-17 02:57:455152
Ryan Hamilton9835e662018-08-02 05:36:275153 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455154
[email protected]4d283b32013-10-17 12:57:275155 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455156
5157 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275158
rch37de576c2015-05-17 20:28:175159 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5160 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455161}
5162
[email protected]93b31772014-06-19 08:03:355163TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035164 // Alternate-protocol job
5165 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595166 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035167 };
Ryan Sleevib8d7ea02018-05-07 20:01:015168 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035169 socket_factory_.AddSocketDataProvider(&quic_data);
5170
5171 // Main job that will proceed when the QUIC job fails.
5172 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025173 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5174 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5175 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035176
Ryan Sleevib8d7ea02018-05-07 20:01:015177 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035178 socket_factory_.AddSocketDataProvider(&http_data);
5179
rtennetib8e80fb2016-05-16 00:12:095180 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325181 CreateSession();
[email protected]65768442014-06-06 23:37:035182
Ryan Hamilton9835e662018-08-02 05:36:275183 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035184
5185 SendRequestAndExpectHttpResponse("hello from http");
5186}
5187
[email protected]eb71ab62014-05-23 07:57:535188TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335189 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015190 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495191 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335192 socket_factory_.AddSocketDataProvider(&quic_data);
5193
5194 // Main job which will succeed even though the alternate job fails.
5195 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025196 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5197 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5198 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335199
Ryan Sleevib8d7ea02018-05-07 20:01:015200 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335201 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565202 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335203
rch3f4b8452016-02-23 16:59:325204 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275205 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335206 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535207
5208 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335209}
5210
[email protected]4fee9672014-01-08 14:47:155211TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155212 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435213 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
5214 mock_quic_data.AddWrite(SYNCHRONOUS,
5215 ConstructClientRequestHeadersPacket(
5216 1, GetNthClientInitiatedStreamId(0), true, true,
5217 GetRequestHeaders("GET", "https", "/")));
5218 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
rcha5399e02015-04-21 19:32:045219 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155220
5221 // When the QUIC connection fails, we will try the request again over HTTP.
5222 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485223 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565224 MockRead("hello world"),
5225 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5226 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155227
Ryan Sleevib8d7ea02018-05-07 20:01:015228 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155229 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565230 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155231
5232 // In order for a new QUIC session to be established via alternate-protocol
5233 // without racing an HTTP connection, we need the host resolution to happen
5234 // synchronously.
5235 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295236 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565237 "");
rch9ae5b3b2016-02-11 00:36:295238 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]4fee9672014-01-08 14:47:155239 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105240 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585241 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5242 CompletionOnceCallback(), &request,
5243 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415244 EXPECT_THAT(rv, IsOk());
[email protected]4fee9672014-01-08 14:47:155245
rch3f4b8452016-02-23 16:59:325246 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275247 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]4fee9672014-01-08 14:47:155248 SendRequestAndExpectHttpResponse("hello world");
5249}
5250
tbansalc3308d72016-08-27 10:25:045251// For an alternative proxy that supports QUIC, test that the request is
5252// successfully fetched by the main job when the alternate proxy job encounters
5253// an error.
5254TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5255 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5256}
5257TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5258 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5259}
5260TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5261 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5262}
5263TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5264 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5265}
5266TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5267 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5268}
5269TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5270 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5271}
5272TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5273 TestAlternativeProxy(ERR_IO_PENDING);
5274}
5275TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5276 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5277}
5278
5279TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5280 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435281 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
5282 mock_quic_data.AddWrite(SYNCHRONOUS,
5283 ConstructClientRequestHeadersPacket(
5284 1, GetNthClientInitiatedStreamId(0), true, true,
5285 GetRequestHeaders("GET", "https", "/")));
5286 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045287 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5288
5289 // When the QUIC connection fails, we will try the request again over HTTP.
5290 MockRead http_reads[] = {
5291 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5292 MockRead("hello world"),
5293 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5294 MockRead(ASYNC, OK)};
5295
Ryan Sleevib8d7ea02018-05-07 20:01:015296 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045297 socket_factory_.AddSocketDataProvider(&http_data);
5298 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5299
5300 TestProxyDelegate test_proxy_delegate;
5301 const HostPortPair host_port_pair("myproxy.org", 443);
5302 test_proxy_delegate.set_alternative_proxy_server(
5303 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5304 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5305
mmenke6ddfbea2017-05-31 21:48:415306 session_context_.proxy_delegate = &test_proxy_delegate;
Ramin Halavatica8d5252018-03-12 05:33:495307 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5308 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045309 request_.url = GURL("http://mail.example.org/");
5310
5311 // In order for a new QUIC session to be established via alternate-protocol
5312 // without racing an HTTP connection, we need the host resolution to happen
5313 // synchronously.
5314 host_resolver_.set_synchronous_mode(true);
5315 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
5316 HostResolver::RequestInfo info(HostPortPair("myproxy.org", 443));
5317 AddressList address;
5318 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585319 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5320 CompletionOnceCallback(), &request,
5321 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415322 EXPECT_THAT(rv, IsOk());
tbansalc3308d72016-08-27 10:25:045323
5324 CreateSession();
5325 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595326 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165327 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045328}
5329
bnc508835902015-05-12 20:10:295330TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585331 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385332 EXPECT_FALSE(
5333 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295334 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525335 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365336 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435337 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5338 mock_quic_data.AddWrite(
5339 SYNCHRONOUS,
5340 ConstructClientRequestHeadersPacket(
5341 2, GetNthClientInitiatedStreamId(0), true, true,
5342 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5343 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5344 1, GetNthClientInitiatedStreamId(0), false,
5345 false, GetResponseHeaders("200 OK")));
5346 mock_quic_data.AddRead(
5347 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5348 false, true, 0, "hello!"));
5349 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505350 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295351 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5352
bncb07c05532015-05-14 19:07:205353 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095354 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325355 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275356 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295357 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385358 EXPECT_TRUE(
5359 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295360}
5361
zhongyi363c91c2017-03-23 23:16:085362// TODO(zhongyi): disabled this broken test as it was not testing the correct
5363// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5364TEST_P(QuicNetworkTransactionTest,
5365 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275366 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595367 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495368 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045369
5370 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045371
5372 test_proxy_delegate.set_alternative_proxy_server(
5373 ProxyServer::FromPacString("QUIC mail.example.org:443"));
mmenke6ddfbea2017-05-31 21:48:415374 session_context_.proxy_delegate = &test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045375
5376 request_.url = GURL("http://mail.example.org/");
5377
5378 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5379 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015380 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045381 socket_factory_.AddSocketDataProvider(&socket_data);
5382
5383 // The non-alternate protocol job needs to hang in order to guarantee that
5384 // the alternate-protocol job will "win".
5385 AddHangingNonAlternateProtocolSocketData();
5386
5387 CreateSession();
5388 request_.method = "POST";
5389 ChunkedUploadDataStream upload_data(0);
5390 upload_data.AppendData("1", 1, true);
5391
5392 request_.upload_data_stream = &upload_data;
5393
5394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5395 TestCompletionCallback callback;
5396 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5398 EXPECT_NE(OK, callback.WaitForResult());
5399
5400 // Verify that the alternative proxy server is not marked as broken.
5401 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5402
5403 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595404 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275405
5406 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5407 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5408 1);
tbansalc3308d72016-08-27 10:25:045409}
5410
rtenneti56977812016-01-15 19:26:565411TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415412 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575413 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565414
5415 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5416 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015417 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565418 socket_factory_.AddSocketDataProvider(&socket_data);
5419
rtennetib8e80fb2016-05-16 00:12:095420 // The non-alternate protocol job needs to hang in order to guarantee that
5421 // the alternate-protocol job will "win".
5422 AddHangingNonAlternateProtocolSocketData();
5423
rtenneti56977812016-01-15 19:26:565424 CreateSession();
5425 request_.method = "POST";
5426 ChunkedUploadDataStream upload_data(0);
5427 upload_data.AppendData("1", 1, true);
5428
5429 request_.upload_data_stream = &upload_data;
5430
bnc691fda62016-08-12 00:43:165431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565432 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165433 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565435 EXPECT_NE(OK, callback.WaitForResult());
5436}
5437
rche11300ef2016-09-02 01:44:285438TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:485439 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285440 ScopedMockNetworkChangeNotifier network_change_notifier;
5441 MockNetworkChangeNotifier* mock_ncn =
5442 network_change_notifier.mock_network_change_notifier();
5443 mock_ncn->ForceNetworkHandlesSupported();
5444 mock_ncn->SetConnectedNetworksList(
5445 {kDefaultNetworkForTests, kNewNetworkForTests});
5446
mmenke6ddfbea2017-05-31 21:48:415447 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285448 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:315449 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285450
5451 MockQuicData socket_data;
5452 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525453 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435454 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
5455 socket_data.AddWrite(SYNCHRONOUS,
5456 ConstructClientRequestHeadersPacket(
5457 2, GetNthClientInitiatedStreamId(0), true, false,
5458 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:285459 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5460 socket_data.AddSocketDataToFactory(&socket_factory_);
5461
5462 MockQuicData socket_data2;
5463 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5464 socket_data2.AddSocketDataToFactory(&socket_factory_);
5465
5466 // The non-alternate protocol job needs to hang in order to guarantee that
5467 // the alternate-protocol job will "win".
5468 AddHangingNonAlternateProtocolSocketData();
5469
5470 CreateSession();
5471 request_.method = "POST";
5472 ChunkedUploadDataStream upload_data(0);
5473
5474 request_.upload_data_stream = &upload_data;
5475
rdsmith1d343be52016-10-21 20:37:505476 std::unique_ptr<HttpNetworkTransaction> trans(
5477 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:285478 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:505479 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:285480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5481
5482 base::RunLoop().RunUntilIdle();
5483 upload_data.AppendData("1", 1, true);
5484 base::RunLoop().RunUntilIdle();
5485
5486 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:505487 trans.reset();
rche11300ef2016-09-02 01:44:285488 session_.reset();
5489}
5490
Ryan Hamilton4b3574532017-10-30 20:17:255491TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
5492 session_params_.origins_to_force_quic_on.insert(
5493 HostPortPair::FromString("mail.example.org:443"));
5494
5495 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525496 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435497 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:255498 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Zhongyi Shi32f2fd02018-04-16 18:23:435499 socket_data.AddWrite(SYNCHRONOUS,
5500 ConstructClientRequestHeadersPacket(
5501 2, GetNthClientInitiatedStreamId(0), true, true,
5502 GetRequestHeaders("GET", "https", "/"), &offset));
5503 socket_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5504 1, GetNthClientInitiatedStreamId(0), false,
5505 false, GetResponseHeaders("200 OK")));
5506 socket_data.AddRead(
5507 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5508 false, true, 0, "hello!"));
5509 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255510 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5511
5512 socket_data.AddSocketDataToFactory(&socket_factory_);
5513
5514 CreateSession();
5515
5516 SendRequestAndExpectQuicResponse("hello!");
5517 session_.reset();
5518}
5519
5520TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
5521 session_params_.origins_to_force_quic_on.insert(
5522 HostPortPair::FromString("mail.example.org:443"));
5523
5524 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525525 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435526 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:255527 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Zhongyi Shi32f2fd02018-04-16 18:23:435528 socket_data.AddWrite(SYNCHRONOUS,
5529 ConstructClientRequestHeadersPacket(
5530 2, GetNthClientInitiatedStreamId(0), true, true,
5531 GetRequestHeaders("GET", "https", "/"), &offset));
5532 socket_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5533 1, GetNthClientInitiatedStreamId(0), false,
5534 false, GetResponseHeaders("200 OK")));
5535 socket_data.AddRead(
5536 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5537 false, true, 0, "hello!"));
5538 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255539 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5540
5541 socket_data.AddSocketDataToFactory(&socket_factory_);
5542
5543 CreateSession();
5544
5545 SendRequestAndExpectQuicResponse("hello!");
5546 session_.reset();
5547}
5548
Ryan Hamilton9edcf1a2017-11-22 05:55:175549TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:485550 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:255551 session_params_.origins_to_force_quic_on.insert(
5552 HostPortPair::FromString("mail.example.org:443"));
5553
5554 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525555 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:255556 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:435557 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:175558 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255559 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5560 }
5561 socket_data.AddSocketDataToFactory(&socket_factory_);
5562
5563 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175564 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
5565 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5566 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
5567 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255568
Ryan Hamilton8d9ee76e2018-05-29 23:52:525569 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:255570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5571 TestCompletionCallback callback;
5572 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175574 while (!callback.have_result()) {
5575 base::RunLoop().RunUntilIdle();
5576 quic_task_runner_->RunUntilIdle();
5577 }
5578 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255579 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175580 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5581 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5582 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525583 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
5584 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255585}
5586
Ryan Hamilton9edcf1a2017-11-22 05:55:175587TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:485588 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:255589 session_params_.origins_to_force_quic_on.insert(
5590 HostPortPair::FromString("mail.example.org:443"));
5591
5592 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525593 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:255594 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:435595 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:175596 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255597 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5598 }
5599 socket_data.AddSocketDataToFactory(&socket_factory_);
5600
5601 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175602 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
5603 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5604 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
5605 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255606
Ryan Hamilton8d9ee76e2018-05-29 23:52:525607 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:255608 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5609 TestCompletionCallback callback;
5610 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175612 while (!callback.have_result()) {
5613 base::RunLoop().RunUntilIdle();
5614 quic_task_runner_->RunUntilIdle();
5615 }
5616 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255617 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175618 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5619 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5620 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525621 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
5622 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255623}
5624
Cherie Shi7596de632018-02-22 07:28:185625TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:485626 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:185627 session_params_.origins_to_force_quic_on.insert(
5628 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:525629 const quic::QuicString error_details =
5630 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
5631 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:185632
5633 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525634 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:185635 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435636 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:185637 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
5638 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525639 socket_data.AddWrite(
5640 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
5641 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:185642 socket_data.AddSocketDataToFactory(&socket_factory_);
5643
5644 CreateSession();
5645
5646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5647 TestCompletionCallback callback;
5648 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5650 base::RunLoop().RunUntilIdle();
5651 ASSERT_TRUE(callback.have_result());
5652 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5653 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5654 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5655}
5656
ckrasic769733c2016-06-30 00:42:135657// Adds coverage to catch regression such as https://crbug.com/622043
5658TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:415659 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:135660 HostPortPair::FromString("mail.example.org:443"));
5661
5662 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525663 quic::QuicStreamOffset header_stream_offset = 0;
5664 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:435665 mock_quic_data.AddWrite(
5666 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
5667 &header_stream_offset));
5668 mock_quic_data.AddWrite(
5669 SYNCHRONOUS,
5670 ConstructClientRequestHeadersPacket(
5671 client_packet_number++, GetNthClientInitiatedStreamId(0), true, true,
5672 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:525673 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435674 mock_quic_data.AddRead(
5675 ASYNC,
5676 ConstructServerPushPromisePacket(
5677 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
5678 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
5679 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:575680 if (client_headers_include_h2_stream_dependency_ &&
Ryan Hamilton8d9ee76e2018-05-29 23:52:525681 version_ > quic::QUIC_VERSION_42) {
Zhongyi Shi32f2fd02018-04-16 18:23:435682 mock_quic_data.AddWrite(
5683 SYNCHRONOUS,
5684 ConstructClientPriorityPacket(client_packet_number++, false,
5685 GetNthServerInitiatedStreamId(0),
5686 GetNthClientInitiatedStreamId(0),
5687 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:575688 }
Zhongyi Shi32f2fd02018-04-16 18:23:435689 mock_quic_data.AddRead(
5690 ASYNC, ConstructServerResponseHeadersPacket(
5691 2, GetNthClientInitiatedStreamId(0), false, false,
5692 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:575693 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435694 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
5695 mock_quic_data.AddRead(
5696 ASYNC, ConstructServerResponseHeadersPacket(
5697 3, GetNthServerInitiatedStreamId(0), false, false,
5698 GetResponseHeaders("200 OK"), &server_header_offset));
5699 mock_quic_data.AddRead(
5700 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
5701 false, true, 0, "hello!"));
Yixin Wangb470bc882018-02-15 18:43:575702 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435703 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
5704 mock_quic_data.AddRead(
5705 ASYNC, ConstructServerDataPacket(5, GetNthServerInitiatedStreamId(0),
5706 false, true, 0, "and hello!"));
5707 mock_quic_data.AddWrite(
5708 SYNCHRONOUS, ConstructClientAckAndRstPacket(
5709 client_packet_number++, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:525710 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:135711 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5712 mock_quic_data.AddRead(ASYNC, 0); // EOF
5713 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5714
5715 // The non-alternate protocol job needs to hang in order to guarantee that
5716 // the alternate-protocol job will "win".
5717 AddHangingNonAlternateProtocolSocketData();
5718
5719 CreateSession();
5720
5721 // PUSH_PROMISE handling in the http layer gets exercised here.
5722 SendRequestAndExpectQuicResponse("hello!");
5723
5724 request_.url = GURL("https://mail.example.org/pushed.jpg");
5725 SendRequestAndExpectQuicResponse("and hello!");
5726
5727 // Check that the NetLog was filled reasonably.
5728 TestNetLogEntry::List entries;
5729 net_log_.GetEntries(&entries);
5730 EXPECT_LT(0u, entries.size());
5731
5732 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
5733 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:005734 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
5735 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:135736 EXPECT_LT(0, pos);
5737}
5738
rch56ec40a2017-06-23 14:48:445739// Regression test for http://crbug.com/719461 in which a promised stream
5740// is closed before the pushed headers arrive, but after the connection
5741// is closed and before the callbacks are executed.
5742TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:485743 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:445744 session_params_.origins_to_force_quic_on.insert(
5745 HostPortPair::FromString("mail.example.org:443"));
5746
5747 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525748 quic::QuicStreamOffset header_stream_offset = 0;
5749 quic::QuicPacketNumber client_packet_number = 1;
rch56ec40a2017-06-23 14:48:445750 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:435751 mock_quic_data.AddWrite(
5752 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
5753 &header_stream_offset));
rch56ec40a2017-06-23 14:48:445754 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:435755 mock_quic_data.AddWrite(
5756 SYNCHRONOUS,
5757 ConstructClientRequestHeadersPacket(
5758 client_packet_number++, GetNthClientInitiatedStreamId(0), true, true,
5759 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:525760 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:445761 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:435762 mock_quic_data.AddRead(
5763 ASYNC,
5764 ConstructServerPushPromisePacket(
5765 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
5766 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
5767 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:575768 if (client_headers_include_h2_stream_dependency_ &&
Ryan Hamilton8d9ee76e2018-05-29 23:52:525769 version_ > quic::QUIC_VERSION_42) {
Zhongyi Shi32f2fd02018-04-16 18:23:435770 mock_quic_data.AddWrite(
5771 SYNCHRONOUS,
5772 ConstructClientPriorityPacket(client_packet_number++, false,
5773 GetNthServerInitiatedStreamId(0),
5774 GetNthClientInitiatedStreamId(0),
5775 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:575776 }
rch56ec40a2017-06-23 14:48:445777 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:435778 mock_quic_data.AddRead(
5779 ASYNC, ConstructServerResponseHeadersPacket(
5780 2, GetNthClientInitiatedStreamId(0), false, false,
5781 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:445782 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:575783 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435784 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:445785 // Response body for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:435786 mock_quic_data.AddRead(
5787 ASYNC, ConstructServerDataPacket(3, GetNthClientInitiatedStreamId(0),
5788 false, true, 0, "hello!"));
rch56ec40a2017-06-23 14:48:445789 // Write error for the third request.
5790 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5791 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5792 mock_quic_data.AddRead(ASYNC, 0); // EOF
5793 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5794
5795 CreateSession();
5796
5797 // Send a request which triggers a push promise from the server.
5798 SendRequestAndExpectQuicResponse("hello!");
5799
5800 // Start a push transaction that will be cancelled after the connection
5801 // is closed, but before the callback is executed.
5802 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:195803 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:445804 session_.get());
5805 TestCompletionCallback callback2;
5806 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
5807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5808 base::RunLoop().RunUntilIdle();
5809
5810 // Cause the connection to close on a write error.
5811 HttpRequestInfo request3;
5812 request3.method = "GET";
5813 request3.url = GURL("https://mail.example.org/");
5814 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105815 request3.traffic_annotation =
5816 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:445817 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
5818 TestCompletionCallback callback3;
5819 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
5820 IsError(ERR_IO_PENDING));
5821
5822 base::RunLoop().RunUntilIdle();
5823
5824 // When |trans2| is destroyed, the underlying stream will be closed.
5825 EXPECT_FALSE(callback2.have_result());
5826 trans2 = nullptr;
5827
5828 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5829}
5830
ckrasicda193a82016-07-09 00:39:365831TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:415832 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:365833 HostPortPair::FromString("mail.example.org:443"));
5834
5835 MockQuicData mock_quic_data;
5836
Ryan Hamilton8d9ee76e2018-05-29 23:52:525837 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435838 mock_quic_data.AddWrite(SYNCHRONOUS,
5839 ConstructInitialSettingsPacket(1, &offset));
ckrasicda193a82016-07-09 00:39:365840
Zhongyi Shi32f2fd02018-04-16 18:23:435841 mock_quic_data.AddWrite(
5842 SYNCHRONOUS,
5843 ConstructClientRequestHeadersAndDataFramesPacket(
5844 2, GetNthClientInitiatedStreamId(0), true, true, DEFAULT_PRIORITY,
5845 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr, {"1"}));
ckrasicda193a82016-07-09 00:39:365846
Zhongyi Shi32f2fd02018-04-16 18:23:435847 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5848 1, GetNthClientInitiatedStreamId(0), false,
5849 false, GetResponseHeaders("200 OK")));
ckrasicda193a82016-07-09 00:39:365850
Zhongyi Shi32f2fd02018-04-16 18:23:435851 mock_quic_data.AddRead(
5852 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5853 false, true, 0, "hello!"));
ckrasicda193a82016-07-09 00:39:365854
Zhongyi Shi32f2fd02018-04-16 18:23:435855 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:365856
5857 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5858 mock_quic_data.AddRead(ASYNC, 0); // EOF
5859 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5860
5861 // The non-alternate protocol job needs to hang in order to guarantee that
5862 // the alternate-protocol job will "win".
5863 AddHangingNonAlternateProtocolSocketData();
5864
5865 CreateSession();
5866 request_.method = "POST";
5867 ChunkedUploadDataStream upload_data(0);
5868 upload_data.AppendData("1", 1, true);
5869
5870 request_.upload_data_stream = &upload_data;
5871
5872 SendRequestAndExpectQuicResponse("hello!");
5873}
5874
allada71b2efb2016-09-09 04:57:485875class QuicURLRequestContext : public URLRequestContext {
5876 public:
5877 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
5878 MockClientSocketFactory* socket_factory)
5879 : storage_(this) {
5880 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:075881 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:045882 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:485883 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:045884 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:595885 storage_.set_proxy_resolution_service(
5886 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:075887 storage_.set_ssl_config_service(
5888 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:485889 storage_.set_http_auth_handler_factory(
5890 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
5891 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:075892 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:045893 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:485894 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:045895 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
5896 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
5897 false));
allada71b2efb2016-09-09 04:57:485898 }
5899
5900 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
5901
5902 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
5903
5904 private:
5905 MockClientSocketFactory* socket_factory_;
5906 URLRequestContextStorage storage_;
5907};
5908
5909TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:415910 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:485911 HostPortPair::FromString("mail.example.org:443"));
5912
5913 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525914 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365915 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435916 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:135917 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:485918 headers["user-agent"] = "";
5919 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:435920 mock_quic_data.AddWrite(SYNCHRONOUS,
5921 ConstructClientRequestHeadersPacket(
5922 2, GetNthClientInitiatedStreamId(0), true, true,
5923 std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:485924
Ryan Hamilton8d9ee76e2018-05-29 23:52:525925 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435926 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5927 1, GetNthClientInitiatedStreamId(0), false,
5928 false, GetResponseHeaders("200 OK"),
5929 &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:485930
ckrasicbf2f59c2017-05-04 23:54:365931 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:435932 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5933 false, true, 0, "Main Resource Data"));
5934 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:485935
5936 mock_quic_data.AddRead(ASYNC, 0); // EOF
5937
5938 CreateSession();
5939
5940 TestDelegate delegate;
5941 QuicURLRequestContext quic_url_request_context(std::move(session_),
5942 &socket_factory_);
5943
5944 mock_quic_data.AddSocketDataToFactory(
5945 &quic_url_request_context.socket_factory());
5946 TestNetworkDelegate network_delegate;
5947 quic_url_request_context.set_network_delegate(&network_delegate);
5948
5949 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:295950 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
5951 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:485952 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
5953 &ssl_data_);
5954
5955 request->Start();
Wez2a31b222018-06-07 22:07:155956 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:485957
5958 EXPECT_LT(0, request->GetTotalSentBytes());
5959 EXPECT_LT(0, request->GetTotalReceivedBytes());
5960 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
5961 request->GetTotalSentBytes());
5962 EXPECT_EQ(network_delegate.total_network_bytes_received(),
5963 request->GetTotalReceivedBytes());
5964 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
5965 request->raw_header_size());
Wez0e717112018-06-18 23:09:225966
5967 // Pump the message loop to allow all data to be consumed.
5968 base::RunLoop().RunUntilIdle();
5969
allada71b2efb2016-09-09 04:57:485970 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
5971 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
5972}
5973
5974TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:415975 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:485976 HostPortPair::FromString("mail.example.org:443"));
5977
5978 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525979 quic::QuicStreamOffset header_stream_offset = 0;
5980 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:435981 mock_quic_data.AddWrite(
5982 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
5983 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:135984 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:485985 headers["user-agent"] = "";
5986 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:435987 mock_quic_data.AddWrite(
5988 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5989 client_packet_number++, GetNthClientInitiatedStreamId(0),
5990 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:485991
Ryan Hamilton8d9ee76e2018-05-29 23:52:525992 quic::QuicStreamOffset server_header_offset = 0;
5993 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:485994
Zhongyi Shi32f2fd02018-04-16 18:23:435995 mock_quic_data.AddRead(
5996 ASYNC,
5997 ConstructServerPushPromisePacket(
5998 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
5999 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
6000 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486001
Yixin Wangb470bc882018-02-15 18:43:576002 if (client_headers_include_h2_stream_dependency_ &&
Ryan Hamilton8d9ee76e2018-05-29 23:52:526003 version_ > quic::QUIC_VERSION_42) {
Zhongyi Shi32f2fd02018-04-16 18:23:436004 mock_quic_data.AddWrite(
6005 SYNCHRONOUS,
6006 ConstructClientPriorityPacket(client_packet_number++, false,
6007 GetNthServerInitiatedStreamId(0),
6008 GetNthClientInitiatedStreamId(0),
6009 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576010 }
6011
allada71b2efb2016-09-09 04:57:486012 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436013 mock_quic_data.AddRead(
6014 ASYNC, ConstructServerResponseHeadersPacket(
6015 2, GetNthClientInitiatedStreamId(0), false, false,
6016 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486017 expected_raw_header_response_size =
6018 server_header_offset - expected_raw_header_response_size;
6019
Yixin Wangb470bc882018-02-15 18:43:576020 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436021 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486022
ckrasicbf2f59c2017-05-04 23:54:366023 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436024 ASYNC, ConstructServerResponseHeadersPacket(
6025 3, GetNthServerInitiatedStreamId(0), false, false,
6026 GetResponseHeaders("200 OK"), &server_header_offset));
6027 mock_quic_data.AddRead(
6028 ASYNC, ConstructServerDataPacket(4, GetNthServerInitiatedStreamId(0),
6029 false, true, 0, "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486030
Yixin Wangb470bc882018-02-15 18:43:576031 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436032 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
ckrasicbf2f59c2017-05-04 23:54:366033 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436034 ASYNC, ConstructServerDataPacket(5, GetNthClientInitiatedStreamId(0),
6035 false, true, 0, "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486036
Zhongyi Shi32f2fd02018-04-16 18:23:436037 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486038
6039 CreateSession();
6040
6041 TestDelegate delegate;
6042 QuicURLRequestContext quic_url_request_context(std::move(session_),
6043 &socket_factory_);
6044
6045 mock_quic_data.AddSocketDataToFactory(
6046 &quic_url_request_context.socket_factory());
6047 TestNetworkDelegate network_delegate;
6048 quic_url_request_context.set_network_delegate(&network_delegate);
6049
6050 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296051 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6052 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486053 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6054 &ssl_data_);
6055
6056 request->Start();
Wez2a31b222018-06-07 22:07:156057 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486058
6059 EXPECT_LT(0, request->GetTotalSentBytes());
6060 EXPECT_LT(0, request->GetTotalReceivedBytes());
6061 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6062 request->GetTotalSentBytes());
6063 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6064 request->GetTotalReceivedBytes());
6065 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6066 request->raw_header_size());
Wez0e717112018-06-18 23:09:226067
6068 // Pump the message loop to allow all data to be consumed.
6069 base::RunLoop().RunUntilIdle();
6070
allada71b2efb2016-09-09 04:57:486071 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6072 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6073}
6074
Yixin Wang10f477ed2017-11-21 04:20:206075TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6076 session_params_.quic_host_whitelist.insert("mail.example.org");
6077
6078 MockRead http_reads[] = {
6079 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6080 MockRead("hello world"),
6081 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6082 MockRead(ASYNC, OK)};
6083
Ryan Sleevib8d7ea02018-05-07 20:01:016084 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206085 socket_factory_.AddSocketDataProvider(&http_data);
6086 AddCertificate(&ssl_data_);
6087 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6088
6089 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526090 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206091 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436092 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6093 mock_quic_data.AddWrite(
6094 SYNCHRONOUS,
6095 ConstructClientRequestHeadersPacket(
6096 2, GetNthClientInitiatedStreamId(0), true, true,
6097 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
6098 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6099 1, GetNthClientInitiatedStreamId(0), false,
6100 false, GetResponseHeaders("200 OK")));
6101 mock_quic_data.AddRead(
6102 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6103 false, true, 0, "hello!"));
6104 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206105 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6106 mock_quic_data.AddRead(ASYNC, 0); // EOF
6107
6108 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6109
6110 AddHangingNonAlternateProtocolSocketData();
6111 CreateSession();
6112
6113 SendRequestAndExpectHttpResponse("hello world");
6114 SendRequestAndExpectQuicResponse("hello!");
6115}
6116
6117TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6118 session_params_.quic_host_whitelist.insert("mail.example.com");
6119
6120 MockRead http_reads[] = {
6121 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6122 MockRead("hello world"),
6123 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6124 MockRead(ASYNC, OK)};
6125
Ryan Sleevib8d7ea02018-05-07 20:01:016126 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206127 socket_factory_.AddSocketDataProvider(&http_data);
6128 AddCertificate(&ssl_data_);
6129 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6130 socket_factory_.AddSocketDataProvider(&http_data);
6131 AddCertificate(&ssl_data_);
6132 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6133
6134 AddHangingNonAlternateProtocolSocketData();
6135 CreateSession();
6136
6137 SendRequestAndExpectHttpResponse("hello world");
6138 SendRequestAndExpectHttpResponse("hello world");
6139}
6140
bnc359ed2a2016-04-29 20:43:456141class QuicNetworkTransactionWithDestinationTest
6142 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016143 public ::testing::WithParamInterface<PoolingTestParams>,
6144 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456145 protected:
6146 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556147 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056148 client_headers_include_h2_stream_dependency_(
6149 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526150 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456151 destination_type_(GetParam().destination_type),
6152 cert_transparency_verifier_(new MultiLogCTVerifier()),
6153 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596154 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456155 auth_handler_factory_(
6156 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6157 random_generator_(0),
6158 ssl_data_(ASYNC, OK) {}
6159
6160 void SetUp() override {
6161 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556162 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456163
mmenke6ddfbea2017-05-31 21:48:416164 HttpNetworkSession::Params session_params;
6165 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346166 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446167 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056168 session_params.quic_headers_include_h2_stream_dependency =
6169 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416170
6171 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456172
Ryan Hamilton8d9ee76e2018-05-29 23:52:526173 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416174 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456175
6176 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276177 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416178 session_context.quic_crypto_client_stream_factory =
6179 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456180
mmenke6ddfbea2017-05-31 21:48:416181 session_context.quic_random = &random_generator_;
6182 session_context.client_socket_factory = &socket_factory_;
6183 session_context.host_resolver = &host_resolver_;
6184 session_context.cert_verifier = &cert_verifier_;
6185 session_context.transport_security_state = &transport_security_state_;
6186 session_context.cert_transparency_verifier =
6187 cert_transparency_verifier_.get();
6188 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6189 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456190 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416191 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596192 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416193 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6194 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456195
mmenke6ddfbea2017-05-31 21:48:416196 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456197 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456198 }
6199
6200 void TearDown() override {
6201 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6202 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556203 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456204 PlatformTest::TearDown();
6205 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556206 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406207 session_.reset();
bnc359ed2a2016-04-29 20:43:456208 }
6209
zhongyie537a002017-06-27 16:48:216210 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456211 HostPortPair destination;
6212 switch (destination_type_) {
6213 case SAME_AS_FIRST:
6214 destination = HostPortPair(origin1_, 443);
6215 break;
6216 case SAME_AS_SECOND:
6217 destination = HostPortPair(origin2_, 443);
6218 break;
6219 case DIFFERENT:
6220 destination = HostPortPair(kDifferentHostname, 443);
6221 break;
6222 }
bnc3472afd2016-11-17 15:27:216223 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456224 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216225 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456226 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446227 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456228 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526229 std::unique_ptr<quic::QuicEncryptedPacket>
6230 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6231 quic::QuicStreamId stream_id,
6232 bool should_include_version,
6233 quic::QuicStreamOffset* offset,
6234 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486235 return ConstructClientRequestHeadersPacket(
6236 packet_number, stream_id, should_include_version, 0, offset, maker);
6237 }
bnc359ed2a2016-04-29 20:43:456238
Ryan Hamilton8d9ee76e2018-05-29 23:52:526239 std::unique_ptr<quic::QuicEncryptedPacket>
6240 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6241 quic::QuicStreamId stream_id,
6242 bool should_include_version,
6243 quic::QuicStreamId parent_stream_id,
6244 quic::QuicStreamOffset* offset,
6245 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136246 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456247 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136248 spdy::SpdyHeaderBlock headers(
6249 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456250 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6251 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486252 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456253 }
6254
Ryan Hamilton8d9ee76e2018-05-29 23:52:526255 std::unique_ptr<quic::QuicEncryptedPacket>
6256 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6257 quic::QuicStreamId stream_id,
6258 bool should_include_version,
6259 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586260 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456261 packet_number, stream_id, should_include_version, nullptr, maker);
6262 }
6263
Ryan Hamilton8d9ee76e2018-05-29 23:52:526264 std::unique_ptr<quic::QuicEncryptedPacket>
6265 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6266 quic::QuicStreamId stream_id,
6267 quic::QuicStreamOffset* offset,
6268 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136269 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456270 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266271 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456272 }
6273
Ryan Hamilton8d9ee76e2018-05-29 23:52:526274 std::unique_ptr<quic::QuicEncryptedPacket>
6275 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6276 quic::QuicStreamId stream_id,
6277 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586278 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6279 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456280 }
6281
Ryan Hamilton8d9ee76e2018-05-29 23:52:526282 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
6283 quic::QuicPacketNumber packet_number,
6284 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456285 QuicTestPacketMaker* maker) {
6286 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
6287 "hello");
6288 }
6289
Ryan Hamilton8d9ee76e2018-05-29 23:52:526290 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
6291 quic::QuicPacketNumber packet_number,
6292 quic::QuicPacketNumber largest_received,
6293 quic::QuicPacketNumber smallest_received,
6294 quic::QuicPacketNumber least_unacked,
bnc359ed2a2016-04-29 20:43:456295 QuicTestPacketMaker* maker) {
6296 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496297 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456298 }
6299
Ryan Hamilton8d9ee76e2018-05-29 23:52:526300 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
6301 quic::QuicPacketNumber packet_number,
6302 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376303 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366304 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376305 }
6306
bnc359ed2a2016-04-29 20:43:456307 void AddRefusedSocketData() {
6308 std::unique_ptr<StaticSocketDataProvider> refused_data(
6309 new StaticSocketDataProvider());
6310 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6311 refused_data->set_connect_data(refused_connect);
6312 socket_factory_.AddSocketDataProvider(refused_data.get());
6313 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6314 }
6315
6316 void AddHangingSocketData() {
6317 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6318 new StaticSocketDataProvider());
6319 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6320 hanging_data->set_connect_data(hanging_connect);
6321 socket_factory_.AddSocketDataProvider(hanging_data.get());
6322 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6323 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6324 }
6325
6326 bool AllDataConsumed() {
6327 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6328 if (!socket_data_ptr->AllReadDataConsumed() ||
6329 !socket_data_ptr->AllWriteDataConsumed()) {
6330 return false;
6331 }
6332 }
6333 return true;
6334 }
6335
6336 void SendRequestAndExpectQuicResponse(const std::string& host) {
6337 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6338 HttpRequestInfo request;
6339 std::string url("https://");
6340 url.append(host);
6341 request.url = GURL(url);
6342 request.load_flags = 0;
6343 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106344 request.traffic_annotation =
6345 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456346 TestCompletionCallback callback;
6347 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016348 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456349
6350 std::string response_data;
robpercival214763f2016-07-01 23:27:016351 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456352 EXPECT_EQ("hello", response_data);
6353
6354 const HttpResponseInfo* response = trans.GetResponseInfo();
6355 ASSERT_TRUE(response != nullptr);
6356 ASSERT_TRUE(response->headers.get() != nullptr);
6357 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6358 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526359 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:446360 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:456361 response->connection_info);
6362 EXPECT_EQ(443, response->socket_address.port());
6363 }
6364
Ryan Hamilton8d9ee76e2018-05-29 23:52:526365 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
6366 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:366367 }
6368
Ryan Hamilton8d9ee76e2018-05-29 23:52:526369 quic::MockClock clock_;
6370 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:056371 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526372 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456373 DestinationType destination_type_;
6374 std::string origin1_;
6375 std::string origin2_;
6376 std::unique_ptr<HttpNetworkSession> session_;
6377 MockClientSocketFactory socket_factory_;
6378 MockHostResolver host_resolver_;
6379 MockCertVerifier cert_verifier_;
6380 TransportSecurityState transport_security_state_;
6381 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236382 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456383 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076384 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596385 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456386 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526387 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:456388 HttpServerPropertiesImpl http_server_properties_;
6389 BoundTestNetLog net_log_;
6390 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6391 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6392 static_socket_data_provider_vector_;
6393 SSLSocketDataProvider ssl_data_;
6394};
6395
Bence Békyce380cb2018-04-26 23:39:556396INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
bnc359ed2a2016-04-29 20:43:456397 QuicNetworkTransactionWithDestinationTest,
6398 ::testing::ValuesIn(GetPoolingTestParams()));
6399
6400// A single QUIC request fails because the certificate does not match the origin
6401// hostname, regardless of whether it matches the alternative service hostname.
6402TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6403 if (destination_type_ == DIFFERENT)
6404 return;
6405
6406 GURL url("https://mail.example.com/");
6407 origin1_ = url.host();
6408
6409 // Not used for requests, but this provides a test case where the certificate
6410 // is valid for the hostname of the alternative service.
6411 origin2_ = "mail.example.org";
6412
zhongyie537a002017-06-27 16:48:216413 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456414
6415 scoped_refptr<X509Certificate> cert(
6416 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246417 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
6418 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:456419
6420 ProofVerifyDetailsChromium verify_details;
6421 verify_details.cert_verify_result.verified_cert = cert;
6422 verify_details.cert_verify_result.is_issued_by_known_root = true;
6423 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6424
6425 MockQuicData mock_quic_data;
6426 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6427 mock_quic_data.AddRead(ASYNC, 0);
6428
6429 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6430
6431 AddRefusedSocketData();
6432
6433 HttpRequestInfo request;
6434 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:106435 request.traffic_annotation =
6436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456437
6438 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6439 TestCompletionCallback callback;
6440 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016441 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:456442
6443 EXPECT_TRUE(AllDataConsumed());
6444}
6445
6446// First request opens QUIC session to alternative service. Second request
6447// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:526448// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:456449TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
6450 origin1_ = "mail.example.org";
6451 origin2_ = "news.example.org";
6452
zhongyie537a002017-06-27 16:48:216453 SetQuicAlternativeService(origin1_);
6454 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456455
6456 scoped_refptr<X509Certificate> cert(
6457 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246458 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
6459 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
6460 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456461
6462 ProofVerifyDetailsChromium verify_details;
6463 verify_details.cert_verify_result.verified_cert = cert;
6464 verify_details.cert_verify_result.is_issued_by_known_root = true;
6465 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6466
Yixin Wang079ad542018-01-11 04:06:056467 QuicTestPacketMaker client_maker(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526468 version_, 0, &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:056469 client_headers_include_h2_stream_dependency_);
6470 QuicTestPacketMaker server_maker(version_, 0, &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526471 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456472
Ryan Hamilton8d9ee76e2018-05-29 23:52:526473 quic::QuicStreamOffset request_header_offset(0);
6474 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:456475
6476 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:056477 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436478 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:056479 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436480 mock_quic_data.AddWrite(SYNCHRONOUS,
6481 ConstructClientRequestHeadersPacket(
6482 2, GetNthClientInitiatedStreamId(0), true,
6483 &request_header_offset, &client_maker));
6484 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6485 1, GetNthClientInitiatedStreamId(0),
6486 &response_header_offset, &server_maker));
6487 mock_quic_data.AddRead(
6488 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6489 &server_maker));
6490 mock_quic_data.AddWrite(SYNCHRONOUS,
6491 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:456492
Yixin Wang079ad542018-01-11 04:06:056493 client_maker.set_hostname(origin2_);
6494 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:456495
Zhongyi Shi32f2fd02018-04-16 18:23:436496 mock_quic_data.AddWrite(
6497 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6498 4, GetNthClientInitiatedStreamId(1), false,
6499 GetNthClientInitiatedStreamId(0), &request_header_offset,
6500 &client_maker));
6501 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6502 3, GetNthClientInitiatedStreamId(1),
6503 &response_header_offset, &server_maker));
6504 mock_quic_data.AddRead(
6505 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
6506 &server_maker));
6507 mock_quic_data.AddWrite(SYNCHRONOUS,
6508 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:456509 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6510 mock_quic_data.AddRead(ASYNC, 0); // EOF
6511
6512 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6513
6514 AddHangingSocketData();
6515 AddHangingSocketData();
6516
6517 SendRequestAndExpectQuicResponse(origin1_);
6518 SendRequestAndExpectQuicResponse(origin2_);
6519
6520 EXPECT_TRUE(AllDataConsumed());
6521}
6522
6523// First request opens QUIC session to alternative service. Second request does
6524// not pool to it, even though destination matches, because certificate is not
6525// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:526526// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:456527TEST_P(QuicNetworkTransactionWithDestinationTest,
6528 DoNotPoolIfCertificateInvalid) {
6529 origin1_ = "news.example.org";
6530 origin2_ = "mail.example.com";
6531
zhongyie537a002017-06-27 16:48:216532 SetQuicAlternativeService(origin1_);
6533 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456534
6535 scoped_refptr<X509Certificate> cert1(
6536 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246537 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
6538 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
6539 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456540
6541 scoped_refptr<X509Certificate> cert2(
6542 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246543 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
6544 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456545
6546 ProofVerifyDetailsChromium verify_details1;
6547 verify_details1.cert_verify_result.verified_cert = cert1;
6548 verify_details1.cert_verify_result.is_issued_by_known_root = true;
6549 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
6550
6551 ProofVerifyDetailsChromium verify_details2;
6552 verify_details2.cert_verify_result.verified_cert = cert2;
6553 verify_details2.cert_verify_result.is_issued_by_known_root = true;
6554 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
6555
Yixin Wang079ad542018-01-11 04:06:056556 QuicTestPacketMaker client_maker1(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526557 version_, 0, &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:056558 client_headers_include_h2_stream_dependency_);
rchbf4c26d2017-04-16 23:17:556559 QuicTestPacketMaker server_maker1(version_, 0, &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526560 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456561
6562 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526563 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:456564 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436565 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
6566 &client_maker1));
6567 mock_quic_data1.AddWrite(SYNCHRONOUS,
6568 ConstructClientRequestHeadersPacket(
6569 2, GetNthClientInitiatedStreamId(0), true,
6570 &header_stream_offset1, &client_maker1));
6571 mock_quic_data1.AddRead(
6572 ASYNC, ConstructServerResponseHeadersPacket(
6573 1, GetNthClientInitiatedStreamId(0), &server_maker1));
6574 mock_quic_data1.AddRead(
6575 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6576 &server_maker1));
6577 mock_quic_data1.AddWrite(
6578 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:456579 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6580 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6581
6582 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6583
Yixin Wang079ad542018-01-11 04:06:056584 QuicTestPacketMaker client_maker2(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526585 version_, 0, &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:056586 client_headers_include_h2_stream_dependency_);
rchbf4c26d2017-04-16 23:17:556587 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526588 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456589
6590 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526591 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:456592 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436593 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
6594 &client_maker2));
6595 mock_quic_data2.AddWrite(SYNCHRONOUS,
6596 ConstructClientRequestHeadersPacket(
6597 2, GetNthClientInitiatedStreamId(0), true,
6598 &header_stream_offset2, &client_maker2));
6599 mock_quic_data2.AddRead(
6600 ASYNC, ConstructServerResponseHeadersPacket(
6601 1, GetNthClientInitiatedStreamId(0), &server_maker2));
6602 mock_quic_data2.AddRead(
6603 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6604 &server_maker2));
6605 mock_quic_data2.AddWrite(
6606 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:456607 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6608 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6609
6610 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6611
bnc359ed2a2016-04-29 20:43:456612 SendRequestAndExpectQuicResponse(origin1_);
6613 SendRequestAndExpectQuicResponse(origin2_);
6614
6615 EXPECT_TRUE(AllDataConsumed());
6616}
6617
ckrasicdee37572017-04-06 22:42:276618// crbug.com/705109 - this confirms that matching request with a body
6619// triggers a crash (pre-fix).
6620TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:416621 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:276622 HostPortPair::FromString("mail.example.org:443"));
6623
6624 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526625 quic::QuicStreamOffset header_stream_offset = 0;
6626 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436627 mock_quic_data.AddWrite(
6628 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6629 &header_stream_offset));
6630 mock_quic_data.AddWrite(
6631 SYNCHRONOUS,
6632 ConstructClientRequestHeadersPacket(
6633 client_packet_number++, GetNthClientInitiatedStreamId(0), true, true,
6634 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526635 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436636 mock_quic_data.AddRead(
6637 ASYNC,
6638 ConstructServerPushPromisePacket(
6639 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
6640 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
6641 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576642 if (client_headers_include_h2_stream_dependency_ &&
Ryan Hamilton8d9ee76e2018-05-29 23:52:526643 version_ > quic::QUIC_VERSION_42) {
Zhongyi Shi32f2fd02018-04-16 18:23:436644 mock_quic_data.AddWrite(
6645 SYNCHRONOUS,
6646 ConstructClientPriorityPacket(client_packet_number++, false,
6647 GetNthServerInitiatedStreamId(0),
6648 GetNthClientInitiatedStreamId(0),
6649 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576650 }
Zhongyi Shi32f2fd02018-04-16 18:23:436651 mock_quic_data.AddRead(
6652 ASYNC, ConstructServerResponseHeadersPacket(
6653 2, GetNthClientInitiatedStreamId(0), false, false,
6654 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576655 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436656 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6657 mock_quic_data.AddRead(
6658 ASYNC, ConstructServerResponseHeadersPacket(
6659 3, GetNthServerInitiatedStreamId(0), false, false,
6660 GetResponseHeaders("200 OK"), &server_header_offset));
6661 mock_quic_data.AddRead(
6662 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
6663 false, true, 0, "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576664 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436665 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
6666 mock_quic_data.AddRead(
6667 ASYNC, ConstructServerDataPacket(5, GetNthServerInitiatedStreamId(0),
6668 false, true, 0, "and hello!"));
ckrasicdee37572017-04-06 22:42:276669
6670 // Because the matching request has a body, we will see the push
6671 // stream get cancelled, and the matching request go out on the
6672 // wire.
Zhongyi Shi32f2fd02018-04-16 18:23:436673 mock_quic_data.AddWrite(
6674 SYNCHRONOUS, ConstructClientAckAndRstPacket(
6675 client_packet_number++, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526676 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:276677 const char kBody[] = "1";
Zhongyi Shi32f2fd02018-04-16 18:23:436678 mock_quic_data.AddWrite(
6679 SYNCHRONOUS,
6680 ConstructClientRequestHeadersAndDataFramesPacket(
6681 client_packet_number++, GetNthClientInitiatedStreamId(1), false, true,
6682 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
6683 GetNthServerInitiatedStreamId(0), &header_stream_offset, nullptr,
6684 {kBody}));
ckrasicdee37572017-04-06 22:42:276685
6686 // We see the same response as for the earlier pushed and cancelled
6687 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:436688 mock_quic_data.AddRead(
6689 ASYNC, ConstructServerResponseHeadersPacket(
6690 6, GetNthClientInitiatedStreamId(1), false, false,
6691 GetResponseHeaders("200 OK"), &server_header_offset));
6692 mock_quic_data.AddRead(
6693 ASYNC, ConstructServerDataPacket(7, GetNthClientInitiatedStreamId(1),
6694 false, true, 0, "and hello!"));
ckrasicdee37572017-04-06 22:42:276695
Yixin Wangb470bc882018-02-15 18:43:576696 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436697 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:276698 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6699 mock_quic_data.AddRead(ASYNC, 0); // EOF
6700 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6701
6702 // The non-alternate protocol job needs to hang in order to guarantee that
6703 // the alternate-protocol job will "win".
6704 AddHangingNonAlternateProtocolSocketData();
6705
6706 CreateSession();
6707
6708 // PUSH_PROMISE handling in the http layer gets exercised here.
6709 SendRequestAndExpectQuicResponse("hello!");
6710
6711 request_.url = GURL("https://mail.example.org/pushed.jpg");
6712 ChunkedUploadDataStream upload_data(0);
6713 upload_data.AppendData("1", 1, true);
6714 request_.upload_data_stream = &upload_data;
6715 SendRequestAndExpectQuicResponse("and hello!");
6716}
6717
Bence Béky7538a952018-02-01 16:59:526718// Regression test for https://crbug.com/797825: If pushed headers describe a
6719// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
6720// not be called (otherwise a DCHECK fails).
6721TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:136722 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:526723 pushed_request_headers[":authority"] = "";
6724 pushed_request_headers[":method"] = "GET";
6725 pushed_request_headers[":path"] = "/";
6726 pushed_request_headers[":scheme"] = "nosuchscheme";
6727
6728 session_params_.origins_to_force_quic_on.insert(
6729 HostPortPair::FromString("mail.example.org:443"));
6730
6731 MockQuicData mock_quic_data;
6732
Ryan Hamilton8d9ee76e2018-05-29 23:52:526733 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:526734 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436735 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6736 mock_quic_data.AddWrite(
6737 SYNCHRONOUS,
6738 ConstructClientRequestHeadersPacket(
6739 2, GetNthClientInitiatedStreamId(0), true, true,
6740 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:526741
Ryan Hamilton8d9ee76e2018-05-29 23:52:526742 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436743 mock_quic_data.AddRead(ASYNC, ConstructServerPushPromisePacket(
6744 1, GetNthClientInitiatedStreamId(0),
6745 GetNthServerInitiatedStreamId(0), false,
6746 std::move(pushed_request_headers),
6747 &server_header_offset, &server_maker_));
6748 mock_quic_data.AddWrite(
6749 SYNCHRONOUS, ConstructClientRstPacket(3, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526750 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:526751
Zhongyi Shi32f2fd02018-04-16 18:23:436752 mock_quic_data.AddRead(
6753 ASYNC, ConstructServerResponseHeadersPacket(
6754 2, GetNthClientInitiatedStreamId(0), false, false,
6755 GetResponseHeaders("200 OK"), &server_header_offset));
6756 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:526757
Zhongyi Shi32f2fd02018-04-16 18:23:436758 mock_quic_data.AddRead(
6759 ASYNC, ConstructServerResponseHeadersPacket(
6760 3, GetNthServerInitiatedStreamId(0), false, false,
6761 GetResponseHeaders("200 OK"), &server_header_offset));
6762 mock_quic_data.AddRead(
6763 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
6764 false, true, 0, "hello!"));
6765 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:526766
6767 mock_quic_data.AddRead(ASYNC, 0);
6768 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6769
6770 // The non-alternate protocol job needs to hang in order to guarantee that
6771 // the alternate-protocol job will "win".
6772 AddHangingNonAlternateProtocolSocketData();
6773
6774 CreateSession();
6775
6776 // PUSH_PROMISE handling in the http layer gets exercised here.
6777 SendRequestAndExpectQuicResponse("hello!");
6778
6779 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6780 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6781}
6782
Yixin Wang46a273ec302018-01-23 17:59:566783// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
6784TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
6785 session_params_.enable_quic = true;
6786 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496787 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566788
6789 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526790 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:566791 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436792 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6793 mock_quic_data.AddWrite(SYNCHRONOUS,
6794 ConstructClientRequestHeadersPacket(
6795 2, GetNthClientInitiatedStreamId(0), true, false,
6796 ConnectRequestHeaders("mail.example.org:443"),
6797 &header_stream_offset));
6798 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6799 1, GetNthClientInitiatedStreamId(0), false,
6800 false, GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:566801
6802 const char get_request[] =
6803 "GET / HTTP/1.1\r\n"
6804 "Host: mail.example.org\r\n"
6805 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436806 mock_quic_data.AddWrite(
6807 SYNCHRONOUS, ConstructClientAckAndDataPacket(
6808 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526809 false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:566810 const char get_response[] =
6811 "HTTP/1.1 200 OK\r\n"
6812 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436813 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526814 ASYNC,
6815 ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0), false,
6816 false, 0, quic::QuicStringPiece(get_response)));
6817
6818 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
6819 3, GetNthClientInitiatedStreamId(0),
6820 false, false, strlen(get_response),
6821 quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:436822 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:566823 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6824
6825 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526826 SYNCHRONOUS, ConstructClientRstPacket(5, GetNthClientInitiatedStreamId(0),
6827 quic::QUIC_STREAM_CANCELLED,
6828 strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:566829
6830 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6831
6832 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6833
6834 CreateSession();
6835
6836 request_.url = GURL("https://mail.example.org/");
6837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6838 HeadersHandler headers_handler;
6839 trans.SetBeforeHeadersSentCallback(
6840 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
6841 base::Unretained(&headers_handler)));
6842 RunTransaction(&trans);
6843 CheckWasHttpResponse(&trans);
6844 CheckResponsePort(&trans, 70);
6845 CheckResponseData(&trans, "0123456789");
6846 EXPECT_TRUE(headers_handler.was_proxied());
6847 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
6848
6849 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6850 // proxy socket to disconnect.
6851 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6852
6853 base::RunLoop().RunUntilIdle();
6854 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6855 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6856}
6857
6858// Performs an HTTP/2 request over QUIC proxy tunnel.
6859TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
6860 session_params_.enable_quic = true;
6861 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496862 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566863
6864 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526865 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:566866 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436867 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6868 mock_quic_data.AddWrite(SYNCHRONOUS,
6869 ConstructClientRequestHeadersPacket(
6870 2, GetNthClientInitiatedStreamId(0), true, false,
6871 ConnectRequestHeaders("mail.example.org:443"),
6872 &header_stream_offset));
6873 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6874 1, GetNthClientInitiatedStreamId(0), false,
6875 false, GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:566876
6877 SpdyTestUtil spdy_util;
6878
Ryan Hamilton0239aac2018-05-19 00:03:136879 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:566880 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Zhongyi Shi32f2fd02018-04-16 18:23:436881 mock_quic_data.AddWrite(
6882 SYNCHRONOUS,
6883 ConstructClientAckAndDataPacket(
6884 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526885 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Ryan Hamilton0239aac2018-05-19 00:03:136886 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:566887 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:436888 mock_quic_data.AddRead(
6889 ASYNC, ConstructServerDataPacket(
6890 2, GetNthClientInitiatedStreamId(0), false, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526891 quic::QuicStringPiece(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:566892
Ryan Hamilton0239aac2018-05-19 00:03:136893 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:196894 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:436895 mock_quic_data.AddRead(
6896 SYNCHRONOUS,
6897 ConstructServerDataPacket(
6898 3, GetNthClientInitiatedStreamId(0), false, false, resp_frame.size(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526899 quic::QuicStringPiece(data_frame.data(), data_frame.size())));
Zhongyi Shi32f2fd02018-04-16 18:23:436900 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:566901 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6902
6903 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436904 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:566905 ConstructClientRstPacket(5, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526906 quic::QUIC_STREAM_CANCELLED, get_frame.size()));
Yixin Wang46a273ec302018-01-23 17:59:566907
6908 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6909
6910 SSLSocketDataProvider ssl_data(ASYNC, OK);
6911 ssl_data.next_proto = kProtoHTTP2;
6912 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
6913
6914 CreateSession();
6915
6916 request_.url = GURL("https://mail.example.org/");
6917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6918 HeadersHandler headers_handler;
6919 trans.SetBeforeHeadersSentCallback(
6920 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
6921 base::Unretained(&headers_handler)));
6922 RunTransaction(&trans);
6923 CheckWasSpdyResponse(&trans);
6924 CheckResponsePort(&trans, 70);
6925 CheckResponseData(&trans, "0123456789");
6926 EXPECT_TRUE(headers_handler.was_proxied());
6927 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
6928
Wez0e717112018-06-18 23:09:226929 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
6930 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:566931 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6932
6933 base::RunLoop().RunUntilIdle();
6934 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6935 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6936}
6937
6938// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
6939// check that the proxy socket is reused for the second request.
6940TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
6941 session_params_.enable_quic = true;
6942 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496943 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566944
6945 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526946 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:566947 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436948 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6949 mock_quic_data.AddWrite(SYNCHRONOUS,
6950 ConstructClientRequestHeadersPacket(
6951 2, GetNthClientInitiatedStreamId(0), true, false,
6952 ConnectRequestHeaders("mail.example.org:443"),
6953 &header_stream_offset));
6954 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6955 1, GetNthClientInitiatedStreamId(0), false,
6956 false, GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:566957
Ryan Hamilton8d9ee76e2018-05-29 23:52:526958 quic::QuicStreamOffset client_data_offset = 0;
6959 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:566960 const char get_request_1[] =
6961 "GET / HTTP/1.1\r\n"
6962 "Host: mail.example.org\r\n"
6963 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436964 mock_quic_data.AddWrite(
6965 SYNCHRONOUS,
6966 ConstructClientAckAndDataPacket(
6967 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526968 client_data_offset, quic::QuicStringPiece(get_request_1)));
Yixin Wang46a273ec302018-01-23 17:59:566969 client_data_offset += strlen(get_request_1);
6970
6971 const char get_response_1[] =
6972 "HTTP/1.1 200 OK\r\n"
6973 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436974 mock_quic_data.AddRead(
6975 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6976 false, false, server_data_offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526977 quic::QuicStringPiece(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:566978 server_data_offset += strlen(get_response_1);
6979
Ryan Hamilton8d9ee76e2018-05-29 23:52:526980 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
6981 3, GetNthClientInitiatedStreamId(0),
6982 false, false, server_data_offset,
6983 quic::QuicStringPiece("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:566984 server_data_offset += 10;
6985
Zhongyi Shi32f2fd02018-04-16 18:23:436986 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:566987
6988 const char get_request_2[] =
6989 "GET /2 HTTP/1.1\r\n"
6990 "Host: mail.example.org\r\n"
6991 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436992 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526993 SYNCHRONOUS,
6994 ConstructClientDataPacket(5, GetNthClientInitiatedStreamId(0), false,
6995 false, client_data_offset,
6996 quic::QuicStringPiece(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:566997 client_data_offset += strlen(get_request_2);
6998
6999 const char get_response_2[] =
7000 "HTTP/1.1 200 OK\r\n"
7001 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437002 mock_quic_data.AddRead(
7003 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
7004 false, false, server_data_offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527005 quic::QuicStringPiece(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:567006 server_data_offset += strlen(get_response_2);
7007
Ryan Hamilton8d9ee76e2018-05-29 23:52:527008 mock_quic_data.AddRead(
7009 SYNCHRONOUS, ConstructServerDataPacket(
7010 5, GetNthClientInitiatedStreamId(0), false, false,
7011 server_data_offset, quic::QuicStringPiece("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:567012 server_data_offset += 7;
7013
Zhongyi Shi32f2fd02018-04-16 18:23:437014 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567015 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7016
7017 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527018 SYNCHRONOUS, ConstructClientRstPacket(7, GetNthClientInitiatedStreamId(0),
7019 quic::QUIC_STREAM_CANCELLED,
7020 client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567021
7022 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7023
7024 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7025
7026 CreateSession();
7027
7028 request_.url = GURL("https://mail.example.org/");
7029 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7030 HeadersHandler headers_handler_1;
7031 trans_1.SetBeforeHeadersSentCallback(
7032 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7033 base::Unretained(&headers_handler_1)));
7034 RunTransaction(&trans_1);
7035 CheckWasHttpResponse(&trans_1);
7036 CheckResponsePort(&trans_1, 70);
7037 CheckResponseData(&trans_1, "0123456789");
7038 EXPECT_TRUE(headers_handler_1.was_proxied());
7039 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7040
7041 request_.url = GURL("https://mail.example.org/2");
7042 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7043 HeadersHandler headers_handler_2;
7044 trans_2.SetBeforeHeadersSentCallback(
7045 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7046 base::Unretained(&headers_handler_2)));
7047 RunTransaction(&trans_2);
7048 CheckWasHttpResponse(&trans_2);
7049 CheckResponsePort(&trans_2, 70);
7050 CheckResponseData(&trans_2, "0123456");
7051 EXPECT_TRUE(headers_handler_2.was_proxied());
7052 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7053
7054 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7055 // proxy socket to disconnect.
7056 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7057
7058 base::RunLoop().RunUntilIdle();
7059 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7060 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7061}
7062
7063// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7064// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7065// server is reused for the second request.
7066TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
7067 session_params_.enable_quic = true;
7068 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497069 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567070
7071 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527072 quic::QuicStreamOffset client_header_stream_offset = 0;
7073 quic::QuicStreamOffset server_header_stream_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437074 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7075 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567076
7077 // CONNECT request and response for first request
Zhongyi Shi32f2fd02018-04-16 18:23:437078 mock_quic_data.AddWrite(SYNCHRONOUS,
7079 ConstructClientRequestHeadersPacket(
7080 2, GetNthClientInitiatedStreamId(0), true, false,
7081 ConnectRequestHeaders("mail.example.org:443"),
7082 &client_header_stream_offset));
7083 mock_quic_data.AddRead(
7084 ASYNC, ConstructServerResponseHeadersPacket(
7085 1, GetNthClientInitiatedStreamId(0), false, false,
7086 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567087
7088 // GET request, response, and data over QUIC tunnel for first request
7089 const char get_request[] =
7090 "GET / HTTP/1.1\r\n"
7091 "Host: mail.example.org\r\n"
7092 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437093 mock_quic_data.AddWrite(
7094 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7095 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527096 false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567097 const char get_response[] =
7098 "HTTP/1.1 200 OK\r\n"
7099 "Content-Length: 10\r\n\r\n";
7100 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527101 ASYNC,
7102 ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0), false,
7103 false, 0, quic::QuicStringPiece(get_response)));
7104 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7105 3, GetNthClientInitiatedStreamId(0),
7106 false, false, strlen(get_response),
7107 quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437108 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567109
7110 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437111 mock_quic_data.AddWrite(
7112 SYNCHRONOUS,
7113 ConstructClientRequestHeadersPacket(
7114 5, GetNthClientInitiatedStreamId(1), false, false,
7115 ConnectRequestHeaders("different.example.org:443"),
7116 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
7117 mock_quic_data.AddRead(
7118 ASYNC, ConstructServerResponseHeadersPacket(
7119 4, GetNthClientInitiatedStreamId(1), false, false,
7120 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567121
7122 // GET request, response, and data over QUIC tunnel for second request
7123 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137124 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567125 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Zhongyi Shi32f2fd02018-04-16 18:23:437126 mock_quic_data.AddWrite(
7127 SYNCHRONOUS,
7128 ConstructClientAckAndDataPacket(
7129 6, false, GetNthClientInitiatedStreamId(1), 4, 4, 1, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527130 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567131
Ryan Hamilton0239aac2018-05-19 00:03:137132 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567133 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437134 mock_quic_data.AddRead(
7135 ASYNC, ConstructServerDataPacket(
7136 5, GetNthClientInitiatedStreamId(1), false, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527137 quic::QuicStringPiece(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567138
Ryan Hamilton0239aac2018-05-19 00:03:137139 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197140 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437141 mock_quic_data.AddRead(
7142 ASYNC,
7143 ConstructServerDataPacket(
7144 6, GetNthClientInitiatedStreamId(1), false, false, resp_frame.size(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527145 quic::QuicStringPiece(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567146
Zhongyi Shi32f2fd02018-04-16 18:23:437147 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567148 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7149
7150 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527151 SYNCHRONOUS, ConstructClientRstPacket(8, GetNthClientInitiatedStreamId(0),
7152 quic::QUIC_STREAM_CANCELLED,
7153 strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567154 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437155 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:567156 ConstructClientRstPacket(9, GetNthClientInitiatedStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527157 quic::QUIC_STREAM_CANCELLED, get_frame.size()));
Yixin Wang46a273ec302018-01-23 17:59:567158
7159 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7160
7161 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7162
7163 SSLSocketDataProvider ssl_data(ASYNC, OK);
7164 ssl_data.next_proto = kProtoHTTP2;
7165 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7166
7167 CreateSession();
7168
7169 request_.url = GURL("https://mail.example.org/");
7170 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7171 HeadersHandler headers_handler_1;
7172 trans_1.SetBeforeHeadersSentCallback(
7173 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7174 base::Unretained(&headers_handler_1)));
7175 RunTransaction(&trans_1);
7176 CheckWasHttpResponse(&trans_1);
7177 CheckResponsePort(&trans_1, 70);
7178 CheckResponseData(&trans_1, "0123456789");
7179 EXPECT_TRUE(headers_handler_1.was_proxied());
7180 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7181
7182 request_.url = GURL("https://different.example.org/");
7183 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7184 HeadersHandler headers_handler_2;
7185 trans_2.SetBeforeHeadersSentCallback(
7186 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7187 base::Unretained(&headers_handler_2)));
7188 RunTransaction(&trans_2);
7189 CheckWasSpdyResponse(&trans_2);
7190 CheckResponsePort(&trans_2, 70);
7191 CheckResponseData(&trans_2, "0123456");
7192 EXPECT_TRUE(headers_handler_2.was_proxied());
7193 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7194
7195 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7196 // proxy socket to disconnect.
7197 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7198
7199 base::RunLoop().RunUntilIdle();
7200 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7201 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7202}
7203
7204// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
7205TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
7206 session_params_.enable_quic = true;
7207 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497208 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567209
7210 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527211 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567212 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437213 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7214 mock_quic_data.AddWrite(SYNCHRONOUS,
7215 ConstructClientRequestHeadersPacket(
7216 2, GetNthClientInitiatedStreamId(0), true, false,
7217 ConnectRequestHeaders("mail.example.org:443"),
7218 &header_stream_offset));
7219 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7220 1, GetNthClientInitiatedStreamId(0), false,
7221 true, GetResponseHeaders("500")));
Yixin Wang46a273ec302018-01-23 17:59:567222 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Ryan Hamilton8d9ee76e2018-05-29 23:52:527223 mock_quic_data.AddWrite(
7224 SYNCHRONOUS,
7225 ConstructClientAckAndRstPacket(3, GetNthClientInitiatedStreamId(0),
7226 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567227
7228 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7229
7230 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7231
7232 CreateSession();
7233
7234 request_.url = GURL("https://mail.example.org/");
7235 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7236 HeadersHandler headers_handler;
7237 trans.SetBeforeHeadersSentCallback(
7238 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7239 base::Unretained(&headers_handler)));
7240 TestCompletionCallback callback;
7241 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7242 EXPECT_EQ(ERR_IO_PENDING, rv);
7243 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7244 EXPECT_EQ(false, headers_handler.was_proxied());
7245
7246 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7247 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7248}
7249
7250// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
7251TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
7252 session_params_.enable_quic = true;
7253 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497254 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567255
7256 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527257 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567258 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437259 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7260 mock_quic_data.AddWrite(SYNCHRONOUS,
7261 ConstructClientRequestHeadersPacket(
7262 2, GetNthClientInitiatedStreamId(0), true, false,
7263 ConnectRequestHeaders("mail.example.org:443"),
7264 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567265 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7266
7267 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7268
7269 CreateSession();
7270
7271 request_.url = GURL("https://mail.example.org/");
7272 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7273 HeadersHandler headers_handler;
7274 trans.SetBeforeHeadersSentCallback(
7275 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7276 base::Unretained(&headers_handler)));
7277 TestCompletionCallback callback;
7278 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7279 EXPECT_EQ(ERR_IO_PENDING, rv);
7280 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7281
7282 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7283 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7284}
7285
7286// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
7287// host. Retries request and succeeds.
7288TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
7289 session_params_.enable_quic = true;
7290 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497291 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567292
7293 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527294 quic::QuicStreamOffset client_header_stream_offset = 0;
7295 quic::QuicStreamOffset server_header_stream_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437296 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7297 1, &client_header_stream_offset));
7298 mock_quic_data.AddWrite(SYNCHRONOUS,
7299 ConstructClientRequestHeadersPacket(
7300 2, GetNthClientInitiatedStreamId(0), true, false,
7301 ConnectRequestHeaders("mail.example.org:443"),
7302 &client_header_stream_offset));
7303 mock_quic_data.AddRead(
7304 ASYNC, ConstructServerResponseHeadersPacket(
7305 1, GetNthClientInitiatedStreamId(0), false, false,
7306 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527307 mock_quic_data.AddWrite(
7308 SYNCHRONOUS,
7309 ConstructClientAckAndRstPacket(3, GetNthClientInitiatedStreamId(0),
7310 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567311
Zhongyi Shi32f2fd02018-04-16 18:23:437312 mock_quic_data.AddWrite(
7313 SYNCHRONOUS,
7314 ConstructClientRequestHeadersPacket(
7315 4, GetNthClientInitiatedStreamId(1), false, false,
7316 ConnectRequestHeaders("mail.example.org:443"),
7317 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
7318 mock_quic_data.AddRead(
7319 ASYNC, ConstructServerResponseHeadersPacket(
7320 2, GetNthClientInitiatedStreamId(1), false, false,
7321 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567322
7323 const char get_request[] =
7324 "GET / HTTP/1.1\r\n"
7325 "Host: mail.example.org\r\n"
7326 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437327 mock_quic_data.AddWrite(
7328 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7329 5, false, GetNthClientInitiatedStreamId(1), 2, 2, 1,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527330 false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567331 const char get_response[] =
7332 "HTTP/1.1 200 OK\r\n"
7333 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437334 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527335 ASYNC,
7336 ConstructServerDataPacket(3, GetNthClientInitiatedStreamId(1), false,
7337 false, 0, quic::QuicStringPiece(get_response)));
7338
7339 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7340 4, GetNthClientInitiatedStreamId(1),
7341 false, false, strlen(get_response),
7342 quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437343 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:567344 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7345
7346 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527347 SYNCHRONOUS, ConstructClientRstPacket(7, GetNthClientInitiatedStreamId(1),
7348 quic::QUIC_STREAM_CANCELLED,
7349 strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567350
7351 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7352
7353 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7354 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
7355
7356 SSLSocketDataProvider ssl_data(ASYNC, OK);
7357 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7358
7359 CreateSession();
7360
7361 request_.url = GURL("https://mail.example.org/");
7362 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7363 HeadersHandler headers_handler;
7364 trans.SetBeforeHeadersSentCallback(
7365 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7366 base::Unretained(&headers_handler)));
7367 TestCompletionCallback callback;
7368 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7369 EXPECT_EQ(ERR_IO_PENDING, rv);
7370 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
7371
7372 rv = trans.RestartIgnoringLastError(callback.callback());
7373 EXPECT_EQ(ERR_IO_PENDING, rv);
7374 EXPECT_EQ(OK, callback.WaitForResult());
7375
7376 CheckWasHttpResponse(&trans);
7377 CheckResponsePort(&trans, 70);
7378 CheckResponseData(&trans, "0123456789");
7379 EXPECT_EQ(true, headers_handler.was_proxied());
7380 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7381
7382 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7383 // proxy socket to disconnect.
7384 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7385
7386 base::RunLoop().RunUntilIdle();
7387 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7388 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7389}
7390
7391// Checks if a request's specified "user-agent" header shows up correctly in the
7392// CONNECT request to a QUIC proxy.
7393TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
7394 session_params_.enable_quic = true;
7395 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497396 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567397
7398 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527399 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567400 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437401 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567402
Ryan Hamilton0239aac2018-05-19 00:03:137403 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:567404 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Zhongyi Shi32f2fd02018-04-16 18:23:437405 mock_quic_data.AddWrite(SYNCHRONOUS,
7406 ConstructClientRequestHeadersPacket(
7407 2, GetNthClientInitiatedStreamId(0), true, false,
7408 std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567409 // Return an error, so the transaction stops here (this test isn't interested
7410 // in the rest).
7411 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7412
7413 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7414
7415 CreateSession();
7416
7417 request_.url = GURL("https://mail.example.org/");
7418 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7419 "Chromium Ultra Awesome X Edition");
7420 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7421 HeadersHandler headers_handler;
7422 trans.SetBeforeHeadersSentCallback(
7423 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7424 base::Unretained(&headers_handler)));
7425 TestCompletionCallback callback;
7426 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7427 EXPECT_EQ(ERR_IO_PENDING, rv);
7428 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7429
7430 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7431 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7432}
7433
Yixin Wang00fc44c2018-01-23 21:12:207434// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7435// HTTP/2 stream dependency and weights given the request priority.
7436TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
7437 session_params_.enable_quic = true;
7438 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497439 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:207440
7441 const RequestPriority request_priority = MEDIUM;
7442
7443 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527444 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:207445 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437446 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7447 mock_quic_data.AddWrite(
7448 SYNCHRONOUS,
7449 ConstructClientRequestHeadersPacket(
7450 2, GetNthClientInitiatedStreamId(0), true, false, request_priority,
7451 ConnectRequestHeaders("mail.example.org:443"), 0,
7452 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:207453 // Return an error, so the transaction stops here (this test isn't interested
7454 // in the rest).
7455 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7456
7457 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7458
7459 CreateSession();
7460
7461 request_.url = GURL("https://mail.example.org/");
7462 HttpNetworkTransaction trans(request_priority, session_.get());
7463 TestCompletionCallback callback;
7464 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7465 EXPECT_EQ(ERR_IO_PENDING, rv);
7466 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7467
7468 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7469 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7470}
7471
Yixin Wang46a273ec302018-01-23 17:59:567472// Test the request-challenge-retry sequence for basic auth, over a QUIC
7473// connection when setting up a QUIC proxy tunnel.
7474TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
7475 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
7476 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:137477 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:567478 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
7479
7480 std::unique_ptr<QuicTestPacketMaker> client_maker;
7481 std::unique_ptr<QuicTestPacketMaker> server_maker;
7482
7483 // On the second pass, the body read of the auth challenge is synchronous, so
7484 // IsConnectedAndIdle returns false. The socket should still be drained and
7485 // reused. See http://crbug.com/544255.
7486 for (int i = 0; i < 2; ++i) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:527487 client_maker.reset(
7488 new QuicTestPacketMaker(version_, 0, &clock_, kDefaultServerHostName,
7489 quic::Perspective::IS_CLIENT,
7490 client_headers_include_h2_stream_dependency_));
7491 server_maker.reset(
7492 new QuicTestPacketMaker(version_, 0, &clock_, kDefaultServerHostName,
7493 quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:567494
7495 session_params_.enable_quic = true;
7496 proxy_resolution_service_ =
7497 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497498 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567499
7500 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527501 quic::QuicStreamOffset client_header_stream_offset = 0;
7502 quic::QuicStreamOffset server_header_stream_offset = 0;
7503 quic::QuicStreamOffset client_data_offset = 0;
7504 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567505
Zhongyi Shi32f2fd02018-04-16 18:23:437506 mock_quic_data.AddWrite(SYNCHRONOUS,
7507 client_maker->MakeInitialSettingsPacket(
7508 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567509
7510 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437511 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:567512 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
7513 2, GetNthClientInitiatedStreamId(0), true, false, default_priority,
7514 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
7515 &client_header_stream_offset));
7516
Ryan Hamilton0239aac2018-05-19 00:03:137517 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:567518 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
7519 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7520 headers["content-length"] = "10";
7521 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:437522 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
7523 1, GetNthClientInitiatedStreamId(0), false, false,
7524 std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567525
7526 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:437527 mock_quic_data.AddRead(
7528 ASYNC, server_maker->MakeDataPacket(
7529 2, GetNthClientInitiatedStreamId(0), false, false,
7530 server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567531 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:437532 mock_quic_data.AddRead(
7533 SYNCHRONOUS, server_maker->MakeDataPacket(
7534 2, GetNthClientInitiatedStreamId(0), false, false,
7535 server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567536 }
7537 server_data_offset += 10;
7538
Zhongyi Shi32f2fd02018-04-16 18:23:437539 mock_quic_data.AddWrite(SYNCHRONOUS,
7540 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:567541
7542 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527543 SYNCHRONOUS, client_maker->MakeRstPacket(
7544 4, false, GetNthClientInitiatedStreamId(0),
7545 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567546
7547 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
7548 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
7549 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437550 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:567551 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
7552 5, GetNthClientInitiatedStreamId(1), false, false, default_priority,
7553 std::move(headers), GetNthClientInitiatedStreamId(0),
7554 &client_header_stream_offset));
7555
7556 // Response to wrong password
7557 headers =
7558 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
7559 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7560 headers["content-length"] = "10";
7561 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:437562 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
7563 3, GetNthClientInitiatedStreamId(1), false, false,
7564 std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567565 mock_quic_data.AddRead(SYNCHRONOUS,
7566 ERR_IO_PENDING); // No more data to read
7567
Zhongyi Shi32f2fd02018-04-16 18:23:437568 mock_quic_data.AddWrite(SYNCHRONOUS,
7569 client_maker->MakeAckAndRstPacket(
7570 6, false, GetNthClientInitiatedStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527571 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:567572
7573 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7574 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
7575
7576 CreateSession();
7577
7578 request_.url = GURL("https://mail.example.org/");
7579 // Ensure that proxy authentication is attempted even
7580 // when the no authentication data flag is set.
7581 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
7582 {
7583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7584 HeadersHandler headers_handler;
7585 trans.SetBeforeHeadersSentCallback(
7586 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7587 base::Unretained(&headers_handler)));
7588 RunTransaction(&trans);
7589
7590 const HttpResponseInfo* response = trans.GetResponseInfo();
7591 ASSERT_TRUE(response != nullptr);
7592 ASSERT_TRUE(response->headers.get() != nullptr);
7593 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
7594 response->headers->GetStatusLine());
7595 EXPECT_TRUE(response->headers->IsKeepAlive());
7596 EXPECT_EQ(407, response->headers->response_code());
7597 EXPECT_EQ(10, response->headers->GetContentLength());
7598 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
7599 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
7600 ASSERT_TRUE(auth_challenge != nullptr);
7601 EXPECT_TRUE(auth_challenge->is_proxy);
7602 EXPECT_EQ("https://proxy.example.org:70",
7603 auth_challenge->challenger.Serialize());
7604 EXPECT_EQ("MyRealm1", auth_challenge->realm);
7605 EXPECT_EQ("basic", auth_challenge->scheme);
7606
7607 TestCompletionCallback callback;
7608 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
7609 callback.callback());
7610 EXPECT_EQ(ERR_IO_PENDING, rv);
7611 EXPECT_EQ(OK, callback.WaitForResult());
7612
7613 response = trans.GetResponseInfo();
7614 ASSERT_TRUE(response != nullptr);
7615 ASSERT_TRUE(response->headers.get() != nullptr);
7616 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
7617 response->headers->GetStatusLine());
7618 EXPECT_TRUE(response->headers->IsKeepAlive());
7619 EXPECT_EQ(407, response->headers->response_code());
7620 EXPECT_EQ(10, response->headers->GetContentLength());
7621 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
7622 auth_challenge = response->auth_challenge.get();
7623 ASSERT_TRUE(auth_challenge != nullptr);
7624 EXPECT_TRUE(auth_challenge->is_proxy);
7625 EXPECT_EQ("https://proxy.example.org:70",
7626 auth_challenge->challenger.Serialize());
7627 EXPECT_EQ("MyRealm1", auth_challenge->realm);
7628 EXPECT_EQ("basic", auth_challenge->scheme);
7629 }
7630 // HttpNetworkTransaction is torn down now that it's out of scope, causing
7631 // the QUIC stream to be cleaned up (since the proxy socket cannot be
7632 // reused because it's not connected).
7633 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7634 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7635 }
7636}
7637
Yixin Wang385652a2018-02-16 02:37:237638TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
7639 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
7640 // in HEADERS frames for requests and PRIORITY frames).
Ryan Hamilton8d9ee76e2018-05-29 23:52:527641 if (version_ <= quic::QUIC_VERSION_42 ||
Yixin Wang385652a2018-02-16 02:37:237642 !client_headers_include_h2_stream_dependency_) {
7643 return;
7644 }
7645
7646 session_params_.origins_to_force_quic_on.insert(
7647 HostPortPair::FromString("mail.example.org:443"));
7648
Ryan Hamilton8d9ee76e2018-05-29 23:52:527649 const quic::QuicStreamId client_stream_0 = GetNthClientInitiatedStreamId(0);
7650 const quic::QuicStreamId client_stream_1 = GetNthClientInitiatedStreamId(1);
7651 const quic::QuicStreamId client_stream_2 = GetNthClientInitiatedStreamId(2);
7652 const quic::QuicStreamId push_stream_0 = GetNthServerInitiatedStreamId(0);
7653 const quic::QuicStreamId push_stream_1 = GetNthServerInitiatedStreamId(1);
Yixin Wang385652a2018-02-16 02:37:237654
7655 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527656 quic::QuicStreamOffset header_stream_offset = 0;
7657 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:237658 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437659 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:237660
7661 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:437662 mock_quic_data.AddWrite(SYNCHRONOUS,
7663 ConstructClientRequestHeadersPacket(
7664 2, client_stream_0, true, true, HIGHEST,
7665 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
7666 &header_stream_offset));
7667 mock_quic_data.AddWrite(SYNCHRONOUS,
7668 ConstructClientRequestHeadersPacket(
7669 3, client_stream_1, true, true, MEDIUM,
7670 GetRequestHeaders("GET", "https", "/1.jpg"),
7671 client_stream_0, &header_stream_offset));
7672 mock_quic_data.AddWrite(SYNCHRONOUS,
7673 ConstructClientRequestHeadersPacket(
7674 4, client_stream_2, true, true, MEDIUM,
7675 GetRequestHeaders("GET", "https", "/2.jpg"),
7676 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:237677
7678 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:437679 mock_quic_data.AddRead(
7680 ASYNC, ConstructServerResponseHeadersPacket(
7681 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
7682 &server_header_offset));
7683 mock_quic_data.AddRead(
7684 ASYNC, ConstructServerResponseHeadersPacket(
7685 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
7686 &server_header_offset));
7687 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
7688 mock_quic_data.AddRead(
7689 ASYNC, ConstructServerResponseHeadersPacket(
7690 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
7691 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:237692
7693 // Server sends two push promises associated with |client_stream_0|; client
7694 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
7695 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437696 mock_quic_data.AddRead(ASYNC,
7697 ConstructServerPushPromisePacket(
7698 4, client_stream_0, push_stream_0, false,
7699 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
7700 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:237701 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437702 SYNCHRONOUS,
7703 ConstructClientAckAndPriorityFramesPacket(
7704 6, false, 4, 3, 1,
7705 {{push_stream_0, client_stream_2,
7706 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
7707 &header_stream_offset));
7708 mock_quic_data.AddRead(ASYNC,
7709 ConstructServerPushPromisePacket(
7710 5, client_stream_0, push_stream_1, false,
7711 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
7712 &server_header_offset, &server_maker_));
7713 mock_quic_data.AddWrite(
7714 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:237715 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
7716 DEFAULT_PRIORITY, &header_stream_offset));
7717
7718 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:437719 mock_quic_data.AddRead(
7720 ASYNC, ConstructServerResponseHeadersPacket(
7721 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
7722 &server_header_offset));
7723 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
7724 mock_quic_data.AddRead(
7725 ASYNC, ConstructServerResponseHeadersPacket(
7726 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
7727 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:237728
7729 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
7730 // priority updates to match the request's priority. Client sends PRIORITY
7731 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:437732 mock_quic_data.AddWrite(
7733 SYNCHRONOUS,
7734 ConstructClientAckAndPriorityFramesPacket(
7735 9, false, 7, 7, 1,
7736 {{push_stream_1, client_stream_2,
7737 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
7738 {push_stream_0, client_stream_0,
7739 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
7740 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:237741
7742 // Server sends data for the three requests and the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:437743 mock_quic_data.AddRead(
7744 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
7745 "hello 0!"));
7746 mock_quic_data.AddRead(
7747 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
7748 "hello 1!"));
7749 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
7750 mock_quic_data.AddRead(
7751 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
7752 "hello 2!"));
7753 mock_quic_data.AddRead(
7754 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
7755 "and hello 0!"));
7756 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
7757 mock_quic_data.AddRead(
7758 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
7759 "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:237760
Zhongyi Shi32f2fd02018-04-16 18:23:437761 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527762 SYNCHRONOUS,
7763 ConstructClientAckAndRstPacket(
7764 12, push_stream_0, quic::QUIC_RST_ACKNOWLEDGEMENT, 12, 12, 1));
Yixin Wang385652a2018-02-16 02:37:237765
7766 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7767 mock_quic_data.AddRead(ASYNC, 0); // EOF
7768 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7769
7770 // The non-alternate protocol job needs to hang in order to guarantee that
7771 // the alternate-protocol job will "win".
7772 AddHangingNonAlternateProtocolSocketData();
7773
7774 CreateSession();
7775
7776 request_.url = GURL("https://mail.example.org/0.jpg");
7777 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
7778 TestCompletionCallback callback_0;
7779 EXPECT_EQ(ERR_IO_PENDING,
7780 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
7781 base::RunLoop().RunUntilIdle();
7782
7783 request_.url = GURL("https://mail.example.org/1.jpg");
7784 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
7785 TestCompletionCallback callback_1;
7786 EXPECT_EQ(ERR_IO_PENDING,
7787 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
7788 base::RunLoop().RunUntilIdle();
7789
7790 request_.url = GURL("https://mail.example.org/2.jpg");
7791 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
7792 TestCompletionCallback callback_2;
7793 EXPECT_EQ(ERR_IO_PENDING,
7794 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
7795 base::RunLoop().RunUntilIdle();
7796
7797 // Client makes request that matches resource pushed in |pushed_stream_0|.
7798 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
7799 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
7800 TestCompletionCallback callback_3;
7801 EXPECT_EQ(ERR_IO_PENDING,
7802 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
7803 base::RunLoop().RunUntilIdle();
7804
7805 EXPECT_TRUE(callback_0.have_result());
7806 EXPECT_EQ(OK, callback_0.WaitForResult());
7807 EXPECT_TRUE(callback_1.have_result());
7808 EXPECT_EQ(OK, callback_1.WaitForResult());
7809 EXPECT_TRUE(callback_2.have_result());
7810 EXPECT_EQ(OK, callback_2.WaitForResult());
7811
7812 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
7813 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
7814 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
7815 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
7816
7817 mock_quic_data.Resume();
7818 base::RunLoop().RunUntilIdle();
7819 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7820 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7821}
7822
[email protected]61a527782013-02-21 03:58:007823} // namespace test
7824} // namespace net