blob: 3e673d5d59cdcae01524e465757ff298ab345efb [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
Zhongyi Shia6b68d112018-09-24 07:49:03819 void SetUpTestForRetryConnectionOnAlternateNetwork() {
820 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
821 session_params_.quic_migrate_sessions_early_v2 = true;
822 session_params_.quic_retry_on_alternate_network_before_handshake = true;
823 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
824 MockNetworkChangeNotifier* mock_ncn =
825 scoped_mock_change_notifier_->mock_network_change_notifier();
826 mock_ncn->ForceNetworkHandlesSupported();
827 mock_ncn->SetConnectedNetworksList(
828 {kDefaultNetworkForTests, kNewNetworkForTests});
829 }
830
tbansalc3308d72016-08-27 10:25:04831 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
832 // alternative proxy. Verifies that if the alternative proxy job returns
833 // |error_code|, the request is fetched successfully by the main job.
834 void TestAlternativeProxy(int error_code) {
835 // Use a non-cryptographic scheme for the request URL since this request
836 // will be fetched via proxy with QUIC as the alternative service.
837 request_.url = GURL("http://example.org/");
838 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27839 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04840 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27841 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04842 };
843
Ryan Sleevib8d7ea02018-05-07 20:01:01844 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04845 socket_factory_.AddSocketDataProvider(&quic_data);
846
847 // Main job succeeds and the alternative job fails.
848 // Add data for two requests that will be read by the main job.
849 MockRead http_reads_1[] = {
850 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
851 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
852 MockRead(ASYNC, OK)};
853
854 MockRead http_reads_2[] = {
855 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
856 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
857 MockRead(ASYNC, OK)};
858
Ryan Sleevib8d7ea02018-05-07 20:01:01859 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
860 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04861 socket_factory_.AddSocketDataProvider(&http_data_1);
862 socket_factory_.AddSocketDataProvider(&http_data_2);
863 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
864 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
865
866 TestProxyDelegate test_proxy_delegate;
867 // Proxy URL is different from the request URL.
868 test_proxy_delegate.set_alternative_proxy_server(
869 ProxyServer::FromPacString("QUIC myproxy.org:443"));
870
Lily Houghton8c2f97d2018-01-22 05:06:59871 proxy_resolution_service_ =
872 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49873 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52874 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04875
876 CreateSession();
877 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
878
879 // The first request should be fetched via the HTTPS proxy.
880 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
881
Reilly Grant89a7e512018-01-20 01:57:16882 // Since the main job succeeded only the alternative proxy server should be
883 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59884 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16885 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04886
887 // Verify that the second request completes successfully, and the
888 // alternative proxy server job is not started.
889 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
890 }
891
Ryan Hamilton8d9ee76e2018-05-29 23:52:52892 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
893 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36894 }
895
Ryan Hamilton8d9ee76e2018-05-29 23:52:52896 quic::QuicStreamId GetNthServerInitiatedStreamId(int n) {
897 return quic::test::GetNthServerInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36898 }
899
Bence Béky230ac612017-08-30 19:17:08900 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49901 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08902 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49903 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08904 }
905
Ryan Hamilton8d9ee76e2018-05-29 23:52:52906 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05907 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52908 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01909 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52910 quic::MockClock clock_;
alyssar2adf3ac2016-05-03 17:12:58911 QuicTestPacketMaker client_maker_;
912 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42913 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00914 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56915 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05916 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43917 MockHostResolver host_resolver_;
918 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11919 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42920 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23921 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38922 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07923 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59924 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42925 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52926 quic::test::MockRandom random_generator_;
bnc6be245c12015-05-15 11:24:07927 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41928 HttpNetworkSession::Params session_params_;
929 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19930 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51931 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42932 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56933 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03934 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12935
936 private:
937 void SendRequestAndExpectQuicResponseMaybeFromProxy(
938 const std::string& expected,
bnc62a44f022015-04-02 15:59:41939 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46940 uint16_t port) {
bnc691fda62016-08-12 00:43:16941 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09942 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16943 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09944 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
945 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16946 RunTransaction(&trans);
947 CheckWasQuicResponse(&trans);
948 CheckResponsePort(&trans, port);
949 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09950 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47951 if (used_proxy) {
952 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
953 } else {
954 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
955 }
tbansal7cec3812015-02-05 21:25:12956 }
[email protected]61a527782013-02-21 03:58:00957};
958
Yixin Wang079ad542018-01-11 04:06:05959INSTANTIATE_TEST_CASE_P(
Yixin Wang385652a2018-02-16 02:37:23960 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05961 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52962 ::testing::Combine(
963 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
964 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20965
Ryan Hamiltona64a5bcf2017-11-30 07:35:28966TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:48967 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28968 base::HistogramTester histograms;
969 session_params_.origins_to_force_quic_on.insert(
970 HostPortPair::FromString("mail.example.org:443"));
971 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27972 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:28973
974 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52975 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28976 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43977 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:28978 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
979 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
980 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
981
982 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
983
984 CreateSession();
985
986 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
987 TestCompletionCallback callback;
988 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
989 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
990 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
991
992 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
993 -ERR_INTERNET_DISCONNECTED, 1);
994 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
995 -ERR_INTERNET_DISCONNECTED, 1);
996}
997
998TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:48999 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281000 base::HistogramTester histograms;
1001 session_params_.origins_to_force_quic_on.insert(
1002 HostPortPair::FromString("mail.example.org:443"));
1003 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271004 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281005
1006 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521007 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281008 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431009 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281010 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1011 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1012 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1013
1014 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1015
1016 CreateSession();
1017
1018 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1019 TestCompletionCallback callback;
1020 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1022 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1023
1024 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1025 -ERR_INTERNET_DISCONNECTED, 1);
1026 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1027 -ERR_INTERNET_DISCONNECTED, 1);
1028}
1029
tbansal180587c2017-02-16 15:13:231030TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411031 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231032 HostPortPair::FromString("mail.example.org:443"));
1033
1034 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521035 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361036 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431037 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1038 mock_quic_data.AddWrite(
1039 SYNCHRONOUS,
1040 ConstructClientRequestHeadersPacket(
1041 2, GetNthClientInitiatedStreamId(0), true, true,
1042 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1043 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1044 1, GetNthClientInitiatedStreamId(0), false,
1045 false, GetResponseHeaders("200 OK")));
1046 mock_quic_data.AddRead(
1047 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1048 false, true, 0, "hello!"));
1049 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231050 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1051
1052 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1053
1054 CreateSession();
1055 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1056
1057 EXPECT_FALSE(
1058 test_socket_performance_watcher_factory_.rtt_notification_received());
1059 SendRequestAndExpectQuicResponse("hello!");
1060 EXPECT_TRUE(
1061 test_socket_performance_watcher_factory_.rtt_notification_received());
1062}
1063
1064TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411065 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231066 HostPortPair::FromString("mail.example.org:443"));
1067
1068 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521069 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361070 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431071 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1072 mock_quic_data.AddWrite(
1073 SYNCHRONOUS,
1074 ConstructClientRequestHeadersPacket(
1075 2, GetNthClientInitiatedStreamId(0), true, true,
1076 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1077 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1078 1, GetNthClientInitiatedStreamId(0), false,
1079 false, GetResponseHeaders("200 OK")));
1080 mock_quic_data.AddRead(
1081 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1082 false, true, 0, "hello!"));
1083 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231084 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1085
1086 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1087
1088 CreateSession();
1089 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1090
1091 EXPECT_FALSE(
1092 test_socket_performance_watcher_factory_.rtt_notification_received());
1093 SendRequestAndExpectQuicResponse("hello!");
1094 EXPECT_FALSE(
1095 test_socket_performance_watcher_factory_.rtt_notification_received());
1096}
1097
[email protected]1e960032013-12-20 19:00:201098TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411099 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571100 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471101
[email protected]1e960032013-12-20 19:00:201102 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521103 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361104 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431105 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1106 mock_quic_data.AddWrite(
1107 SYNCHRONOUS,
1108 ConstructClientRequestHeadersPacket(
1109 2, GetNthClientInitiatedStreamId(0), true, true,
1110 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1111 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1112 1, GetNthClientInitiatedStreamId(0), false,
1113 false, GetResponseHeaders("200 OK")));
1114 mock_quic_data.AddRead(
1115 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1116 false, true, 0, "hello!"));
1117 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591118 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471119
rcha5399e02015-04-21 19:32:041120 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471121
[email protected]4dca587c2013-03-07 16:54:471122 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471123
[email protected]aa9b14d2013-05-10 23:45:191124 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471125
[email protected]98b20ce2013-05-10 05:55:261126 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461127 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191128 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261129 EXPECT_LT(0u, entries.size());
1130
1131 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291132 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001133 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1134 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261135 EXPECT_LT(0, pos);
1136
rchfd527212015-08-25 00:41:261137 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291138 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261139 entries, 0,
mikecirone8b85c432016-09-08 19:11:001140 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1141 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261142 EXPECT_LT(0, pos);
1143
rtennetia004d332015-08-28 06:44:571144 std::string packet_number;
1145 ASSERT_TRUE(entries[pos].GetStringValue("packet_number", &packet_number));
1146 EXPECT_EQ("1", packet_number);
[email protected]98b20ce2013-05-10 05:55:261147
rchfd527212015-08-25 00:41:261148 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1149 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001150 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1151 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261152 EXPECT_LT(0, pos);
1153
[email protected]98b20ce2013-05-10 05:55:261154 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291155 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001156 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1157 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261158 EXPECT_LT(0, pos);
1159
1160 int log_stream_id;
1161 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
[email protected]1e960032013-12-20 19:00:201162 EXPECT_EQ(3, log_stream_id);
[email protected]4dca587c2013-03-07 16:54:471163}
1164
rchbd089ab2017-05-26 23:05:041165TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411166 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041167 HostPortPair::FromString("mail.example.org:443"));
1168
1169 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521170 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041171 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431172 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1173 mock_quic_data.AddWrite(
1174 SYNCHRONOUS,
1175 ConstructClientRequestHeadersPacket(
1176 2, GetNthClientInitiatedStreamId(0), true, true,
1177 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131178 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041179 response_headers["key1"] = std::string(30000, 'A');
1180 response_headers["key2"] = std::string(30000, 'A');
1181 response_headers["key3"] = std::string(30000, 'A');
1182 response_headers["key4"] = std::string(30000, 'A');
1183 response_headers["key5"] = std::string(30000, 'A');
1184 response_headers["key6"] = std::string(30000, 'A');
1185 response_headers["key7"] = std::string(30000, 'A');
1186 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamilton0239aac2018-05-19 00:03:131187 spdy::SpdyHeadersIR headers_frame(GetNthClientInitiatedStreamId(0),
1188 std::move(response_headers));
1189 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1190 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041191 response_framer.SerializeFrame(headers_frame);
1192
Ryan Hamilton8d9ee76e2018-05-29 23:52:521193 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041194 size_t chunk_size = 1200;
1195 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1196 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431197 mock_quic_data.AddRead(
1198 ASYNC, ConstructServerDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521199 packet_number++, quic::kHeadersStreamId, false, false,
1200 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041201 }
1202
1203 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:431204 ASYNC,
rchbd089ab2017-05-26 23:05:041205 ConstructServerDataPacket(packet_number, GetNthClientInitiatedStreamId(0),
1206 false, true, 0, "hello!"));
1207 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431208 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1209 mock_quic_data.AddWrite(ASYNC,
1210 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041211
1212 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1213
1214 CreateSession();
1215
1216 SendRequestAndExpectQuicResponse("hello!");
1217}
1218
1219TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481220 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411221 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041222 HostPortPair::FromString("mail.example.org:443"));
1223
1224 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521225 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041226 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431227 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1228 mock_quic_data.AddWrite(
1229 SYNCHRONOUS,
1230 ConstructClientRequestHeadersPacket(
1231 2, GetNthClientInitiatedStreamId(0), true, true,
1232 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131233 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041234 response_headers["key1"] = std::string(30000, 'A');
1235 response_headers["key2"] = std::string(30000, 'A');
1236 response_headers["key3"] = std::string(30000, 'A');
1237 response_headers["key4"] = std::string(30000, 'A');
1238 response_headers["key5"] = std::string(30000, 'A');
1239 response_headers["key6"] = std::string(30000, 'A');
1240 response_headers["key7"] = std::string(30000, 'A');
1241 response_headers["key8"] = std::string(30000, 'A');
1242 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamilton0239aac2018-05-19 00:03:131243 spdy::SpdyHeadersIR headers_frame(GetNthClientInitiatedStreamId(0),
1244 std::move(response_headers));
1245 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1246 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041247 response_framer.SerializeFrame(headers_frame);
1248
Ryan Hamilton8d9ee76e2018-05-29 23:52:521249 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041250 size_t chunk_size = 1200;
1251 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1252 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431253 mock_quic_data.AddRead(
1254 ASYNC, ConstructServerDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521255 packet_number++, quic::kHeadersStreamId, false, false,
1256 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041257 }
1258
1259 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:431260 ASYNC,
rchbd089ab2017-05-26 23:05:041261 ConstructServerDataPacket(packet_number, GetNthClientInitiatedStreamId(0),
1262 false, true, 0, "hello!"));
1263 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431264 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1265 mock_quic_data.AddWrite(
1266 ASYNC, ConstructClientAckAndRstPacket(4, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:521267 quic::QUIC_HEADERS_TOO_LARGE,
Zhongyi Shi32f2fd02018-04-16 18:23:431268 packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041269
1270 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1271
1272 CreateSession();
1273
1274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1275 TestCompletionCallback callback;
1276 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1278 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1279}
1280
rcha2bd44b2016-07-02 00:42:551281TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411282 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551283
Ryan Hamilton9835e662018-08-02 05:36:271284 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551285
1286 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521287 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361288 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431289 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1290 mock_quic_data.AddWrite(
1291 SYNCHRONOUS,
1292 ConstructClientRequestHeadersPacket(
1293 2, GetNthClientInitiatedStreamId(0), true, true,
1294 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1295 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1296 1, GetNthClientInitiatedStreamId(0), false,
1297 false, GetResponseHeaders("200 OK")));
1298 mock_quic_data.AddRead(
1299 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1300 false, true, 0, "hello!"));
1301 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551302 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1303
1304 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1305
1306 CreateSession();
1307
1308 SendRequestAndExpectQuicResponse("hello!");
1309 EXPECT_TRUE(
1310 test_socket_performance_watcher_factory_.rtt_notification_received());
1311}
1312
[email protected]cf3e3cd62014-02-05 16:16:161313TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411314 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591315 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491316 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161317
[email protected]cf3e3cd62014-02-05 16:16:161318 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521319 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361320 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431321 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1322 mock_quic_data.AddWrite(
1323 SYNCHRONOUS,
1324 ConstructClientRequestHeadersPacket(
1325 2, GetNthClientInitiatedStreamId(0), true, true,
1326 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
1327 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1328 1, GetNthClientInitiatedStreamId(0), false,
1329 false, GetResponseHeaders("200 OK")));
1330 mock_quic_data.AddRead(
1331 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1332 false, true, 0, "hello!"));
1333 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501334 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591335 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161336
rcha5399e02015-04-21 19:32:041337 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161338
tbansal0f56a39a2016-04-07 22:03:381339 EXPECT_FALSE(
1340 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161341 // There is no need to set up an alternate protocol job, because
1342 // no attempt will be made to speak to the proxy over TCP.
1343
rch9ae5b3b2016-02-11 00:36:291344 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161345 CreateSession();
1346
bnc62a44f022015-04-02 15:59:411347 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381348 EXPECT_TRUE(
1349 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161350}
1351
bnc313ba9c2015-06-11 15:42:311352// Regression test for https://crbug.com/492458. Test that for an HTTP
1353// connection through a QUIC proxy, the certificate exhibited by the proxy is
1354// checked against the proxy hostname, not the origin hostname.
1355TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291356 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311357 const std::string proxy_host = "www.example.org";
1358
mmenke6ddfbea2017-05-31 21:48:411359 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591360 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491361 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311362
alyssar2adf3ac2016-05-03 17:12:581363 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311364 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521365 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361366 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431367 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1368 mock_quic_data.AddWrite(
1369 SYNCHRONOUS,
1370 ConstructClientRequestHeadersPacket(
1371 2, GetNthClientInitiatedStreamId(0), true, true,
1372 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
1373 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1374 1, GetNthClientInitiatedStreamId(0), false,
1375 false, GetResponseHeaders("200 OK")));
1376 mock_quic_data.AddRead(
1377 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1378 false, true, 0, "hello!"));
1379 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501380 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591381 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311382 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1383
1384 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291385 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311386 ASSERT_TRUE(cert.get());
1387 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241388 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1389 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311390 ProofVerifyDetailsChromium verify_details;
1391 verify_details.cert_verify_result.verified_cert = cert;
1392 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561393 ProofVerifyDetailsChromium verify_details2;
1394 verify_details2.cert_verify_result.verified_cert = cert;
1395 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311396
1397 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091398 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321399 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271400 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311401 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1402}
1403
rchbe69cb902016-02-11 01:10:481404TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341405 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481406 HostPortPair origin("www.example.org", 443);
1407 HostPortPair alternative("mail.example.org", 443);
1408
1409 base::FilePath certs_dir = GetTestCertsDirectory();
1410 scoped_refptr<X509Certificate> cert(
1411 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1412 ASSERT_TRUE(cert.get());
1413 // TODO(rch): the connection should be "to" the origin, so if the cert is
1414 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241415 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1416 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481417 ProofVerifyDetailsChromium verify_details;
1418 verify_details.cert_verify_result.verified_cert = cert;
1419 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1420
alyssar2adf3ac2016-05-03 17:12:581421 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481422 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521423 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361424 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431425 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1426 mock_quic_data.AddWrite(
1427 SYNCHRONOUS,
1428 ConstructClientRequestHeadersPacket(
1429 2, GetNthClientInitiatedStreamId(0), true, true,
1430 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1431 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1432 1, GetNthClientInitiatedStreamId(0), false,
1433 false, GetResponseHeaders("200 OK")));
1434 mock_quic_data.AddRead(
1435 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1436 false, true, 0, "hello!"));
1437 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481438 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1439 mock_quic_data.AddRead(ASYNC, 0);
1440 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1441
1442 request_.url = GURL("https://" + origin.host());
1443 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271444 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091445 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321446 CreateSession();
rchbe69cb902016-02-11 01:10:481447
1448 SendRequestAndExpectQuicResponse("hello!");
1449}
1450
zhongyief3f4ce52017-07-05 23:53:281451TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521452 quic::QuicTransportVersion unsupported_version =
1453 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281454 // Add support for another QUIC version besides |version_|. Also find a
1455 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521456 for (const quic::QuicTransportVersion& version :
1457 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281458 if (version == version_)
1459 continue;
1460 if (supported_versions_.size() != 2) {
1461 supported_versions_.push_back(version);
1462 continue;
1463 }
1464 unsupported_version = version;
1465 break;
1466 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521467 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281468
1469 // Set up alternative service to use QUIC with a version that is not
1470 // supported.
1471 url::SchemeHostPort server(request_.url);
1472 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1473 443);
1474 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1475 http_server_properties_.SetQuicAlternativeService(
1476 server, alternative_service, expiration, {unsupported_version});
1477
1478 AlternativeServiceInfoVector alt_svc_info_vector =
1479 http_server_properties_.GetAlternativeServiceInfos(server);
1480 EXPECT_EQ(1u, alt_svc_info_vector.size());
1481 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1482 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1483 EXPECT_EQ(unsupported_version,
1484 alt_svc_info_vector[0].advertised_versions()[0]);
1485
1486 // First request should still be sent via TCP as the QUIC version advertised
1487 // in the stored AlternativeService is not supported by the client. However,
1488 // the response from the server will advertise new Alt-Svc with supported
1489 // versions.
1490 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521491 GenerateQuicVersionsListForAltSvcHeader(
1492 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281493 std::string altsvc_header =
1494 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1495 advertised_versions_list_str.c_str());
1496 MockRead http_reads[] = {
1497 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1498 MockRead("hello world"),
1499 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1500 MockRead(ASYNC, OK)};
1501
Ryan Sleevib8d7ea02018-05-07 20:01:011502 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281503 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081504 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281505 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1506
1507 // Second request should be sent via QUIC as a new list of verions supported
1508 // by the client has been advertised by the server.
1509 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521510 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281511 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431512 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1513 mock_quic_data.AddWrite(
1514 SYNCHRONOUS,
1515 ConstructClientRequestHeadersPacket(
1516 2, GetNthClientInitiatedStreamId(0), true, true,
1517 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1518 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1519 1, GetNthClientInitiatedStreamId(0), false,
1520 false, GetResponseHeaders("200 OK")));
1521 mock_quic_data.AddRead(
1522 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1523 false, true, 0, "hello!"));
1524 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281525 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1526 mock_quic_data.AddRead(ASYNC, 0); // EOF
1527
1528 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1529
1530 AddHangingNonAlternateProtocolSocketData();
1531
1532 CreateSession(supported_versions_);
1533
1534 SendRequestAndExpectHttpResponse("hello world");
1535 SendRequestAndExpectQuicResponse("hello!");
1536
1537 // Check alternative service list is updated with new versions.
1538 alt_svc_info_vector =
1539 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1540 EXPECT_EQ(1u, alt_svc_info_vector.size());
1541 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1542 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1543 // Advertised versions will be lised in a sorted order.
1544 std::sort(supported_versions_.begin(), supported_versions_.end());
1545 EXPECT_EQ(supported_versions_[0],
1546 alt_svc_info_vector[0].advertised_versions()[0]);
1547 EXPECT_EQ(supported_versions_[1],
1548 alt_svc_info_vector[0].advertised_versions()[1]);
1549}
1550
bncaccd4962017-04-06 21:00:261551// Regression test for https://crbug.com/546991.
1552// The server might not be able to serve a request on an alternative connection,
1553// and might send a 421 Misdirected Request response status to indicate this.
1554// HttpNetworkTransaction should reset the request and retry without using
1555// alternative services.
1556TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1557 // Set up alternative service to use QUIC.
1558 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1559 // that overrides |enable_alternative_services|.
1560 url::SchemeHostPort server(request_.url);
1561 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1562 443);
1563 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211564 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441565 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261566
davidbena4449722017-05-05 23:30:531567 // First try: The alternative job uses QUIC and reports an HTTP 421
1568 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1569 // paused at Connect(), so it will never exit the socket pool. This ensures
1570 // that the alternate job always wins the race and keeps whether the
1571 // |http_data| exits the socket pool before the main job is aborted
1572 // deterministic. The first main job gets aborted without the socket pool ever
1573 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261574 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521575 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361576 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431577 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1578 mock_quic_data.AddWrite(
1579 SYNCHRONOUS,
1580 ConstructClientRequestHeadersPacket(
1581 2, GetNthClientInitiatedStreamId(0), true, true,
1582 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
1583 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1584 1, GetNthClientInitiatedStreamId(0), false,
1585 true, GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261586 mock_quic_data.AddRead(ASYNC, OK);
1587 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1588
davidbena4449722017-05-05 23:30:531589 // Second try: The main job uses TCP, and there is no alternate job. Once the
1590 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1591 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261592 // Note that if there was an alternative QUIC Job created for the second try,
1593 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1594 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531595 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1596 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1597 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1598 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1599 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1600 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011601 reads, writes);
bncaccd4962017-04-06 21:00:261602 socket_factory_.AddSocketDataProvider(&http_data);
1603 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1604
bncaccd4962017-04-06 21:00:261605 CreateSession();
1606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531607
1608 // Run until |mock_quic_data| has failed and |http_data| has paused.
1609 TestCompletionCallback callback;
1610 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1612 base::RunLoop().RunUntilIdle();
1613
1614 // |mock_quic_data| must have run to completion.
1615 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1616 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1617
1618 // Now that the QUIC data has been consumed, unblock |http_data|.
1619 http_data.socket()->OnConnectComplete(MockConnect());
1620
1621 // The retry logic must hide the 421 status. The transaction succeeds on
1622 // |http_data|.
1623 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261624 CheckWasHttpResponse(&trans);
1625 CheckResponsePort(&trans, 443);
1626 CheckResponseData(&trans, "hello!");
1627}
1628
[email protected]1e960032013-12-20 19:00:201629TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411630 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571631 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301632
tbansalfdf5665b2015-09-21 22:46:401633 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521634 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361635 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431636 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401637 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401638 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371639 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361640 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431641 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301642 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401643 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431644 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401645
1646 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1647 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301648
1649 CreateSession();
1650
tbansal0f56a39a2016-04-07 22:03:381651 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401652 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161653 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401654 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161655 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1657 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381658 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531659
1660 NetErrorDetails details;
1661 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521662 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401663 }
[email protected]cebe3282013-05-22 23:49:301664}
1665
tbansalc8a94ea2015-11-02 23:58:511666TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1667 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411668 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571669 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511670
1671 MockRead http_reads[] = {
1672 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1673 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1674 MockRead(ASYNC, OK)};
1675
Ryan Sleevib8d7ea02018-05-07 20:01:011676 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511677 socket_factory_.AddSocketDataProvider(&data);
1678 SSLSocketDataProvider ssl(ASYNC, OK);
1679 socket_factory_.AddSSLSocketDataProvider(&ssl);
1680
1681 CreateSession();
1682
1683 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381684 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511685}
1686
bncc958faa2015-07-31 18:14:521687TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521688 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561689 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1690 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521691 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1692 MockRead(ASYNC, OK)};
1693
Ryan Sleevib8d7ea02018-05-07 20:01:011694 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521695 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081696 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561697 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521698
1699 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521700 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361701 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431702 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1703 mock_quic_data.AddWrite(
1704 SYNCHRONOUS,
1705 ConstructClientRequestHeadersPacket(
1706 2, GetNthClientInitiatedStreamId(0), true, true,
1707 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1708 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1709 1, GetNthClientInitiatedStreamId(0), false,
1710 false, GetResponseHeaders("200 OK")));
1711 mock_quic_data.AddRead(
1712 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1713 false, true, 0, "hello!"));
1714 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521715 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591716 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521717
1718 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1719
rtennetib8e80fb2016-05-16 00:12:091720 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321721 CreateSession();
bncc958faa2015-07-31 18:14:521722
1723 SendRequestAndExpectHttpResponse("hello world");
1724 SendRequestAndExpectQuicResponse("hello!");
1725}
1726
zhongyia00ca012017-07-06 23:36:391727TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1728 // Both server advertises and client supports two QUIC versions.
1729 // Only |version_| is advertised and supported.
1730 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1731 // PacketMakers are using |version_|.
1732
1733 // Add support for another QUIC version besides |version_| on the client side.
1734 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521735 quic::QuicTransportVersion advertised_version_2 =
1736 quic::QUIC_VERSION_UNSUPPORTED;
1737 for (const quic::QuicTransportVersion& version :
1738 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391739 if (version == version_)
1740 continue;
1741 if (supported_versions_.size() != 2) {
1742 supported_versions_.push_back(version);
1743 continue;
1744 }
1745 advertised_version_2 = version;
1746 break;
1747 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521748 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391749
1750 std::string QuicAltSvcWithVersionHeader =
1751 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1752 advertised_version_2, version_);
1753
1754 MockRead http_reads[] = {
1755 MockRead("HTTP/1.1 200 OK\r\n"),
1756 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1757 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1758 MockRead(ASYNC, OK)};
1759
Ryan Sleevib8d7ea02018-05-07 20:01:011760 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391761 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081762 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391763 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1764
1765 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521766 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391767 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431768 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1769 mock_quic_data.AddWrite(
1770 SYNCHRONOUS,
1771 ConstructClientRequestHeadersPacket(
1772 2, GetNthClientInitiatedStreamId(0), true, true,
1773 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1774 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1775 1, GetNthClientInitiatedStreamId(0), false,
1776 false, GetResponseHeaders("200 OK")));
1777 mock_quic_data.AddRead(
1778 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1779 false, true, 0, "hello!"));
1780 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391781 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1782 mock_quic_data.AddRead(ASYNC, 0); // EOF
1783
1784 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1785
1786 AddHangingNonAlternateProtocolSocketData();
1787 CreateSession(supported_versions_);
1788
1789 SendRequestAndExpectHttpResponse("hello world");
1790 SendRequestAndExpectQuicResponse("hello!");
1791}
1792
1793TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1794 // Client and server mutually support more than one QUIC_VERSION.
1795 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1796 // which is verified as the PacketMakers are using |version_|.
1797
Ryan Hamilton8d9ee76e2018-05-29 23:52:521798 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1799 for (const quic::QuicTransportVersion& version :
1800 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391801 if (version == version_)
1802 continue;
1803 common_version_2 = version;
1804 break;
1805 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521806 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391807
1808 supported_versions_.push_back(
1809 common_version_2); // Supported but unpreferred.
1810
1811 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1812 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1813
1814 MockRead http_reads[] = {
1815 MockRead("HTTP/1.1 200 OK\r\n"),
1816 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1817 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1818 MockRead(ASYNC, OK)};
1819
Ryan Sleevib8d7ea02018-05-07 20:01:011820 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391821 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081822 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391823 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1824
1825 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521826 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391827 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431828 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1829 mock_quic_data.AddWrite(
1830 SYNCHRONOUS,
1831 ConstructClientRequestHeadersPacket(
1832 2, GetNthClientInitiatedStreamId(0), true, true,
1833 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1834 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1835 1, GetNthClientInitiatedStreamId(0), false,
1836 false, GetResponseHeaders("200 OK")));
1837 mock_quic_data.AddRead(
1838 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1839 false, true, 0, "hello!"));
1840 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391841 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1842 mock_quic_data.AddRead(ASYNC, 0); // EOF
1843
1844 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1845
1846 AddHangingNonAlternateProtocolSocketData();
1847 CreateSession(supported_versions_);
1848
1849 SendRequestAndExpectHttpResponse("hello world");
1850 SendRequestAndExpectQuicResponse("hello!");
1851}
1852
rchf47265dc2016-03-21 21:33:121853TEST_P(QuicNetworkTransactionTest,
1854 UseAlternativeServiceWithProbabilityForQuic) {
1855 MockRead http_reads[] = {
1856 MockRead("HTTP/1.1 200 OK\r\n"),
1857 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1858 MockRead("hello world"),
1859 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1860 MockRead(ASYNC, OK)};
1861
Ryan Sleevib8d7ea02018-05-07 20:01:011862 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121863 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081864 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121865 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1866
1867 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521868 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361869 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431870 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1871 mock_quic_data.AddWrite(
1872 SYNCHRONOUS,
1873 ConstructClientRequestHeadersPacket(
1874 2, GetNthClientInitiatedStreamId(0), true, true,
1875 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1876 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1877 1, GetNthClientInitiatedStreamId(0), false,
1878 false, GetResponseHeaders("200 OK")));
1879 mock_quic_data.AddRead(
1880 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1881 false, true, 0, "hello!"));
1882 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121883 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1884 mock_quic_data.AddRead(ASYNC, 0); // EOF
1885
1886 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1887
rtennetib8e80fb2016-05-16 00:12:091888 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121889 CreateSession();
1890
1891 SendRequestAndExpectHttpResponse("hello world");
1892 SendRequestAndExpectQuicResponse("hello!");
1893}
1894
zhongyi3d4a55e72016-04-22 20:36:461895TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1896 MockRead http_reads[] = {
1897 MockRead("HTTP/1.1 200 OK\r\n"),
1898 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1899 MockRead("hello world"),
1900 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1901 MockRead(ASYNC, OK)};
1902
Ryan Sleevib8d7ea02018-05-07 20:01:011903 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461904 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081905 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1907
1908 CreateSession();
bncb26024382016-06-29 02:39:451909 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461910 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:451911 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:461912 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401913 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461914 session_->http_server_properties();
1915 url::SchemeHostPort http_server("http", "mail.example.org", 443);
1916 url::SchemeHostPort https_server("https", "mail.example.org", 443);
1917 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:461918 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:341919 2u,
1920 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:451921 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:341922 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:461923}
1924
1925TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
1926 MockRead http_reads[] = {
1927 MockRead("HTTP/1.1 200 OK\r\n"),
1928 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1929 MockRead("hello world"),
1930 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1931 MockRead(ASYNC, OK)};
1932
Ryan Sleevib8d7ea02018-05-07 20:01:011933 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:081934 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461935
1936 socket_factory_.AddSocketDataProvider(&http_data);
1937 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1938 socket_factory_.AddSocketDataProvider(&http_data);
1939 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1940
1941 CreateSession();
1942
1943 // Send https request and set alternative services if response header
1944 // advertises alternative service for mail.example.org.
1945 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401946 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461947 session_->http_server_properties();
1948
1949 const url::SchemeHostPort https_server(request_.url);
1950 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:341951 EXPECT_EQ(
1952 2u,
1953 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:461954
1955 // Send http request to the same origin but with diffrent scheme, should not
1956 // use QUIC.
1957 request_.url = GURL("http://mail.example.org:443");
1958 SendRequestAndExpectHttpResponse("hello world");
1959}
1960
zhongyie537a002017-06-27 16:48:211961TEST_P(QuicNetworkTransactionTest,
1962 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:441963 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521964 for (const quic::QuicTransportVersion& version :
1965 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:441966 if (version == version_)
1967 continue;
1968 supported_versions_.push_back(version);
1969 break;
1970 }
1971
zhongyie537a002017-06-27 16:48:211972 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521973 GenerateQuicVersionsListForAltSvcHeader(
1974 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:211975 std::string altsvc_header =
1976 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1977 advertised_versions_list_str.c_str());
1978 MockRead http_reads[] = {
1979 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1980 MockRead("hello world"),
1981 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1982 MockRead(ASYNC, OK)};
1983
Ryan Sleevib8d7ea02018-05-07 20:01:011984 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:211985 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081986 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:211987 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1988
1989 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521990 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:211991 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431992 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1993 mock_quic_data.AddWrite(
1994 SYNCHRONOUS,
1995 ConstructClientRequestHeadersPacket(
1996 2, GetNthClientInitiatedStreamId(0), true, true,
1997 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1998 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1999 1, GetNthClientInitiatedStreamId(0), false,
2000 false, GetResponseHeaders("200 OK")));
2001 mock_quic_data.AddRead(
2002 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
2003 false, true, 0, "hello!"));
2004 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212005 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2006 mock_quic_data.AddRead(ASYNC, 0); // EOF
2007
2008 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2009
2010 AddHangingNonAlternateProtocolSocketData();
2011
zhongyi86838d52017-06-30 01:19:442012 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212013
2014 SendRequestAndExpectHttpResponse("hello world");
2015 SendRequestAndExpectQuicResponse("hello!");
2016
2017 // Check alternative service is set with only mutually supported versions.
2018 const url::SchemeHostPort https_server(request_.url);
2019 const AlternativeServiceInfoVector alt_svc_info_vector =
2020 session_->http_server_properties()->GetAlternativeServiceInfos(
2021 https_server);
2022 EXPECT_EQ(1u, alt_svc_info_vector.size());
2023 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2024 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2025 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442026 std::sort(supported_versions_.begin(), supported_versions_.end());
2027 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212028 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442029 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212030 alt_svc_info_vector[0].advertised_versions()[1]);
2031}
2032
danzh3134c2562016-08-12 14:07:522033TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442034 std::string altsvc_header =
2035 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072036 MockRead http_reads[] = {
2037 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2038 MockRead("hello world"),
2039 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2040 MockRead(ASYNC, OK)};
2041
Ryan Sleevib8d7ea02018-05-07 20:01:012042 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072043 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082044 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072045 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2046
2047 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522048 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362049 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432050 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2051 mock_quic_data.AddWrite(
2052 SYNCHRONOUS,
2053 ConstructClientRequestHeadersPacket(
2054 2, GetNthClientInitiatedStreamId(0), true, true,
2055 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2056 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2057 1, GetNthClientInitiatedStreamId(0), false,
2058 false, GetResponseHeaders("200 OK")));
2059 mock_quic_data.AddRead(
2060 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
2061 false, true, 0, "hello!"));
2062 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072063 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592064 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072065
2066 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2067
rtennetib8e80fb2016-05-16 00:12:092068 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322069 CreateSession();
bnc8be55ebb2015-10-30 14:12:072070
2071 SendRequestAndExpectHttpResponse("hello world");
2072 SendRequestAndExpectQuicResponse("hello!");
2073}
2074
zhongyi6b5a3892016-03-12 04:46:202075TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092076 if (version_ == quic::QUIC_VERSION_99) {
2077 // Not available under version 99
2078 return;
2079 }
zhongyi6b5a3892016-03-12 04:46:202080 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522081 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362082 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432083 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2084 mock_quic_data.AddWrite(
2085 SYNCHRONOUS,
2086 ConstructClientRequestHeadersPacket(
2087 2, GetNthClientInitiatedStreamId(0), true, true,
2088 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2089 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2090 1, GetNthClientInitiatedStreamId(0), false,
2091 false, GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202092 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522093 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432094 mock_quic_data.AddRead(SYNCHRONOUS,
2095 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522096 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432097 "connection migration with port change only"));
2098 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
2099 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
2100 3, GetNthClientInitiatedStreamId(0),
2101 false, true, 0, "hello!"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522102 mock_quic_data.AddWrite(
2103 SYNCHRONOUS,
2104 ConstructClientAckAndRstPacket(4, GetNthClientInitiatedStreamId(0),
2105 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202106 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2107 mock_quic_data.AddRead(ASYNC, 0); // EOF
2108
2109 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2110
2111 // The non-alternate protocol job needs to hang in order to guarantee that
2112 // the alternate-protocol job will "win".
2113 AddHangingNonAlternateProtocolSocketData();
2114
2115 // In order for a new QUIC session to be established via alternate-protocol
2116 // without racing an HTTP connection, we need the host resolution to happen
2117 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2118 // connection to the the server, in this test we require confirmation
2119 // before encrypting so the HTTP job will still start.
2120 host_resolver_.set_synchronous_mode(true);
2121 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2122 "");
2123 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2124 AddressList address;
maksim.sisov31452af2016-07-27 06:38:102125 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582126 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2127 CompletionOnceCallback(), &request,
2128 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412129 EXPECT_THAT(rv, IsOk());
zhongyi6b5a3892016-03-12 04:46:202130
2131 CreateSession();
2132 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272133 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202134
bnc691fda62016-08-12 00:43:162135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202136 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412137 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202139
2140 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522141 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012142 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202143
2144 // Check whether this transaction is correctly marked as received a go-away
2145 // because of migrating port.
2146 NetErrorDetails details;
2147 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162148 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202149 EXPECT_TRUE(details.quic_port_migration_detected);
2150}
2151
Zhongyi Shia6b68d112018-09-24 07:49:032152// This test verifies that a new QUIC connection will be attempted on the
2153// alternate network if the original QUIC connection fails with idle timeout
2154// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2155// alternate network as well, QUIC is marked as broken and the brokenness will
2156// not expire when default network changes.
2157TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2158 SetUpTestForRetryConnectionOnAlternateNetwork();
2159
2160 std::string request_data;
2161 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2162 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2163
2164 // The request will initially go out over QUIC.
2165 MockQuicData quic_data;
2166 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2167 int packet_num = 1;
2168 quic_data.AddWrite(SYNCHRONOUS,
2169 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2170 // Retranmit the handshake messages.
2171 quic_data.AddWrite(SYNCHRONOUS,
2172 client_maker_.MakeDummyCHLOPacket(packet_num++));
2173 quic_data.AddWrite(SYNCHRONOUS,
2174 client_maker_.MakeDummyCHLOPacket(packet_num++));
2175 quic_data.AddWrite(SYNCHRONOUS,
2176 client_maker_.MakeDummyCHLOPacket(packet_num++));
2177 quic_data.AddWrite(SYNCHRONOUS,
2178 client_maker_.MakeDummyCHLOPacket(packet_num++));
2179 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2180 if (version_ <= quic::QUIC_VERSION_39) {
2181 quic_data.AddWrite(SYNCHRONOUS,
2182 client_maker_.MakeDummyCHLOPacket(packet_num++));
2183 }
2184 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2185 quic_data.AddWrite(SYNCHRONOUS,
2186 client_maker_.MakeConnectionClosePacket(
2187 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2188 "No recent network activity."));
2189 quic_data.AddSocketDataToFactory(&socket_factory_);
2190
2191 // Add successful TCP data so that TCP job will succeed.
2192 MockWrite http_writes[] = {
2193 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2194 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2195 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2196
2197 MockRead http_reads[] = {
2198 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2199 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2200 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2201 SequencedSocketData http_data(http_reads, http_writes);
2202 socket_factory_.AddSocketDataProvider(&http_data);
2203 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2204
2205 // Add data for the second QUIC connection to fail.
2206 MockQuicData quic_data2;
2207 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2208 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2209 quic_data2.AddSocketDataToFactory(&socket_factory_);
2210
2211 // Resolve the host resolution synchronously.
2212 host_resolver_.set_synchronous_mode(true);
2213 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2214 "");
2215 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2216 AddressList address;
2217 std::unique_ptr<HostResolver::Request> request;
2218 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2219 CompletionOnceCallback(), &request,
2220 net_log_.bound());
2221 EXPECT_THAT(rv, IsOk());
2222
2223 CreateSession();
2224 session_->quic_stream_factory()->set_require_confirmation(true);
2225 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2226 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2227 QuicStreamFactoryPeer::SetAlarmFactory(
2228 session_->quic_stream_factory(),
2229 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2230 &clock_));
2231 // Add alternate protocol mapping to race QUIC and TCP.
2232 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2233 // peer.
2234 AddQuicAlternateProtocolMapping(
2235 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2236
2237 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2238 TestCompletionCallback callback;
2239 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2241
2242 // Pump the message loop to get the request started.
2243 // Request will be served with TCP job.
2244 base::RunLoop().RunUntilIdle();
2245 EXPECT_THAT(callback.WaitForResult(), IsOk());
2246 CheckResponseData(&trans, "TCP succeeds");
2247
2248 // Fire the retransmission alarm, from this point, connection will idle
2249 // timeout after 4 seconds.
Zhongyi Shia15736c2018-09-25 00:31:182250 if (!quic::GetQuicReloadableFlag(
2251 quic_fix_time_of_first_packet_sent_after_receiving)) {
2252 quic_task_runner_->RunNextTask();
2253 }
Zhongyi Shia6b68d112018-09-24 07:49:032254 // Fast forward to idle timeout the original connection. A new connection will
2255 // be kicked off on the alternate network.
2256 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2257 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2258 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2259
2260 // Run the message loop to execute posted tasks, which will report job status.
2261 base::RunLoop().RunUntilIdle();
2262
2263 // Verify that QUIC is marked as broken.
2264 ExpectBrokenAlternateProtocolMapping();
2265
2266 // Deliver a message to notify the new network becomes default, the brokenness
2267 // will not expire as QUIC is broken on both networks.
2268 scoped_mock_change_notifier_->mock_network_change_notifier()
2269 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2270 ExpectBrokenAlternateProtocolMapping();
2271
2272 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2273 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2274}
2275
2276// This test verifies that a new QUIC connection will be attempted on the
2277// alternate network if the original QUIC connection fails with idle timeout
2278// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2279// alternate network, QUIC is marked as broken. The brokenness will expire when
2280// the default network changes.
2281TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2282 SetUpTestForRetryConnectionOnAlternateNetwork();
2283
2284 std::string request_data;
2285 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2286 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2287
2288 // The request will initially go out over QUIC.
2289 MockQuicData quic_data;
2290 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2291 int packet_num = 1;
2292 quic_data.AddWrite(SYNCHRONOUS,
2293 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2294 // Retranmit the handshake messages.
2295 quic_data.AddWrite(SYNCHRONOUS,
2296 client_maker_.MakeDummyCHLOPacket(packet_num++));
2297 quic_data.AddWrite(SYNCHRONOUS,
2298 client_maker_.MakeDummyCHLOPacket(packet_num++));
2299 quic_data.AddWrite(SYNCHRONOUS,
2300 client_maker_.MakeDummyCHLOPacket(packet_num++));
2301 quic_data.AddWrite(SYNCHRONOUS,
2302 client_maker_.MakeDummyCHLOPacket(packet_num++));
2303 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2304 if (version_ <= quic::QUIC_VERSION_39) {
2305 quic_data.AddWrite(SYNCHRONOUS,
2306 client_maker_.MakeDummyCHLOPacket(packet_num++));
2307 }
2308 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2309 quic_data.AddWrite(SYNCHRONOUS,
2310 client_maker_.MakeConnectionClosePacket(
2311 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2312 "No recent network activity."));
2313 quic_data.AddSocketDataToFactory(&socket_factory_);
2314
2315 // Add successful TCP data so that TCP job will succeed.
2316 MockWrite http_writes[] = {
2317 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2318 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2319 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2320
2321 MockRead http_reads[] = {
2322 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2323 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2324 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2325 SequencedSocketData http_data(http_reads, http_writes);
2326 socket_factory_.AddSocketDataProvider(&http_data);
2327 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2328
2329 // Quic connection will be retried on the alternate network after the initial
2330 // one fails on the default network.
2331 MockQuicData quic_data2;
2332 quic::QuicStreamOffset header_stream_offset = 0;
2333 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2334 quic_data2.AddWrite(SYNCHRONOUS,
2335 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2336
2337 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2338 quic_data2.AddWrite(SYNCHRONOUS,
2339 ConstructInitialSettingsPacket(2, &header_stream_offset));
2340 quic_data2.AddSocketDataToFactory(&socket_factory_);
2341
2342 // Resolve the host resolution synchronously.
2343 host_resolver_.set_synchronous_mode(true);
2344 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2345 "");
2346 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2347 AddressList address;
2348 std::unique_ptr<HostResolver::Request> request;
2349 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2350 CompletionOnceCallback(), &request,
2351 net_log_.bound());
2352 EXPECT_THAT(rv, IsOk());
2353
2354 CreateSession();
2355 session_->quic_stream_factory()->set_require_confirmation(true);
2356 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2357 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2358 QuicStreamFactoryPeer::SetAlarmFactory(
2359 session_->quic_stream_factory(),
2360 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2361 &clock_));
2362 // Add alternate protocol mapping to race QUIC and TCP.
2363 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2364 // peer.
2365 AddQuicAlternateProtocolMapping(
2366 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2367
2368 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2369 TestCompletionCallback callback;
2370 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2371 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2372
2373 // Pump the message loop to get the request started.
2374 // Request will be served with TCP job.
2375 base::RunLoop().RunUntilIdle();
2376 EXPECT_THAT(callback.WaitForResult(), IsOk());
2377 CheckResponseData(&trans, "TCP succeeds");
2378
2379 // Fire the retransmission alarm, after which connection will idle
2380 // timeout after 4 seconds.
Zhongyi Shia15736c2018-09-25 00:31:182381 if (!quic::GetQuicReloadableFlag(
2382 quic_fix_time_of_first_packet_sent_after_receiving)) {
2383 quic_task_runner_->RunNextTask();
2384 }
Zhongyi Shia6b68d112018-09-24 07:49:032385 // Fast forward to idle timeout the original connection. A new connection will
2386 // be kicked off on the alternate network.
2387 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2388 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2389 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2390
2391 // The second connection hasn't finish handshake, verify that QUIC is not
2392 // marked as broken.
2393 ExpectQuicAlternateProtocolMapping();
2394 // Explicitly confirm the handshake on the second connection.
2395 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2396 quic::QuicSession::HANDSHAKE_CONFIRMED);
2397 // Run message loop to execute posted tasks, which will notify JoController
2398 // about the orphaned job status.
2399 base::RunLoop().RunUntilIdle();
2400
2401 // Verify that QUIC is marked as broken.
2402 ExpectBrokenAlternateProtocolMapping();
2403
2404 // Deliver a message to notify the new network becomes default, the previous
2405 // brokenness will be clear as the brokenness is bond with old default
2406 // network.
2407 scoped_mock_change_notifier_->mock_network_change_notifier()
2408 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2409 ExpectQuicAlternateProtocolMapping();
2410
2411 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2412 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2413}
2414
2415// This test verifies that a new QUIC connection will be attempted on the
2416// alternate network if the original QUIC connection fails with idle timeout
2417// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2418// alternative network succeeds, QUIC is not marked as broken.
2419TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2420 SetUpTestForRetryConnectionOnAlternateNetwork();
2421
2422 std::string request_data;
2423 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2424 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2425
2426 // The request will initially go out over QUIC.
2427 MockQuicData quic_data;
2428 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2429 int packet_num = 1;
2430 quic_data.AddWrite(SYNCHRONOUS,
2431 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2432 // Retranmit the handshake messages.
2433 quic_data.AddWrite(SYNCHRONOUS,
2434 client_maker_.MakeDummyCHLOPacket(packet_num++));
2435 quic_data.AddWrite(SYNCHRONOUS,
2436 client_maker_.MakeDummyCHLOPacket(packet_num++));
2437 quic_data.AddWrite(SYNCHRONOUS,
2438 client_maker_.MakeDummyCHLOPacket(packet_num++));
2439 quic_data.AddWrite(SYNCHRONOUS,
2440 client_maker_.MakeDummyCHLOPacket(packet_num++));
2441 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2442 // quic_fix_has_pending_crypto_data is introduced and enabled.
2443 if (version_ <= quic::QUIC_VERSION_39) {
2444 quic_data.AddWrite(SYNCHRONOUS,
2445 client_maker_.MakeDummyCHLOPacket(packet_num++));
2446 }
2447 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2448 quic_data.AddWrite(SYNCHRONOUS,
2449 client_maker_.MakeConnectionClosePacket(
2450 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2451 "No recent network activity."));
2452 quic_data.AddSocketDataToFactory(&socket_factory_);
2453
2454 // Add hanging TCP data so that TCP job will never succeeded.
2455 AddHangingNonAlternateProtocolSocketData();
2456
2457 // Quic connection will then be retried on the alternate network.
2458 MockQuicData quic_data2;
2459 quic::QuicStreamOffset header_stream_offset = 0;
2460 quic_data2.AddWrite(SYNCHRONOUS,
2461 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2462
2463 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2464 quic_data2.AddWrite(SYNCHRONOUS,
2465 ConstructInitialSettingsPacket(2, &header_stream_offset));
2466 quic_data2.AddWrite(
2467 SYNCHRONOUS,
2468 ConstructClientRequestHeadersPacket(
2469 3, GetNthClientInitiatedStreamId(0), true, true,
2470 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2471 quic_data2.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2472 1, GetNthClientInitiatedStreamId(0), false,
2473 false, GetResponseHeaders("200 OK")));
2474 quic_data2.AddRead(
2475 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
2476 false, true, 0, "hello!"));
2477 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2478 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2479 quic_data2.AddSocketDataToFactory(&socket_factory_);
2480
2481 // Resolve the host resolution synchronously.
2482 host_resolver_.set_synchronous_mode(true);
2483 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2484 "");
2485 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2486 AddressList address;
2487 std::unique_ptr<HostResolver::Request> request;
2488 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2489 CompletionOnceCallback(), &request,
2490 net_log_.bound());
2491 EXPECT_THAT(rv, IsOk());
2492
2493 CreateSession();
2494 session_->quic_stream_factory()->set_require_confirmation(true);
2495 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2496 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2497 QuicStreamFactoryPeer::SetAlarmFactory(
2498 session_->quic_stream_factory(),
2499 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2500 &clock_));
2501 // Add alternate protocol mapping to race QUIC and TCP.
2502 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2503 // peer.
2504 AddQuicAlternateProtocolMapping(
2505 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2506
2507 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2508 TestCompletionCallback callback;
2509 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2510 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2511
2512 // Pump the message loop to get the request started.
2513 base::RunLoop().RunUntilIdle();
Zhongyi Shia15736c2018-09-25 00:31:182514 if (!quic::GetQuicReloadableFlag(
2515 quic_fix_time_of_first_packet_sent_after_receiving)) {
2516 quic_task_runner_->RunNextTask();
2517 }
Zhongyi Shia6b68d112018-09-24 07:49:032518
2519 // Fast forward to idle timeout the original connection. A new connection will
2520 // be kicked off on the alternate network.
2521 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2522 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2523 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2524
2525 // Verify that QUIC is not marked as broken.
2526 ExpectQuicAlternateProtocolMapping();
2527 // Explicitly confirm the handshake on the second connection.
2528 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2529 quic::QuicSession::HANDSHAKE_CONFIRMED);
2530
2531 // Read the response.
2532 EXPECT_THAT(callback.WaitForResult(), IsOk());
2533 CheckResponseData(&trans, "hello!");
2534 // Verify that QUIC is not marked as broken.
2535 ExpectQuicAlternateProtocolMapping();
2536
2537 // Deliver a message to notify the new network becomes default.
2538 scoped_mock_change_notifier_->mock_network_change_notifier()
2539 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2540 ExpectQuicAlternateProtocolMapping();
2541 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2542 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2543}
2544
rch9ecde09b2017-04-08 00:18:232545// Verify that if a QUIC connection times out, the QuicHttpStream will
2546// return QUIC_PROTOCOL_ERROR.
2547TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482548 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412549 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232550
2551 // The request will initially go out over QUIC.
2552 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522553 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132554 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232555 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2556
2557 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522558 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2559 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432560 quic_data.AddWrite(SYNCHRONOUS,
2561 client_maker_.MakeRequestHeadersPacketAndSaveData(
2562 1, GetNthClientInitiatedStreamId(0), true, true,
2563 priority, GetRequestHeaders("GET", "https", "/"), 0,
2564 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232565
2566 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522567 quic::QuicStreamOffset settings_offset = header_stream_offset;
2568 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432569 quic_data.AddWrite(SYNCHRONOUS,
2570 client_maker_.MakeInitialSettingsPacketAndSaveData(
2571 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232572 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522573 quic_data.AddWrite(
2574 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
2575 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232576 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:432577 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522578 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432579 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232580 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522581 quic_data.AddWrite(
2582 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
2583 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432584 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522585 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432586 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232587 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:522588 quic_data.AddWrite(
2589 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
2590 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432591 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522592 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432593 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232594 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522595 quic_data.AddWrite(
2596 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
2597 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432598 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522599 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432600 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232601
Zhongyi Shi32f2fd02018-04-16 18:23:432602 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522603 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432604 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222605
rch9ecde09b2017-04-08 00:18:232606 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2607 quic_data.AddRead(ASYNC, OK);
2608 quic_data.AddSocketDataToFactory(&socket_factory_);
2609
2610 // In order for a new QUIC session to be established via alternate-protocol
2611 // without racing an HTTP connection, we need the host resolution to happen
2612 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2613 // connection to the the server, in this test we require confirmation
2614 // before encrypting so the HTTP job will still start.
2615 host_resolver_.set_synchronous_mode(true);
2616 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2617 "");
2618 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2619 AddressList address;
2620 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582621 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2622 CompletionOnceCallback(), &request,
2623 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412624 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232625
2626 CreateSession();
2627 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552628 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232629 QuicStreamFactoryPeer::SetAlarmFactory(
2630 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192631 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552632 &clock_));
rch9ecde09b2017-04-08 00:18:232633
Ryan Hamilton9835e662018-08-02 05:36:272634 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232635
2636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2637 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412638 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232639 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2640
2641 // Pump the message loop to get the request started.
2642 base::RunLoop().RunUntilIdle();
2643 // Explicitly confirm the handshake.
2644 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522645 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232646
2647 // Run the QUIC session to completion.
2648 quic_task_runner_->RunUntilIdle();
2649
2650 ExpectQuicAlternateProtocolMapping();
2651 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2652 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2653}
2654
2655// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2656// return QUIC_PROTOCOL_ERROR.
2657TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482658 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522659 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232660
2661 // The request will initially go out over QUIC.
2662 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522663 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132664 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232665 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2666
2667 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522668 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2669 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432670 quic_data.AddWrite(SYNCHRONOUS,
2671 client_maker_.MakeRequestHeadersPacketAndSaveData(
2672 1, GetNthClientInitiatedStreamId(0), true, true,
2673 priority, GetRequestHeaders("GET", "https", "/"), 0,
2674 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232675
2676 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522677 quic::QuicStreamOffset settings_offset = header_stream_offset;
2678 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432679 quic_data.AddWrite(SYNCHRONOUS,
2680 client_maker_.MakeInitialSettingsPacketAndSaveData(
2681 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232682 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522683 quic_data.AddWrite(
2684 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
2685 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232686 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:432687 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522688 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432689 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232690 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522691 quic_data.AddWrite(
2692 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
2693 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432694 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522695 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432696 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232697 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:522698 quic_data.AddWrite(
2699 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
2700 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432701 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522702 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432703 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232704 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522705 quic_data.AddWrite(
2706 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
2707 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432708 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522709 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432710 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232711 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522712 quic_data.AddWrite(
2713 SYNCHRONOUS, client_maker_.MakeDataPacket(11, quic::kHeadersStreamId,
2714 true, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432715 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522716 12, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432717 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232718 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432719 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522720 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432721 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232722
2723 quic_data.AddRead(ASYNC, OK);
2724 quic_data.AddSocketDataToFactory(&socket_factory_);
2725
2726 // In order for a new QUIC session to be established via alternate-protocol
2727 // without racing an HTTP connection, we need the host resolution to happen
2728 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2729 // connection to the the server, in this test we require confirmation
2730 // before encrypting so the HTTP job will still start.
2731 host_resolver_.set_synchronous_mode(true);
2732 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2733 "");
2734 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2735 AddressList address;
2736 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582737 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2738 CompletionOnceCallback(), &request,
2739 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412740 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232741
2742 CreateSession();
2743 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552744 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232745 QuicStreamFactoryPeer::SetAlarmFactory(
2746 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192747 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552748 &clock_));
rch9ecde09b2017-04-08 00:18:232749
Ryan Hamilton9835e662018-08-02 05:36:272750 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232751
2752 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2753 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412754 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2756
2757 // Pump the message loop to get the request started.
2758 base::RunLoop().RunUntilIdle();
2759 // Explicitly confirm the handshake.
2760 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522761 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232762
2763 // Run the QUIC session to completion.
2764 quic_task_runner_->RunUntilIdle();
2765
2766 ExpectQuicAlternateProtocolMapping();
2767 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2768 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2769}
2770
2771// Verify that if a QUIC connection RTOs, while there are no active streams
2772// QUIC will not be marked as broken.
2773TEST_P(QuicNetworkTransactionTest,
2774 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522775 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232776
2777 // The request will initially go out over QUIC.
2778 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522779 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132780 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232781 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2782
2783 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522784 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2785 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432786 quic_data.AddWrite(SYNCHRONOUS,
2787 client_maker_.MakeRequestHeadersPacketAndSaveData(
2788 1, GetNthClientInitiatedStreamId(0), true, true,
2789 priority, GetRequestHeaders("GET", "https", "/"), 0,
2790 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232791
2792 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522793 quic::QuicStreamOffset settings_offset = header_stream_offset;
2794 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432795 quic_data.AddWrite(SYNCHRONOUS,
2796 client_maker_.MakeInitialSettingsPacketAndSaveData(
2797 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232798
Zhongyi Shi32f2fd02018-04-16 18:23:432799 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
2800 3, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522801 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232802 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522803 quic_data.AddWrite(
2804 SYNCHRONOUS, client_maker_.MakeDataPacket(4, quic::kHeadersStreamId, true,
2805 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232806 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:432807 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522808 5, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432809 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232810 // RTO 1
Zhongyi Shi32f2fd02018-04-16 18:23:432811 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
2812 6, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522813 quic::QUIC_STREAM_CANCELLED));
2814 quic_data.AddWrite(
2815 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
2816 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232817 // RTO 2
Zhongyi Shi32f2fd02018-04-16 18:23:432818 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522819 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432820 settings_offset, settings_data));
2821 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
2822 9, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522823 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232824 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522825 quic_data.AddWrite(
2826 SYNCHRONOUS, client_maker_.MakeDataPacket(10, quic::kHeadersStreamId,
2827 true, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432828 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522829 11, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:432830 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232831 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432832 quic_data.AddWrite(
2833 SYNCHRONOUS,
2834 client_maker_.MakeRstPacket(12, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522835 quic::QUIC_STREAM_CANCELLED));
2836 quic_data.AddWrite(
2837 SYNCHRONOUS, client_maker_.MakeDataPacket(13, quic::kHeadersStreamId,
2838 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232839 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432840 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522841 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432842 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232843
2844 quic_data.AddRead(ASYNC, OK);
2845 quic_data.AddSocketDataToFactory(&socket_factory_);
2846
2847 // In order for a new QUIC session to be established via alternate-protocol
2848 // without racing an HTTP connection, we need the host resolution to happen
2849 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2850 // connection to the the server, in this test we require confirmation
2851 // before encrypting so the HTTP job will still start.
2852 host_resolver_.set_synchronous_mode(true);
2853 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2854 "");
2855 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2856 AddressList address;
2857 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582858 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2859 CompletionOnceCallback(), &request,
2860 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412861 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232862
2863 CreateSession();
2864 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552865 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232866 QuicStreamFactoryPeer::SetAlarmFactory(
2867 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192868 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552869 &clock_));
rch9ecde09b2017-04-08 00:18:232870
Ryan Hamilton9835e662018-08-02 05:36:272871 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232872
Jeremy Roman0579ed62017-08-29 15:56:192873 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232874 session_.get());
2875 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412876 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232877 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2878
2879 // Pump the message loop to get the request started.
2880 base::RunLoop().RunUntilIdle();
2881 // Explicitly confirm the handshake.
2882 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522883 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232884
2885 // Now cancel the request.
2886 trans.reset();
2887
2888 // Run the QUIC session to completion.
2889 quic_task_runner_->RunUntilIdle();
2890
2891 ExpectQuicAlternateProtocolMapping();
2892
2893 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2894}
2895
rch2f2991c2017-04-13 19:28:172896// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2897// the request fails with QUIC_PROTOCOL_ERROR.
2898TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482899 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172900 // The request will initially go out over QUIC.
2901 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522902 quic::QuicStreamOffset header_stream_offset = 0;
2903 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2904 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432905 quic_data.AddWrite(
2906 SYNCHRONOUS,
2907 ConstructClientRequestHeadersPacket(
2908 1, GetNthClientInitiatedStreamId(0), true, true,
2909 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522910 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432911 quic_data.AddWrite(SYNCHRONOUS,
2912 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:172913 // Peer sending data from an non-existing stream causes this end to raise
2914 // error and close connection.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522915 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
2916 1, false, 99, quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:172917 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:432918 quic_data.AddWrite(SYNCHRONOUS,
2919 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522920 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
2921 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:172922 quic_data.AddSocketDataToFactory(&socket_factory_);
2923
2924 // In order for a new QUIC session to be established via alternate-protocol
2925 // without racing an HTTP connection, we need the host resolution to happen
2926 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2927 // connection to the the server, in this test we require confirmation
2928 // before encrypting so the HTTP job will still start.
2929 host_resolver_.set_synchronous_mode(true);
2930 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2931 "");
2932 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2933 AddressList address;
2934 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582935 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2936 CompletionOnceCallback(), &request,
2937 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412938 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:172939
2940 CreateSession();
2941
Ryan Hamilton9835e662018-08-02 05:36:272942 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172943
2944 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2945 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412946 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:172947 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2948
2949 // Pump the message loop to get the request started.
2950 base::RunLoop().RunUntilIdle();
2951 // Explicitly confirm the handshake.
2952 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522953 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:172954
2955 ASSERT_FALSE(quic_data.AllReadDataConsumed());
2956
2957 // Run the QUIC session to completion.
2958 base::RunLoop().RunUntilIdle();
2959 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2960 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2961
2962 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2963 ExpectQuicAlternateProtocolMapping();
2964 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2965}
2966
rch9ecde09b2017-04-08 00:18:232967// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
2968// connection times out, then QUIC will be marked as broken and the request
2969// retried over TCP.
2970TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:412971 session_params_.mark_quic_broken_when_network_blackholes = true;
2972 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232973
2974 // The request will initially go out over QUIC.
2975 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522976 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132977 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232978 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2979
2980 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522981 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2982 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432983 quic_data.AddWrite(SYNCHRONOUS,
2984 client_maker_.MakeRequestHeadersPacketAndSaveData(
2985 1, GetNthClientInitiatedStreamId(0), true, true,
2986 priority, GetRequestHeaders("GET", "https", "/"), 0,
2987 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232988
2989 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522990 quic::QuicStreamOffset settings_offset = header_stream_offset;
2991 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432992 quic_data.AddWrite(SYNCHRONOUS,
2993 client_maker_.MakeInitialSettingsPacketAndSaveData(
2994 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232995 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522996 quic_data.AddWrite(
2997 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
2998 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232999 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:433000 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523001 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433002 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233003 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523004 quic_data.AddWrite(
3005 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
3006 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433007 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523008 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433009 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233010 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523011 quic_data.AddWrite(
3012 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
3013 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433014 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523015 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433016 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233017 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523018 quic_data.AddWrite(
3019 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
3020 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433021 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523022 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433023 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233024
Zhongyi Shi32f2fd02018-04-16 18:23:433025 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523026 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433027 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223028
rch9ecde09b2017-04-08 00:18:233029 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3030 quic_data.AddRead(ASYNC, OK);
3031 quic_data.AddSocketDataToFactory(&socket_factory_);
3032
3033 // After that fails, it will be resent via TCP.
3034 MockWrite http_writes[] = {
3035 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3036 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3037 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3038
3039 MockRead http_reads[] = {
3040 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3041 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3042 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013043 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233044 socket_factory_.AddSocketDataProvider(&http_data);
3045 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3046
3047 // In order for a new QUIC session to be established via alternate-protocol
3048 // without racing an HTTP connection, we need the host resolution to happen
3049 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3050 // connection to the the server, in this test we require confirmation
3051 // before encrypting so the HTTP job will still start.
3052 host_resolver_.set_synchronous_mode(true);
3053 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3054 "");
3055 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3056 AddressList address;
3057 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583058 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3059 CompletionOnceCallback(), &request,
3060 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413061 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233062
3063 CreateSession();
3064 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553065 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233066 QuicStreamFactoryPeer::SetAlarmFactory(
3067 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193068 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553069 &clock_));
rch9ecde09b2017-04-08 00:18:233070
Ryan Hamilton9835e662018-08-02 05:36:273071 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233072
3073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3074 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413075 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3077
3078 // Pump the message loop to get the request started.
3079 base::RunLoop().RunUntilIdle();
3080 // Explicitly confirm the handshake.
3081 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523082 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233083
3084 // Run the QUIC session to completion.
3085 quic_task_runner_->RunUntilIdle();
3086 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3087
3088 // Let the transaction proceed which will result in QUIC being marked
3089 // as broken and the request falling back to TCP.
3090 EXPECT_THAT(callback.WaitForResult(), IsOk());
3091
3092 ExpectBrokenAlternateProtocolMapping();
3093 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3094 ASSERT_FALSE(http_data.AllReadDataConsumed());
3095
3096 // Read the response body over TCP.
3097 CheckResponseData(&trans, "hello world");
3098 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3099 ASSERT_TRUE(http_data.AllReadDataConsumed());
3100}
3101
rch2f2991c2017-04-13 19:28:173102// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3103// connection times out, then QUIC will be marked as broken and the request
3104// retried over TCP.
3105TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413106 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173107
3108 // The request will initially go out over QUIC.
3109 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523110 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133111 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173112 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3113
3114 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523115 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3116 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433117 quic_data.AddWrite(SYNCHRONOUS,
3118 client_maker_.MakeRequestHeadersPacketAndSaveData(
3119 1, GetNthClientInitiatedStreamId(0), true, true,
3120 priority, GetRequestHeaders("GET", "https", "/"), 0,
3121 nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173122
3123 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523124 quic::QuicStreamOffset settings_offset = header_stream_offset;
3125 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433126 quic_data.AddWrite(SYNCHRONOUS,
3127 client_maker_.MakeInitialSettingsPacketAndSaveData(
3128 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173129 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523130 quic_data.AddWrite(
3131 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
3132 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173133 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:433134 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523135 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433136 settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173137 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523138 quic_data.AddWrite(
3139 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
3140 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433141 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523142 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433143 settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173144 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523145 quic_data.AddWrite(
3146 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
3147 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433148 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523149 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433150 settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173151 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523152 quic_data.AddWrite(
3153 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
3154 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433155 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523156 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433157 settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173158
Zhongyi Shi32f2fd02018-04-16 18:23:433159 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523160 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433161 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223162
rch2f2991c2017-04-13 19:28:173163 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3164 quic_data.AddRead(ASYNC, OK);
3165 quic_data.AddSocketDataToFactory(&socket_factory_);
3166
3167 // After that fails, it will be resent via TCP.
3168 MockWrite http_writes[] = {
3169 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3170 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3171 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3172
3173 MockRead http_reads[] = {
3174 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3175 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3176 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013177 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173178 socket_factory_.AddSocketDataProvider(&http_data);
3179 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3180
3181 // In order for a new QUIC session to be established via alternate-protocol
3182 // without racing an HTTP connection, we need the host resolution to happen
3183 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3184 // connection to the the server, in this test we require confirmation
3185 // before encrypting so the HTTP job will still start.
3186 host_resolver_.set_synchronous_mode(true);
3187 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3188 "");
3189 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3190 AddressList address;
3191 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583192 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3193 CompletionOnceCallback(), &request,
3194 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413195 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173196
3197 CreateSession();
3198 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553199 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173200 QuicStreamFactoryPeer::SetAlarmFactory(
3201 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193202 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553203 &clock_));
rch2f2991c2017-04-13 19:28:173204
Ryan Hamilton9835e662018-08-02 05:36:273205 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173206
3207 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3208 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413209 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173210 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3211
3212 // Pump the message loop to get the request started.
3213 base::RunLoop().RunUntilIdle();
3214 // Explicitly confirm the handshake.
3215 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523216 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173217
3218 // Run the QUIC session to completion.
3219 quic_task_runner_->RunUntilIdle();
3220 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3221
3222 ExpectQuicAlternateProtocolMapping();
3223
3224 // Let the transaction proceed which will result in QUIC being marked
3225 // as broken and the request falling back to TCP.
3226 EXPECT_THAT(callback.WaitForResult(), IsOk());
3227
3228 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3229 ASSERT_FALSE(http_data.AllReadDataConsumed());
3230
3231 // Read the response body over TCP.
3232 CheckResponseData(&trans, "hello world");
3233 ExpectBrokenAlternateProtocolMapping();
3234 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3235 ASSERT_TRUE(http_data.AllReadDataConsumed());
3236}
3237
rch9ecde09b2017-04-08 00:18:233238// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3239// connection times out, then QUIC will be marked as broken but the request
3240// will not be retried over TCP.
3241TEST_P(QuicNetworkTransactionTest,
3242 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413243 session_params_.mark_quic_broken_when_network_blackholes = true;
3244 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233245
3246 // The request will initially go out over QUIC.
3247 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523248 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133249 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233250 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3251
3252 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523253 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3254 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433255 quic_data.AddWrite(SYNCHRONOUS,
3256 client_maker_.MakeRequestHeadersPacketAndSaveData(
3257 1, GetNthClientInitiatedStreamId(0), true, true,
3258 priority, GetRequestHeaders("GET", "https", "/"), 0,
3259 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233260
3261 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523262 quic::QuicStreamOffset settings_offset = header_stream_offset;
3263 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433264 quic_data.AddWrite(SYNCHRONOUS,
3265 client_maker_.MakeInitialSettingsPacketAndSaveData(
3266 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233267
Zhongyi Shi32f2fd02018-04-16 18:23:433268 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
3269 1, GetNthClientInitiatedStreamId(0), false,
3270 false, GetResponseHeaders("200 OK")));
3271 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523272 quic_data.AddWrite(
3273 SYNCHRONOUS,
3274 ConstructClientAckPacket(3, 1, 1, 1,
3275 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233276
3277 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523278 quic_data.AddWrite(
3279 SYNCHRONOUS, client_maker_.MakeDataPacket(4, quic::kHeadersStreamId,
3280 false, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233281 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:433282 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523283 5, quic::kHeadersStreamId, false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433284 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233285 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523286 quic_data.AddWrite(
3287 SYNCHRONOUS, client_maker_.MakeDataPacket(6, quic::kHeadersStreamId,
3288 false, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433289 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523290 7, quic::kHeadersStreamId, false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433291 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233292 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523293 quic_data.AddWrite(
3294 SYNCHRONOUS, client_maker_.MakeDataPacket(8, quic::kHeadersStreamId,
3295 false, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433296 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523297 9, quic::kHeadersStreamId, false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433298 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233299 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523300 quic_data.AddWrite(
3301 SYNCHRONOUS, client_maker_.MakeDataPacket(10, quic::kHeadersStreamId,
3302 false, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433303 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523304 11, quic::kHeadersStreamId, false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433305 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233306
Zhongyi Shia15736c2018-09-25 00:31:183307 if (quic::GetQuicReloadableFlag(
3308 quic_fix_time_of_first_packet_sent_after_receiving)) {
3309 quic_data.AddWrite(
3310 SYNCHRONOUS,
3311 client_maker_.MakeAckAndConnectionClosePacket(
3312 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3313 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3314
3315 } else {
3316 quic_data.AddWrite(
3317 SYNCHRONOUS,
3318 client_maker_.MakeAckAndConnectionClosePacket(
3319 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3320 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3321 }
Fan Yang928f1632017-12-14 18:55:223322
rch9ecde09b2017-04-08 00:18:233323 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3324 quic_data.AddRead(ASYNC, OK);
3325 quic_data.AddSocketDataToFactory(&socket_factory_);
3326
3327 // In order for a new QUIC session to be established via alternate-protocol
3328 // without racing an HTTP connection, we need the host resolution to happen
3329 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3330 // connection to the the server, in this test we require confirmation
3331 // before encrypting so the HTTP job will still start.
3332 host_resolver_.set_synchronous_mode(true);
3333 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3334 "");
3335 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3336 AddressList address;
3337 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583338 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3339 CompletionOnceCallback(), &request,
3340 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413341 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233342
3343 CreateSession();
3344 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553345 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233346 QuicStreamFactoryPeer::SetAlarmFactory(
3347 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193348 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553349 &clock_));
rch9ecde09b2017-04-08 00:18:233350
Ryan Hamilton9835e662018-08-02 05:36:273351 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233352
3353 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3354 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413355 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233356 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3357
3358 // Pump the message loop to get the request started.
3359 base::RunLoop().RunUntilIdle();
3360 // Explicitly confirm the handshake.
3361 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523362 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233363
3364 // Pump the message loop to get the request started.
3365 base::RunLoop().RunUntilIdle();
3366
3367 // Run the QUIC session to completion.
3368 quic_task_runner_->RunUntilIdle();
3369 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3370
3371 // Let the transaction proceed which will result in QUIC being marked
3372 // as broken and the request falling back to TCP.
3373 EXPECT_THAT(callback.WaitForResult(), IsOk());
3374
3375 ExpectBrokenAlternateProtocolMapping();
3376 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3377
3378 std::string response_data;
3379 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3380 IsError(ERR_QUIC_PROTOCOL_ERROR));
3381}
3382
3383// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3384// connection RTOs, then QUIC will be marked as broken and the request retried
3385// over TCP.
3386TEST_P(QuicNetworkTransactionTest,
3387 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413388 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523389 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233390
3391 // The request will initially go out over QUIC.
3392 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523393 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133394 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233395 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3396
3397 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523398 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3399 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433400 quic_data.AddWrite(SYNCHRONOUS,
3401 client_maker_.MakeRequestHeadersPacketAndSaveData(
3402 1, GetNthClientInitiatedStreamId(0), true, true,
3403 priority, GetRequestHeaders("GET", "https", "/"), 0,
3404 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233405
3406 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523407 quic::QuicStreamOffset settings_offset = header_stream_offset;
3408 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433409 quic_data.AddWrite(SYNCHRONOUS,
3410 client_maker_.MakeInitialSettingsPacketAndSaveData(
3411 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233412 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523413 quic_data.AddWrite(
3414 SYNCHRONOUS, client_maker_.MakeDataPacket(3, quic::kHeadersStreamId, true,
3415 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233416 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:433417 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523418 4, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433419 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233420 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523421 quic_data.AddWrite(
3422 SYNCHRONOUS, client_maker_.MakeDataPacket(5, quic::kHeadersStreamId, true,
3423 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433424 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523425 6, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433426 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233427 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523428 quic_data.AddWrite(
3429 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
3430 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433431 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523432 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433433 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233434 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523435 quic_data.AddWrite(
3436 SYNCHRONOUS, client_maker_.MakeDataPacket(9, quic::kHeadersStreamId, true,
3437 false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433438 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523439 10, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433440 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233441 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523442 quic_data.AddWrite(
3443 SYNCHRONOUS, client_maker_.MakeDataPacket(11, quic::kHeadersStreamId,
3444 true, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433445 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523446 12, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433447 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233448
Zhongyi Shi32f2fd02018-04-16 18:23:433449 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523450 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433451 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233452
3453 quic_data.AddRead(ASYNC, OK);
3454 quic_data.AddSocketDataToFactory(&socket_factory_);
3455
3456 // After that fails, it will be resent via TCP.
3457 MockWrite http_writes[] = {
3458 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3459 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3460 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3461
3462 MockRead http_reads[] = {
3463 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3464 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3465 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013466 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233467 socket_factory_.AddSocketDataProvider(&http_data);
3468 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3469
3470 // In order for a new QUIC session to be established via alternate-protocol
3471 // without racing an HTTP connection, we need the host resolution to happen
3472 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3473 // connection to the the server, in this test we require confirmation
3474 // before encrypting so the HTTP job will still start.
3475 host_resolver_.set_synchronous_mode(true);
3476 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3477 "");
3478 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3479 AddressList address;
3480 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583481 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3482 CompletionOnceCallback(), &request,
3483 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413484 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233485
3486 CreateSession();
3487 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553488 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233489 QuicStreamFactoryPeer::SetAlarmFactory(
3490 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193491 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553492 &clock_));
rch9ecde09b2017-04-08 00:18:233493
Ryan Hamilton9835e662018-08-02 05:36:273494 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233495
3496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3497 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413498 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233499 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3500
3501 // Pump the message loop to get the request started.
3502 base::RunLoop().RunUntilIdle();
3503 // Explicitly confirm the handshake.
3504 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523505 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233506
3507 // Run the QUIC session to completion.
3508 quic_task_runner_->RunUntilIdle();
3509 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3510
3511 // Let the transaction proceed which will result in QUIC being marked
3512 // as broken and the request falling back to TCP.
3513 EXPECT_THAT(callback.WaitForResult(), IsOk());
3514
3515 ExpectBrokenAlternateProtocolMapping();
3516 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3517 ASSERT_FALSE(http_data.AllReadDataConsumed());
3518
3519 // Read the response body over TCP.
3520 CheckResponseData(&trans, "hello world");
3521 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3522 ASSERT_TRUE(http_data.AllReadDataConsumed());
3523}
3524
3525// Verify that if a QUIC connection RTOs, while there are no active streams
3526// QUIC will be marked as broken.
3527TEST_P(QuicNetworkTransactionTest,
3528 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413529 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523530 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233531
3532 // The request will initially go out over QUIC.
3533 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523534 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133535 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233536 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3537
3538 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523539 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3540 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433541 quic_data.AddWrite(SYNCHRONOUS,
3542 client_maker_.MakeRequestHeadersPacketAndSaveData(
3543 1, GetNthClientInitiatedStreamId(0), true, true,
3544 priority, GetRequestHeaders("GET", "https", "/"), 0,
3545 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233546
3547 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523548 quic::QuicStreamOffset settings_offset = header_stream_offset;
3549 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433550 quic_data.AddWrite(SYNCHRONOUS,
3551 client_maker_.MakeInitialSettingsPacketAndSaveData(
3552 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233553
Zhongyi Shi32f2fd02018-04-16 18:23:433554 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
3555 3, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523556 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233557 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523558 quic_data.AddWrite(
3559 SYNCHRONOUS, client_maker_.MakeDataPacket(4, quic::kHeadersStreamId, true,
3560 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233561 // TLP 2
Zhongyi Shi32f2fd02018-04-16 18:23:433562 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523563 5, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433564 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233565 // RTO 1
Zhongyi Shi32f2fd02018-04-16 18:23:433566 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
3567 6, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523568 quic::QUIC_STREAM_CANCELLED));
3569 quic_data.AddWrite(
3570 SYNCHRONOUS, client_maker_.MakeDataPacket(7, quic::kHeadersStreamId, true,
3571 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233572 // RTO 2
Zhongyi Shi32f2fd02018-04-16 18:23:433573 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523574 8, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433575 settings_offset, settings_data));
3576 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
3577 9, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523578 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233579 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523580 quic_data.AddWrite(
3581 SYNCHRONOUS, client_maker_.MakeDataPacket(10, quic::kHeadersStreamId,
3582 true, false, 0, request_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433583 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDataPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523584 11, quic::kHeadersStreamId, true, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433585 settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233586 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433587 quic_data.AddWrite(
3588 SYNCHRONOUS,
3589 client_maker_.MakeRstPacket(12, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523590 quic::QUIC_STREAM_CANCELLED));
3591 quic_data.AddWrite(
3592 SYNCHRONOUS, client_maker_.MakeDataPacket(13, quic::kHeadersStreamId,
3593 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233594 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433595 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523596 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433597 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233598
3599 quic_data.AddRead(ASYNC, OK);
3600 quic_data.AddSocketDataToFactory(&socket_factory_);
3601
3602 // In order for a new QUIC session to be established via alternate-protocol
3603 // without racing an HTTP connection, we need the host resolution to happen
3604 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3605 // connection to the the server, in this test we require confirmation
3606 // before encrypting so the HTTP job will still start.
3607 host_resolver_.set_synchronous_mode(true);
3608 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3609 "");
3610 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3611 AddressList address;
3612 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583613 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3614 CompletionOnceCallback(), &request,
3615 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413616 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233617
3618 CreateSession();
3619 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553620 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233621 QuicStreamFactoryPeer::SetAlarmFactory(
3622 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193623 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553624 &clock_));
rch9ecde09b2017-04-08 00:18:233625
Ryan Hamilton9835e662018-08-02 05:36:273626 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233627
Jeremy Roman0579ed62017-08-29 15:56:193628 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233629 session_.get());
3630 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413631 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233632 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3633
3634 // Pump the message loop to get the request started.
3635 base::RunLoop().RunUntilIdle();
3636 // Explicitly confirm the handshake.
3637 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523638 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233639
3640 // Now cancel the request.
3641 trans.reset();
3642
3643 // Run the QUIC session to completion.
3644 quic_task_runner_->RunUntilIdle();
3645
3646 ExpectBrokenAlternateProtocolMapping();
3647
3648 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3649}
3650
rch2f2991c2017-04-13 19:28:173651// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3652// protocol error occurs after the handshake is confirmed, the request
3653// retried over TCP and the QUIC will be marked as broken.
3654TEST_P(QuicNetworkTransactionTest,
3655 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413656 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173657
3658 // The request will initially go out over QUIC.
3659 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523660 quic::QuicStreamOffset header_stream_offset = 0;
3661 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3662 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433663 quic_data.AddWrite(
3664 SYNCHRONOUS,
3665 ConstructClientRequestHeadersPacket(
3666 1, GetNthClientInitiatedStreamId(0), true, true,
3667 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523668 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433669 quic_data.AddWrite(SYNCHRONOUS,
3670 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173671 // Peer sending data from an non-existing stream causes this end to raise
3672 // error and close connection.
Ryan Hamilton8d9ee76e2018-05-29 23:52:523673 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
3674 1, false, 99, quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173675 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433676 quic_data.AddWrite(SYNCHRONOUS,
3677 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523678 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3679 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173680 quic_data.AddSocketDataToFactory(&socket_factory_);
3681
3682 // After that fails, it will be resent via TCP.
3683 MockWrite http_writes[] = {
3684 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3685 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3686 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3687
3688 MockRead http_reads[] = {
3689 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3690 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3691 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013692 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173693 socket_factory_.AddSocketDataProvider(&http_data);
3694 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3695
3696 // In order for a new QUIC session to be established via alternate-protocol
3697 // without racing an HTTP connection, we need the host resolution to happen
3698 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3699 // connection to the the server, in this test we require confirmation
3700 // before encrypting so the HTTP job will still start.
3701 host_resolver_.set_synchronous_mode(true);
3702 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3703 "");
3704 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3705 AddressList address;
3706 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583707 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3708 CompletionOnceCallback(), &request,
3709 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413710 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173711
3712 CreateSession();
3713
Ryan Hamilton9835e662018-08-02 05:36:273714 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173715
3716 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3717 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413718 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3720
3721 // Pump the message loop to get the request started.
3722 base::RunLoop().RunUntilIdle();
3723 // Explicitly confirm the handshake.
3724 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523725 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173726
3727 // Run the QUIC session to completion.
3728 base::RunLoop().RunUntilIdle();
3729 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3730
3731 ExpectQuicAlternateProtocolMapping();
3732
3733 // Let the transaction proceed which will result in QUIC being marked
3734 // as broken and the request falling back to TCP.
3735 EXPECT_THAT(callback.WaitForResult(), IsOk());
3736
3737 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3738 ASSERT_FALSE(http_data.AllReadDataConsumed());
3739
3740 // Read the response body over TCP.
3741 CheckResponseData(&trans, "hello world");
3742 ExpectBrokenAlternateProtocolMapping();
3743 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3744 ASSERT_TRUE(http_data.AllReadDataConsumed());
3745}
3746
rch30943ee2017-06-12 21:28:443747// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3748// request is reset from, then QUIC will be marked as broken and the request
3749// retried over TCP.
3750TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443751 // The request will initially go out over QUIC.
3752 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523753 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133754 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443755 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3756
3757 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523758 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3759 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433760 quic_data.AddWrite(SYNCHRONOUS,
3761 client_maker_.MakeRequestHeadersPacketAndSaveData(
3762 1, GetNthClientInitiatedStreamId(0), true, true,
3763 priority, GetRequestHeaders("GET", "https", "/"), 0,
3764 nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443765
3766 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523767 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3768 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433769 quic_data.AddWrite(SYNCHRONOUS,
3770 client_maker_.MakeInitialSettingsPacketAndSaveData(
3771 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443772
Zhongyi Shi32f2fd02018-04-16 18:23:433773 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
3774 1, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523775 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443776
3777 quic_data.AddRead(ASYNC, OK);
3778 quic_data.AddSocketDataToFactory(&socket_factory_);
3779
3780 // After that fails, it will be resent via TCP.
3781 MockWrite http_writes[] = {
3782 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3783 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3784 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3785
3786 MockRead http_reads[] = {
3787 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3788 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3789 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013790 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443791 socket_factory_.AddSocketDataProvider(&http_data);
3792 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3793
3794 // In order for a new QUIC session to be established via alternate-protocol
3795 // without racing an HTTP connection, we need the host resolution to happen
3796 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3797 // connection to the the server, in this test we require confirmation
3798 // before encrypting so the HTTP job will still start.
3799 host_resolver_.set_synchronous_mode(true);
3800 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3801 "");
3802 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3803 AddressList address;
3804 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583805 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3806 CompletionOnceCallback(), &request,
3807 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413808 EXPECT_THAT(rv, IsOk());
rch30943ee2017-06-12 21:28:443809
3810 CreateSession();
3811
Ryan Hamilton9835e662018-08-02 05:36:273812 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443813
3814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3815 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413816 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3818
3819 // Pump the message loop to get the request started.
3820 base::RunLoop().RunUntilIdle();
3821 // Explicitly confirm the handshake.
3822 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523823 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443824
3825 // Run the QUIC session to completion.
3826 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3827
3828 ExpectQuicAlternateProtocolMapping();
3829
3830 // Let the transaction proceed which will result in QUIC being marked
3831 // as broken and the request falling back to TCP.
3832 EXPECT_THAT(callback.WaitForResult(), IsOk());
3833
3834 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3835 ASSERT_FALSE(http_data.AllReadDataConsumed());
3836
3837 // Read the response body over TCP.
3838 CheckResponseData(&trans, "hello world");
3839 ExpectBrokenAlternateProtocolMapping();
3840 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3841 ASSERT_TRUE(http_data.AllReadDataConsumed());
3842}
3843
Ryan Hamilton6c2a2a82017-12-15 02:06:283844// Verify that when an origin has two alt-svc advertisements, one local and one
3845// remote, that when the local is broken the request will go over QUIC via
3846// the remote Alt-Svc.
3847// This is a regression test for crbug/825646.
3848TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3849 session_params_.quic_allow_remote_alt_svc = true;
3850
3851 GURL origin1 = request_.url; // mail.example.org
3852 GURL origin2("https://www.example.org/");
3853 ASSERT_NE(origin1.host(), origin2.host());
3854
3855 scoped_refptr<X509Certificate> cert(
3856 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243857 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3858 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283859
3860 ProofVerifyDetailsChromium verify_details;
3861 verify_details.cert_verify_result.verified_cert = cert;
3862 verify_details.cert_verify_result.is_issued_by_known_root = true;
3863 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3864
3865 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523866 quic::QuicStreamOffset request_header_offset(0);
3867 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283868 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433869 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3870 mock_quic_data.AddWrite(
3871 SYNCHRONOUS,
3872 ConstructClientRequestHeadersPacket(
3873 2, GetNthClientInitiatedStreamId(0), true, true,
3874 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3875 mock_quic_data.AddRead(
3876 ASYNC, ConstructServerResponseHeadersPacket(
3877 1, GetNthClientInitiatedStreamId(0), false, false,
3878 GetResponseHeaders("200 OK"), &response_header_offset));
3879 mock_quic_data.AddRead(
3880 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
3881 false, true, 0, "hello!"));
3882 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283883 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3884 mock_quic_data.AddRead(ASYNC, 0); // EOF
3885
3886 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3887 MockQuicData mock_quic_data2;
3888 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3889 AddHangingNonAlternateProtocolSocketData();
3890
3891 CreateSession();
3892
3893 // Set up alternative service for |origin1|.
3894 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3895 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3896 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3897 AlternativeServiceInfoVector alternative_services;
3898 alternative_services.push_back(
3899 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3900 local_alternative, expiration,
3901 session_->params().quic_supported_versions));
3902 alternative_services.push_back(
3903 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3904 remote_alternative, expiration,
3905 session_->params().quic_supported_versions));
3906 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
3907 alternative_services);
3908
3909 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
3910
3911 SendRequestAndExpectQuicResponse("hello!");
3912}
3913
rch30943ee2017-06-12 21:28:443914// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3915// request is reset from, then QUIC will be marked as broken and the request
3916// retried over TCP. Then, subsequent requests will go over a new QUIC
3917// connection instead of going back to the broken QUIC connection.
3918// This is a regression tests for crbug/731303.
3919TEST_P(QuicNetworkTransactionTest,
3920 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:343921 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443922
3923 GURL origin1 = request_.url;
3924 GURL origin2("https://www.example.org/");
3925 ASSERT_NE(origin1.host(), origin2.host());
3926
3927 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523928 quic::QuicStreamOffset request_header_offset(0);
3929 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:443930
3931 scoped_refptr<X509Certificate> cert(
3932 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243933 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3934 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:443935
3936 ProofVerifyDetailsChromium verify_details;
3937 verify_details.cert_verify_result.verified_cert = cert;
3938 verify_details.cert_verify_result.is_issued_by_known_root = true;
3939 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3940
3941 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433942 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:443943 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433944 mock_quic_data.AddWrite(
3945 SYNCHRONOUS,
3946 ConstructClientRequestHeadersPacket(
3947 2, GetNthClientInitiatedStreamId(0), true, true,
3948 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3949 mock_quic_data.AddRead(
3950 ASYNC, ConstructServerResponseHeadersPacket(
3951 1, GetNthClientInitiatedStreamId(0), false, false,
3952 GetResponseHeaders("200 OK"), &response_header_offset));
3953 mock_quic_data.AddRead(
3954 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
3955 false, true, 0, "hello!"));
3956 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:443957
3958 // Second request will go over the pooled QUIC connection, but will be
3959 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:053960 QuicTestPacketMaker client_maker2(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523961 version_, 0, &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:053962 client_headers_include_h2_stream_dependency_);
rch30943ee2017-06-12 21:28:443963 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523964 quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:433965 mock_quic_data.AddWrite(
3966 SYNCHRONOUS,
3967 ConstructClientRequestHeadersPacket(
3968 4, GetNthClientInitiatedStreamId(1), false, true,
3969 GetRequestHeaders("GET", "https", "/", &client_maker2),
3970 GetNthClientInitiatedStreamId(0), &request_header_offset));
3971 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
3972 3, false, GetNthClientInitiatedStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523973 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443974 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3975 mock_quic_data.AddRead(ASYNC, 0); // EOF
3976
3977 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3978
3979 // After that fails, it will be resent via TCP.
3980 MockWrite http_writes[] = {
3981 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3982 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
3983 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3984
3985 MockRead http_reads[] = {
3986 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3987 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3988 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013989 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443990 socket_factory_.AddSocketDataProvider(&http_data);
3991 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3992
Ryan Hamilton6c2a2a82017-12-15 02:06:283993 // Then the next request to the second origin will be sent over TCP.
3994 socket_factory_.AddSocketDataProvider(&http_data);
3995 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:443996
3997 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563998 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
3999 QuicStreamFactoryPeer::SetAlarmFactory(
4000 session_->quic_stream_factory(),
4001 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4002 &clock_));
rch30943ee2017-06-12 21:28:444003
4004 // Set up alternative service for |origin1|.
4005 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244006 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214007 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244008 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444009 supported_versions_);
rch30943ee2017-06-12 21:28:444010
4011 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244012 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214013 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244014 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444015 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344016
rch30943ee2017-06-12 21:28:444017 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524018 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444019 SendRequestAndExpectQuicResponse("hello!");
4020
4021 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524022 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444023 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4024 request_.url = origin2;
4025 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284026 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244027 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284028 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244029 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444030
4031 // The third request should use a new QUIC connection, not the broken
4032 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284033 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444034}
4035
bnc8be55ebb2015-10-30 14:12:074036TEST_P(QuicNetworkTransactionTest,
4037 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4038 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444039 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074040 MockRead http_reads[] = {
4041 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4042 MockRead("hello world"),
4043 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4044 MockRead(ASYNC, OK)};
4045
Ryan Sleevib8d7ea02018-05-07 20:01:014046 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074047 socket_factory_.AddSocketDataProvider(&http_data);
4048 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4049 socket_factory_.AddSocketDataProvider(&http_data);
4050 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4051
rch3f4b8452016-02-23 16:59:324052 CreateSession();
bnc8be55ebb2015-10-30 14:12:074053
4054 SendRequestAndExpectHttpResponse("hello world");
4055 SendRequestAndExpectHttpResponse("hello world");
4056}
4057
Xida Chen9bfe0b62018-04-24 19:52:214058// When multiple alternative services are advertised, HttpStreamFactory should
4059// select the alternative service which uses existing QUIC session if available.
4060// If no existing QUIC session can be used, use the first alternative service
4061// from the list.
zhongyi32569c62016-01-08 02:54:304062TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344063 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524064 MockRead http_reads[] = {
4065 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294066 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524067 MockRead("hello world"),
4068 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4069 MockRead(ASYNC, OK)};
4070
Ryan Sleevib8d7ea02018-05-07 20:01:014071 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524072 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084073 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564074 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524075
Ryan Hamilton8d9ee76e2018-05-29 23:52:524076 quic::QuicStreamOffset request_header_offset = 0;
4077 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304078 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294079 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304080 // alternative service list.
bncc958faa2015-07-31 18:14:524081 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364082 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434083 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4084 mock_quic_data.AddWrite(
4085 SYNCHRONOUS,
4086 ConstructClientRequestHeadersPacket(
4087 2, GetNthClientInitiatedStreamId(0), true, true,
4088 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304089
4090 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294091 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4092 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434093 mock_quic_data.AddRead(
4094 ASYNC,
4095 ConstructServerResponseHeadersPacket(
4096 1, GetNthClientInitiatedStreamId(0), false, false,
4097 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
4098 mock_quic_data.AddRead(
4099 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4100 false, true, 0, "hello!"));
4101 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304102
4103 // Second QUIC request data.
4104 // Connection pooling, using existing session, no need to include version
4105 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584106 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434107 SYNCHRONOUS,
4108 ConstructClientRequestHeadersPacket(
4109 4, GetNthClientInitiatedStreamId(1), false, true,
4110 GetRequestHeaders("GET", "https", "/"),
4111 GetNthClientInitiatedStreamId(0), &request_header_offset));
4112 mock_quic_data.AddRead(
4113 ASYNC, ConstructServerResponseHeadersPacket(
4114 3, GetNthClientInitiatedStreamId(1), false, false,
4115 GetResponseHeaders("200 OK"), &response_header_offset));
4116 mock_quic_data.AddRead(
4117 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
4118 false, true, 0, "hello!"));
4119 mock_quic_data.AddWrite(
4120 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524121 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594122 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524123
4124 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4125
rtennetib8e80fb2016-05-16 00:12:094126 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324127 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564128 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4129 QuicStreamFactoryPeer::SetAlarmFactory(
4130 session_->quic_stream_factory(),
4131 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4132 &clock_));
bncc958faa2015-07-31 18:14:524133
4134 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304135
bnc359ed2a2016-04-29 20:43:454136 SendRequestAndExpectQuicResponse("hello!");
4137 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304138}
4139
tbansal6490783c2016-09-20 17:55:274140// Check that an existing QUIC connection to an alternative proxy server is
4141// used.
4142TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4143 base::HistogramTester histogram_tester;
4144
Ryan Hamilton8d9ee76e2018-05-29 23:52:524145 quic::QuicStreamOffset request_header_offset = 0;
4146 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274147 // First QUIC request data.
4148 // Open a session to foo.example.org:443 using the first entry of the
4149 // alternative service list.
4150 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364151 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434152 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4153 mock_quic_data.AddWrite(
4154 SYNCHRONOUS,
4155 ConstructClientRequestHeadersPacket(
4156 2, GetNthClientInitiatedStreamId(0), true, true,
4157 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274158
4159 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434160 mock_quic_data.AddRead(
4161 ASYNC,
4162 ConstructServerResponseHeadersPacket(
4163 1, GetNthClientInitiatedStreamId(0), false, false,
4164 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
4165 mock_quic_data.AddRead(
4166 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4167 false, true, 0, "hello!"));
4168 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274169
4170 // Second QUIC request data.
4171 // Connection pooling, using existing session, no need to include version
4172 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274173 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434174 SYNCHRONOUS,
4175 ConstructClientRequestHeadersPacket(
4176 4, GetNthClientInitiatedStreamId(1), false, true,
4177 GetRequestHeaders("GET", "http", "/"),
4178 GetNthClientInitiatedStreamId(0), &request_header_offset));
4179 mock_quic_data.AddRead(
4180 ASYNC, ConstructServerResponseHeadersPacket(
4181 3, GetNthClientInitiatedStreamId(1), false, false,
4182 GetResponseHeaders("200 OK"), &response_header_offset));
4183 mock_quic_data.AddRead(
4184 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
4185 false, true, 0, "hello!"));
4186 mock_quic_data.AddWrite(
4187 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274188 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4189 mock_quic_data.AddRead(ASYNC, 0); // EOF
4190
4191 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4192
4193 AddHangingNonAlternateProtocolSocketData();
4194
4195 TestProxyDelegate test_proxy_delegate;
4196
Lily Houghton8c2f97d2018-01-22 05:06:594197 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494198 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274199
4200 test_proxy_delegate.set_alternative_proxy_server(
4201 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524202 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274203
4204 request_.url = GURL("http://mail.example.org/");
4205
4206 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564207 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4208 QuicStreamFactoryPeer::SetAlarmFactory(
4209 session_->quic_stream_factory(),
4210 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4211 &clock_));
tbansal6490783c2016-09-20 17:55:274212
4213 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4214 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4215 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4216 1);
4217
4218 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4219 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4220 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4221 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4222 1);
4223}
4224
Ryan Hamilton8d9ee76e2018-05-29 23:52:524225// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454226// even if alternative service destination is different.
4227TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344228 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304229 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524230 quic::QuicStreamOffset request_header_offset(0);
4231 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454232
rch5cb522462017-04-25 20:18:364233 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434234 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454235 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434236 mock_quic_data.AddWrite(
4237 SYNCHRONOUS,
4238 ConstructClientRequestHeadersPacket(
4239 2, GetNthClientInitiatedStreamId(0), true, true,
4240 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4241 mock_quic_data.AddRead(
4242 ASYNC, ConstructServerResponseHeadersPacket(
4243 1, GetNthClientInitiatedStreamId(0), false, false,
4244 GetResponseHeaders("200 OK"), &response_header_offset));
4245 mock_quic_data.AddRead(
4246 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4247 false, true, 0, "hello!"));
4248 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304249
bnc359ed2a2016-04-29 20:43:454250 // Second request.
alyssar2adf3ac2016-05-03 17:12:584251 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434252 SYNCHRONOUS,
4253 ConstructClientRequestHeadersPacket(
4254 4, GetNthClientInitiatedStreamId(1), false, true,
4255 GetRequestHeaders("GET", "https", "/"),
4256 GetNthClientInitiatedStreamId(0), &request_header_offset));
4257 mock_quic_data.AddRead(
4258 ASYNC, ConstructServerResponseHeadersPacket(
4259 3, GetNthClientInitiatedStreamId(1), false, false,
4260 GetResponseHeaders("200 OK"), &response_header_offset));
4261 mock_quic_data.AddRead(
4262 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
4263 false, true, 0, "hello!"));
4264 mock_quic_data.AddWrite(
4265 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304266 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4267 mock_quic_data.AddRead(ASYNC, 0); // EOF
4268
4269 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454270
4271 AddHangingNonAlternateProtocolSocketData();
4272 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304273
rch3f4b8452016-02-23 16:59:324274 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564275 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4276 QuicStreamFactoryPeer::SetAlarmFactory(
4277 session_->quic_stream_factory(),
4278 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4279 &clock_));
zhongyi32569c62016-01-08 02:54:304280
bnc359ed2a2016-04-29 20:43:454281 const char destination1[] = "first.example.com";
4282 const char destination2[] = "second.example.com";
4283
4284 // Set up alternative service entry to destination1.
4285 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214286 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454287 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214288 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444289 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454290 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524291 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454292 SendRequestAndExpectQuicResponse("hello!");
4293
4294 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214295 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214296 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444297 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524298 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454299 // even though alternative service destination is different.
4300 SendRequestAndExpectQuicResponse("hello!");
4301}
4302
4303// Pool to existing session with matching destination and matching certificate
4304// even if origin is different, and even if the alternative service with
4305// matching destination is not the first one on the list.
4306TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344307 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454308 GURL origin1 = request_.url;
4309 GURL origin2("https://www.example.org/");
4310 ASSERT_NE(origin1.host(), origin2.host());
4311
4312 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524313 quic::QuicStreamOffset request_header_offset(0);
4314 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454315
rch5cb522462017-04-25 20:18:364316 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434317 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454318 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434319 mock_quic_data.AddWrite(
4320 SYNCHRONOUS,
4321 ConstructClientRequestHeadersPacket(
4322 2, GetNthClientInitiatedStreamId(0), true, true,
4323 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4324 mock_quic_data.AddRead(
4325 ASYNC, ConstructServerResponseHeadersPacket(
4326 1, GetNthClientInitiatedStreamId(0), false, false,
4327 GetResponseHeaders("200 OK"), &response_header_offset));
4328 mock_quic_data.AddRead(
4329 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4330 false, true, 0, "hello!"));
4331 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454332
4333 // Second request.
Yixin Wang079ad542018-01-11 04:06:054334 QuicTestPacketMaker client_maker2(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524335 version_, 0, &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054336 client_headers_include_h2_stream_dependency_);
rchbf4c26d2017-04-16 23:17:554337 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524338 quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584339 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434340 SYNCHRONOUS,
4341 ConstructClientRequestHeadersPacket(
4342 4, GetNthClientInitiatedStreamId(1), false, true,
4343 GetRequestHeaders("GET", "https", "/", &client_maker2),
4344 GetNthClientInitiatedStreamId(0), &request_header_offset));
4345 mock_quic_data.AddRead(
4346 ASYNC, ConstructServerResponseHeadersPacket(
4347 3, GetNthClientInitiatedStreamId(1), false, false,
4348 GetResponseHeaders("200 OK"), &response_header_offset));
4349 mock_quic_data.AddRead(
4350 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
4351 false, true, 0, "hello!"));
4352 mock_quic_data.AddWrite(
4353 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454354 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4355 mock_quic_data.AddRead(ASYNC, 0); // EOF
4356
4357 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4358
4359 AddHangingNonAlternateProtocolSocketData();
4360 AddHangingNonAlternateProtocolSocketData();
4361
4362 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564363 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4364 QuicStreamFactoryPeer::SetAlarmFactory(
4365 session_->quic_stream_factory(),
4366 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4367 &clock_));
bnc359ed2a2016-04-29 20:43:454368
4369 const char destination1[] = "first.example.com";
4370 const char destination2[] = "second.example.com";
4371
4372 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214373 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454374 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214375 http_server_properties_.SetQuicAlternativeService(
4376 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444377 supported_versions_);
bnc359ed2a2016-04-29 20:43:454378
4379 // Set up multiple alternative service entries for |origin2|,
4380 // the first one with a different destination as for |origin1|,
4381 // the second one with the same. The second one should be used,
4382 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214383 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454384 AlternativeServiceInfoVector alternative_services;
4385 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214386 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4387 alternative_service2, expiration,
4388 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454389 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214390 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4391 alternative_service1, expiration,
4392 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454393 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4394 alternative_services);
bnc359ed2a2016-04-29 20:43:454395 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524396 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454397 SendRequestAndExpectQuicResponse("hello!");
4398
4399 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524400 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454401 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584402
bnc359ed2a2016-04-29 20:43:454403 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304404}
4405
4406// Multiple origins have listed the same alternative services. When there's a
4407// existing QUIC session opened by a request to other origin,
4408// if the cert is valid, should select this QUIC session to make the request
4409// if this is also the first existing QUIC session.
4410TEST_P(QuicNetworkTransactionTest,
4411 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344412 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294413 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304414
rch9ae5b3b2016-02-11 00:36:294415 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304416 MockRead http_reads[] = {
4417 MockRead("HTTP/1.1 200 OK\r\n"),
4418 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294419 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304420 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4421 MockRead(ASYNC, OK)};
4422
Ryan Sleevib8d7ea02018-05-07 20:01:014423 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304424 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084425 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304426 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4427
4428 // HTTP data for request to mail.example.org.
4429 MockRead http_reads2[] = {
4430 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294431 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304432 MockRead("hello world from mail.example.org"),
4433 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4434 MockRead(ASYNC, OK)};
4435
Ryan Sleevib8d7ea02018-05-07 20:01:014436 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304437 socket_factory_.AddSocketDataProvider(&http_data2);
4438 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4439
Ryan Hamilton8d9ee76e2018-05-29 23:52:524440 quic::QuicStreamOffset request_header_offset = 0;
4441 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304442
Yixin Wang079ad542018-01-11 04:06:054443 QuicTestPacketMaker client_maker(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524444 version_, 0, &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054445 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584446 server_maker_.set_hostname("www.example.org");
4447 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304448 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364449 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434450 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304451 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584452 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434453 SYNCHRONOUS,
4454 ConstructClientRequestHeadersPacket(
4455 2, GetNthClientInitiatedStreamId(0), true, true,
4456 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4457
4458 mock_quic_data.AddRead(
4459 ASYNC, ConstructServerResponseHeadersPacket(
4460 1, GetNthClientInitiatedStreamId(0), false, false,
4461 GetResponseHeaders("200 OK"), &response_header_offset));
4462 mock_quic_data.AddRead(ASYNC, ConstructServerDataPacket(
4463 2, GetNthClientInitiatedStreamId(0), false,
4464 true, 0, "hello from mail QUIC!"));
4465 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4466 // Second QUIC request data.
4467 mock_quic_data.AddWrite(
4468 SYNCHRONOUS,
4469 ConstructClientRequestHeadersPacket(
4470 4, GetNthClientInitiatedStreamId(1), false, true,
4471 GetRequestHeaders("GET", "https", "/", &client_maker),
4472 GetNthClientInitiatedStreamId(0), &request_header_offset));
4473 mock_quic_data.AddRead(
4474 ASYNC, ConstructServerResponseHeadersPacket(
4475 3, GetNthClientInitiatedStreamId(1), false, false,
4476 GetResponseHeaders("200 OK"), &response_header_offset));
4477 mock_quic_data.AddRead(ASYNC, ConstructServerDataPacket(
4478 4, GetNthClientInitiatedStreamId(1), false,
4479 true, 0, "hello from mail QUIC!"));
4480 mock_quic_data.AddWrite(
4481 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304482 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4483 mock_quic_data.AddRead(ASYNC, 0); // EOF
4484
4485 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304486
rtennetib8e80fb2016-05-16 00:12:094487 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324488 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564489 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4490 QuicStreamFactoryPeer::SetAlarmFactory(
4491 session_->quic_stream_factory(),
4492 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4493 &clock_));
zhongyi32569c62016-01-08 02:54:304494
4495 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294496 request_.url = GURL("https://www.example.org/");
4497 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304498 request_.url = GURL("https://mail.example.org/");
4499 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4500
rch9ae5b3b2016-02-11 00:36:294501 // Open a QUIC session to mail.example.org:443 when making request
4502 // to mail.example.org.
4503 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454504 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304505
rch9ae5b3b2016-02-11 00:36:294506 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304507 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454508 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524509}
4510
4511TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524512 MockRead http_reads[] = {
4513 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564514 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524515 MockRead("hello world"),
4516 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4517 MockRead(ASYNC, OK)};
4518
Ryan Sleevib8d7ea02018-05-07 20:01:014519 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524520 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084521 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564522 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524523
rtennetib8e80fb2016-05-16 00:12:094524 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324525 CreateSession();
bncc958faa2015-07-31 18:14:524526
4527 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454528
4529 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344530 AlternativeServiceInfoVector alternative_service_info_vector =
4531 http_server_properties_.GetAlternativeServiceInfos(http_server);
4532 ASSERT_EQ(1u, alternative_service_info_vector.size());
4533 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544534 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344535 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4536 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4537 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524538}
4539
4540TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524541 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564542 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4543 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524544 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4545 MockRead(ASYNC, OK)};
4546
Ryan Sleevib8d7ea02018-05-07 20:01:014547 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524548 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084549 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564550 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524551
4552 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524553 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364554 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434555 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4556 mock_quic_data.AddWrite(
4557 SYNCHRONOUS,
4558 ConstructClientRequestHeadersPacket(
4559 2, GetNthClientInitiatedStreamId(0), true, true,
4560 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4561 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4562 1, GetNthClientInitiatedStreamId(0), false,
4563 false, GetResponseHeaders("200 OK")));
4564 mock_quic_data.AddRead(
4565 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4566 false, true, 0, "hello!"));
4567 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524568 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4569 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524570
4571 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4572
rtennetib8e80fb2016-05-16 00:12:094573 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324574 CreateSession();
bncc958faa2015-07-31 18:14:524575
bnc3472afd2016-11-17 15:27:214576 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524577 HostPortPair::FromURL(request_.url));
4578 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4579 alternative_service);
4580 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4581 alternative_service));
4582
4583 SendRequestAndExpectHttpResponse("hello world");
4584 SendRequestAndExpectQuicResponse("hello!");
4585
mmenkee24011922015-12-17 22:12:594586 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524587
4588 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4589 alternative_service));
rchac7f35e2017-03-15 20:42:304590 EXPECT_NE(nullptr,
4591 http_server_properties_.GetServerNetworkStats(
4592 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524593}
4594
bncc958faa2015-07-31 18:14:524595TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524596 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564597 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4598 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524599 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4600 MockRead(ASYNC, OK)};
4601
Ryan Sleevib8d7ea02018-05-07 20:01:014602 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524603 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564604 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524605
4606 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524607 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364608 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434609 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4610 mock_quic_data.AddWrite(
4611 SYNCHRONOUS,
4612 ConstructClientRequestHeadersPacket(
4613 2, GetNthClientInitiatedStreamId(0), true, true,
4614 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4615 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4616 1, GetNthClientInitiatedStreamId(0), false,
4617 false, GetResponseHeaders("200 OK")));
4618 mock_quic_data.AddRead(
4619 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4620 false, true, 0, "hello!"));
4621 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524622 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4623
4624 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4625
4626 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324627 CreateSession();
bncc958faa2015-07-31 18:14:524628
4629 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4630 SendRequestAndExpectHttpResponse("hello world");
4631}
4632
tbansalc3308d72016-08-27 10:25:044633// Tests that the connection to an HTTPS proxy is raced with an available
4634// alternative proxy server.
4635TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274636 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594637 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494638 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044639
4640 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524641 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364642 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434643 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4644 mock_quic_data.AddWrite(
4645 SYNCHRONOUS,
4646 ConstructClientRequestHeadersPacket(
4647 2, GetNthClientInitiatedStreamId(0), true, true,
4648 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
4649 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4650 1, GetNthClientInitiatedStreamId(0), false,
4651 false, GetResponseHeaders("200 OK")));
4652 mock_quic_data.AddRead(
4653 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4654 false, true, 0, "hello!"));
4655 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044656 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4657 mock_quic_data.AddRead(ASYNC, 0); // EOF
4658
4659 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4660
4661 // There is no need to set up main job, because no attempt will be made to
4662 // speak to the proxy over TCP.
4663 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044664 TestProxyDelegate test_proxy_delegate;
4665 const HostPortPair host_port_pair("mail.example.org", 443);
4666
4667 test_proxy_delegate.set_alternative_proxy_server(
4668 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524669 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044670 CreateSession();
4671 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4672
4673 // The main job needs to hang in order to guarantee that the alternative
4674 // proxy server job will "win".
4675 AddHangingNonAlternateProtocolSocketData();
4676
4677 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4678
4679 // Verify that the alternative proxy server is not marked as broken.
4680 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4681
4682 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594683 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274684
4685 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4686 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4687 1);
tbansalc3308d72016-08-27 10:25:044688}
4689
bnc1c196c6e2016-05-28 13:51:484690TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304691 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274692 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304693
4694 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564695 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294696 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564697 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304698
4699 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564700 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484701 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564702 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304703
Ryan Sleevib8d7ea02018-05-07 20:01:014704 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504705 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084706 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504707 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304708
4709 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454710 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304711 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454712 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304713 };
Ryan Sleevib8d7ea02018-05-07 20:01:014714 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504715 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304716
4717 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014718 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504719 socket_factory_.AddSocketDataProvider(&http_data2);
4720 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304721
bnc912a04b2016-04-20 14:19:504722 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304723
4724 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304725 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174726 ASSERT_TRUE(http_data.AllReadDataConsumed());
4727 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304728
4729 // Now run the second request in which the QUIC socket hangs,
4730 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304731 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454732 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304733
rch37de576c2015-05-17 20:28:174734 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4735 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454736 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304737}
4738
[email protected]1e960032013-12-20 19:00:204739TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204740 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524741 quic::QuicStreamOffset header_stream_offset = 0;
4742 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4743 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434744 mock_quic_data.AddWrite(
4745 SYNCHRONOUS,
4746 ConstructClientRequestHeadersPacket(
4747 1, GetNthClientInitiatedStreamId(0), true, true,
4748 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4749 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4750 1, GetNthClientInitiatedStreamId(0), false,
4751 false, GetResponseHeaders("200 OK")));
4752 mock_quic_data.AddRead(
4753 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4754 false, true, 0, "hello!"));
4755 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504756 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594757 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484758
rcha5399e02015-04-21 19:32:044759 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484760
rtennetib8e80fb2016-05-16 00:12:094761 // The non-alternate protocol job needs to hang in order to guarantee that
4762 // the alternate-protocol job will "win".
4763 AddHangingNonAlternateProtocolSocketData();
4764
rch3f4b8452016-02-23 16:59:324765 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274766 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194767 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304768
4769 EXPECT_EQ(nullptr,
4770 http_server_properties_.GetServerNetworkStats(
4771 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484772}
4773
[email protected]1e960032013-12-20 19:00:204774TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204775 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524776 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4777 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434778 mock_quic_data.AddWrite(SYNCHRONOUS,
4779 ConstructClientRequestHeadersPacket(
4780 1, GetNthClientInitiatedStreamId(0), true, true,
4781 GetRequestHeaders("GET", "https", "/")));
4782 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4783 1, GetNthClientInitiatedStreamId(0), false,
4784 false, GetResponseHeaders("200 OK")));
4785 mock_quic_data.AddRead(
4786 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4787 false, true, 0, "hello!"));
4788 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504789 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594790 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044791 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274792
4793 // In order for a new QUIC session to be established via alternate-protocol
4794 // without racing an HTTP connection, we need the host resolution to happen
4795 // synchronously.
4796 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294797 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564798 "");
rch9ae5b3b2016-02-11 00:36:294799 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]3a120a6b2013-06-25 01:08:274800 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104801 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584802 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4803 CompletionOnceCallback(), &request,
4804 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414805 EXPECT_THAT(rv, IsOk());
[email protected]3a120a6b2013-06-25 01:08:274806
rtennetib8e80fb2016-05-16 00:12:094807 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324808 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274809 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274810 SendRequestAndExpectQuicResponse("hello!");
4811}
4812
[email protected]0fc924b2014-03-31 04:34:154813TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494814 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4815 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154816
4817 // Since we are using a proxy, the QUIC job will not succeed.
4818 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294819 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4820 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564821 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154822
4823 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564824 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484825 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564826 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154827
Ryan Sleevib8d7ea02018-05-07 20:01:014828 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154829 socket_factory_.AddSocketDataProvider(&http_data);
4830
4831 // In order for a new QUIC session to be established via alternate-protocol
4832 // without racing an HTTP connection, we need the host resolution to happen
4833 // synchronously.
4834 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294835 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564836 "");
rch9ae5b3b2016-02-11 00:36:294837 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]0fc924b2014-03-31 04:34:154838 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104839 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584840 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4841 CompletionOnceCallback(), &request,
4842 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414843 EXPECT_THAT(rv, IsOk());
[email protected]0fc924b2014-03-31 04:34:154844
rch9ae5b3b2016-02-11 00:36:294845 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324846 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274847 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154848 SendRequestAndExpectHttpResponse("hello world");
4849}
4850
[email protected]1e960032013-12-20 19:00:204851TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:204852 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524853 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364854 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434855 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4856 mock_quic_data.AddWrite(
4857 SYNCHRONOUS,
4858 ConstructClientRequestHeadersPacket(
4859 2, GetNthClientInitiatedStreamId(0), true, true,
4860 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4861 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4862 1, GetNthClientInitiatedStreamId(0), false,
4863 false, GetResponseHeaders("200 OK")));
4864 mock_quic_data.AddRead(
4865 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4866 false, true, 0, "hello!"));
4867 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594868 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044869 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124870
rtennetib8e80fb2016-05-16 00:12:094871 // The non-alternate protocol job needs to hang in order to guarantee that
4872 // the alternate-protocol job will "win".
4873 AddHangingNonAlternateProtocolSocketData();
4874
[email protected]11c05872013-08-20 02:04:124875 // In order for a new QUIC session to be established via alternate-protocol
4876 // without racing an HTTP connection, we need the host resolution to happen
4877 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4878 // connection to the the server, in this test we require confirmation
4879 // before encrypting so the HTTP job will still start.
4880 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294881 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564882 "");
rch9ae5b3b2016-02-11 00:36:294883 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]11c05872013-08-20 02:04:124884 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104885 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584886 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4887 CompletionOnceCallback(), &request,
4888 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414889 EXPECT_THAT(rv, IsOk());
[email protected]11c05872013-08-20 02:04:124890
rch3f4b8452016-02-23 16:59:324891 CreateSession();
[email protected]11c05872013-08-20 02:04:124892 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274893 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124894
bnc691fda62016-08-12 00:43:164895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124896 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:414897 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014898 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124899
4900 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524901 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014902 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504903
bnc691fda62016-08-12 00:43:164904 CheckWasQuicResponse(&trans);
4905 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:124906}
4907
Steven Valdez58097ec32018-07-16 18:29:044908TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
4909 MockQuicData mock_quic_data;
4910 quic::QuicStreamOffset client_header_stream_offset = 0;
4911 quic::QuicStreamOffset server_header_stream_offset = 0;
4912 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4913 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
4914 mock_quic_data.AddWrite(SYNCHRONOUS,
4915 ConstructClientRequestHeadersPacket(
4916 1, GetNthClientInitiatedStreamId(0), true, true,
4917 GetRequestHeaders("GET", "https", "/"),
4918 &client_header_stream_offset));
4919 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4920 1, GetNthClientInitiatedStreamId(0), false,
4921 false, GetResponseHeaders("425 TOO_EARLY"),
4922 &server_header_stream_offset));
4923 mock_quic_data.AddWrite(
4924 SYNCHRONOUS,
4925 ConstructClientAckAndRstPacket(2, GetNthClientInitiatedStreamId(0),
4926 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
4927
4928 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4929
4930 spdy::SpdySettingsIR settings_frame;
4931 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
4932 quic::kDefaultMaxUncompressedHeaderSize);
4933 spdy::SpdySerializedFrame spdy_frame(
4934 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
4935 mock_quic_data.AddWrite(
4936 SYNCHRONOUS,
4937 client_maker_.MakeDataPacket(
4938 3, 3, false, false, client_header_stream_offset,
4939 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
4940 client_header_stream_offset += spdy_frame.size();
4941
4942 mock_quic_data.AddWrite(
4943 SYNCHRONOUS,
4944 ConstructClientRequestHeadersPacket(
4945 4, GetNthClientInitiatedStreamId(1), false, true,
4946 GetRequestHeaders("GET", "https", "/"),
4947 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
4948 mock_quic_data.AddRead(
4949 ASYNC, ConstructServerResponseHeadersPacket(
4950 2, GetNthClientInitiatedStreamId(1), false, false,
4951 GetResponseHeaders("200 OK"), &server_header_stream_offset));
4952 mock_quic_data.AddRead(
4953 ASYNC, ConstructServerDataPacket(3, GetNthClientInitiatedStreamId(1),
4954 false, true, 0, "hello!"));
4955 mock_quic_data.AddWrite(
4956 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
4957 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4958 mock_quic_data.AddRead(ASYNC, 0); // EOF
4959
4960 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4961
4962 // In order for a new QUIC session to be established via alternate-protocol
4963 // without racing an HTTP connection, we need the host resolution to happen
4964 // synchronously.
4965 host_resolver_.set_synchronous_mode(true);
4966 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4967 "");
4968 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
4969 AddressList address;
4970 std::unique_ptr<HostResolver::Request> request;
4971 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4972 CompletionOnceCallback(), &request, net_log_.bound());
4973
4974 AddHangingNonAlternateProtocolSocketData();
4975 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274976 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:564977 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4978 QuicStreamFactoryPeer::SetAlarmFactory(
4979 session_->quic_stream_factory(),
4980 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4981 &clock_));
Steven Valdez58097ec32018-07-16 18:29:044982
4983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4984 TestCompletionCallback callback;
4985 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
4986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4987
4988 // Confirm the handshake after the 425 Too Early.
4989 base::RunLoop().RunUntilIdle();
4990
4991 // The handshake hasn't been confirmed yet, so the retry should not have
4992 // succeeded.
4993 EXPECT_FALSE(callback.have_result());
4994
4995 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
4996 quic::QuicSession::HANDSHAKE_CONFIRMED);
4997
4998 EXPECT_THAT(callback.WaitForResult(), IsOk());
4999 CheckWasQuicResponse(&trans);
5000 CheckResponseData(&trans, "hello!");
5001}
5002
5003TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5004 MockQuicData mock_quic_data;
5005 quic::QuicStreamOffset client_header_stream_offset = 0;
5006 quic::QuicStreamOffset server_header_stream_offset = 0;
5007 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5008 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
5009 mock_quic_data.AddWrite(SYNCHRONOUS,
5010 ConstructClientRequestHeadersPacket(
5011 1, GetNthClientInitiatedStreamId(0), true, true,
5012 GetRequestHeaders("GET", "https", "/"),
5013 &client_header_stream_offset));
5014 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5015 1, GetNthClientInitiatedStreamId(0), false,
5016 false, GetResponseHeaders("425 TOO_EARLY"),
5017 &server_header_stream_offset));
5018 mock_quic_data.AddWrite(
5019 SYNCHRONOUS,
5020 ConstructClientAckAndRstPacket(2, GetNthClientInitiatedStreamId(0),
5021 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5022
5023 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5024
5025 spdy::SpdySettingsIR settings_frame;
5026 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5027 quic::kDefaultMaxUncompressedHeaderSize);
5028 spdy::SpdySerializedFrame spdy_frame(
5029 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5030 mock_quic_data.AddWrite(
5031 SYNCHRONOUS,
5032 client_maker_.MakeDataPacket(
5033 3, 3, false, false, client_header_stream_offset,
5034 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5035 client_header_stream_offset += spdy_frame.size();
5036
5037 mock_quic_data.AddWrite(
5038 SYNCHRONOUS,
5039 ConstructClientRequestHeadersPacket(
5040 4, GetNthClientInitiatedStreamId(1), false, true,
5041 GetRequestHeaders("GET", "https", "/"),
5042 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
5043 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5044 2, GetNthClientInitiatedStreamId(1), false,
5045 false, GetResponseHeaders("425 TOO_EARLY"),
5046 &server_header_stream_offset));
5047 mock_quic_data.AddWrite(
5048 SYNCHRONOUS,
5049 ConstructClientAckAndRstPacket(5, GetNthClientInitiatedStreamId(1),
5050 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
5051 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5052 mock_quic_data.AddRead(ASYNC, 0); // EOF
5053
5054 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5055
5056 // In order for a new QUIC session to be established via alternate-protocol
5057 // without racing an HTTP connection, we need the host resolution to happen
5058 // synchronously.
5059 host_resolver_.set_synchronous_mode(true);
5060 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5061 "");
5062 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5063 AddressList address;
5064 std::unique_ptr<HostResolver::Request> request;
5065 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5066 CompletionOnceCallback(), &request, net_log_.bound());
5067
5068 AddHangingNonAlternateProtocolSocketData();
5069 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275070 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565071 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5072 QuicStreamFactoryPeer::SetAlarmFactory(
5073 session_->quic_stream_factory(),
5074 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5075 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045076
5077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5078 TestCompletionCallback callback;
5079 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5081
5082 // Confirm the handshake after the 425 Too Early.
5083 base::RunLoop().RunUntilIdle();
5084
5085 // The handshake hasn't been confirmed yet, so the retry should not have
5086 // succeeded.
5087 EXPECT_FALSE(callback.have_result());
5088
5089 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5090 quic::QuicSession::HANDSHAKE_CONFIRMED);
5091
5092 EXPECT_THAT(callback.WaitForResult(), IsOk());
5093 const HttpResponseInfo* response = trans.GetResponseInfo();
5094 ASSERT_TRUE(response != nullptr);
5095 ASSERT_TRUE(response->headers.get() != nullptr);
5096 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5097 EXPECT_TRUE(response->was_fetched_via_spdy);
5098 EXPECT_TRUE(response->was_alpn_negotiated);
5099 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5100 response->connection_info);
5101}
5102
zhongyica364fbb2015-12-12 03:39:125103TEST_P(QuicNetworkTransactionTest,
5104 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485105 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125106 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525107 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365108 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435109 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5110 mock_quic_data.AddWrite(
5111 SYNCHRONOUS,
5112 ConstructClientRequestHeadersPacket(
5113 2, GetNthClientInitiatedStreamId(0), true, true,
5114 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125115 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525116 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435117 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125118 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5119
5120 // The non-alternate protocol job needs to hang in order to guarantee that
5121 // the alternate-protocol job will "win".
5122 AddHangingNonAlternateProtocolSocketData();
5123
5124 // In order for a new QUIC session to be established via alternate-protocol
5125 // without racing an HTTP connection, we need the host resolution to happen
5126 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5127 // connection to the the server, in this test we require confirmation
5128 // before encrypting so the HTTP job will still start.
5129 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295130 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125131 "");
rch9ae5b3b2016-02-11 00:36:295132 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125133 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105134 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585135 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5136 CompletionOnceCallback(), &request,
5137 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415138 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125139
rch3f4b8452016-02-23 16:59:325140 CreateSession();
zhongyica364fbb2015-12-12 03:39:125141 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275142 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125143
bnc691fda62016-08-12 00:43:165144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125145 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415146 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015147 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125148
5149 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525150 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015151 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125152
5153 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525154 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125155
bnc691fda62016-08-12 00:43:165156 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125157 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525158 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5159 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125160}
5161
5162TEST_P(QuicNetworkTransactionTest,
5163 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485164 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125165 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525166 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365167 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435168 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5169 mock_quic_data.AddWrite(
5170 SYNCHRONOUS,
5171 ConstructClientRequestHeadersPacket(
5172 2, GetNthClientInitiatedStreamId(0), true, true,
5173 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215174 // Peer sending data from an non-existing stream causes this end to raise
5175 // error and close connection.
5176 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525177 ASYNC,
5178 ConstructServerRstPacket(1, false, 99, quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215179 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525180 mock_quic_data.AddWrite(
5181 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5182 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5183 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125184 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5185
5186 // The non-alternate protocol job needs to hang in order to guarantee that
5187 // the alternate-protocol job will "win".
5188 AddHangingNonAlternateProtocolSocketData();
5189
5190 // In order for a new QUIC session to be established via alternate-protocol
5191 // without racing an HTTP connection, we need the host resolution to happen
5192 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5193 // connection to the the server, in this test we require confirmation
5194 // before encrypting so the HTTP job will still start.
5195 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295196 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125197 "");
rch9ae5b3b2016-02-11 00:36:295198 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125199 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105200 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585201 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5202 CompletionOnceCallback(), &request,
5203 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415204 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125205
rch3f4b8452016-02-23 16:59:325206 CreateSession();
zhongyica364fbb2015-12-12 03:39:125207 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275208 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125209
bnc691fda62016-08-12 00:43:165210 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125211 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415212 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015213 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125214
5215 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525216 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015217 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125218 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525219 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125220
bnc691fda62016-08-12 00:43:165221 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525222 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125223}
5224
rchcd5f1c62016-06-23 02:43:485225TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5226 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525227 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365228 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435229 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5230 mock_quic_data.AddWrite(
5231 SYNCHRONOUS,
5232 ConstructClientRequestHeadersPacket(
5233 2, GetNthClientInitiatedStreamId(0), true, true,
5234 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485235 // Read the response headers, then a RST_STREAM frame.
Zhongyi Shi32f2fd02018-04-16 18:23:435236 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5237 1, GetNthClientInitiatedStreamId(0), false,
5238 false, GetResponseHeaders("200 OK")));
5239 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
5240 2, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:525241 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435242 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485243 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5244 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5245
5246 // The non-alternate protocol job needs to hang in order to guarantee that
5247 // the alternate-protocol job will "win".
5248 AddHangingNonAlternateProtocolSocketData();
5249
5250 // In order for a new QUIC session to be established via alternate-protocol
5251 // without racing an HTTP connection, we need the host resolution to happen
5252 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5253 // connection to the the server, in this test we require confirmation
5254 // before encrypting so the HTTP job will still start.
5255 host_resolver_.set_synchronous_mode(true);
5256 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5257 "");
5258 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5259 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105260 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585261 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5262 CompletionOnceCallback(), &request,
5263 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415264 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485265
5266 CreateSession();
5267 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275268 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485269
bnc691fda62016-08-12 00:43:165270 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485271 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415272 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485274
5275 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525276 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485277 // Read the headers.
robpercival214763f2016-07-01 23:27:015278 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485279
bnc691fda62016-08-12 00:43:165280 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485281 ASSERT_TRUE(response != nullptr);
5282 ASSERT_TRUE(response->headers.get() != nullptr);
5283 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5284 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525285 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445286 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5287 response->connection_info);
rchcd5f1c62016-06-23 02:43:485288
5289 std::string response_data;
bnc691fda62016-08-12 00:43:165290 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485291}
5292
5293TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485294 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485295 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525296 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365297 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435298 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5299 mock_quic_data.AddWrite(
5300 SYNCHRONOUS,
5301 ConstructClientRequestHeadersPacket(
5302 2, GetNthClientInitiatedStreamId(0), true, true,
5303 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5304 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
5305 1, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:525306 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485307 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5308 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5309
5310 // The non-alternate protocol job needs to hang in order to guarantee that
5311 // the alternate-protocol job will "win".
5312 AddHangingNonAlternateProtocolSocketData();
5313
5314 // In order for a new QUIC session to be established via alternate-protocol
5315 // without racing an HTTP connection, we need the host resolution to happen
5316 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5317 // connection to the the server, in this test we require confirmation
5318 // before encrypting so the HTTP job will still start.
5319 host_resolver_.set_synchronous_mode(true);
5320 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5321 "");
5322 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5323 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105324 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585325 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5326 CompletionOnceCallback(), &request,
5327 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415328 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485329
5330 CreateSession();
5331 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275332 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485333
bnc691fda62016-08-12 00:43:165334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485335 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415336 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015337 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485338
5339 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525340 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485341 // Read the headers.
robpercival214763f2016-07-01 23:27:015342 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485343}
5344
[email protected]1e960032013-12-20 19:00:205345TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305346 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525347 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585348 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305349 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505350 MockRead(ASYNC, close->data(), close->length()),
5351 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5352 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305353 };
Ryan Sleevib8d7ea02018-05-07 20:01:015354 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305355 socket_factory_.AddSocketDataProvider(&quic_data);
5356
5357 // Main job which will succeed even though the alternate job fails.
5358 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025359 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5360 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5361 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305362
Ryan Sleevib8d7ea02018-05-07 20:01:015363 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305364 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565365 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305366
rch3f4b8452016-02-23 16:59:325367 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275368 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195369 SendRequestAndExpectHttpResponse("hello from http");
5370 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305371}
5372
[email protected]1e960032013-12-20 19:00:205373TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595374 // Alternate-protocol job
5375 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025376 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595377 };
Ryan Sleevib8d7ea02018-05-07 20:01:015378 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595379 socket_factory_.AddSocketDataProvider(&quic_data);
5380
5381 // Main job which will succeed even though the alternate job fails.
5382 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025383 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5384 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5385 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595386
Ryan Sleevib8d7ea02018-05-07 20:01:015387 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595388 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565389 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595390
rch3f4b8452016-02-23 16:59:325391 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595392
Ryan Hamilton9835e662018-08-02 05:36:275393 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195394 SendRequestAndExpectHttpResponse("hello from http");
5395 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595396}
5397
[email protected]00c159f2014-05-21 22:38:165398TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535399 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165400 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025401 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165402 };
Ryan Sleevib8d7ea02018-05-07 20:01:015403 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165404 socket_factory_.AddSocketDataProvider(&quic_data);
5405
[email protected]eb71ab62014-05-23 07:57:535406 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165407 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025408 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165409 };
5410
Ryan Sleevib8d7ea02018-05-07 20:01:015411 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165412 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5413 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565414 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165415
rtennetib8e80fb2016-05-16 00:12:095416 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325417 CreateSession();
[email protected]00c159f2014-05-21 22:38:165418
Ryan Hamilton9835e662018-08-02 05:36:275419 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165420 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165421 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165422 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015423 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5424 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165425 ExpectQuicAlternateProtocolMapping();
5426}
5427
Zhongyi Shia0cef1082017-08-25 01:49:505428TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5429 // Tests that TCP job is delayed and QUIC job does not require confirmation
5430 // if QUIC was recently supported on the same IP on start.
5431
5432 // Set QUIC support on the last IP address, which is same with the local IP
5433 // address. Require confirmation mode will be turned off immediately when
5434 // local IP address is sorted out after we configure the UDP socket.
5435 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5436
5437 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525438 quic::QuicStreamOffset header_stream_offset = 0;
5439 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5440 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:435441 mock_quic_data.AddWrite(
5442 SYNCHRONOUS,
5443 ConstructClientRequestHeadersPacket(
5444 1, GetNthClientInitiatedStreamId(0), true, true,
5445 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5446 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5447 1, GetNthClientInitiatedStreamId(0), false,
5448 false, GetResponseHeaders("200 OK")));
5449 mock_quic_data.AddRead(
5450 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5451 false, true, 0, "hello!"));
5452 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505453 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5454 mock_quic_data.AddRead(ASYNC, 0); // EOF
5455
5456 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5457 // No HTTP data is mocked as TCP job never starts in this case.
5458
5459 CreateSession();
5460 // QuicStreamFactory by default requires confirmation on construction.
5461 session_->quic_stream_factory()->set_require_confirmation(true);
5462
Ryan Hamilton9835e662018-08-02 05:36:275463 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505464
5465 // Stall host resolution so that QUIC job will not succeed synchronously.
5466 // Socket will not be configured immediately and QUIC support is not sorted
5467 // out, TCP job will still be delayed as server properties indicates QUIC
5468 // support on last IP address.
5469 host_resolver_.set_synchronous_mode(false);
5470
5471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5472 TestCompletionCallback callback;
5473 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5474 IsError(ERR_IO_PENDING));
5475 // Complete host resolution in next message loop so that QUIC job could
5476 // proceed.
5477 base::RunLoop().RunUntilIdle();
5478 EXPECT_THAT(callback.WaitForResult(), IsOk());
5479
5480 CheckWasQuicResponse(&trans);
5481 CheckResponseData(&trans, "hello!");
5482}
5483
5484TEST_P(QuicNetworkTransactionTest,
5485 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5486 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5487 // was recently supported on a different IP address on start.
5488
5489 // Set QUIC support on the last IP address, which is different with the local
5490 // IP address. Require confirmation mode will remain when local IP address is
5491 // sorted out after we configure the UDP socket.
5492 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5493
5494 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525495 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505496 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435497 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5498 mock_quic_data.AddWrite(
5499 SYNCHRONOUS,
5500 ConstructClientRequestHeadersPacket(
5501 2, GetNthClientInitiatedStreamId(0), true, true,
5502 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5503 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5504 1, GetNthClientInitiatedStreamId(0), false,
5505 false, GetResponseHeaders("200 OK")));
5506 mock_quic_data.AddRead(
5507 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5508 false, true, 0, "hello!"));
5509 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505510 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5511 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5512 // No HTTP data is mocked as TCP job will be delayed and never starts.
5513
5514 CreateSession();
5515 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275516 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505517
5518 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5519 // Socket will not be configured immediately and QUIC support is not sorted
5520 // out, TCP job will still be delayed as server properties indicates QUIC
5521 // support on last IP address.
5522 host_resolver_.set_synchronous_mode(false);
5523
5524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5525 TestCompletionCallback callback;
5526 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5527 IsError(ERR_IO_PENDING));
5528
5529 // Complete host resolution in next message loop so that QUIC job could
5530 // proceed.
5531 base::RunLoop().RunUntilIdle();
5532 // Explicitly confirm the handshake so that QUIC job could succeed.
5533 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525534 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505535 EXPECT_THAT(callback.WaitForResult(), IsOk());
5536
5537 CheckWasQuicResponse(&trans);
5538 CheckResponseData(&trans, "hello!");
5539}
5540
Ryan Hamilton75f197262017-08-17 14:00:075541TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5542 // Test that NetErrorDetails is correctly populated, even if the
5543 // handshake has not yet been confirmed and no stream has been created.
5544
5545 // QUIC job will pause. When resumed, it will fail.
5546 MockQuicData mock_quic_data;
5547 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5548 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5549 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5550
5551 // Main job will also fail.
5552 MockRead http_reads[] = {
5553 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5554 };
5555
Ryan Sleevib8d7ea02018-05-07 20:01:015556 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075557 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5558 socket_factory_.AddSocketDataProvider(&http_data);
5559 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5560
5561 AddHangingNonAlternateProtocolSocketData();
5562 CreateSession();
5563 // Require handshake confirmation to ensure that no QUIC streams are
5564 // created, and to ensure that the TCP job does not wait for the QUIC
5565 // job to fail before it starts.
5566 session_->quic_stream_factory()->set_require_confirmation(true);
5567
Ryan Hamilton9835e662018-08-02 05:36:275568 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075569 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5570 TestCompletionCallback callback;
5571 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5572 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5573 // Allow the TCP job to fail.
5574 base::RunLoop().RunUntilIdle();
5575 // Now let the QUIC job fail.
5576 mock_quic_data.Resume();
5577 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5578 ExpectQuicAlternateProtocolMapping();
5579 NetErrorDetails details;
5580 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525581 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075582}
5583
[email protected]1e960032013-12-20 19:00:205584TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455585 // Alternate-protocol job
5586 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025587 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455588 };
Ryan Sleevib8d7ea02018-05-07 20:01:015589 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455590 socket_factory_.AddSocketDataProvider(&quic_data);
5591
[email protected]c92c1b52014-05-31 04:16:065592 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015593 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065594 socket_factory_.AddSocketDataProvider(&quic_data2);
5595
[email protected]4d283b32013-10-17 12:57:275596 // Final job that will proceed when the QUIC job fails.
5597 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025598 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5599 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5600 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275601
Ryan Sleevib8d7ea02018-05-07 20:01:015602 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275603 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565604 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275605
rtennetiafccbc062016-05-16 18:21:145606 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325607 CreateSession();
[email protected]77c6c162013-08-17 02:57:455608
Ryan Hamilton9835e662018-08-02 05:36:275609 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455610
[email protected]4d283b32013-10-17 12:57:275611 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455612
5613 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275614
rch37de576c2015-05-17 20:28:175615 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5616 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455617}
5618
[email protected]93b31772014-06-19 08:03:355619TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035620 // Alternate-protocol job
5621 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595622 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035623 };
Ryan Sleevib8d7ea02018-05-07 20:01:015624 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035625 socket_factory_.AddSocketDataProvider(&quic_data);
5626
5627 // Main job that will proceed when the QUIC job fails.
5628 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025629 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5630 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5631 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035632
Ryan Sleevib8d7ea02018-05-07 20:01:015633 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035634 socket_factory_.AddSocketDataProvider(&http_data);
5635
rtennetib8e80fb2016-05-16 00:12:095636 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325637 CreateSession();
[email protected]65768442014-06-06 23:37:035638
Ryan Hamilton9835e662018-08-02 05:36:275639 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035640
5641 SendRequestAndExpectHttpResponse("hello from http");
5642}
5643
[email protected]eb71ab62014-05-23 07:57:535644TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335645 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015646 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495647 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335648 socket_factory_.AddSocketDataProvider(&quic_data);
5649
5650 // Main job which will succeed even though the alternate job fails.
5651 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025652 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5653 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5654 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335655
Ryan Sleevib8d7ea02018-05-07 20:01:015656 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335657 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565658 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335659
rch3f4b8452016-02-23 16:59:325660 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275661 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335662 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535663
5664 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335665}
5666
[email protected]4fee9672014-01-08 14:47:155667TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155668 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435669 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
5670 mock_quic_data.AddWrite(SYNCHRONOUS,
5671 ConstructClientRequestHeadersPacket(
5672 1, GetNthClientInitiatedStreamId(0), true, true,
5673 GetRequestHeaders("GET", "https", "/")));
5674 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
rcha5399e02015-04-21 19:32:045675 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155676
5677 // When the QUIC connection fails, we will try the request again over HTTP.
5678 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485679 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565680 MockRead("hello world"),
5681 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5682 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155683
Ryan Sleevib8d7ea02018-05-07 20:01:015684 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155685 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565686 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155687
5688 // In order for a new QUIC session to be established via alternate-protocol
5689 // without racing an HTTP connection, we need the host resolution to happen
5690 // synchronously.
5691 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295692 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565693 "");
rch9ae5b3b2016-02-11 00:36:295694 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]4fee9672014-01-08 14:47:155695 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105696 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585697 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5698 CompletionOnceCallback(), &request,
5699 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415700 EXPECT_THAT(rv, IsOk());
[email protected]4fee9672014-01-08 14:47:155701
rch3f4b8452016-02-23 16:59:325702 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275703 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]4fee9672014-01-08 14:47:155704 SendRequestAndExpectHttpResponse("hello world");
5705}
5706
tbansalc3308d72016-08-27 10:25:045707// For an alternative proxy that supports QUIC, test that the request is
5708// successfully fetched by the main job when the alternate proxy job encounters
5709// an error.
5710TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5711 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5712}
5713TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5714 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5715}
5716TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5717 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5718}
5719TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5720 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5721}
5722TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5723 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5724}
5725TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5726 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5727}
5728TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5729 TestAlternativeProxy(ERR_IO_PENDING);
5730}
5731TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5732 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5733}
5734
5735TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5736 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435737 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
5738 mock_quic_data.AddWrite(SYNCHRONOUS,
5739 ConstructClientRequestHeadersPacket(
5740 1, GetNthClientInitiatedStreamId(0), true, true,
5741 GetRequestHeaders("GET", "https", "/")));
5742 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045743 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5744
5745 // When the QUIC connection fails, we will try the request again over HTTP.
5746 MockRead http_reads[] = {
5747 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5748 MockRead("hello world"),
5749 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5750 MockRead(ASYNC, OK)};
5751
Ryan Sleevib8d7ea02018-05-07 20:01:015752 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045753 socket_factory_.AddSocketDataProvider(&http_data);
5754 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5755
5756 TestProxyDelegate test_proxy_delegate;
5757 const HostPortPair host_port_pair("myproxy.org", 443);
5758 test_proxy_delegate.set_alternative_proxy_server(
5759 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5760 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5761
Ramin Halavatica8d5252018-03-12 05:33:495762 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5763 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525764 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045765 request_.url = GURL("http://mail.example.org/");
5766
5767 // In order for a new QUIC session to be established via alternate-protocol
5768 // without racing an HTTP connection, we need the host resolution to happen
5769 // synchronously.
5770 host_resolver_.set_synchronous_mode(true);
5771 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
5772 HostResolver::RequestInfo info(HostPortPair("myproxy.org", 443));
5773 AddressList address;
5774 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585775 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5776 CompletionOnceCallback(), &request,
5777 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415778 EXPECT_THAT(rv, IsOk());
tbansalc3308d72016-08-27 10:25:045779
5780 CreateSession();
5781 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595782 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165783 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045784}
5785
bnc508835902015-05-12 20:10:295786TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585787 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385788 EXPECT_FALSE(
5789 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295790 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525791 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365792 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435793 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5794 mock_quic_data.AddWrite(
5795 SYNCHRONOUS,
5796 ConstructClientRequestHeadersPacket(
5797 2, GetNthClientInitiatedStreamId(0), true, true,
5798 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5799 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5800 1, GetNthClientInitiatedStreamId(0), false,
5801 false, GetResponseHeaders("200 OK")));
5802 mock_quic_data.AddRead(
5803 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5804 false, true, 0, "hello!"));
5805 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505806 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295807 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5808
bncb07c05532015-05-14 19:07:205809 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095810 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325811 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275812 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295813 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385814 EXPECT_TRUE(
5815 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295816}
5817
zhongyi363c91c2017-03-23 23:16:085818// TODO(zhongyi): disabled this broken test as it was not testing the correct
5819// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5820TEST_P(QuicNetworkTransactionTest,
5821 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275822 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595823 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495824 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045825
5826 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045827
5828 test_proxy_delegate.set_alternative_proxy_server(
5829 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525830 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045831
5832 request_.url = GURL("http://mail.example.org/");
5833
5834 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5835 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015836 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045837 socket_factory_.AddSocketDataProvider(&socket_data);
5838
5839 // The non-alternate protocol job needs to hang in order to guarantee that
5840 // the alternate-protocol job will "win".
5841 AddHangingNonAlternateProtocolSocketData();
5842
5843 CreateSession();
5844 request_.method = "POST";
5845 ChunkedUploadDataStream upload_data(0);
5846 upload_data.AppendData("1", 1, true);
5847
5848 request_.upload_data_stream = &upload_data;
5849
5850 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5851 TestCompletionCallback callback;
5852 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5854 EXPECT_NE(OK, callback.WaitForResult());
5855
5856 // Verify that the alternative proxy server is not marked as broken.
5857 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5858
5859 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595860 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275861
5862 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5863 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5864 1);
tbansalc3308d72016-08-27 10:25:045865}
5866
rtenneti56977812016-01-15 19:26:565867TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415868 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575869 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565870
5871 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5872 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015873 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565874 socket_factory_.AddSocketDataProvider(&socket_data);
5875
rtennetib8e80fb2016-05-16 00:12:095876 // The non-alternate protocol job needs to hang in order to guarantee that
5877 // the alternate-protocol job will "win".
5878 AddHangingNonAlternateProtocolSocketData();
5879
rtenneti56977812016-01-15 19:26:565880 CreateSession();
5881 request_.method = "POST";
5882 ChunkedUploadDataStream upload_data(0);
5883 upload_data.AppendData("1", 1, true);
5884
5885 request_.upload_data_stream = &upload_data;
5886
bnc691fda62016-08-12 00:43:165887 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565888 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165889 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565891 EXPECT_NE(OK, callback.WaitForResult());
5892}
5893
rche11300ef2016-09-02 01:44:285894TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:485895 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285896 ScopedMockNetworkChangeNotifier network_change_notifier;
5897 MockNetworkChangeNotifier* mock_ncn =
5898 network_change_notifier.mock_network_change_notifier();
5899 mock_ncn->ForceNetworkHandlesSupported();
5900 mock_ncn->SetConnectedNetworksList(
5901 {kDefaultNetworkForTests, kNewNetworkForTests});
5902
mmenke6ddfbea2017-05-31 21:48:415903 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285904 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:315905 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285906
5907 MockQuicData socket_data;
5908 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525909 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435910 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
5911 socket_data.AddWrite(SYNCHRONOUS,
5912 ConstructClientRequestHeadersPacket(
5913 2, GetNthClientInitiatedStreamId(0), true, false,
5914 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:285915 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5916 socket_data.AddSocketDataToFactory(&socket_factory_);
5917
5918 MockQuicData socket_data2;
5919 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5920 socket_data2.AddSocketDataToFactory(&socket_factory_);
5921
5922 // The non-alternate protocol job needs to hang in order to guarantee that
5923 // the alternate-protocol job will "win".
5924 AddHangingNonAlternateProtocolSocketData();
5925
5926 CreateSession();
5927 request_.method = "POST";
5928 ChunkedUploadDataStream upload_data(0);
5929
5930 request_.upload_data_stream = &upload_data;
5931
rdsmith1d343be52016-10-21 20:37:505932 std::unique_ptr<HttpNetworkTransaction> trans(
5933 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:285934 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:505935 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:285936 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5937
5938 base::RunLoop().RunUntilIdle();
5939 upload_data.AppendData("1", 1, true);
5940 base::RunLoop().RunUntilIdle();
5941
5942 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:505943 trans.reset();
rche11300ef2016-09-02 01:44:285944 session_.reset();
5945}
5946
Ryan Hamilton4b3574532017-10-30 20:17:255947TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
5948 session_params_.origins_to_force_quic_on.insert(
5949 HostPortPair::FromString("mail.example.org:443"));
5950
5951 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525952 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435953 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:255954 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Zhongyi Shi32f2fd02018-04-16 18:23:435955 socket_data.AddWrite(SYNCHRONOUS,
5956 ConstructClientRequestHeadersPacket(
5957 2, GetNthClientInitiatedStreamId(0), true, true,
5958 GetRequestHeaders("GET", "https", "/"), &offset));
5959 socket_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5960 1, GetNthClientInitiatedStreamId(0), false,
5961 false, GetResponseHeaders("200 OK")));
5962 socket_data.AddRead(
5963 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5964 false, true, 0, "hello!"));
5965 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255966 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:165967 socket_data.AddWrite(
5968 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
5969 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
5970 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:255971
5972 socket_data.AddSocketDataToFactory(&socket_factory_);
5973
5974 CreateSession();
5975
5976 SendRequestAndExpectQuicResponse("hello!");
5977 session_.reset();
5978}
5979
5980TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
5981 session_params_.origins_to_force_quic_on.insert(
5982 HostPortPair::FromString("mail.example.org:443"));
5983
5984 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525985 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435986 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:255987 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Zhongyi Shi32f2fd02018-04-16 18:23:435988 socket_data.AddWrite(SYNCHRONOUS,
5989 ConstructClientRequestHeadersPacket(
5990 2, GetNthClientInitiatedStreamId(0), true, true,
5991 GetRequestHeaders("GET", "https", "/"), &offset));
5992 socket_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5993 1, GetNthClientInitiatedStreamId(0), false,
5994 false, GetResponseHeaders("200 OK")));
5995 socket_data.AddRead(
5996 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5997 false, true, 0, "hello!"));
5998 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255999 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166000 socket_data.AddWrite(
6001 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6002 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6003 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256004
6005 socket_data.AddSocketDataToFactory(&socket_factory_);
6006
6007 CreateSession();
6008
6009 SendRequestAndExpectQuicResponse("hello!");
6010 session_.reset();
6011}
6012
Ryan Hamilton9edcf1a2017-11-22 05:55:176013TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486014 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256015 session_params_.origins_to_force_quic_on.insert(
6016 HostPortPair::FromString("mail.example.org:443"));
6017
6018 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526019 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256020 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436021 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176022 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256023 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6024 }
6025 socket_data.AddSocketDataToFactory(&socket_factory_);
6026
6027 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176028 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6029 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6030 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6031 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256032
Ryan Hamilton8d9ee76e2018-05-29 23:52:526033 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6035 TestCompletionCallback callback;
6036 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176038 while (!callback.have_result()) {
6039 base::RunLoop().RunUntilIdle();
6040 quic_task_runner_->RunUntilIdle();
6041 }
6042 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256043 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176044 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6045 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6046 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526047 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6048 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256049}
6050
Ryan Hamilton9edcf1a2017-11-22 05:55:176051TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486052 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256053 session_params_.origins_to_force_quic_on.insert(
6054 HostPortPair::FromString("mail.example.org:443"));
6055
6056 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526057 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256058 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436059 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176060 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256061 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6062 }
6063 socket_data.AddSocketDataToFactory(&socket_factory_);
6064
6065 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176066 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6067 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6068 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6069 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256070
Ryan Hamilton8d9ee76e2018-05-29 23:52:526071 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256072 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6073 TestCompletionCallback callback;
6074 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6075 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176076 while (!callback.have_result()) {
6077 base::RunLoop().RunUntilIdle();
6078 quic_task_runner_->RunUntilIdle();
6079 }
6080 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256081 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176082 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6083 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6084 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526085 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6086 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256087}
6088
Cherie Shi7596de632018-02-22 07:28:186089TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486090 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186091 session_params_.origins_to_force_quic_on.insert(
6092 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526093 const quic::QuicString error_details =
6094 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6095 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186096
6097 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526098 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186099 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436100 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186101 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6102 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526103 socket_data.AddWrite(
6104 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6105 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186106 socket_data.AddSocketDataToFactory(&socket_factory_);
6107
6108 CreateSession();
6109
6110 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6111 TestCompletionCallback callback;
6112 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6114 base::RunLoop().RunUntilIdle();
6115 ASSERT_TRUE(callback.have_result());
6116 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6117 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6118 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6119}
6120
ckrasic769733c2016-06-30 00:42:136121// Adds coverage to catch regression such as https://crbug.com/622043
6122TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416123 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136124 HostPortPair::FromString("mail.example.org:443"));
6125
6126 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526127 quic::QuicStreamOffset header_stream_offset = 0;
6128 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436129 mock_quic_data.AddWrite(
6130 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6131 &header_stream_offset));
6132 mock_quic_data.AddWrite(
6133 SYNCHRONOUS,
6134 ConstructClientRequestHeadersPacket(
6135 client_packet_number++, GetNthClientInitiatedStreamId(0), true, true,
6136 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526137 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436138 mock_quic_data.AddRead(
6139 ASYNC,
6140 ConstructServerPushPromisePacket(
6141 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
6142 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
6143 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576144 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266145 version_ >= quic::QUIC_VERSION_43) {
Zhongyi Shi32f2fd02018-04-16 18:23:436146 mock_quic_data.AddWrite(
6147 SYNCHRONOUS,
6148 ConstructClientPriorityPacket(client_packet_number++, false,
6149 GetNthServerInitiatedStreamId(0),
6150 GetNthClientInitiatedStreamId(0),
6151 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576152 }
Zhongyi Shi32f2fd02018-04-16 18:23:436153 mock_quic_data.AddRead(
6154 ASYNC, ConstructServerResponseHeadersPacket(
6155 2, GetNthClientInitiatedStreamId(0), false, false,
6156 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576157 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436158 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6159 mock_quic_data.AddRead(
6160 ASYNC, ConstructServerResponseHeadersPacket(
6161 3, GetNthServerInitiatedStreamId(0), false, false,
6162 GetResponseHeaders("200 OK"), &server_header_offset));
6163 mock_quic_data.AddRead(
6164 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
6165 false, true, 0, "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576166 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436167 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
6168 mock_quic_data.AddRead(
6169 ASYNC, ConstructServerDataPacket(5, GetNthServerInitiatedStreamId(0),
6170 false, true, 0, "and hello!"));
6171 mock_quic_data.AddWrite(
6172 SYNCHRONOUS, ConstructClientAckAndRstPacket(
6173 client_packet_number++, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526174 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136175 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6176 mock_quic_data.AddRead(ASYNC, 0); // EOF
6177 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6178
6179 // The non-alternate protocol job needs to hang in order to guarantee that
6180 // the alternate-protocol job will "win".
6181 AddHangingNonAlternateProtocolSocketData();
6182
6183 CreateSession();
6184
6185 // PUSH_PROMISE handling in the http layer gets exercised here.
6186 SendRequestAndExpectQuicResponse("hello!");
6187
6188 request_.url = GURL("https://mail.example.org/pushed.jpg");
6189 SendRequestAndExpectQuicResponse("and hello!");
6190
6191 // Check that the NetLog was filled reasonably.
6192 TestNetLogEntry::List entries;
6193 net_log_.GetEntries(&entries);
6194 EXPECT_LT(0u, entries.size());
6195
6196 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6197 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006198 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6199 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136200 EXPECT_LT(0, pos);
6201}
6202
rch56ec40a2017-06-23 14:48:446203// Regression test for http://crbug.com/719461 in which a promised stream
6204// is closed before the pushed headers arrive, but after the connection
6205// is closed and before the callbacks are executed.
6206TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486207 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446208 session_params_.origins_to_force_quic_on.insert(
6209 HostPortPair::FromString("mail.example.org:443"));
6210
6211 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526212 quic::QuicStreamOffset header_stream_offset = 0;
6213 quic::QuicPacketNumber client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446214 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436215 mock_quic_data.AddWrite(
6216 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6217 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446218 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436219 mock_quic_data.AddWrite(
6220 SYNCHRONOUS,
6221 ConstructClientRequestHeadersPacket(
6222 client_packet_number++, GetNthClientInitiatedStreamId(0), true, true,
6223 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526224 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446225 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436226 mock_quic_data.AddRead(
6227 ASYNC,
6228 ConstructServerPushPromisePacket(
6229 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
6230 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
6231 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576232 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266233 version_ >= quic::QUIC_VERSION_43) {
Zhongyi Shi32f2fd02018-04-16 18:23:436234 mock_quic_data.AddWrite(
6235 SYNCHRONOUS,
6236 ConstructClientPriorityPacket(client_packet_number++, false,
6237 GetNthServerInitiatedStreamId(0),
6238 GetNthClientInitiatedStreamId(0),
6239 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576240 }
rch56ec40a2017-06-23 14:48:446241 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436242 mock_quic_data.AddRead(
6243 ASYNC, ConstructServerResponseHeadersPacket(
6244 2, GetNthClientInitiatedStreamId(0), false, false,
6245 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446246 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576247 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436248 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446249 // Response body for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436250 mock_quic_data.AddRead(
6251 ASYNC, ConstructServerDataPacket(3, GetNthClientInitiatedStreamId(0),
6252 false, true, 0, "hello!"));
rch56ec40a2017-06-23 14:48:446253 // Write error for the third request.
6254 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6255 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6256 mock_quic_data.AddRead(ASYNC, 0); // EOF
6257 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6258
6259 CreateSession();
6260
6261 // Send a request which triggers a push promise from the server.
6262 SendRequestAndExpectQuicResponse("hello!");
6263
6264 // Start a push transaction that will be cancelled after the connection
6265 // is closed, but before the callback is executed.
6266 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196267 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446268 session_.get());
6269 TestCompletionCallback callback2;
6270 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6272 base::RunLoop().RunUntilIdle();
6273
6274 // Cause the connection to close on a write error.
6275 HttpRequestInfo request3;
6276 request3.method = "GET";
6277 request3.url = GURL("https://mail.example.org/");
6278 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106279 request3.traffic_annotation =
6280 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446281 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6282 TestCompletionCallback callback3;
6283 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6284 IsError(ERR_IO_PENDING));
6285
6286 base::RunLoop().RunUntilIdle();
6287
6288 // When |trans2| is destroyed, the underlying stream will be closed.
6289 EXPECT_FALSE(callback2.have_result());
6290 trans2 = nullptr;
6291
6292 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6293}
6294
ckrasicda193a82016-07-09 00:39:366295TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416296 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366297 HostPortPair::FromString("mail.example.org:443"));
6298
6299 MockQuicData mock_quic_data;
6300
Ryan Hamilton8d9ee76e2018-05-29 23:52:526301 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436302 mock_quic_data.AddWrite(SYNCHRONOUS,
6303 ConstructInitialSettingsPacket(1, &offset));
ckrasicda193a82016-07-09 00:39:366304
Zhongyi Shi32f2fd02018-04-16 18:23:436305 mock_quic_data.AddWrite(
6306 SYNCHRONOUS,
6307 ConstructClientRequestHeadersAndDataFramesPacket(
6308 2, GetNthClientInitiatedStreamId(0), true, true, DEFAULT_PRIORITY,
6309 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr, {"1"}));
ckrasicda193a82016-07-09 00:39:366310
Zhongyi Shi32f2fd02018-04-16 18:23:436311 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6312 1, GetNthClientInitiatedStreamId(0), false,
6313 false, GetResponseHeaders("200 OK")));
ckrasicda193a82016-07-09 00:39:366314
Zhongyi Shi32f2fd02018-04-16 18:23:436315 mock_quic_data.AddRead(
6316 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6317 false, true, 0, "hello!"));
ckrasicda193a82016-07-09 00:39:366318
Zhongyi Shi32f2fd02018-04-16 18:23:436319 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366320
6321 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6322 mock_quic_data.AddRead(ASYNC, 0); // EOF
6323 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6324
6325 // The non-alternate protocol job needs to hang in order to guarantee that
6326 // the alternate-protocol job will "win".
6327 AddHangingNonAlternateProtocolSocketData();
6328
6329 CreateSession();
6330 request_.method = "POST";
6331 ChunkedUploadDataStream upload_data(0);
6332 upload_data.AppendData("1", 1, true);
6333
6334 request_.upload_data_stream = &upload_data;
6335
6336 SendRequestAndExpectQuicResponse("hello!");
6337}
6338
allada71b2efb2016-09-09 04:57:486339class QuicURLRequestContext : public URLRequestContext {
6340 public:
6341 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6342 MockClientSocketFactory* socket_factory)
6343 : storage_(this) {
6344 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076345 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046346 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486347 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046348 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596349 storage_.set_proxy_resolution_service(
6350 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076351 storage_.set_ssl_config_service(
6352 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486353 storage_.set_http_auth_handler_factory(
6354 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6355 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076356 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046357 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486358 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046359 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6360 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6361 false));
allada71b2efb2016-09-09 04:57:486362 }
6363
6364 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6365
6366 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6367
6368 private:
6369 MockClientSocketFactory* socket_factory_;
6370 URLRequestContextStorage storage_;
6371};
6372
6373TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416374 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486375 HostPortPair::FromString("mail.example.org:443"));
6376
6377 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526378 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366379 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436380 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136381 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486382 headers["user-agent"] = "";
6383 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436384 mock_quic_data.AddWrite(SYNCHRONOUS,
6385 ConstructClientRequestHeadersPacket(
6386 2, GetNthClientInitiatedStreamId(0), true, true,
6387 std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486388
Ryan Hamilton8d9ee76e2018-05-29 23:52:526389 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436390 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6391 1, GetNthClientInitiatedStreamId(0), false,
6392 false, GetResponseHeaders("200 OK"),
6393 &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486394
ckrasicbf2f59c2017-05-04 23:54:366395 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436396 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6397 false, true, 0, "Main Resource Data"));
6398 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486399
6400 mock_quic_data.AddRead(ASYNC, 0); // EOF
6401
6402 CreateSession();
6403
6404 TestDelegate delegate;
6405 QuicURLRequestContext quic_url_request_context(std::move(session_),
6406 &socket_factory_);
6407
6408 mock_quic_data.AddSocketDataToFactory(
6409 &quic_url_request_context.socket_factory());
6410 TestNetworkDelegate network_delegate;
6411 quic_url_request_context.set_network_delegate(&network_delegate);
6412
6413 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296414 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6415 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486416 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6417 &ssl_data_);
6418
6419 request->Start();
Wez2a31b222018-06-07 22:07:156420 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486421
6422 EXPECT_LT(0, request->GetTotalSentBytes());
6423 EXPECT_LT(0, request->GetTotalReceivedBytes());
6424 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6425 request->GetTotalSentBytes());
6426 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6427 request->GetTotalReceivedBytes());
6428 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6429 request->raw_header_size());
Wez0e717112018-06-18 23:09:226430
6431 // Pump the message loop to allow all data to be consumed.
6432 base::RunLoop().RunUntilIdle();
6433
allada71b2efb2016-09-09 04:57:486434 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6435 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6436}
6437
6438TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416439 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486440 HostPortPair::FromString("mail.example.org:443"));
6441
6442 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526443 quic::QuicStreamOffset header_stream_offset = 0;
6444 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436445 mock_quic_data.AddWrite(
6446 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6447 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136448 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486449 headers["user-agent"] = "";
6450 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436451 mock_quic_data.AddWrite(
6452 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6453 client_packet_number++, GetNthClientInitiatedStreamId(0),
6454 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486455
Ryan Hamilton8d9ee76e2018-05-29 23:52:526456 quic::QuicStreamOffset server_header_offset = 0;
6457 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486458
Zhongyi Shi32f2fd02018-04-16 18:23:436459 mock_quic_data.AddRead(
6460 ASYNC,
6461 ConstructServerPushPromisePacket(
6462 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
6463 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
6464 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486465
Yixin Wangb470bc882018-02-15 18:43:576466 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266467 version_ >= quic::QUIC_VERSION_43) {
Zhongyi Shi32f2fd02018-04-16 18:23:436468 mock_quic_data.AddWrite(
6469 SYNCHRONOUS,
6470 ConstructClientPriorityPacket(client_packet_number++, false,
6471 GetNthServerInitiatedStreamId(0),
6472 GetNthClientInitiatedStreamId(0),
6473 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576474 }
6475
allada71b2efb2016-09-09 04:57:486476 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436477 mock_quic_data.AddRead(
6478 ASYNC, ConstructServerResponseHeadersPacket(
6479 2, GetNthClientInitiatedStreamId(0), false, false,
6480 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486481 expected_raw_header_response_size =
6482 server_header_offset - expected_raw_header_response_size;
6483
Yixin Wangb470bc882018-02-15 18:43:576484 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436485 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486486
ckrasicbf2f59c2017-05-04 23:54:366487 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436488 ASYNC, ConstructServerResponseHeadersPacket(
6489 3, GetNthServerInitiatedStreamId(0), false, false,
6490 GetResponseHeaders("200 OK"), &server_header_offset));
6491 mock_quic_data.AddRead(
6492 ASYNC, ConstructServerDataPacket(4, GetNthServerInitiatedStreamId(0),
6493 false, true, 0, "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486494
Yixin Wangb470bc882018-02-15 18:43:576495 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436496 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
ckrasicbf2f59c2017-05-04 23:54:366497 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436498 ASYNC, ConstructServerDataPacket(5, GetNthClientInitiatedStreamId(0),
6499 false, true, 0, "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486500
Zhongyi Shi32f2fd02018-04-16 18:23:436501 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486502
6503 CreateSession();
6504
6505 TestDelegate delegate;
6506 QuicURLRequestContext quic_url_request_context(std::move(session_),
6507 &socket_factory_);
6508
6509 mock_quic_data.AddSocketDataToFactory(
6510 &quic_url_request_context.socket_factory());
6511 TestNetworkDelegate network_delegate;
6512 quic_url_request_context.set_network_delegate(&network_delegate);
6513
6514 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296515 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6516 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486517 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6518 &ssl_data_);
6519
6520 request->Start();
Wez2a31b222018-06-07 22:07:156521 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486522
6523 EXPECT_LT(0, request->GetTotalSentBytes());
6524 EXPECT_LT(0, request->GetTotalReceivedBytes());
6525 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6526 request->GetTotalSentBytes());
6527 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6528 request->GetTotalReceivedBytes());
6529 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6530 request->raw_header_size());
Wez0e717112018-06-18 23:09:226531
6532 // Pump the message loop to allow all data to be consumed.
6533 base::RunLoop().RunUntilIdle();
6534
allada71b2efb2016-09-09 04:57:486535 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6536 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6537}
6538
Yixin Wang10f477ed2017-11-21 04:20:206539TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6540 session_params_.quic_host_whitelist.insert("mail.example.org");
6541
6542 MockRead http_reads[] = {
6543 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6544 MockRead("hello world"),
6545 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6546 MockRead(ASYNC, OK)};
6547
Ryan Sleevib8d7ea02018-05-07 20:01:016548 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206549 socket_factory_.AddSocketDataProvider(&http_data);
6550 AddCertificate(&ssl_data_);
6551 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6552
6553 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526554 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206555 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436556 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6557 mock_quic_data.AddWrite(
6558 SYNCHRONOUS,
6559 ConstructClientRequestHeadersPacket(
6560 2, GetNthClientInitiatedStreamId(0), true, true,
6561 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
6562 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6563 1, GetNthClientInitiatedStreamId(0), false,
6564 false, GetResponseHeaders("200 OK")));
6565 mock_quic_data.AddRead(
6566 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6567 false, true, 0, "hello!"));
6568 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206569 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6570 mock_quic_data.AddRead(ASYNC, 0); // EOF
6571
6572 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6573
6574 AddHangingNonAlternateProtocolSocketData();
6575 CreateSession();
6576
6577 SendRequestAndExpectHttpResponse("hello world");
6578 SendRequestAndExpectQuicResponse("hello!");
6579}
6580
6581TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6582 session_params_.quic_host_whitelist.insert("mail.example.com");
6583
6584 MockRead http_reads[] = {
6585 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6586 MockRead("hello world"),
6587 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6588 MockRead(ASYNC, OK)};
6589
Ryan Sleevib8d7ea02018-05-07 20:01:016590 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206591 socket_factory_.AddSocketDataProvider(&http_data);
6592 AddCertificate(&ssl_data_);
6593 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6594 socket_factory_.AddSocketDataProvider(&http_data);
6595 AddCertificate(&ssl_data_);
6596 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6597
6598 AddHangingNonAlternateProtocolSocketData();
6599 CreateSession();
6600
6601 SendRequestAndExpectHttpResponse("hello world");
6602 SendRequestAndExpectHttpResponse("hello world");
6603}
6604
bnc359ed2a2016-04-29 20:43:456605class QuicNetworkTransactionWithDestinationTest
6606 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016607 public ::testing::WithParamInterface<PoolingTestParams>,
6608 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456609 protected:
6610 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556611 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056612 client_headers_include_h2_stream_dependency_(
6613 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526614 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456615 destination_type_(GetParam().destination_type),
6616 cert_transparency_verifier_(new MultiLogCTVerifier()),
6617 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596618 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456619 auth_handler_factory_(
6620 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6621 random_generator_(0),
6622 ssl_data_(ASYNC, OK) {}
6623
6624 void SetUp() override {
6625 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556626 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456627
mmenke6ddfbea2017-05-31 21:48:416628 HttpNetworkSession::Params session_params;
6629 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346630 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446631 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056632 session_params.quic_headers_include_h2_stream_dependency =
6633 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416634
6635 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456636
Ryan Hamilton8d9ee76e2018-05-29 23:52:526637 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416638 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456639
6640 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276641 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416642 session_context.quic_crypto_client_stream_factory =
6643 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456644
mmenke6ddfbea2017-05-31 21:48:416645 session_context.quic_random = &random_generator_;
6646 session_context.client_socket_factory = &socket_factory_;
6647 session_context.host_resolver = &host_resolver_;
6648 session_context.cert_verifier = &cert_verifier_;
6649 session_context.transport_security_state = &transport_security_state_;
6650 session_context.cert_transparency_verifier =
6651 cert_transparency_verifier_.get();
6652 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6653 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456654 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416655 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596656 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416657 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6658 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456659
mmenke6ddfbea2017-05-31 21:48:416660 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456661 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456662 }
6663
6664 void TearDown() override {
6665 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6666 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556667 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456668 PlatformTest::TearDown();
6669 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556670 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406671 session_.reset();
bnc359ed2a2016-04-29 20:43:456672 }
6673
zhongyie537a002017-06-27 16:48:216674 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456675 HostPortPair destination;
6676 switch (destination_type_) {
6677 case SAME_AS_FIRST:
6678 destination = HostPortPair(origin1_, 443);
6679 break;
6680 case SAME_AS_SECOND:
6681 destination = HostPortPair(origin2_, 443);
6682 break;
6683 case DIFFERENT:
6684 destination = HostPortPair(kDifferentHostname, 443);
6685 break;
6686 }
bnc3472afd2016-11-17 15:27:216687 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456688 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216689 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456690 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446691 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456692 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526693 std::unique_ptr<quic::QuicEncryptedPacket>
6694 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6695 quic::QuicStreamId stream_id,
6696 bool should_include_version,
6697 quic::QuicStreamOffset* offset,
6698 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486699 return ConstructClientRequestHeadersPacket(
6700 packet_number, stream_id, should_include_version, 0, offset, maker);
6701 }
bnc359ed2a2016-04-29 20:43:456702
Ryan Hamilton8d9ee76e2018-05-29 23:52:526703 std::unique_ptr<quic::QuicEncryptedPacket>
6704 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6705 quic::QuicStreamId stream_id,
6706 bool should_include_version,
6707 quic::QuicStreamId parent_stream_id,
6708 quic::QuicStreamOffset* offset,
6709 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136710 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456711 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136712 spdy::SpdyHeaderBlock headers(
6713 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456714 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6715 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486716 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456717 }
6718
Ryan Hamilton8d9ee76e2018-05-29 23:52:526719 std::unique_ptr<quic::QuicEncryptedPacket>
6720 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6721 quic::QuicStreamId stream_id,
6722 bool should_include_version,
6723 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586724 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456725 packet_number, stream_id, should_include_version, nullptr, maker);
6726 }
6727
Ryan Hamilton8d9ee76e2018-05-29 23:52:526728 std::unique_ptr<quic::QuicEncryptedPacket>
6729 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6730 quic::QuicStreamId stream_id,
6731 quic::QuicStreamOffset* offset,
6732 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136733 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456734 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266735 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456736 }
6737
Ryan Hamilton8d9ee76e2018-05-29 23:52:526738 std::unique_ptr<quic::QuicEncryptedPacket>
6739 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6740 quic::QuicStreamId stream_id,
6741 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586742 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6743 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456744 }
6745
Ryan Hamilton8d9ee76e2018-05-29 23:52:526746 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
6747 quic::QuicPacketNumber packet_number,
6748 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456749 QuicTestPacketMaker* maker) {
6750 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
6751 "hello");
6752 }
6753
Ryan Hamilton8d9ee76e2018-05-29 23:52:526754 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
6755 quic::QuicPacketNumber packet_number,
6756 quic::QuicPacketNumber largest_received,
6757 quic::QuicPacketNumber smallest_received,
6758 quic::QuicPacketNumber least_unacked,
bnc359ed2a2016-04-29 20:43:456759 QuicTestPacketMaker* maker) {
6760 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496761 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456762 }
6763
Ryan Hamilton8d9ee76e2018-05-29 23:52:526764 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
6765 quic::QuicPacketNumber packet_number,
6766 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376767 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366768 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376769 }
6770
bnc359ed2a2016-04-29 20:43:456771 void AddRefusedSocketData() {
6772 std::unique_ptr<StaticSocketDataProvider> refused_data(
6773 new StaticSocketDataProvider());
6774 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6775 refused_data->set_connect_data(refused_connect);
6776 socket_factory_.AddSocketDataProvider(refused_data.get());
6777 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6778 }
6779
6780 void AddHangingSocketData() {
6781 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6782 new StaticSocketDataProvider());
6783 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6784 hanging_data->set_connect_data(hanging_connect);
6785 socket_factory_.AddSocketDataProvider(hanging_data.get());
6786 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6787 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6788 }
6789
6790 bool AllDataConsumed() {
6791 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6792 if (!socket_data_ptr->AllReadDataConsumed() ||
6793 !socket_data_ptr->AllWriteDataConsumed()) {
6794 return false;
6795 }
6796 }
6797 return true;
6798 }
6799
6800 void SendRequestAndExpectQuicResponse(const std::string& host) {
6801 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6802 HttpRequestInfo request;
6803 std::string url("https://");
6804 url.append(host);
6805 request.url = GURL(url);
6806 request.load_flags = 0;
6807 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106808 request.traffic_annotation =
6809 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456810 TestCompletionCallback callback;
6811 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016812 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456813
6814 std::string response_data;
robpercival214763f2016-07-01 23:27:016815 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456816 EXPECT_EQ("hello", response_data);
6817
6818 const HttpResponseInfo* response = trans.GetResponseInfo();
6819 ASSERT_TRUE(response != nullptr);
6820 ASSERT_TRUE(response->headers.get() != nullptr);
6821 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6822 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526823 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:446824 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:456825 response->connection_info);
6826 EXPECT_EQ(443, response->socket_address.port());
6827 }
6828
Ryan Hamilton8d9ee76e2018-05-29 23:52:526829 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
6830 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:366831 }
6832
Ryan Hamilton8d9ee76e2018-05-29 23:52:526833 quic::MockClock clock_;
6834 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:056835 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526836 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456837 DestinationType destination_type_;
6838 std::string origin1_;
6839 std::string origin2_;
6840 std::unique_ptr<HttpNetworkSession> session_;
6841 MockClientSocketFactory socket_factory_;
6842 MockHostResolver host_resolver_;
6843 MockCertVerifier cert_verifier_;
6844 TransportSecurityState transport_security_state_;
6845 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236846 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456847 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076848 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596849 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456850 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526851 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:456852 HttpServerPropertiesImpl http_server_properties_;
6853 BoundTestNetLog net_log_;
6854 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6855 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6856 static_socket_data_provider_vector_;
6857 SSLSocketDataProvider ssl_data_;
6858};
6859
Bence Békyce380cb2018-04-26 23:39:556860INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
bnc359ed2a2016-04-29 20:43:456861 QuicNetworkTransactionWithDestinationTest,
6862 ::testing::ValuesIn(GetPoolingTestParams()));
6863
6864// A single QUIC request fails because the certificate does not match the origin
6865// hostname, regardless of whether it matches the alternative service hostname.
6866TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6867 if (destination_type_ == DIFFERENT)
6868 return;
6869
6870 GURL url("https://mail.example.com/");
6871 origin1_ = url.host();
6872
6873 // Not used for requests, but this provides a test case where the certificate
6874 // is valid for the hostname of the alternative service.
6875 origin2_ = "mail.example.org";
6876
zhongyie537a002017-06-27 16:48:216877 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456878
6879 scoped_refptr<X509Certificate> cert(
6880 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246881 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
6882 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:456883
6884 ProofVerifyDetailsChromium verify_details;
6885 verify_details.cert_verify_result.verified_cert = cert;
6886 verify_details.cert_verify_result.is_issued_by_known_root = true;
6887 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6888
6889 MockQuicData mock_quic_data;
6890 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6891 mock_quic_data.AddRead(ASYNC, 0);
6892
6893 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6894
6895 AddRefusedSocketData();
6896
6897 HttpRequestInfo request;
6898 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:106899 request.traffic_annotation =
6900 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456901
6902 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6903 TestCompletionCallback callback;
6904 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016905 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:456906
6907 EXPECT_TRUE(AllDataConsumed());
6908}
6909
6910// First request opens QUIC session to alternative service. Second request
6911// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:526912// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:456913TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
6914 origin1_ = "mail.example.org";
6915 origin2_ = "news.example.org";
6916
zhongyie537a002017-06-27 16:48:216917 SetQuicAlternativeService(origin1_);
6918 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456919
6920 scoped_refptr<X509Certificate> cert(
6921 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246922 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
6923 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
6924 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456925
6926 ProofVerifyDetailsChromium verify_details;
6927 verify_details.cert_verify_result.verified_cert = cert;
6928 verify_details.cert_verify_result.is_issued_by_known_root = true;
6929 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6930
Yixin Wang079ad542018-01-11 04:06:056931 QuicTestPacketMaker client_maker(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526932 version_, 0, &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:056933 client_headers_include_h2_stream_dependency_);
6934 QuicTestPacketMaker server_maker(version_, 0, &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526935 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456936
Ryan Hamilton8d9ee76e2018-05-29 23:52:526937 quic::QuicStreamOffset request_header_offset(0);
6938 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:456939
6940 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:056941 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436942 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:056943 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436944 mock_quic_data.AddWrite(SYNCHRONOUS,
6945 ConstructClientRequestHeadersPacket(
6946 2, GetNthClientInitiatedStreamId(0), true,
6947 &request_header_offset, &client_maker));
6948 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6949 1, GetNthClientInitiatedStreamId(0),
6950 &response_header_offset, &server_maker));
6951 mock_quic_data.AddRead(
6952 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6953 &server_maker));
6954 mock_quic_data.AddWrite(SYNCHRONOUS,
6955 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:456956
Yixin Wang079ad542018-01-11 04:06:056957 client_maker.set_hostname(origin2_);
6958 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:456959
Zhongyi Shi32f2fd02018-04-16 18:23:436960 mock_quic_data.AddWrite(
6961 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6962 4, GetNthClientInitiatedStreamId(1), false,
6963 GetNthClientInitiatedStreamId(0), &request_header_offset,
6964 &client_maker));
6965 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6966 3, GetNthClientInitiatedStreamId(1),
6967 &response_header_offset, &server_maker));
6968 mock_quic_data.AddRead(
6969 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
6970 &server_maker));
6971 mock_quic_data.AddWrite(SYNCHRONOUS,
6972 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:456973 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6974 mock_quic_data.AddRead(ASYNC, 0); // EOF
6975
6976 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6977
6978 AddHangingSocketData();
6979 AddHangingSocketData();
6980
Fan Yangc9e00dc2018-10-09 14:17:566981 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6982 QuicStreamFactoryPeer::SetAlarmFactory(
6983 session_->quic_stream_factory(),
6984 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
6985 &clock_));
6986
bnc359ed2a2016-04-29 20:43:456987 SendRequestAndExpectQuicResponse(origin1_);
6988 SendRequestAndExpectQuicResponse(origin2_);
6989
6990 EXPECT_TRUE(AllDataConsumed());
6991}
6992
6993// First request opens QUIC session to alternative service. Second request does
6994// not pool to it, even though destination matches, because certificate is not
6995// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:526996// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:456997TEST_P(QuicNetworkTransactionWithDestinationTest,
6998 DoNotPoolIfCertificateInvalid) {
6999 origin1_ = "news.example.org";
7000 origin2_ = "mail.example.com";
7001
zhongyie537a002017-06-27 16:48:217002 SetQuicAlternativeService(origin1_);
7003 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457004
7005 scoped_refptr<X509Certificate> cert1(
7006 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247007 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7008 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7009 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457010
7011 scoped_refptr<X509Certificate> cert2(
7012 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247013 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7014 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457015
7016 ProofVerifyDetailsChromium verify_details1;
7017 verify_details1.cert_verify_result.verified_cert = cert1;
7018 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7019 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7020
7021 ProofVerifyDetailsChromium verify_details2;
7022 verify_details2.cert_verify_result.verified_cert = cert2;
7023 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7024 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7025
Yixin Wang079ad542018-01-11 04:06:057026 QuicTestPacketMaker client_maker1(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527027 version_, 0, &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057028 client_headers_include_h2_stream_dependency_);
rchbf4c26d2017-04-16 23:17:557029 QuicTestPacketMaker server_maker1(version_, 0, &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527030 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457031
7032 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527033 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457034 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437035 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7036 &client_maker1));
7037 mock_quic_data1.AddWrite(SYNCHRONOUS,
7038 ConstructClientRequestHeadersPacket(
7039 2, GetNthClientInitiatedStreamId(0), true,
7040 &header_stream_offset1, &client_maker1));
7041 mock_quic_data1.AddRead(
7042 ASYNC, ConstructServerResponseHeadersPacket(
7043 1, GetNthClientInitiatedStreamId(0), &server_maker1));
7044 mock_quic_data1.AddRead(
7045 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
7046 &server_maker1));
7047 mock_quic_data1.AddWrite(
7048 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457049 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7050 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7051
7052 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7053
Yixin Wang079ad542018-01-11 04:06:057054 QuicTestPacketMaker client_maker2(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527055 version_, 0, &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057056 client_headers_include_h2_stream_dependency_);
rchbf4c26d2017-04-16 23:17:557057 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527058 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457059
7060 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527061 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457062 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437063 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7064 &client_maker2));
7065 mock_quic_data2.AddWrite(SYNCHRONOUS,
7066 ConstructClientRequestHeadersPacket(
7067 2, GetNthClientInitiatedStreamId(0), true,
7068 &header_stream_offset2, &client_maker2));
7069 mock_quic_data2.AddRead(
7070 ASYNC, ConstructServerResponseHeadersPacket(
7071 1, GetNthClientInitiatedStreamId(0), &server_maker2));
7072 mock_quic_data2.AddRead(
7073 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
7074 &server_maker2));
7075 mock_quic_data2.AddWrite(
7076 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457077 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7078 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7079
7080 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7081
bnc359ed2a2016-04-29 20:43:457082 SendRequestAndExpectQuicResponse(origin1_);
7083 SendRequestAndExpectQuicResponse(origin2_);
7084
7085 EXPECT_TRUE(AllDataConsumed());
7086}
7087
ckrasicdee37572017-04-06 22:42:277088// crbug.com/705109 - this confirms that matching request with a body
7089// triggers a crash (pre-fix).
7090TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417091 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277092 HostPortPair::FromString("mail.example.org:443"));
7093
7094 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527095 quic::QuicStreamOffset header_stream_offset = 0;
7096 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437097 mock_quic_data.AddWrite(
7098 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7099 &header_stream_offset));
7100 mock_quic_data.AddWrite(
7101 SYNCHRONOUS,
7102 ConstructClientRequestHeadersPacket(
7103 client_packet_number++, GetNthClientInitiatedStreamId(0), true, true,
7104 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527105 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437106 mock_quic_data.AddRead(
7107 ASYNC,
7108 ConstructServerPushPromisePacket(
7109 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
7110 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7111 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577112 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267113 version_ >= quic::QUIC_VERSION_43) {
Zhongyi Shi32f2fd02018-04-16 18:23:437114 mock_quic_data.AddWrite(
7115 SYNCHRONOUS,
7116 ConstructClientPriorityPacket(client_packet_number++, false,
7117 GetNthServerInitiatedStreamId(0),
7118 GetNthClientInitiatedStreamId(0),
7119 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577120 }
Zhongyi Shi32f2fd02018-04-16 18:23:437121 mock_quic_data.AddRead(
7122 ASYNC, ConstructServerResponseHeadersPacket(
7123 2, GetNthClientInitiatedStreamId(0), false, false,
7124 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577125 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437126 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7127 mock_quic_data.AddRead(
7128 ASYNC, ConstructServerResponseHeadersPacket(
7129 3, GetNthServerInitiatedStreamId(0), false, false,
7130 GetResponseHeaders("200 OK"), &server_header_offset));
7131 mock_quic_data.AddRead(
7132 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
7133 false, true, 0, "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577134 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437135 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
7136 mock_quic_data.AddRead(
7137 ASYNC, ConstructServerDataPacket(5, GetNthServerInitiatedStreamId(0),
7138 false, true, 0, "and hello!"));
ckrasicdee37572017-04-06 22:42:277139
7140 // Because the matching request has a body, we will see the push
7141 // stream get cancelled, and the matching request go out on the
7142 // wire.
Zhongyi Shi32f2fd02018-04-16 18:23:437143 mock_quic_data.AddWrite(
7144 SYNCHRONOUS, ConstructClientAckAndRstPacket(
7145 client_packet_number++, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527146 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277147 const char kBody[] = "1";
Zhongyi Shi32f2fd02018-04-16 18:23:437148 mock_quic_data.AddWrite(
7149 SYNCHRONOUS,
7150 ConstructClientRequestHeadersAndDataFramesPacket(
7151 client_packet_number++, GetNthClientInitiatedStreamId(1), false, true,
7152 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7153 GetNthServerInitiatedStreamId(0), &header_stream_offset, nullptr,
7154 {kBody}));
ckrasicdee37572017-04-06 22:42:277155
7156 // We see the same response as for the earlier pushed and cancelled
7157 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437158 mock_quic_data.AddRead(
7159 ASYNC, ConstructServerResponseHeadersPacket(
7160 6, GetNthClientInitiatedStreamId(1), false, false,
7161 GetResponseHeaders("200 OK"), &server_header_offset));
7162 mock_quic_data.AddRead(
7163 ASYNC, ConstructServerDataPacket(7, GetNthClientInitiatedStreamId(1),
7164 false, true, 0, "and hello!"));
ckrasicdee37572017-04-06 22:42:277165
Yixin Wangb470bc882018-02-15 18:43:577166 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437167 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277168 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7169 mock_quic_data.AddRead(ASYNC, 0); // EOF
7170 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7171
7172 // The non-alternate protocol job needs to hang in order to guarantee that
7173 // the alternate-protocol job will "win".
7174 AddHangingNonAlternateProtocolSocketData();
7175
7176 CreateSession();
7177
7178 // PUSH_PROMISE handling in the http layer gets exercised here.
7179 SendRequestAndExpectQuicResponse("hello!");
7180
7181 request_.url = GURL("https://mail.example.org/pushed.jpg");
7182 ChunkedUploadDataStream upload_data(0);
7183 upload_data.AppendData("1", 1, true);
7184 request_.upload_data_stream = &upload_data;
7185 SendRequestAndExpectQuicResponse("and hello!");
7186}
7187
Bence Béky7538a952018-02-01 16:59:527188// Regression test for https://crbug.com/797825: If pushed headers describe a
7189// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7190// not be called (otherwise a DCHECK fails).
7191TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137192 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527193 pushed_request_headers[":authority"] = "";
7194 pushed_request_headers[":method"] = "GET";
7195 pushed_request_headers[":path"] = "/";
7196 pushed_request_headers[":scheme"] = "nosuchscheme";
7197
7198 session_params_.origins_to_force_quic_on.insert(
7199 HostPortPair::FromString("mail.example.org:443"));
7200
7201 MockQuicData mock_quic_data;
7202
Ryan Hamilton8d9ee76e2018-05-29 23:52:527203 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527204 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437205 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7206 mock_quic_data.AddWrite(
7207 SYNCHRONOUS,
7208 ConstructClientRequestHeadersPacket(
7209 2, GetNthClientInitiatedStreamId(0), true, true,
7210 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527211
Ryan Hamilton8d9ee76e2018-05-29 23:52:527212 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437213 mock_quic_data.AddRead(ASYNC, ConstructServerPushPromisePacket(
7214 1, GetNthClientInitiatedStreamId(0),
7215 GetNthServerInitiatedStreamId(0), false,
7216 std::move(pushed_request_headers),
7217 &server_header_offset, &server_maker_));
7218 mock_quic_data.AddWrite(
7219 SYNCHRONOUS, ConstructClientRstPacket(3, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527220 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527221
Zhongyi Shi32f2fd02018-04-16 18:23:437222 mock_quic_data.AddRead(
7223 ASYNC, ConstructServerResponseHeadersPacket(
7224 2, GetNthClientInitiatedStreamId(0), false, false,
7225 GetResponseHeaders("200 OK"), &server_header_offset));
7226 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527227
Zhongyi Shi32f2fd02018-04-16 18:23:437228 mock_quic_data.AddRead(
7229 ASYNC, ConstructServerResponseHeadersPacket(
7230 3, GetNthServerInitiatedStreamId(0), false, false,
7231 GetResponseHeaders("200 OK"), &server_header_offset));
7232 mock_quic_data.AddRead(
7233 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
7234 false, true, 0, "hello!"));
7235 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527236
7237 mock_quic_data.AddRead(ASYNC, 0);
7238 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7239
7240 // The non-alternate protocol job needs to hang in order to guarantee that
7241 // the alternate-protocol job will "win".
7242 AddHangingNonAlternateProtocolSocketData();
7243
7244 CreateSession();
7245
7246 // PUSH_PROMISE handling in the http layer gets exercised here.
7247 SendRequestAndExpectQuicResponse("hello!");
7248
7249 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7250 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7251}
7252
Yixin Wang46a273ec302018-01-23 17:59:567253// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
7254TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
7255 session_params_.enable_quic = true;
7256 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497257 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567258
7259 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527260 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567261 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437262 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7263 mock_quic_data.AddWrite(SYNCHRONOUS,
7264 ConstructClientRequestHeadersPacket(
7265 2, GetNthClientInitiatedStreamId(0), true, false,
7266 ConnectRequestHeaders("mail.example.org:443"),
7267 &header_stream_offset));
7268 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7269 1, GetNthClientInitiatedStreamId(0), false,
7270 false, GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567271
7272 const char get_request[] =
7273 "GET / HTTP/1.1\r\n"
7274 "Host: mail.example.org\r\n"
7275 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437276 mock_quic_data.AddWrite(
7277 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7278 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527279 false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567280 const char get_response[] =
7281 "HTTP/1.1 200 OK\r\n"
7282 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437283 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527284 ASYNC,
7285 ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0), false,
7286 false, 0, quic::QuicStringPiece(get_response)));
7287
7288 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7289 3, GetNthClientInitiatedStreamId(0),
7290 false, false, strlen(get_response),
7291 quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437292 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567293 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7294
7295 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527296 SYNCHRONOUS, ConstructClientRstPacket(5, GetNthClientInitiatedStreamId(0),
7297 quic::QUIC_STREAM_CANCELLED,
7298 strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567299
7300 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7301
7302 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7303
7304 CreateSession();
7305
7306 request_.url = GURL("https://mail.example.org/");
7307 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7308 HeadersHandler headers_handler;
7309 trans.SetBeforeHeadersSentCallback(
7310 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7311 base::Unretained(&headers_handler)));
7312 RunTransaction(&trans);
7313 CheckWasHttpResponse(&trans);
7314 CheckResponsePort(&trans, 70);
7315 CheckResponseData(&trans, "0123456789");
7316 EXPECT_TRUE(headers_handler.was_proxied());
7317 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7318
7319 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7320 // proxy socket to disconnect.
7321 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7322
7323 base::RunLoop().RunUntilIdle();
7324 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7325 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7326}
7327
7328// Performs an HTTP/2 request over QUIC proxy tunnel.
7329TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
7330 session_params_.enable_quic = true;
7331 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497332 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567333
7334 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527335 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567336 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437337 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7338 mock_quic_data.AddWrite(SYNCHRONOUS,
7339 ConstructClientRequestHeadersPacket(
7340 2, GetNthClientInitiatedStreamId(0), true, false,
7341 ConnectRequestHeaders("mail.example.org:443"),
7342 &header_stream_offset));
7343 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7344 1, GetNthClientInitiatedStreamId(0), false,
7345 false, GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567346
7347 SpdyTestUtil spdy_util;
7348
Ryan Hamilton0239aac2018-05-19 00:03:137349 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567350 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Zhongyi Shi32f2fd02018-04-16 18:23:437351 mock_quic_data.AddWrite(
7352 SYNCHRONOUS,
7353 ConstructClientAckAndDataPacket(
7354 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527355 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Ryan Hamilton0239aac2018-05-19 00:03:137356 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567357 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437358 mock_quic_data.AddRead(
7359 ASYNC, ConstructServerDataPacket(
7360 2, GetNthClientInitiatedStreamId(0), false, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527361 quic::QuicStringPiece(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567362
Ryan Hamilton0239aac2018-05-19 00:03:137363 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197364 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437365 mock_quic_data.AddRead(
7366 SYNCHRONOUS,
7367 ConstructServerDataPacket(
7368 3, GetNthClientInitiatedStreamId(0), false, false, resp_frame.size(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527369 quic::QuicStringPiece(data_frame.data(), data_frame.size())));
Zhongyi Shi32f2fd02018-04-16 18:23:437370 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567371 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7372
7373 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437374 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:567375 ConstructClientRstPacket(5, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527376 quic::QUIC_STREAM_CANCELLED, get_frame.size()));
Yixin Wang46a273ec302018-01-23 17:59:567377
7378 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7379
7380 SSLSocketDataProvider ssl_data(ASYNC, OK);
7381 ssl_data.next_proto = kProtoHTTP2;
7382 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7383
7384 CreateSession();
7385
7386 request_.url = GURL("https://mail.example.org/");
7387 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7388 HeadersHandler headers_handler;
7389 trans.SetBeforeHeadersSentCallback(
7390 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7391 base::Unretained(&headers_handler)));
7392 RunTransaction(&trans);
7393 CheckWasSpdyResponse(&trans);
7394 CheckResponsePort(&trans, 70);
7395 CheckResponseData(&trans, "0123456789");
7396 EXPECT_TRUE(headers_handler.was_proxied());
7397 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7398
Wez0e717112018-06-18 23:09:227399 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7400 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567401 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7402
7403 base::RunLoop().RunUntilIdle();
7404 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7405 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7406}
7407
7408// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7409// check that the proxy socket is reused for the second request.
7410TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
7411 session_params_.enable_quic = true;
7412 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497413 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567414
7415 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527416 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567417 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437418 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7419 mock_quic_data.AddWrite(SYNCHRONOUS,
7420 ConstructClientRequestHeadersPacket(
7421 2, GetNthClientInitiatedStreamId(0), true, false,
7422 ConnectRequestHeaders("mail.example.org:443"),
7423 &header_stream_offset));
7424 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7425 1, GetNthClientInitiatedStreamId(0), false,
7426 false, GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567427
Ryan Hamilton8d9ee76e2018-05-29 23:52:527428 quic::QuicStreamOffset client_data_offset = 0;
7429 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567430 const char get_request_1[] =
7431 "GET / HTTP/1.1\r\n"
7432 "Host: mail.example.org\r\n"
7433 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437434 mock_quic_data.AddWrite(
7435 SYNCHRONOUS,
7436 ConstructClientAckAndDataPacket(
7437 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527438 client_data_offset, quic::QuicStringPiece(get_request_1)));
Yixin Wang46a273ec302018-01-23 17:59:567439 client_data_offset += strlen(get_request_1);
7440
7441 const char get_response_1[] =
7442 "HTTP/1.1 200 OK\r\n"
7443 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437444 mock_quic_data.AddRead(
7445 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
7446 false, false, server_data_offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527447 quic::QuicStringPiece(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:567448 server_data_offset += strlen(get_response_1);
7449
Ryan Hamilton8d9ee76e2018-05-29 23:52:527450 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7451 3, GetNthClientInitiatedStreamId(0),
7452 false, false, server_data_offset,
7453 quic::QuicStringPiece("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:567454 server_data_offset += 10;
7455
Zhongyi Shi32f2fd02018-04-16 18:23:437456 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567457
7458 const char get_request_2[] =
7459 "GET /2 HTTP/1.1\r\n"
7460 "Host: mail.example.org\r\n"
7461 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437462 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527463 SYNCHRONOUS,
7464 ConstructClientDataPacket(5, GetNthClientInitiatedStreamId(0), false,
7465 false, client_data_offset,
7466 quic::QuicStringPiece(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:567467 client_data_offset += strlen(get_request_2);
7468
7469 const char get_response_2[] =
7470 "HTTP/1.1 200 OK\r\n"
7471 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437472 mock_quic_data.AddRead(
7473 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
7474 false, false, server_data_offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527475 quic::QuicStringPiece(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:567476 server_data_offset += strlen(get_response_2);
7477
Ryan Hamilton8d9ee76e2018-05-29 23:52:527478 mock_quic_data.AddRead(
7479 SYNCHRONOUS, ConstructServerDataPacket(
7480 5, GetNthClientInitiatedStreamId(0), false, false,
7481 server_data_offset, quic::QuicStringPiece("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:567482 server_data_offset += 7;
7483
Zhongyi Shi32f2fd02018-04-16 18:23:437484 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567485 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7486
7487 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527488 SYNCHRONOUS, ConstructClientRstPacket(7, GetNthClientInitiatedStreamId(0),
7489 quic::QUIC_STREAM_CANCELLED,
7490 client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567491
7492 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7493
7494 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7495
7496 CreateSession();
7497
7498 request_.url = GURL("https://mail.example.org/");
7499 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7500 HeadersHandler headers_handler_1;
7501 trans_1.SetBeforeHeadersSentCallback(
7502 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7503 base::Unretained(&headers_handler_1)));
7504 RunTransaction(&trans_1);
7505 CheckWasHttpResponse(&trans_1);
7506 CheckResponsePort(&trans_1, 70);
7507 CheckResponseData(&trans_1, "0123456789");
7508 EXPECT_TRUE(headers_handler_1.was_proxied());
7509 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7510
7511 request_.url = GURL("https://mail.example.org/2");
7512 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7513 HeadersHandler headers_handler_2;
7514 trans_2.SetBeforeHeadersSentCallback(
7515 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7516 base::Unretained(&headers_handler_2)));
7517 RunTransaction(&trans_2);
7518 CheckWasHttpResponse(&trans_2);
7519 CheckResponsePort(&trans_2, 70);
7520 CheckResponseData(&trans_2, "0123456");
7521 EXPECT_TRUE(headers_handler_2.was_proxied());
7522 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7523
7524 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7525 // proxy socket to disconnect.
7526 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7527
7528 base::RunLoop().RunUntilIdle();
7529 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7530 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7531}
7532
7533// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7534// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7535// server is reused for the second request.
7536TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
7537 session_params_.enable_quic = true;
7538 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497539 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567540
7541 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527542 quic::QuicStreamOffset client_header_stream_offset = 0;
7543 quic::QuicStreamOffset server_header_stream_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437544 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7545 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567546
7547 // CONNECT request and response for first request
Zhongyi Shi32f2fd02018-04-16 18:23:437548 mock_quic_data.AddWrite(SYNCHRONOUS,
7549 ConstructClientRequestHeadersPacket(
7550 2, GetNthClientInitiatedStreamId(0), true, false,
7551 ConnectRequestHeaders("mail.example.org:443"),
7552 &client_header_stream_offset));
7553 mock_quic_data.AddRead(
7554 ASYNC, ConstructServerResponseHeadersPacket(
7555 1, GetNthClientInitiatedStreamId(0), false, false,
7556 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567557
7558 // GET request, response, and data over QUIC tunnel for first request
7559 const char get_request[] =
7560 "GET / HTTP/1.1\r\n"
7561 "Host: mail.example.org\r\n"
7562 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437563 mock_quic_data.AddWrite(
7564 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7565 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527566 false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567567 const char get_response[] =
7568 "HTTP/1.1 200 OK\r\n"
7569 "Content-Length: 10\r\n\r\n";
7570 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527571 ASYNC,
7572 ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0), false,
7573 false, 0, quic::QuicStringPiece(get_response)));
7574 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7575 3, GetNthClientInitiatedStreamId(0),
7576 false, false, strlen(get_response),
7577 quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437578 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567579
7580 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437581 mock_quic_data.AddWrite(
7582 SYNCHRONOUS,
7583 ConstructClientRequestHeadersPacket(
7584 5, GetNthClientInitiatedStreamId(1), false, false,
7585 ConnectRequestHeaders("different.example.org:443"),
7586 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
7587 mock_quic_data.AddRead(
7588 ASYNC, ConstructServerResponseHeadersPacket(
7589 4, GetNthClientInitiatedStreamId(1), false, false,
7590 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567591
7592 // GET request, response, and data over QUIC tunnel for second request
7593 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137594 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567595 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Zhongyi Shi32f2fd02018-04-16 18:23:437596 mock_quic_data.AddWrite(
7597 SYNCHRONOUS,
7598 ConstructClientAckAndDataPacket(
7599 6, false, GetNthClientInitiatedStreamId(1), 4, 4, 1, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527600 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567601
Ryan Hamilton0239aac2018-05-19 00:03:137602 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567603 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437604 mock_quic_data.AddRead(
7605 ASYNC, ConstructServerDataPacket(
7606 5, GetNthClientInitiatedStreamId(1), false, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527607 quic::QuicStringPiece(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567608
Ryan Hamilton0239aac2018-05-19 00:03:137609 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197610 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437611 mock_quic_data.AddRead(
7612 ASYNC,
7613 ConstructServerDataPacket(
7614 6, GetNthClientInitiatedStreamId(1), false, false, resp_frame.size(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527615 quic::QuicStringPiece(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567616
Zhongyi Shi32f2fd02018-04-16 18:23:437617 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567618 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7619
7620 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527621 SYNCHRONOUS, ConstructClientRstPacket(8, GetNthClientInitiatedStreamId(0),
7622 quic::QUIC_STREAM_CANCELLED,
7623 strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567624 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437625 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:567626 ConstructClientRstPacket(9, GetNthClientInitiatedStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527627 quic::QUIC_STREAM_CANCELLED, get_frame.size()));
Yixin Wang46a273ec302018-01-23 17:59:567628
7629 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7630
7631 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7632
7633 SSLSocketDataProvider ssl_data(ASYNC, OK);
7634 ssl_data.next_proto = kProtoHTTP2;
7635 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7636
7637 CreateSession();
7638
7639 request_.url = GURL("https://mail.example.org/");
7640 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7641 HeadersHandler headers_handler_1;
7642 trans_1.SetBeforeHeadersSentCallback(
7643 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7644 base::Unretained(&headers_handler_1)));
7645 RunTransaction(&trans_1);
7646 CheckWasHttpResponse(&trans_1);
7647 CheckResponsePort(&trans_1, 70);
7648 CheckResponseData(&trans_1, "0123456789");
7649 EXPECT_TRUE(headers_handler_1.was_proxied());
7650 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7651
7652 request_.url = GURL("https://different.example.org/");
7653 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7654 HeadersHandler headers_handler_2;
7655 trans_2.SetBeforeHeadersSentCallback(
7656 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7657 base::Unretained(&headers_handler_2)));
7658 RunTransaction(&trans_2);
7659 CheckWasSpdyResponse(&trans_2);
7660 CheckResponsePort(&trans_2, 70);
7661 CheckResponseData(&trans_2, "0123456");
7662 EXPECT_TRUE(headers_handler_2.was_proxied());
7663 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7664
7665 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7666 // proxy socket to disconnect.
7667 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7668
7669 base::RunLoop().RunUntilIdle();
7670 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7671 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7672}
7673
7674// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
7675TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
7676 session_params_.enable_quic = true;
7677 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497678 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567679
7680 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527681 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567682 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437683 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7684 mock_quic_data.AddWrite(SYNCHRONOUS,
7685 ConstructClientRequestHeadersPacket(
7686 2, GetNthClientInitiatedStreamId(0), true, false,
7687 ConnectRequestHeaders("mail.example.org:443"),
7688 &header_stream_offset));
7689 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7690 1, GetNthClientInitiatedStreamId(0), false,
7691 true, GetResponseHeaders("500")));
Yixin Wang46a273ec302018-01-23 17:59:567692 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Ryan Hamilton8d9ee76e2018-05-29 23:52:527693 mock_quic_data.AddWrite(
7694 SYNCHRONOUS,
7695 ConstructClientAckAndRstPacket(3, GetNthClientInitiatedStreamId(0),
7696 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567697
7698 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7699
7700 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7701
7702 CreateSession();
7703
7704 request_.url = GURL("https://mail.example.org/");
7705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7706 HeadersHandler headers_handler;
7707 trans.SetBeforeHeadersSentCallback(
7708 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7709 base::Unretained(&headers_handler)));
7710 TestCompletionCallback callback;
7711 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7712 EXPECT_EQ(ERR_IO_PENDING, rv);
7713 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7714 EXPECT_EQ(false, headers_handler.was_proxied());
7715
7716 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7717 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7718}
7719
7720// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
7721TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
7722 session_params_.enable_quic = true;
7723 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497724 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567725
7726 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527727 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567728 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437729 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7730 mock_quic_data.AddWrite(SYNCHRONOUS,
7731 ConstructClientRequestHeadersPacket(
7732 2, GetNthClientInitiatedStreamId(0), true, false,
7733 ConnectRequestHeaders("mail.example.org:443"),
7734 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567735 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7736
7737 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7738
7739 CreateSession();
7740
7741 request_.url = GURL("https://mail.example.org/");
7742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7743 HeadersHandler headers_handler;
7744 trans.SetBeforeHeadersSentCallback(
7745 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7746 base::Unretained(&headers_handler)));
7747 TestCompletionCallback callback;
7748 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7749 EXPECT_EQ(ERR_IO_PENDING, rv);
7750 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7751
7752 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7753 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7754}
7755
7756// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
7757// host. Retries request and succeeds.
7758TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
7759 session_params_.enable_quic = true;
7760 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497761 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567762
7763 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527764 quic::QuicStreamOffset client_header_stream_offset = 0;
7765 quic::QuicStreamOffset server_header_stream_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437766 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7767 1, &client_header_stream_offset));
7768 mock_quic_data.AddWrite(SYNCHRONOUS,
7769 ConstructClientRequestHeadersPacket(
7770 2, GetNthClientInitiatedStreamId(0), true, false,
7771 ConnectRequestHeaders("mail.example.org:443"),
7772 &client_header_stream_offset));
7773 mock_quic_data.AddRead(
7774 ASYNC, ConstructServerResponseHeadersPacket(
7775 1, GetNthClientInitiatedStreamId(0), false, false,
7776 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527777 mock_quic_data.AddWrite(
7778 SYNCHRONOUS,
7779 ConstructClientAckAndRstPacket(3, GetNthClientInitiatedStreamId(0),
7780 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567781
Zhongyi Shi32f2fd02018-04-16 18:23:437782 mock_quic_data.AddWrite(
7783 SYNCHRONOUS,
7784 ConstructClientRequestHeadersPacket(
7785 4, GetNthClientInitiatedStreamId(1), false, false,
7786 ConnectRequestHeaders("mail.example.org:443"),
7787 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
7788 mock_quic_data.AddRead(
7789 ASYNC, ConstructServerResponseHeadersPacket(
7790 2, GetNthClientInitiatedStreamId(1), false, false,
7791 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567792
7793 const char get_request[] =
7794 "GET / HTTP/1.1\r\n"
7795 "Host: mail.example.org\r\n"
7796 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437797 mock_quic_data.AddWrite(
7798 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7799 5, false, GetNthClientInitiatedStreamId(1), 2, 2, 1,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527800 false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567801 const char get_response[] =
7802 "HTTP/1.1 200 OK\r\n"
7803 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437804 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527805 ASYNC,
7806 ConstructServerDataPacket(3, GetNthClientInitiatedStreamId(1), false,
7807 false, 0, quic::QuicStringPiece(get_response)));
7808
7809 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7810 4, GetNthClientInitiatedStreamId(1),
7811 false, false, strlen(get_response),
7812 quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437813 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:567814 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7815
7816 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527817 SYNCHRONOUS, ConstructClientRstPacket(7, GetNthClientInitiatedStreamId(1),
7818 quic::QUIC_STREAM_CANCELLED,
7819 strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567820
7821 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7822
7823 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7824 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
7825
7826 SSLSocketDataProvider ssl_data(ASYNC, OK);
7827 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7828
7829 CreateSession();
7830
7831 request_.url = GURL("https://mail.example.org/");
7832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7833 HeadersHandler headers_handler;
7834 trans.SetBeforeHeadersSentCallback(
7835 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7836 base::Unretained(&headers_handler)));
7837 TestCompletionCallback callback;
7838 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7839 EXPECT_EQ(ERR_IO_PENDING, rv);
7840 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
7841
7842 rv = trans.RestartIgnoringLastError(callback.callback());
7843 EXPECT_EQ(ERR_IO_PENDING, rv);
7844 EXPECT_EQ(OK, callback.WaitForResult());
7845
7846 CheckWasHttpResponse(&trans);
7847 CheckResponsePort(&trans, 70);
7848 CheckResponseData(&trans, "0123456789");
7849 EXPECT_EQ(true, headers_handler.was_proxied());
7850 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7851
7852 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7853 // proxy socket to disconnect.
7854 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7855
7856 base::RunLoop().RunUntilIdle();
7857 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7858 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7859}
7860
7861// Checks if a request's specified "user-agent" header shows up correctly in the
7862// CONNECT request to a QUIC proxy.
7863TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
7864 session_params_.enable_quic = true;
7865 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497866 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567867
7868 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527869 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567870 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437871 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567872
Ryan Hamilton0239aac2018-05-19 00:03:137873 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:567874 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Zhongyi Shi32f2fd02018-04-16 18:23:437875 mock_quic_data.AddWrite(SYNCHRONOUS,
7876 ConstructClientRequestHeadersPacket(
7877 2, GetNthClientInitiatedStreamId(0), true, false,
7878 std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567879 // Return an error, so the transaction stops here (this test isn't interested
7880 // in the rest).
7881 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7882
7883 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7884
7885 CreateSession();
7886
7887 request_.url = GURL("https://mail.example.org/");
7888 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7889 "Chromium Ultra Awesome X Edition");
7890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7891 HeadersHandler headers_handler;
7892 trans.SetBeforeHeadersSentCallback(
7893 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7894 base::Unretained(&headers_handler)));
7895 TestCompletionCallback callback;
7896 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7897 EXPECT_EQ(ERR_IO_PENDING, rv);
7898 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7899
7900 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7901 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7902}
7903
Yixin Wang00fc44c2018-01-23 21:12:207904// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7905// HTTP/2 stream dependency and weights given the request priority.
7906TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
7907 session_params_.enable_quic = true;
7908 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497909 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:207910
7911 const RequestPriority request_priority = MEDIUM;
7912
7913 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527914 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:207915 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437916 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7917 mock_quic_data.AddWrite(
7918 SYNCHRONOUS,
7919 ConstructClientRequestHeadersPacket(
7920 2, GetNthClientInitiatedStreamId(0), true, false, request_priority,
7921 ConnectRequestHeaders("mail.example.org:443"), 0,
7922 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:207923 // Return an error, so the transaction stops here (this test isn't interested
7924 // in the rest).
7925 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7926
7927 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7928
7929 CreateSession();
7930
7931 request_.url = GURL("https://mail.example.org/");
7932 HttpNetworkTransaction trans(request_priority, session_.get());
7933 TestCompletionCallback callback;
7934 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7935 EXPECT_EQ(ERR_IO_PENDING, rv);
7936 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7937
7938 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7939 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7940}
7941
Yixin Wang46a273ec302018-01-23 17:59:567942// Test the request-challenge-retry sequence for basic auth, over a QUIC
7943// connection when setting up a QUIC proxy tunnel.
7944TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
7945 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
7946 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:137947 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:567948 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
7949
7950 std::unique_ptr<QuicTestPacketMaker> client_maker;
7951 std::unique_ptr<QuicTestPacketMaker> server_maker;
7952
7953 // On the second pass, the body read of the auth challenge is synchronous, so
7954 // IsConnectedAndIdle returns false. The socket should still be drained and
7955 // reused. See http://crbug.com/544255.
7956 for (int i = 0; i < 2; ++i) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:527957 client_maker.reset(
7958 new QuicTestPacketMaker(version_, 0, &clock_, kDefaultServerHostName,
7959 quic::Perspective::IS_CLIENT,
7960 client_headers_include_h2_stream_dependency_));
7961 server_maker.reset(
7962 new QuicTestPacketMaker(version_, 0, &clock_, kDefaultServerHostName,
7963 quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:567964
7965 session_params_.enable_quic = true;
7966 proxy_resolution_service_ =
7967 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497968 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567969
7970 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527971 quic::QuicStreamOffset client_header_stream_offset = 0;
7972 quic::QuicStreamOffset server_header_stream_offset = 0;
7973 quic::QuicStreamOffset client_data_offset = 0;
7974 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567975
Zhongyi Shi32f2fd02018-04-16 18:23:437976 mock_quic_data.AddWrite(SYNCHRONOUS,
7977 client_maker->MakeInitialSettingsPacket(
7978 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567979
7980 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437981 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:567982 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
7983 2, GetNthClientInitiatedStreamId(0), true, false, default_priority,
7984 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
7985 &client_header_stream_offset));
7986
Ryan Hamilton0239aac2018-05-19 00:03:137987 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:567988 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
7989 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7990 headers["content-length"] = "10";
7991 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:437992 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
7993 1, GetNthClientInitiatedStreamId(0), false, false,
7994 std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567995
7996 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:437997 mock_quic_data.AddRead(
7998 ASYNC, server_maker->MakeDataPacket(
7999 2, GetNthClientInitiatedStreamId(0), false, false,
8000 server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568001 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438002 mock_quic_data.AddRead(
8003 SYNCHRONOUS, server_maker->MakeDataPacket(
8004 2, GetNthClientInitiatedStreamId(0), false, false,
8005 server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568006 }
8007 server_data_offset += 10;
8008
Zhongyi Shi32f2fd02018-04-16 18:23:438009 mock_quic_data.AddWrite(SYNCHRONOUS,
8010 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568011
8012 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528013 SYNCHRONOUS, client_maker->MakeRstPacket(
8014 4, false, GetNthClientInitiatedStreamId(0),
8015 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:568016
8017 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8018 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8019 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438020 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568021 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8022 5, GetNthClientInitiatedStreamId(1), false, false, default_priority,
8023 std::move(headers), GetNthClientInitiatedStreamId(0),
8024 &client_header_stream_offset));
8025
8026 // Response to wrong password
8027 headers =
8028 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8029 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8030 headers["content-length"] = "10";
8031 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438032 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
8033 3, GetNthClientInitiatedStreamId(1), false, false,
8034 std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568035 mock_quic_data.AddRead(SYNCHRONOUS,
8036 ERR_IO_PENDING); // No more data to read
8037
Zhongyi Shi32f2fd02018-04-16 18:23:438038 mock_quic_data.AddWrite(SYNCHRONOUS,
8039 client_maker->MakeAckAndRstPacket(
8040 6, false, GetNthClientInitiatedStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:528041 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568042
8043 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8044 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8045
8046 CreateSession();
8047
8048 request_.url = GURL("https://mail.example.org/");
8049 // Ensure that proxy authentication is attempted even
8050 // when the no authentication data flag is set.
8051 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8052 {
8053 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8054 HeadersHandler headers_handler;
8055 trans.SetBeforeHeadersSentCallback(
8056 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8057 base::Unretained(&headers_handler)));
8058 RunTransaction(&trans);
8059
8060 const HttpResponseInfo* response = trans.GetResponseInfo();
8061 ASSERT_TRUE(response != nullptr);
8062 ASSERT_TRUE(response->headers.get() != nullptr);
8063 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8064 response->headers->GetStatusLine());
8065 EXPECT_TRUE(response->headers->IsKeepAlive());
8066 EXPECT_EQ(407, response->headers->response_code());
8067 EXPECT_EQ(10, response->headers->GetContentLength());
8068 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8069 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8070 ASSERT_TRUE(auth_challenge != nullptr);
8071 EXPECT_TRUE(auth_challenge->is_proxy);
8072 EXPECT_EQ("https://proxy.example.org:70",
8073 auth_challenge->challenger.Serialize());
8074 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8075 EXPECT_EQ("basic", auth_challenge->scheme);
8076
8077 TestCompletionCallback callback;
8078 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8079 callback.callback());
8080 EXPECT_EQ(ERR_IO_PENDING, rv);
8081 EXPECT_EQ(OK, callback.WaitForResult());
8082
8083 response = trans.GetResponseInfo();
8084 ASSERT_TRUE(response != nullptr);
8085 ASSERT_TRUE(response->headers.get() != nullptr);
8086 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8087 response->headers->GetStatusLine());
8088 EXPECT_TRUE(response->headers->IsKeepAlive());
8089 EXPECT_EQ(407, response->headers->response_code());
8090 EXPECT_EQ(10, response->headers->GetContentLength());
8091 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8092 auth_challenge = response->auth_challenge.get();
8093 ASSERT_TRUE(auth_challenge != nullptr);
8094 EXPECT_TRUE(auth_challenge->is_proxy);
8095 EXPECT_EQ("https://proxy.example.org:70",
8096 auth_challenge->challenger.Serialize());
8097 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8098 EXPECT_EQ("basic", auth_challenge->scheme);
8099 }
8100 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8101 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8102 // reused because it's not connected).
8103 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8104 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8105 }
8106}
8107
Yixin Wang385652a2018-02-16 02:37:238108TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8109 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8110 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268111 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238112 !client_headers_include_h2_stream_dependency_) {
8113 return;
8114 }
8115
8116 session_params_.origins_to_force_quic_on.insert(
8117 HostPortPair::FromString("mail.example.org:443"));
8118
Ryan Hamilton8d9ee76e2018-05-29 23:52:528119 const quic::QuicStreamId client_stream_0 = GetNthClientInitiatedStreamId(0);
8120 const quic::QuicStreamId client_stream_1 = GetNthClientInitiatedStreamId(1);
8121 const quic::QuicStreamId client_stream_2 = GetNthClientInitiatedStreamId(2);
8122 const quic::QuicStreamId push_stream_0 = GetNthServerInitiatedStreamId(0);
8123 const quic::QuicStreamId push_stream_1 = GetNthServerInitiatedStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238124
8125 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528126 quic::QuicStreamOffset header_stream_offset = 0;
8127 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238128 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438129 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238130
8131 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438132 mock_quic_data.AddWrite(SYNCHRONOUS,
8133 ConstructClientRequestHeadersPacket(
8134 2, client_stream_0, true, true, HIGHEST,
8135 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8136 &header_stream_offset));
8137 mock_quic_data.AddWrite(SYNCHRONOUS,
8138 ConstructClientRequestHeadersPacket(
8139 3, client_stream_1, true, true, MEDIUM,
8140 GetRequestHeaders("GET", "https", "/1.jpg"),
8141 client_stream_0, &header_stream_offset));
8142 mock_quic_data.AddWrite(SYNCHRONOUS,
8143 ConstructClientRequestHeadersPacket(
8144 4, client_stream_2, true, true, MEDIUM,
8145 GetRequestHeaders("GET", "https", "/2.jpg"),
8146 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238147
8148 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438149 mock_quic_data.AddRead(
8150 ASYNC, ConstructServerResponseHeadersPacket(
8151 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8152 &server_header_offset));
8153 mock_quic_data.AddRead(
8154 ASYNC, ConstructServerResponseHeadersPacket(
8155 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8156 &server_header_offset));
8157 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8158 mock_quic_data.AddRead(
8159 ASYNC, ConstructServerResponseHeadersPacket(
8160 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8161 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238162
8163 // Server sends two push promises associated with |client_stream_0|; client
8164 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8165 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438166 mock_quic_data.AddRead(ASYNC,
8167 ConstructServerPushPromisePacket(
8168 4, client_stream_0, push_stream_0, false,
8169 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8170 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238171 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438172 SYNCHRONOUS,
8173 ConstructClientAckAndPriorityFramesPacket(
8174 6, false, 4, 3, 1,
8175 {{push_stream_0, client_stream_2,
8176 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8177 &header_stream_offset));
8178 mock_quic_data.AddRead(ASYNC,
8179 ConstructServerPushPromisePacket(
8180 5, client_stream_0, push_stream_1, false,
8181 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8182 &server_header_offset, &server_maker_));
8183 mock_quic_data.AddWrite(
8184 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238185 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8186 DEFAULT_PRIORITY, &header_stream_offset));
8187
8188 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438189 mock_quic_data.AddRead(
8190 ASYNC, ConstructServerResponseHeadersPacket(
8191 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8192 &server_header_offset));
8193 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8194 mock_quic_data.AddRead(
8195 ASYNC, ConstructServerResponseHeadersPacket(
8196 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8197 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238198
8199 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8200 // priority updates to match the request's priority. Client sends PRIORITY
8201 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438202 mock_quic_data.AddWrite(
8203 SYNCHRONOUS,
8204 ConstructClientAckAndPriorityFramesPacket(
8205 9, false, 7, 7, 1,
8206 {{push_stream_1, client_stream_2,
8207 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8208 {push_stream_0, client_stream_0,
8209 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8210 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238211
8212 // Server sends data for the three requests and the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438213 mock_quic_data.AddRead(
8214 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
8215 "hello 0!"));
8216 mock_quic_data.AddRead(
8217 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
8218 "hello 1!"));
8219 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8220 mock_quic_data.AddRead(
8221 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
8222 "hello 2!"));
8223 mock_quic_data.AddRead(
8224 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
8225 "and hello 0!"));
8226 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8227 mock_quic_data.AddRead(
8228 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
8229 "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238230
Zhongyi Shi32f2fd02018-04-16 18:23:438231 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528232 SYNCHRONOUS,
8233 ConstructClientAckAndRstPacket(
8234 12, push_stream_0, quic::QUIC_RST_ACKNOWLEDGEMENT, 12, 12, 1));
Yixin Wang385652a2018-02-16 02:37:238235
8236 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8237 mock_quic_data.AddRead(ASYNC, 0); // EOF
8238 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8239
8240 // The non-alternate protocol job needs to hang in order to guarantee that
8241 // the alternate-protocol job will "win".
8242 AddHangingNonAlternateProtocolSocketData();
8243
8244 CreateSession();
8245
8246 request_.url = GURL("https://mail.example.org/0.jpg");
8247 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8248 TestCompletionCallback callback_0;
8249 EXPECT_EQ(ERR_IO_PENDING,
8250 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8251 base::RunLoop().RunUntilIdle();
8252
8253 request_.url = GURL("https://mail.example.org/1.jpg");
8254 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8255 TestCompletionCallback callback_1;
8256 EXPECT_EQ(ERR_IO_PENDING,
8257 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8258 base::RunLoop().RunUntilIdle();
8259
8260 request_.url = GURL("https://mail.example.org/2.jpg");
8261 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8262 TestCompletionCallback callback_2;
8263 EXPECT_EQ(ERR_IO_PENDING,
8264 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8265 base::RunLoop().RunUntilIdle();
8266
8267 // Client makes request that matches resource pushed in |pushed_stream_0|.
8268 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8269 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8270 TestCompletionCallback callback_3;
8271 EXPECT_EQ(ERR_IO_PENDING,
8272 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8273 base::RunLoop().RunUntilIdle();
8274
8275 EXPECT_TRUE(callback_0.have_result());
8276 EXPECT_EQ(OK, callback_0.WaitForResult());
8277 EXPECT_TRUE(callback_1.have_result());
8278 EXPECT_EQ(OK, callback_1.WaitForResult());
8279 EXPECT_TRUE(callback_2.have_result());
8280 EXPECT_EQ(OK, callback_2.WaitForResult());
8281
8282 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8283 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8284 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8285 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8286
8287 mock_quic_data.Resume();
8288 base::RunLoop().RunUntilIdle();
8289 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8290 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8291}
8292
[email protected]61a527782013-02-21 03:58:008293} // namespace test
8294} // namespace net