blob: fae3d65c905c10f600b090b1197d020c2c336795 [file] [log] [blame]
[email protected]61a527782013-02-21 03:58:001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rchbd089ab2017-05-26 23:05:045#include <algorithm>
bnc359ed2a2016-04-29 20:43:456#include <ostream>
bnc912a04b2016-04-20 14:19:507#include <string>
8#include <utility>
[email protected]1e960032013-12-20 19:00:209#include <vector>
10
[email protected]61a527782013-02-21 03:58:0011#include "base/compiler_specific.h"
Avi Drissman13fc8932015-12-20 04:40:4612#include "base/macros.h"
mmenke651bae7f2015-12-18 21:26:4513#include "base/run_loop.h"
[email protected]98b20ce2013-05-10 05:55:2614#include "base/stl_util.h"
zhongyie537a002017-06-27 16:48:2115#include "base/strings/string_number_conversions.h"
Bence Békyd74f4382018-02-20 18:26:1916#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0717#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4718#include "base/test/metrics/histogram_tester.h"
rtenneti56977812016-01-15 19:26:5619#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5820#include "net/base/completion_once_callback.h"
mgershaf9a9232017-04-13 20:19:0321#include "net/base/mock_network_change_notifier.h"
[email protected]61a527782013-02-21 03:58:0022#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0423#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2024#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1125#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1226#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5327#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0028#include "net/http/http_auth_handler_factory.h"
29#include "net/http/http_network_session.h"
30#include "net/http/http_network_transaction.h"
31#include "net/http/http_server_properties_impl.h"
32#include "net/http/http_stream.h"
33#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1934#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1135#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0036#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5137#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4638#include "net/log/test_net_log_entry.h"
39#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4040#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0341#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4042#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0843#include "net/quic/crypto/proof_verifier_chromium.h"
44#include "net/quic/mock_crypto_client_stream_factory.h"
45#include "net/quic/mock_quic_data.h"
46#include "net/quic/quic_chromium_alarm_factory.h"
47#include "net/quic/quic_http_stream.h"
48#include "net/quic/quic_http_utils.h"
49#include "net/quic/quic_stream_factory_peer.h"
50#include "net/quic/quic_test_packet_maker.h"
51#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0052#include "net/socket/client_socket_factory.h"
53#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2154#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2855#include "net/socket/socket_performance_watcher.h"
56#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0057#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5858#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5759#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2960#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0161#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4362#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0163#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1664#include "net/third_party/quic/core/crypto/quic_decrypter.h"
65#include "net/third_party/quic/core/crypto/quic_encrypter.h"
66#include "net/third_party/quic/core/quic_framer.h"
Ryan Hamilton47cf9d12018-10-17 04:33:0967#include "net/third_party/quic/core/quic_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1668#include "net/third_party/quic/platform/api/quic_str_cat.h"
69#include "net/third_party/quic/platform/api/quic_string_piece.h"
70#include "net/third_party/quic/platform/api/quic_test.h"
71#include "net/third_party/quic/test_tools/crypto_test_utils.h"
72#include "net/third_party/quic/test_tools/mock_clock.h"
73#include "net/third_party/quic/test_tools/mock_random.h"
74#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
75#include "net/third_party/quic/test_tools/quic_test_utils.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2976#include "net/third_party/spdy/core/spdy_frame_builder.h"
77#include "net/third_party/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2978#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
allada71b2efb2016-09-09 04:57:4879#include "net/url_request/url_request.h"
80#include "net/url_request/url_request_job_factory_impl.h"
81#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0182#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0083#include "testing/gtest/include/gtest/gtest.h"
84#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4685#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0086
Reilly Grant89a7e512018-01-20 01:57:1687using ::testing::ElementsAre;
88using ::testing::Key;
89
bnc508835902015-05-12 20:10:2990namespace net {
91namespace test {
[email protected]61a527782013-02-21 03:58:0092
93namespace {
94
bnc359ed2a2016-04-29 20:43:4595enum DestinationType {
96 // In pooling tests with two requests for different origins to the same
97 // destination, the destination should be
98 SAME_AS_FIRST, // the same as the first origin,
99 SAME_AS_SECOND, // the same as the second origin, or
100 DIFFERENT, // different from both.
101};
102
rchf114d982015-10-21 01:34:56103static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52104 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12105static const char kQuicAlternativeServiceWithProbabilityHeader[] =
106 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56107static const char kQuicAlternativeServiceDifferentPortHeader[] =
108 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20109
rch9ae5b3b2016-02-11 00:36:29110const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45111const char kDifferentHostname[] = "different.example.com";
112
113// Run QuicNetworkTransactionWithDestinationTest instances with all value
114// combinations of version and destination_type.
115struct PoolingTestParams {
116 friend std::ostream& operator<<(std::ostream& os,
117 const PoolingTestParams& p) {
118 os << "{ version: " << QuicVersionToString(p.version)
119 << ", destination_type: ";
120 switch (p.destination_type) {
121 case SAME_AS_FIRST:
122 os << "SAME_AS_FIRST";
123 break;
124 case SAME_AS_SECOND:
125 os << "SAME_AS_SECOND";
126 break;
127 case DIFFERENT:
128 os << "DIFFERENT";
129 break;
130 }
Yixin Wang079ad542018-01-11 04:06:05131 os << ", client_headers_include_h2_stream_dependency: "
132 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45133 os << " }";
134 return os;
135 }
136
Ryan Hamilton8d9ee76e2018-05-29 23:52:52137 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45138 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05139 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45140};
141
zhongyie537a002017-06-27 16:48:21142std::string GenerateQuicVersionsListForAltSvcHeader(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52143 const quic::QuicTransportVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21144 std::string result = "";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52145 for (const quic::QuicTransportVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21146 if (!result.empty())
147 result.append(",");
148 result.append(base::IntToString(version));
149 }
150 return result;
151}
152
bnc359ed2a2016-04-29 20:43:45153std::vector<PoolingTestParams> GetPoolingTestParams() {
154 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52155 quic::QuicTransportVersionVector all_supported_versions =
156 quic::AllSupportedTransportVersions();
157 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05158 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
159 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
160 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
161 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
162 params.push_back(PoolingTestParams{version, DIFFERENT, false});
163 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45164 }
165 return params;
166}
bncb07c05532015-05-14 19:07:20167
[email protected]61a527782013-02-21 03:58:00168} // namespace
169
ryansturm49a8cb12016-06-15 16:51:09170class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12171 public:
ryansturm49a8cb12016-06-15 16:51:09172 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12173
ryansturm49a8cb12016-06-15 16:51:09174 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12175
ryansturm49a8cb12016-06-15 16:51:09176 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
177 HttpRequestHeaders* request_headers) {
178 if (!proxy_info.is_http() && !proxy_info.is_https() &&
179 !proxy_info.is_quic()) {
180 return;
181 }
182 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12183 }
184
185 private:
ryansturm49a8cb12016-06-15 16:51:09186 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12187};
188
tbansal0f56a39a2016-04-07 22:03:38189class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40190 public:
tbansal180587c2017-02-16 15:13:23191 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
192 bool* rtt_notification_received)
193 : should_notify_updated_rtt_(should_notify_updated_rtt),
194 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38195 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40196
tbansal180587c2017-02-16 15:13:23197 bool ShouldNotifyUpdatedRTT() const override {
198 return *should_notify_updated_rtt_;
199 }
tbansalfdf5665b2015-09-21 22:46:40200
tbansal0f56a39a2016-04-07 22:03:38201 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
202 *rtt_notification_received_ = true;
203 }
204
205 void OnConnectionChanged() override {}
206
207 private:
tbansal180587c2017-02-16 15:13:23208 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38209 bool* rtt_notification_received_;
210
211 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
212};
213
214class TestSocketPerformanceWatcherFactory
215 : public SocketPerformanceWatcherFactory {
216 public:
217 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23218 : watcher_count_(0u),
219 should_notify_updated_rtt_(true),
220 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38221 ~TestSocketPerformanceWatcherFactory() override {}
222
223 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42224 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41225 const Protocol protocol,
226 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51227 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38228 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51229 }
230 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42231 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23232 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
233 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40234 }
235
tbansalc8a94ea2015-11-02 23:58:51236 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40237
tbansalc8a94ea2015-11-02 23:58:51238 bool rtt_notification_received() const { return rtt_notification_received_; }
239
tbansal180587c2017-02-16 15:13:23240 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
241 should_notify_updated_rtt_ = should_notify_updated_rtt;
242 }
243
tbansalc8a94ea2015-11-02 23:58:51244 private:
tbansal0f56a39a2016-04-07 22:03:38245 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23246 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51247 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38248
249 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51250};
251
Ryan Hamilton8d9ee76e2018-05-29 23:52:52252class QuicNetworkTransactionTest
253 : public PlatformTest,
254 public ::testing::WithParamInterface<
255 std::tuple<quic::QuicTransportVersion, bool>>,
256 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00257 protected:
[email protected]1c04f9522013-02-21 20:32:43258 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05259 : version_(std::get<0>(GetParam())),
260 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52261 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc90be5dd782016-11-09 16:28:44262 client_maker_(version_,
Fan Yang32c5a112018-12-10 20:06:33263 quic::EmptyQuicConnectionId(),
rchbf4c26d2017-04-16 23:17:55264 &clock_,
alyssar2adf3ac2016-05-03 17:12:58265 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52266 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05267 client_headers_include_h2_stream_dependency_),
bnc90be5dd782016-11-09 16:28:44268 server_maker_(version_,
Fan Yang32c5a112018-12-10 20:06:33269 quic::EmptyQuicConnectionId(),
rchbf4c26d2017-04-16 23:17:55270 &clock_,
alyssar2adf3ac2016-05-03 17:12:58271 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52272 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05273 false),
rtenneti052774e2015-11-24 21:00:12274 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43275 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59276 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
[email protected]1c04f9522013-02-21 20:32:43277 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30278 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
[email protected]457d6952013-12-13 09:24:58279 random_generator_(0),
rchf114d982015-10-21 01:34:56280 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19281 request_.method = "GET";
rchf114d982015-10-21 01:34:56282 std::string url("https://");
bncb07c05532015-05-14 19:07:20283 url.append(kDefaultServerHostName);
284 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19285 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10286 request_.traffic_annotation =
287 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52288 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56289
290 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29291 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56292 verify_details_.cert_verify_result.verified_cert = cert;
293 verify_details_.cert_verify_result.is_issued_by_known_root = true;
294 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43295 }
[email protected]61a527782013-02-21 03:58:00296
dcheng67be2b1f2014-10-27 21:47:29297 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00298 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55299 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00300 }
301
dcheng67be2b1f2014-10-27 21:47:29302 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00303 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
304 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55305 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00306 PlatformTest::TearDown();
307 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55308 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40309 session_.reset();
[email protected]61a527782013-02-21 03:58:00310 }
311
Ryan Hamilton8d9ee76e2018-05-29 23:52:52312 std::unique_ptr<quic::QuicEncryptedPacket>
313 ConstructClientConnectionClosePacket(quic::QuicPacketNumber num) {
Bin Wu5311aca2018-01-22 01:19:03314 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52315 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30316 }
317
Ryan Hamilton8d9ee76e2018-05-29 23:52:52318 std::unique_ptr<quic::QuicEncryptedPacket>
319 ConstructServerConnectionClosePacket(quic::QuicPacketNumber num) {
Bin Wu5311aca2018-01-22 01:19:03320 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52321 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58322 }
323
Ryan Hamilton8d9ee76e2018-05-29 23:52:52324 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
325 quic::QuicPacketNumber num,
326 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20327 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58328 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20329 }
330
Ryan Hamilton8d9ee76e2018-05-29 23:52:52331 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
332 quic::QuicPacketNumber packet_number,
333 quic::QuicPacketNumber largest_received,
334 quic::QuicPacketNumber smallest_received,
335 quic::QuicPacketNumber least_unacked) {
fayang3bcb8b502016-12-07 21:44:37336 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49337 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37338 }
339
Ryan Hamilton8d9ee76e2018-05-29 23:52:52340 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
341 quic::QuicPacketNumber packet_number,
342 quic::QuicPacketNumber largest_received,
343 quic::QuicPacketNumber smallest_received,
344 quic::QuicPacketNumber least_unacked,
345 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23346 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49347 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23348 ack_delay_time);
349 }
350
Ryan Hamilton8d9ee76e2018-05-29 23:52:52351 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
352 quic::QuicPacketNumber num,
353 quic::QuicStreamId stream_id,
354 quic::QuicRstStreamErrorCode error_code,
355 quic::QuicPacketNumber largest_received,
356 quic::QuicPacketNumber smallest_received,
357 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58358 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49359 num, false, stream_id, error_code, largest_received, smallest_received,
360 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20361 }
362
Ryan Hamilton8d9ee76e2018-05-29 23:52:52363 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
364 quic::QuicPacketNumber num,
365 quic::QuicStreamId stream_id,
366 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56367 size_t bytes_written) {
368 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
369 bytes_written);
370 }
371
Ryan Hamilton8d9ee76e2018-05-29 23:52:52372 std::unique_ptr<quic::QuicEncryptedPacket>
373 ConstructClientAckAndConnectionClosePacket(
374 quic::QuicPacketNumber packet_number,
375 quic::QuicPacketNumber largest_received,
376 quic::QuicPacketNumber smallest_received,
377 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58378 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49379 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20380 }
[email protected]61a527782013-02-21 03:58:00381
Ryan Hamilton8d9ee76e2018-05-29 23:52:52382 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58383 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 quic::QuicPacketNumber num,
385 quic::QuicTime::Delta delta_time_largest_observed,
386 quic::QuicPacketNumber largest_received,
387 quic::QuicPacketNumber smallest_received,
388 quic::QuicPacketNumber least_unacked,
389 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50390 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58391 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12392 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49393 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12394 }
395
Ryan Hamilton8d9ee76e2018-05-29 23:52:52396 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
397 quic::QuicPacketNumber num,
zhongyica364fbb2015-12-12 03:39:12398 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52399 quic::QuicStreamId stream_id,
400 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58401 return server_maker_.MakeRstPacket(num, include_version, stream_id,
402 error_code);
zhongyica364fbb2015-12-12 03:39:12403 }
404
Ryan Hamilton8d9ee76e2018-05-29 23:52:52405 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
406 quic::QuicPacketNumber packet_number,
407 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36408 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37409 }
410
Ryan Hamilton8d9ee76e2018-05-29 23:52:52411 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
412 quic::QuicPacketNumber packet_number,
413 quic::QuicPacketNumber largest_received,
414 quic::QuicPacketNumber smallest_received,
415 quic::QuicPacketNumber least_unacked) {
fayang3bcb8b502016-12-07 21:44:37416 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49417 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37418 }
419
Ryan Hamilton8d9ee76e2018-05-29 23:52:52420 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
421 quic::QuicPacketNumber packet_number,
Yixin Wangb470bc882018-02-15 18:43:57422 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 quic::QuicStreamId id,
424 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57425 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52426 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57427 return client_maker_.MakePriorityPacket(
428 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23429 ConvertRequestPriorityToQuicPriority(request_priority), offset);
430 }
431
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25433 ConstructClientAckAndPriorityFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52434 quic::QuicPacketNumber packet_number,
Yixin Wang385652a2018-02-16 02:37:23435 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52436 quic::QuicPacketNumber largest_received,
437 quic::QuicPacketNumber smallest_received,
438 quic::QuicPacketNumber least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25439 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
440 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52441 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25442 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23443 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25444 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57445 }
446
zhongyi32569c62016-01-08 02:54:30447 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13448 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
449 const std::string& scheme,
450 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58451 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30452 }
453
454 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13455 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
456 const std::string& scheme,
457 const std::string& path,
458 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50459 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00460 }
461
Ryan Hamilton0239aac2018-05-19 00:03:13462 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56463 return client_maker_.ConnectRequestHeaders(host_port);
464 }
465
Ryan Hamilton0239aac2018-05-19 00:03:13466 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58467 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00468 }
469
zhongyi32569c62016-01-08 02:54:30470 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13471 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
472 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58473 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30474 }
475
Ryan Hamilton8d9ee76e2018-05-29 23:52:52476 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
477 quic::QuicPacketNumber packet_number,
478 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05479 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00480 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52481 quic::QuicStreamOffset offset,
482 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58483 return server_maker_.MakeDataPacket(
484 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00485 }
486
Ryan Hamilton8d9ee76e2018-05-29 23:52:52487 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
488 quic::QuicPacketNumber packet_number,
489 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36490 bool should_include_version,
491 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52492 quic::QuicStreamOffset offset,
493 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36494 return client_maker_.MakeDataPacket(
495 packet_number, stream_id, should_include_version, fin, offset, data);
496 }
497
Renjied172e812019-01-16 05:12:35498 std::unique_ptr<quic::QuicEncryptedPacket>
499 ConstructClientMultipleDataFramesPacket(
500 quic::QuicPacketNumber packet_number,
501 quic::QuicStreamId stream_id,
502 bool should_include_version,
503 bool fin,
504 quic::QuicStreamOffset offset,
505 const std::vector<std::string> data_writes) {
506 return client_maker_.MakeMultipleDataFramesPacket(packet_number, stream_id,
507 should_include_version,
508 fin, offset, data_writes);
509 }
510
Ryan Hamilton8d9ee76e2018-05-29 23:52:52511 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
512 quic::QuicPacketNumber packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56513 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52514 quic::QuicStreamId stream_id,
515 quic::QuicPacketNumber largest_received,
516 quic::QuicPacketNumber smallest_received,
517 quic::QuicPacketNumber least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56518 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52519 quic::QuicStreamOffset offset,
520 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56521 return client_maker_.MakeAckAndDataPacket(
522 packet_number, include_version, stream_id, largest_received,
523 smallest_received, least_unacked, fin, offset, data);
524 }
525
Renjied172e812019-01-16 05:12:35526 std::unique_ptr<quic::QuicEncryptedPacket>
527 ConstructClientAckAndMultipleDataFramesPacket(
528 quic::QuicPacketNumber packet_number,
529 bool include_version,
530 quic::QuicStreamId stream_id,
531 quic::QuicPacketNumber largest_received,
532 quic::QuicPacketNumber smallest_received,
533 quic::QuicPacketNumber least_unacked,
534 bool fin,
535 quic::QuicStreamOffset offset,
536 const std::vector<std::string> data_writes) {
537 return client_maker_.MakeAckAndMultipleDataFramesPacket(
538 packet_number, include_version, stream_id, largest_received,
539 smallest_received, least_unacked, fin, offset, data_writes);
540 }
541
Ryan Hamilton8d9ee76e2018-05-29 23:52:52542 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
543 quic::QuicPacketNumber packet_number,
544 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36545 bool should_include_version,
546 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 quic::QuicStreamOffset* offset,
548 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36549 return client_maker_.MakeForceHolDataPacket(
550 packet_number, stream_id, should_include_version, fin, offset, data);
551 }
552
Ryan Hamilton8d9ee76e2018-05-29 23:52:52553 std::unique_ptr<quic::QuicEncryptedPacket>
554 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
555 quic::QuicStreamId stream_id,
556 bool should_include_version,
557 bool fin,
558 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56559 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
560 should_include_version, fin,
561 std::move(headers), nullptr);
562 }
563
Ryan Hamilton8d9ee76e2018-05-29 23:52:52564 std::unique_ptr<quic::QuicEncryptedPacket>
565 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
566 quic::QuicStreamId stream_id,
567 bool should_include_version,
568 bool fin,
569 spdy::SpdyHeaderBlock headers,
570 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48571 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
572 should_include_version, fin,
573 std::move(headers), 0, offset);
574 }
575
Ryan Hamilton8d9ee76e2018-05-29 23:52:52576 std::unique_ptr<quic::QuicEncryptedPacket>
577 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
578 quic::QuicStreamId stream_id,
579 bool should_include_version,
580 bool fin,
581 spdy::SpdyHeaderBlock headers,
582 quic::QuicStreamId parent_stream_id,
583 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56584 return ConstructClientRequestHeadersPacket(
585 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48586 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30587 }
588
Ryan Hamilton8d9ee76e2018-05-29 23:52:52589 std::unique_ptr<quic::QuicEncryptedPacket>
590 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
591 quic::QuicStreamId stream_id,
592 bool should_include_version,
593 bool fin,
594 RequestPriority request_priority,
595 spdy::SpdyHeaderBlock headers,
596 quic::QuicStreamId parent_stream_id,
597 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13598 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56599 ConvertRequestPriorityToQuicPriority(request_priority);
600 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
601 packet_number, stream_id, should_include_version, fin, priority,
602 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00603 }
604
Ryan Hamilton8d9ee76e2018-05-29 23:52:52605 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25606 ConstructClientRequestHeadersAndDataFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52607 quic::QuicPacketNumber packet_number,
608 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25609 bool should_include_version,
610 bool fin,
611 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13612 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52613 quic::QuicStreamId parent_stream_id,
614 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25615 size_t* spdy_headers_frame_length,
616 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13617 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25618 ConvertRequestPriorityToQuicPriority(request_priority);
619 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
620 packet_number, stream_id, should_include_version, fin, priority,
621 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
622 data_writes);
623 }
624
Ryan Hamilton8d9ee76e2018-05-29 23:52:52625 std::unique_ptr<quic::QuicEncryptedPacket>
626 ConstructClientMultipleDataFramesPacket(quic::QuicPacketNumber packet_number,
627 quic::QuicStreamId stream_id,
628 bool should_include_version,
629 bool fin,
630 const std::vector<std::string>& data,
631 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27632 return client_maker_.MakeMultipleDataFramesPacket(
633 packet_number, stream_id, should_include_version, fin, offset, data);
634 }
635
Ryan Hamilton8d9ee76e2018-05-29 23:52:52636 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
637 quic::QuicPacketNumber packet_number,
638 quic::QuicStreamId stream_id,
639 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13640 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13641 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52642 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13643 QuicTestPacketMaker* maker) {
644 return maker->MakePushPromisePacket(
645 packet_number, stream_id, promised_stream_id, should_include_version,
646 false, std::move(headers), nullptr, offset);
647 }
648
Ryan Hamilton8d9ee76e2018-05-29 23:52:52649 std::unique_ptr<quic::QuicEncryptedPacket>
650 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
651 quic::QuicStreamId stream_id,
652 bool should_include_version,
653 bool fin,
654 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27655 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
656 should_include_version, fin,
657 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30658 }
659
Ryan Hamilton8d9ee76e2018-05-29 23:52:52660 std::unique_ptr<quic::QuicEncryptedPacket>
661 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
662 quic::QuicStreamId stream_id,
663 bool should_include_version,
664 bool fin,
665 spdy::SpdyHeaderBlock headers,
666 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58667 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25668 packet_number, stream_id, should_include_version, fin,
669 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30670 }
671
Renjief49758b2019-01-11 23:32:41672 quic::QuicString ConstructDataHeader(size_t body_len) {
673 if (version_ != quic::QUIC_VERSION_99) {
674 return "";
675 }
676 quic::HttpEncoder encoder;
677 std::unique_ptr<char[]> buffer;
678 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
679 return quic::QuicString(buffer.get(), header_length);
680 }
681
Ryan Hamilton8d9ee76e2018-05-29 23:52:52682 void CreateSession(
683 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41684 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21685 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05686 session_params_.quic_headers_include_h2_stream_dependency =
687 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00688
mmenke6ddfbea2017-05-31 21:48:41689 session_context_.quic_clock = &clock_;
690 session_context_.quic_random = &random_generator_;
691 session_context_.client_socket_factory = &socket_factory_;
692 session_context_.quic_crypto_client_stream_factory =
693 &crypto_client_stream_factory_;
694 session_context_.host_resolver = &host_resolver_;
695 session_context_.cert_verifier = &cert_verifier_;
696 session_context_.transport_security_state = &transport_security_state_;
697 session_context_.cert_transparency_verifier =
698 cert_transparency_verifier_.get();
699 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
700 session_context_.socket_performance_watcher_factory =
701 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59702 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41703 session_context_.ssl_config_service = ssl_config_service_.get();
704 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
705 session_context_.http_server_properties = &http_server_properties_;
706 session_context_.net_log = net_log_.bound().net_log();
707
708 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12709 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56710 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
711 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00712 }
713
zhongyi86838d52017-06-30 01:19:44714 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21715
bnc691fda62016-08-12 00:43:16716 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19717 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42718 ASSERT_TRUE(response != nullptr);
719 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19720 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
721 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52722 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44723 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19724 response->connection_info);
725 }
726
bnc691fda62016-08-12 00:43:16727 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41728 const HttpResponseInfo* response = trans->GetResponseInfo();
729 ASSERT_TRUE(response != nullptr);
730 EXPECT_EQ(port, response->socket_address.port());
731 }
732
bnc691fda62016-08-12 00:43:16733 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19734 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42735 ASSERT_TRUE(response != nullptr);
736 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19737 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
738 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52739 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52740 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19741 response->connection_info);
742 }
743
Yixin Wang46a273ec302018-01-23 17:59:56744 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
745 const HttpResponseInfo* response = trans->GetResponseInfo();
746 ASSERT_TRUE(response != nullptr);
747 ASSERT_TRUE(response->headers.get() != nullptr);
748 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
749 EXPECT_TRUE(response->was_fetched_via_spdy);
750 EXPECT_TRUE(response->was_alpn_negotiated);
751 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
752 response->connection_info);
753 }
754
bnc691fda62016-08-12 00:43:16755 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19756 const std::string& expected) {
757 std::string response_data;
bnc691fda62016-08-12 00:43:16758 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19759 EXPECT_EQ(expected, response_data);
760 }
761
bnc691fda62016-08-12 00:43:16762 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19763 TestCompletionCallback callback;
764 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01765 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
766 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19767 }
768
769 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16770 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
771 RunTransaction(&trans);
772 CheckWasHttpResponse(&trans);
773 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19774 }
775
tbansalc3308d72016-08-27 10:25:04776 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
777 bool used_proxy,
778 uint16_t port) {
779 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
780 HeadersHandler headers_handler;
781 trans.SetBeforeHeadersSentCallback(
782 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
783 base::Unretained(&headers_handler)));
784 RunTransaction(&trans);
785 CheckWasHttpResponse(&trans);
786 CheckResponsePort(&trans, port);
787 CheckResponseData(&trans, expected);
788 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47789 if (used_proxy) {
790 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
791 } else {
792 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
793 }
tbansalc3308d72016-08-27 10:25:04794 }
795
[email protected]aa9b14d2013-05-10 23:45:19796 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56797 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12798 }
799
bnc62a44f022015-04-02 15:59:41800 void SendRequestAndExpectQuicResponseFromProxyOnPort(
801 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46802 uint16_t port) {
bnc62a44f022015-04-02 15:59:41803 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19804 }
805
806 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27807 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19808 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46809 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21810 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12811 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21812 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44813 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19814 }
815
rchbe69cb902016-02-11 01:10:48816 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27817 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48818 const HostPortPair& alternative) {
819 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46820 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21821 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48822 alternative.port());
823 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21824 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44825 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48826 }
827
[email protected]aa9b14d2013-05-10 23:45:19828 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46829 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34830 const AlternativeServiceInfoVector alternative_service_info_vector =
831 http_server_properties_.GetAlternativeServiceInfos(server);
832 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07833 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54834 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19835 }
836
[email protected]4d590c9c2014-05-02 05:14:33837 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46838 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34839 const AlternativeServiceInfoVector alternative_service_info_vector =
840 http_server_properties_.GetAlternativeServiceInfos(server);
841 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54842 EXPECT_EQ(
843 kProtoQUIC,
844 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23845 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54846 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33847 }
848
[email protected]aa9b14d2013-05-10 23:45:19849 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42850 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30851 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30852 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30853 hanging_data->set_connect_data(hanging_connect);
854 hanging_data_.push_back(std::move(hanging_data));
855 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56856 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19857 }
858
Zhongyi Shia6b68d112018-09-24 07:49:03859 void SetUpTestForRetryConnectionOnAlternateNetwork() {
860 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
861 session_params_.quic_migrate_sessions_early_v2 = true;
862 session_params_.quic_retry_on_alternate_network_before_handshake = true;
863 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
864 MockNetworkChangeNotifier* mock_ncn =
865 scoped_mock_change_notifier_->mock_network_change_notifier();
866 mock_ncn->ForceNetworkHandlesSupported();
867 mock_ncn->SetConnectedNetworksList(
868 {kDefaultNetworkForTests, kNewNetworkForTests});
869 }
870
tbansalc3308d72016-08-27 10:25:04871 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
872 // alternative proxy. Verifies that if the alternative proxy job returns
873 // |error_code|, the request is fetched successfully by the main job.
874 void TestAlternativeProxy(int error_code) {
875 // Use a non-cryptographic scheme for the request URL since this request
876 // will be fetched via proxy with QUIC as the alternative service.
877 request_.url = GURL("http://example.org/");
878 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27879 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04880 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27881 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04882 };
883
Ryan Sleevib8d7ea02018-05-07 20:01:01884 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04885 socket_factory_.AddSocketDataProvider(&quic_data);
886
887 // Main job succeeds and the alternative job fails.
888 // Add data for two requests that will be read by the main job.
889 MockRead http_reads_1[] = {
890 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
891 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
892 MockRead(ASYNC, OK)};
893
894 MockRead http_reads_2[] = {
895 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
896 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
897 MockRead(ASYNC, OK)};
898
Ryan Sleevib8d7ea02018-05-07 20:01:01899 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
900 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04901 socket_factory_.AddSocketDataProvider(&http_data_1);
902 socket_factory_.AddSocketDataProvider(&http_data_2);
903 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
904 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
905
906 TestProxyDelegate test_proxy_delegate;
907 // Proxy URL is different from the request URL.
908 test_proxy_delegate.set_alternative_proxy_server(
909 ProxyServer::FromPacString("QUIC myproxy.org:443"));
910
Lily Houghton8c2f97d2018-01-22 05:06:59911 proxy_resolution_service_ =
912 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49913 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52914 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04915
916 CreateSession();
917 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
918
919 // The first request should be fetched via the HTTPS proxy.
920 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
921
Reilly Grant89a7e512018-01-20 01:57:16922 // Since the main job succeeded only the alternative proxy server should be
923 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59924 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16925 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04926
927 // Verify that the second request completes successfully, and the
928 // alternative proxy server job is not started.
929 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
930 }
931
Fan Yang32c5a112018-12-10 20:06:33932 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
933 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36934 }
935
Fan Yang32c5a112018-12-10 20:06:33936 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
937 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36938 }
939
Bence Béky230ac612017-08-30 19:17:08940 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49941 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08942 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49943 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08944 }
945
Ryan Hamilton8d9ee76e2018-05-29 23:52:52946 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05947 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52948 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01949 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52950 quic::MockClock clock_;
alyssar2adf3ac2016-05-03 17:12:58951 QuicTestPacketMaker client_maker_;
952 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42953 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00954 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56955 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05956 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43957 MockHostResolver host_resolver_;
958 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11959 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42960 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23961 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38962 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07963 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59964 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42965 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52966 quic::test::MockRandom random_generator_;
bnc6be245c12015-05-15 11:24:07967 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41968 HttpNetworkSession::Params session_params_;
969 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19970 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51971 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42972 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56973 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03974 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12975
976 private:
977 void SendRequestAndExpectQuicResponseMaybeFromProxy(
978 const std::string& expected,
bnc62a44f022015-04-02 15:59:41979 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46980 uint16_t port) {
bnc691fda62016-08-12 00:43:16981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09982 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16983 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09984 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
985 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16986 RunTransaction(&trans);
987 CheckWasQuicResponse(&trans);
988 CheckResponsePort(&trans, port);
989 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09990 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47991 if (used_proxy) {
992 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
993 } else {
994 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
995 }
tbansal7cec3812015-02-05 21:25:12996 }
[email protected]61a527782013-02-21 03:58:00997};
998
Yixin Wang079ad542018-01-11 04:06:05999INSTANTIATE_TEST_CASE_P(
Yixin Wang385652a2018-02-16 02:37:231000 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051001 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521002 ::testing::Combine(
1003 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1004 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201005
Ryan Hamiltona64a5bcf2017-11-30 07:35:281006TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481007 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281008 base::HistogramTester histograms;
1009 session_params_.origins_to_force_quic_on.insert(
1010 HostPortPair::FromString("mail.example.org:443"));
1011 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271012 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281013
1014 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521015 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281016 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431017 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281018 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1019 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1020 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1021
1022 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1023
1024 CreateSession();
1025
1026 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1027 TestCompletionCallback callback;
1028 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1029 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1030 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1031
1032 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1033 -ERR_INTERNET_DISCONNECTED, 1);
1034 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1035 -ERR_INTERNET_DISCONNECTED, 1);
1036}
1037
1038TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481039 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281040 base::HistogramTester histograms;
1041 session_params_.origins_to_force_quic_on.insert(
1042 HostPortPair::FromString("mail.example.org:443"));
1043 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271044 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281045
1046 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521047 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281048 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431049 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281050 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1051 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1052 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1053
1054 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1055
1056 CreateSession();
1057
1058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1059 TestCompletionCallback callback;
1060 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1062 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1063
1064 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1065 -ERR_INTERNET_DISCONNECTED, 1);
1066 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1067 -ERR_INTERNET_DISCONNECTED, 1);
1068}
1069
tbansal180587c2017-02-16 15:13:231070TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411071 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231072 HostPortPair::FromString("mail.example.org:443"));
1073
1074 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521075 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361076 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431077 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1078 mock_quic_data.AddWrite(
1079 SYNCHRONOUS,
1080 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331081 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431082 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431083 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331084 ASYNC, ConstructServerResponseHeadersPacket(
1085 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1086 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411087 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331088 mock_quic_data.AddRead(
1089 ASYNC, ConstructServerDataPacket(
1090 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411091 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431092 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231093 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1094
1095 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1096
1097 CreateSession();
1098 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1099
1100 EXPECT_FALSE(
1101 test_socket_performance_watcher_factory_.rtt_notification_received());
1102 SendRequestAndExpectQuicResponse("hello!");
1103 EXPECT_TRUE(
1104 test_socket_performance_watcher_factory_.rtt_notification_received());
1105}
1106
1107TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411108 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231109 HostPortPair::FromString("mail.example.org:443"));
1110
1111 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521112 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361113 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431114 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1115 mock_quic_data.AddWrite(
1116 SYNCHRONOUS,
1117 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331118 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431119 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431120 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331121 ASYNC, ConstructServerResponseHeadersPacket(
1122 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1123 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411124 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331125 mock_quic_data.AddRead(
1126 ASYNC, ConstructServerDataPacket(
1127 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411128 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431129 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231130 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1131
1132 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1133
1134 CreateSession();
1135 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1136
1137 EXPECT_FALSE(
1138 test_socket_performance_watcher_factory_.rtt_notification_received());
1139 SendRequestAndExpectQuicResponse("hello!");
1140 EXPECT_FALSE(
1141 test_socket_performance_watcher_factory_.rtt_notification_received());
1142}
1143
[email protected]1e960032013-12-20 19:00:201144TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411145 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571146 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471147
[email protected]1e960032013-12-20 19:00:201148 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521149 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361150 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431151 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1152 mock_quic_data.AddWrite(
1153 SYNCHRONOUS,
1154 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331155 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431156 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431157 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331158 ASYNC, ConstructServerResponseHeadersPacket(
1159 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1160 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411161 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331162 mock_quic_data.AddRead(
1163 ASYNC, ConstructServerDataPacket(
1164 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411165 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431166 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591167 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471168
rcha5399e02015-04-21 19:32:041169 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471170
[email protected]4dca587c2013-03-07 16:54:471171 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471172
[email protected]aa9b14d2013-05-10 23:45:191173 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471174
[email protected]98b20ce2013-05-10 05:55:261175 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461176 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191177 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261178 EXPECT_LT(0u, entries.size());
1179
1180 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291181 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001182 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1183 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261184 EXPECT_LT(0, pos);
1185
rchfd527212015-08-25 00:41:261186 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291187 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261188 entries, 0,
mikecirone8b85c432016-09-08 19:11:001189 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1190 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261191 EXPECT_LT(0, pos);
1192
Eric Romanaefc98c2018-12-18 21:38:011193 int packet_number;
1194 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1195 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261196
rchfd527212015-08-25 00:41:261197 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1198 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001199 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1200 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261201 EXPECT_LT(0, pos);
1202
[email protected]98b20ce2013-05-10 05:55:261203 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291204 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001205 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1206 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261207 EXPECT_LT(0, pos);
1208
1209 int log_stream_id;
1210 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381211 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1212 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471213}
1214
rchbd089ab2017-05-26 23:05:041215TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411216 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041217 HostPortPair::FromString("mail.example.org:443"));
1218
1219 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521220 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041221 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431222 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1223 mock_quic_data.AddWrite(
1224 SYNCHRONOUS,
1225 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331226 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431227 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131228 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041229 response_headers["key1"] = std::string(30000, 'A');
1230 response_headers["key2"] = std::string(30000, 'A');
1231 response_headers["key3"] = std::string(30000, 'A');
1232 response_headers["key4"] = std::string(30000, 'A');
1233 response_headers["key5"] = std::string(30000, 'A');
1234 response_headers["key6"] = std::string(30000, 'A');
1235 response_headers["key7"] = std::string(30000, 'A');
1236 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331237 spdy::SpdyHeadersIR headers_frame(
1238 GetNthClientInitiatedBidirectionalStreamId(0),
1239 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131240 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1241 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041242 response_framer.SerializeFrame(headers_frame);
1243
Ryan Hamilton8d9ee76e2018-05-29 23:52:521244 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041245 size_t chunk_size = 1200;
1246 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1247 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431248 mock_quic_data.AddRead(
1249 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091250 packet_number++,
1251 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521252 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041253 }
1254
Renjief49758b2019-01-11 23:32:411255 quic::QuicString header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041256 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331257 ASYNC, ConstructServerDataPacket(
1258 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411259 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041260 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431261 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1262 mock_quic_data.AddWrite(ASYNC,
1263 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041264
1265 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1266
1267 CreateSession();
1268
1269 SendRequestAndExpectQuicResponse("hello!");
1270}
1271
1272TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481273 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411274 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041275 HostPortPair::FromString("mail.example.org:443"));
1276
1277 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521278 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041279 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431280 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1281 mock_quic_data.AddWrite(
1282 SYNCHRONOUS,
1283 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331284 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431285 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131286 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041287 response_headers["key1"] = std::string(30000, 'A');
1288 response_headers["key2"] = std::string(30000, 'A');
1289 response_headers["key3"] = std::string(30000, 'A');
1290 response_headers["key4"] = std::string(30000, 'A');
1291 response_headers["key5"] = std::string(30000, 'A');
1292 response_headers["key6"] = std::string(30000, 'A');
1293 response_headers["key7"] = std::string(30000, 'A');
1294 response_headers["key8"] = std::string(30000, 'A');
1295 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331296 spdy::SpdyHeadersIR headers_frame(
1297 GetNthClientInitiatedBidirectionalStreamId(0),
1298 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131299 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1300 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041301 response_framer.SerializeFrame(headers_frame);
1302
Ryan Hamilton8d9ee76e2018-05-29 23:52:521303 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041304 size_t chunk_size = 1200;
1305 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1306 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431307 mock_quic_data.AddRead(
1308 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091309 packet_number++,
1310 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521311 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041312 }
1313
Renjief49758b2019-01-11 23:32:411314 quic::QuicString header = ConstructDataHeader(6);
1315
rchbd089ab2017-05-26 23:05:041316 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331317 ASYNC, ConstructServerDataPacket(
1318 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411319 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041320 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431321 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1322 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331323 ASYNC, ConstructClientAckAndRstPacket(
1324 4, GetNthClientInitiatedBidirectionalStreamId(0),
1325 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041326
1327 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1328
1329 CreateSession();
1330
1331 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1332 TestCompletionCallback callback;
1333 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1335 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1336}
1337
rcha2bd44b2016-07-02 00:42:551338TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411339 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551340
Ryan Hamilton9835e662018-08-02 05:36:271341 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551342
1343 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521344 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361345 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431346 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1347 mock_quic_data.AddWrite(
1348 SYNCHRONOUS,
1349 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331350 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431351 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431352 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331353 ASYNC, ConstructServerResponseHeadersPacket(
1354 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1355 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411356 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331357 mock_quic_data.AddRead(
1358 ASYNC, ConstructServerDataPacket(
1359 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411360 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431361 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551362 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1363
1364 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1365
1366 CreateSession();
1367
1368 SendRequestAndExpectQuicResponse("hello!");
1369 EXPECT_TRUE(
1370 test_socket_performance_watcher_factory_.rtt_notification_received());
1371}
1372
[email protected]cf3e3cd62014-02-05 16:16:161373TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411374 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591375 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491376 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161377
[email protected]cf3e3cd62014-02-05 16:16:161378 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521379 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361380 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431381 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1382 mock_quic_data.AddWrite(
1383 SYNCHRONOUS,
1384 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331385 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431386 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431387 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331388 ASYNC, ConstructServerResponseHeadersPacket(
1389 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1390 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411391 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331392 mock_quic_data.AddRead(
1393 ASYNC, ConstructServerDataPacket(
1394 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411395 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431396 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501397 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591398 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161399
rcha5399e02015-04-21 19:32:041400 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161401
tbansal0f56a39a2016-04-07 22:03:381402 EXPECT_FALSE(
1403 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161404 // There is no need to set up an alternate protocol job, because
1405 // no attempt will be made to speak to the proxy over TCP.
1406
rch9ae5b3b2016-02-11 00:36:291407 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161408 CreateSession();
1409
bnc62a44f022015-04-02 15:59:411410 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381411 EXPECT_TRUE(
1412 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161413}
1414
bnc313ba9c2015-06-11 15:42:311415// Regression test for https://crbug.com/492458. Test that for an HTTP
1416// connection through a QUIC proxy, the certificate exhibited by the proxy is
1417// checked against the proxy hostname, not the origin hostname.
1418TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291419 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311420 const std::string proxy_host = "www.example.org";
1421
mmenke6ddfbea2017-05-31 21:48:411422 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591423 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491424 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311425
alyssar2adf3ac2016-05-03 17:12:581426 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311427 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521428 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361429 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431430 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1431 mock_quic_data.AddWrite(
1432 SYNCHRONOUS,
1433 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331434 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431435 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431436 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331437 ASYNC, ConstructServerResponseHeadersPacket(
1438 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1439 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411440 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331441 mock_quic_data.AddRead(
1442 ASYNC, ConstructServerDataPacket(
1443 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411444 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431445 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501446 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591447 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311448 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1449
1450 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291451 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311452 ASSERT_TRUE(cert.get());
1453 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241454 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1455 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311456 ProofVerifyDetailsChromium verify_details;
1457 verify_details.cert_verify_result.verified_cert = cert;
1458 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561459 ProofVerifyDetailsChromium verify_details2;
1460 verify_details2.cert_verify_result.verified_cert = cert;
1461 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311462
1463 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091464 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321465 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271466 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311467 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1468}
1469
rchbe69cb902016-02-11 01:10:481470TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341471 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481472 HostPortPair origin("www.example.org", 443);
1473 HostPortPair alternative("mail.example.org", 443);
1474
1475 base::FilePath certs_dir = GetTestCertsDirectory();
1476 scoped_refptr<X509Certificate> cert(
1477 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1478 ASSERT_TRUE(cert.get());
1479 // TODO(rch): the connection should be "to" the origin, so if the cert is
1480 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241481 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1482 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481483 ProofVerifyDetailsChromium verify_details;
1484 verify_details.cert_verify_result.verified_cert = cert;
1485 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1486
alyssar2adf3ac2016-05-03 17:12:581487 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481488 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521489 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361490 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431491 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1492 mock_quic_data.AddWrite(
1493 SYNCHRONOUS,
1494 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331495 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431496 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431497 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331498 ASYNC, ConstructServerResponseHeadersPacket(
1499 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1500 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411501 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331502 mock_quic_data.AddRead(
1503 ASYNC, ConstructServerDataPacket(
1504 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411505 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431506 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481507 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1508 mock_quic_data.AddRead(ASYNC, 0);
1509 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1510
1511 request_.url = GURL("https://" + origin.host());
1512 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271513 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091514 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321515 CreateSession();
rchbe69cb902016-02-11 01:10:481516
1517 SendRequestAndExpectQuicResponse("hello!");
1518}
1519
zhongyief3f4ce52017-07-05 23:53:281520TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521521 quic::QuicTransportVersion unsupported_version =
1522 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281523 // Add support for another QUIC version besides |version_|. Also find a
1524 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521525 for (const quic::QuicTransportVersion& version :
1526 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281527 if (version == version_)
1528 continue;
1529 if (supported_versions_.size() != 2) {
1530 supported_versions_.push_back(version);
1531 continue;
1532 }
1533 unsupported_version = version;
1534 break;
1535 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521536 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281537
1538 // Set up alternative service to use QUIC with a version that is not
1539 // supported.
1540 url::SchemeHostPort server(request_.url);
1541 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1542 443);
1543 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1544 http_server_properties_.SetQuicAlternativeService(
1545 server, alternative_service, expiration, {unsupported_version});
1546
1547 AlternativeServiceInfoVector alt_svc_info_vector =
1548 http_server_properties_.GetAlternativeServiceInfos(server);
1549 EXPECT_EQ(1u, alt_svc_info_vector.size());
1550 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1551 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1552 EXPECT_EQ(unsupported_version,
1553 alt_svc_info_vector[0].advertised_versions()[0]);
1554
1555 // First request should still be sent via TCP as the QUIC version advertised
1556 // in the stored AlternativeService is not supported by the client. However,
1557 // the response from the server will advertise new Alt-Svc with supported
1558 // versions.
1559 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521560 GenerateQuicVersionsListForAltSvcHeader(
1561 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281562 std::string altsvc_header =
1563 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1564 advertised_versions_list_str.c_str());
1565 MockRead http_reads[] = {
1566 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1567 MockRead("hello world"),
1568 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1569 MockRead(ASYNC, OK)};
1570
Ryan Sleevib8d7ea02018-05-07 20:01:011571 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281572 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081573 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281574 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1575
1576 // Second request should be sent via QUIC as a new list of verions supported
1577 // by the client has been advertised by the server.
1578 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521579 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281580 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431581 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1582 mock_quic_data.AddWrite(
1583 SYNCHRONOUS,
1584 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331585 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431586 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431587 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331588 ASYNC, ConstructServerResponseHeadersPacket(
1589 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1590 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411591 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331592 mock_quic_data.AddRead(
1593 ASYNC, ConstructServerDataPacket(
1594 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411595 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431596 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281597 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1598 mock_quic_data.AddRead(ASYNC, 0); // EOF
1599
1600 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1601
1602 AddHangingNonAlternateProtocolSocketData();
1603
1604 CreateSession(supported_versions_);
1605
1606 SendRequestAndExpectHttpResponse("hello world");
1607 SendRequestAndExpectQuicResponse("hello!");
1608
1609 // Check alternative service list is updated with new versions.
1610 alt_svc_info_vector =
1611 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1612 EXPECT_EQ(1u, alt_svc_info_vector.size());
1613 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1614 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1615 // Advertised versions will be lised in a sorted order.
1616 std::sort(supported_versions_.begin(), supported_versions_.end());
1617 EXPECT_EQ(supported_versions_[0],
1618 alt_svc_info_vector[0].advertised_versions()[0]);
1619 EXPECT_EQ(supported_versions_[1],
1620 alt_svc_info_vector[0].advertised_versions()[1]);
1621}
1622
bncaccd4962017-04-06 21:00:261623// Regression test for https://crbug.com/546991.
1624// The server might not be able to serve a request on an alternative connection,
1625// and might send a 421 Misdirected Request response status to indicate this.
1626// HttpNetworkTransaction should reset the request and retry without using
1627// alternative services.
1628TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1629 // Set up alternative service to use QUIC.
1630 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1631 // that overrides |enable_alternative_services|.
1632 url::SchemeHostPort server(request_.url);
1633 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1634 443);
1635 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211636 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441637 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261638
davidbena4449722017-05-05 23:30:531639 // First try: The alternative job uses QUIC and reports an HTTP 421
1640 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1641 // paused at Connect(), so it will never exit the socket pool. This ensures
1642 // that the alternate job always wins the race and keeps whether the
1643 // |http_data| exits the socket pool before the main job is aborted
1644 // deterministic. The first main job gets aborted without the socket pool ever
1645 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261646 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521647 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361648 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431649 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1650 mock_quic_data.AddWrite(
1651 SYNCHRONOUS,
1652 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331653 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431654 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331655 mock_quic_data.AddRead(
1656 ASYNC, ConstructServerResponseHeadersPacket(
1657 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1658 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261659 mock_quic_data.AddRead(ASYNC, OK);
1660 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1661
davidbena4449722017-05-05 23:30:531662 // Second try: The main job uses TCP, and there is no alternate job. Once the
1663 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1664 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261665 // Note that if there was an alternative QUIC Job created for the second try,
1666 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1667 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531668 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1669 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1670 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1671 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1672 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1673 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011674 reads, writes);
bncaccd4962017-04-06 21:00:261675 socket_factory_.AddSocketDataProvider(&http_data);
1676 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1677
bncaccd4962017-04-06 21:00:261678 CreateSession();
1679 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531680
1681 // Run until |mock_quic_data| has failed and |http_data| has paused.
1682 TestCompletionCallback callback;
1683 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1684 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1685 base::RunLoop().RunUntilIdle();
1686
1687 // |mock_quic_data| must have run to completion.
1688 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1689 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1690
1691 // Now that the QUIC data has been consumed, unblock |http_data|.
1692 http_data.socket()->OnConnectComplete(MockConnect());
1693
1694 // The retry logic must hide the 421 status. The transaction succeeds on
1695 // |http_data|.
1696 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261697 CheckWasHttpResponse(&trans);
1698 CheckResponsePort(&trans, 443);
1699 CheckResponseData(&trans, "hello!");
1700}
1701
[email protected]1e960032013-12-20 19:00:201702TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411703 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571704 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301705
tbansalfdf5665b2015-09-21 22:46:401706 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521707 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361708 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431709 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401710 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401711 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371712 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361713 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431714 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301715 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401716 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431717 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401718
1719 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1720 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301721
1722 CreateSession();
1723
tbansal0f56a39a2016-04-07 22:03:381724 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401725 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161726 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401727 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161728 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1730 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381731 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531732
1733 NetErrorDetails details;
1734 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521735 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401736 }
[email protected]cebe3282013-05-22 23:49:301737}
1738
tbansalc8a94ea2015-11-02 23:58:511739TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1740 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411741 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571742 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511743
1744 MockRead http_reads[] = {
1745 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1746 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1747 MockRead(ASYNC, OK)};
1748
Ryan Sleevib8d7ea02018-05-07 20:01:011749 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511750 socket_factory_.AddSocketDataProvider(&data);
1751 SSLSocketDataProvider ssl(ASYNC, OK);
1752 socket_factory_.AddSSLSocketDataProvider(&ssl);
1753
1754 CreateSession();
1755
1756 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381757 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511758}
1759
bncc958faa2015-07-31 18:14:521760TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521761 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561762 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1763 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521764 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1765 MockRead(ASYNC, OK)};
1766
Ryan Sleevib8d7ea02018-05-07 20:01:011767 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521768 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081769 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561770 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521771
1772 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521773 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361774 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431775 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1776 mock_quic_data.AddWrite(
1777 SYNCHRONOUS,
1778 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331779 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431780 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431781 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331782 ASYNC, ConstructServerResponseHeadersPacket(
1783 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1784 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411785 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331786 mock_quic_data.AddRead(
1787 ASYNC, ConstructServerDataPacket(
1788 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411789 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431790 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521791 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591792 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521793
1794 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1795
rtennetib8e80fb2016-05-16 00:12:091796 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321797 CreateSession();
bncc958faa2015-07-31 18:14:521798
1799 SendRequestAndExpectHttpResponse("hello world");
1800 SendRequestAndExpectQuicResponse("hello!");
1801}
1802
zhongyia00ca012017-07-06 23:36:391803TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1804 // Both server advertises and client supports two QUIC versions.
1805 // Only |version_| is advertised and supported.
1806 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1807 // PacketMakers are using |version_|.
1808
1809 // Add support for another QUIC version besides |version_| on the client side.
1810 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521811 quic::QuicTransportVersion advertised_version_2 =
1812 quic::QUIC_VERSION_UNSUPPORTED;
1813 for (const quic::QuicTransportVersion& version :
1814 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391815 if (version == version_)
1816 continue;
1817 if (supported_versions_.size() != 2) {
1818 supported_versions_.push_back(version);
1819 continue;
1820 }
1821 advertised_version_2 = version;
1822 break;
1823 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521824 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391825
1826 std::string QuicAltSvcWithVersionHeader =
1827 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1828 advertised_version_2, version_);
1829
1830 MockRead http_reads[] = {
1831 MockRead("HTTP/1.1 200 OK\r\n"),
1832 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1833 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1834 MockRead(ASYNC, OK)};
1835
Ryan Sleevib8d7ea02018-05-07 20:01:011836 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391837 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081838 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391839 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1840
1841 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521842 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391843 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431844 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1845 mock_quic_data.AddWrite(
1846 SYNCHRONOUS,
1847 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331848 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431849 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431850 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331851 ASYNC, ConstructServerResponseHeadersPacket(
1852 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1853 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411854 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331855 mock_quic_data.AddRead(
1856 ASYNC, ConstructServerDataPacket(
1857 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411858 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431859 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391860 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1861 mock_quic_data.AddRead(ASYNC, 0); // EOF
1862
1863 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1864
1865 AddHangingNonAlternateProtocolSocketData();
1866 CreateSession(supported_versions_);
1867
1868 SendRequestAndExpectHttpResponse("hello world");
1869 SendRequestAndExpectQuicResponse("hello!");
1870}
1871
1872TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1873 // Client and server mutually support more than one QUIC_VERSION.
1874 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1875 // which is verified as the PacketMakers are using |version_|.
1876
Ryan Hamilton8d9ee76e2018-05-29 23:52:521877 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1878 for (const quic::QuicTransportVersion& version :
1879 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391880 if (version == version_)
1881 continue;
1882 common_version_2 = version;
1883 break;
1884 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521885 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391886
1887 supported_versions_.push_back(
1888 common_version_2); // Supported but unpreferred.
1889
1890 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1891 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1892
1893 MockRead http_reads[] = {
1894 MockRead("HTTP/1.1 200 OK\r\n"),
1895 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1896 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1897 MockRead(ASYNC, OK)};
1898
Ryan Sleevib8d7ea02018-05-07 20:01:011899 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391900 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081901 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391902 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1903
1904 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521905 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391906 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431907 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1908 mock_quic_data.AddWrite(
1909 SYNCHRONOUS,
1910 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331911 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431912 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431913 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331914 ASYNC, ConstructServerResponseHeadersPacket(
1915 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1916 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411917 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331918 mock_quic_data.AddRead(
1919 ASYNC, ConstructServerDataPacket(
1920 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411921 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431922 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391923 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1924 mock_quic_data.AddRead(ASYNC, 0); // EOF
1925
1926 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1927
1928 AddHangingNonAlternateProtocolSocketData();
1929 CreateSession(supported_versions_);
1930
1931 SendRequestAndExpectHttpResponse("hello world");
1932 SendRequestAndExpectQuicResponse("hello!");
1933}
1934
rchf47265dc2016-03-21 21:33:121935TEST_P(QuicNetworkTransactionTest,
1936 UseAlternativeServiceWithProbabilityForQuic) {
1937 MockRead http_reads[] = {
1938 MockRead("HTTP/1.1 200 OK\r\n"),
1939 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1940 MockRead("hello world"),
1941 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1942 MockRead(ASYNC, OK)};
1943
Ryan Sleevib8d7ea02018-05-07 20:01:011944 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121945 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081946 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121947 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1948
1949 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521950 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361951 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431952 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1953 mock_quic_data.AddWrite(
1954 SYNCHRONOUS,
1955 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331956 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431957 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431958 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331959 ASYNC, ConstructServerResponseHeadersPacket(
1960 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1961 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411962 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331963 mock_quic_data.AddRead(
1964 ASYNC, ConstructServerDataPacket(
1965 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411966 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431967 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121968 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1969 mock_quic_data.AddRead(ASYNC, 0); // EOF
1970
1971 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1972
rtennetib8e80fb2016-05-16 00:12:091973 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121974 CreateSession();
1975
1976 SendRequestAndExpectHttpResponse("hello world");
1977 SendRequestAndExpectQuicResponse("hello!");
1978}
1979
zhongyi3d4a55e72016-04-22 20:36:461980TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1981 MockRead http_reads[] = {
1982 MockRead("HTTP/1.1 200 OK\r\n"),
1983 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1984 MockRead("hello world"),
1985 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1986 MockRead(ASYNC, OK)};
1987
Ryan Sleevib8d7ea02018-05-07 20:01:011988 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461989 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081990 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461991 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1992
1993 CreateSession();
bncb26024382016-06-29 02:39:451994 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461995 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:451996 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:461997 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401998 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461999 session_->http_server_properties();
2000 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2001 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2002 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462003 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342004 2u,
2005 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452006 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342007 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462008}
2009
2010TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2011 MockRead http_reads[] = {
2012 MockRead("HTTP/1.1 200 OK\r\n"),
2013 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2014 MockRead("hello world"),
2015 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2016 MockRead(ASYNC, OK)};
2017
Ryan Sleevib8d7ea02018-05-07 20:01:012018 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082019 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462020
2021 socket_factory_.AddSocketDataProvider(&http_data);
2022 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2023 socket_factory_.AddSocketDataProvider(&http_data);
2024 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2025
2026 CreateSession();
2027
2028 // Send https request and set alternative services if response header
2029 // advertises alternative service for mail.example.org.
2030 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402031 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462032 session_->http_server_properties();
2033
2034 const url::SchemeHostPort https_server(request_.url);
2035 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342036 EXPECT_EQ(
2037 2u,
2038 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462039
2040 // Send http request to the same origin but with diffrent scheme, should not
2041 // use QUIC.
2042 request_.url = GURL("http://mail.example.org:443");
2043 SendRequestAndExpectHttpResponse("hello world");
2044}
2045
zhongyie537a002017-06-27 16:48:212046TEST_P(QuicNetworkTransactionTest,
2047 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442048 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522049 for (const quic::QuicTransportVersion& version :
2050 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:442051 if (version == version_)
2052 continue;
2053 supported_versions_.push_back(version);
2054 break;
2055 }
2056
zhongyie537a002017-06-27 16:48:212057 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:522058 GenerateQuicVersionsListForAltSvcHeader(
2059 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:212060 std::string altsvc_header =
2061 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2062 advertised_versions_list_str.c_str());
2063 MockRead http_reads[] = {
2064 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2065 MockRead("hello world"),
2066 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2067 MockRead(ASYNC, OK)};
2068
Ryan Sleevib8d7ea02018-05-07 20:01:012069 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212070 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082071 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212072 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2073
2074 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522075 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212076 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432077 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2078 mock_quic_data.AddWrite(
2079 SYNCHRONOUS,
2080 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332081 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432082 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432083 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332084 ASYNC, ConstructServerResponseHeadersPacket(
2085 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2086 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412087 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332088 mock_quic_data.AddRead(
2089 ASYNC, ConstructServerDataPacket(
2090 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412091 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432092 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212093 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2094 mock_quic_data.AddRead(ASYNC, 0); // EOF
2095
2096 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2097
2098 AddHangingNonAlternateProtocolSocketData();
2099
zhongyi86838d52017-06-30 01:19:442100 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212101
2102 SendRequestAndExpectHttpResponse("hello world");
2103 SendRequestAndExpectQuicResponse("hello!");
2104
2105 // Check alternative service is set with only mutually supported versions.
2106 const url::SchemeHostPort https_server(request_.url);
2107 const AlternativeServiceInfoVector alt_svc_info_vector =
2108 session_->http_server_properties()->GetAlternativeServiceInfos(
2109 https_server);
2110 EXPECT_EQ(1u, alt_svc_info_vector.size());
2111 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2112 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2113 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442114 std::sort(supported_versions_.begin(), supported_versions_.end());
2115 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212116 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442117 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212118 alt_svc_info_vector[0].advertised_versions()[1]);
2119}
2120
danzh3134c2562016-08-12 14:07:522121TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442122 std::string altsvc_header =
2123 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072124 MockRead http_reads[] = {
2125 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2126 MockRead("hello world"),
2127 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2128 MockRead(ASYNC, OK)};
2129
Ryan Sleevib8d7ea02018-05-07 20:01:012130 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072131 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082132 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072133 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2134
2135 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522136 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362137 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432138 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2139 mock_quic_data.AddWrite(
2140 SYNCHRONOUS,
2141 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332142 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432143 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432144 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332145 ASYNC, ConstructServerResponseHeadersPacket(
2146 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2147 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412148 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332149 mock_quic_data.AddRead(
2150 ASYNC, ConstructServerDataPacket(
2151 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412152 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432153 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072154 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592155 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072156
2157 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2158
rtennetib8e80fb2016-05-16 00:12:092159 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322160 CreateSession();
bnc8be55ebb2015-10-30 14:12:072161
2162 SendRequestAndExpectHttpResponse("hello world");
2163 SendRequestAndExpectQuicResponse("hello!");
2164}
2165
zhongyi6b5a3892016-03-12 04:46:202166TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092167 if (version_ == quic::QUIC_VERSION_99) {
2168 // Not available under version 99
2169 return;
2170 }
zhongyi6b5a3892016-03-12 04:46:202171 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522172 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362173 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432174 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2175 mock_quic_data.AddWrite(
2176 SYNCHRONOUS,
2177 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332178 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432179 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332180 mock_quic_data.AddRead(
2181 ASYNC, ConstructServerResponseHeadersPacket(
2182 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2183 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202184 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522185 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432186 mock_quic_data.AddRead(SYNCHRONOUS,
2187 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522188 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432189 "connection migration with port change only"));
2190 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:412191 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332192 mock_quic_data.AddRead(
2193 SYNCHRONOUS, ConstructServerDataPacket(
2194 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412195 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332196 mock_quic_data.AddWrite(SYNCHRONOUS,
2197 ConstructClientAckAndRstPacket(
2198 4, GetNthClientInitiatedBidirectionalStreamId(0),
2199 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202200 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2201 mock_quic_data.AddRead(ASYNC, 0); // EOF
2202
2203 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2204
2205 // The non-alternate protocol job needs to hang in order to guarantee that
2206 // the alternate-protocol job will "win".
2207 AddHangingNonAlternateProtocolSocketData();
2208
2209 // In order for a new QUIC session to be established via alternate-protocol
2210 // without racing an HTTP connection, we need the host resolution to happen
2211 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2212 // connection to the the server, in this test we require confirmation
2213 // before encrypting so the HTTP job will still start.
2214 host_resolver_.set_synchronous_mode(true);
2215 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2216 "");
2217 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2218 AddressList address;
maksim.sisov31452af2016-07-27 06:38:102219 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582220 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2221 CompletionOnceCallback(), &request,
2222 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412223 EXPECT_THAT(rv, IsOk());
zhongyi6b5a3892016-03-12 04:46:202224
2225 CreateSession();
2226 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272227 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202228
bnc691fda62016-08-12 00:43:162229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202230 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412231 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012232 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202233
2234 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522235 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012236 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202237
2238 // Check whether this transaction is correctly marked as received a go-away
2239 // because of migrating port.
2240 NetErrorDetails details;
2241 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162242 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202243 EXPECT_TRUE(details.quic_port_migration_detected);
2244}
2245
Zhongyi Shia6b68d112018-09-24 07:49:032246// This test verifies that a new QUIC connection will be attempted on the
2247// alternate network if the original QUIC connection fails with idle timeout
2248// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2249// alternate network as well, QUIC is marked as broken and the brokenness will
2250// not expire when default network changes.
2251TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2252 SetUpTestForRetryConnectionOnAlternateNetwork();
2253
2254 std::string request_data;
2255 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2256 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2257
2258 // The request will initially go out over QUIC.
2259 MockQuicData quic_data;
2260 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2261 int packet_num = 1;
2262 quic_data.AddWrite(SYNCHRONOUS,
2263 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2264 // Retranmit the handshake messages.
2265 quic_data.AddWrite(SYNCHRONOUS,
2266 client_maker_.MakeDummyCHLOPacket(packet_num++));
2267 quic_data.AddWrite(SYNCHRONOUS,
2268 client_maker_.MakeDummyCHLOPacket(packet_num++));
2269 quic_data.AddWrite(SYNCHRONOUS,
2270 client_maker_.MakeDummyCHLOPacket(packet_num++));
2271 quic_data.AddWrite(SYNCHRONOUS,
2272 client_maker_.MakeDummyCHLOPacket(packet_num++));
2273 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2274 if (version_ <= quic::QUIC_VERSION_39) {
2275 quic_data.AddWrite(SYNCHRONOUS,
2276 client_maker_.MakeDummyCHLOPacket(packet_num++));
2277 }
2278 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2279 quic_data.AddWrite(SYNCHRONOUS,
2280 client_maker_.MakeConnectionClosePacket(
2281 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2282 "No recent network activity."));
2283 quic_data.AddSocketDataToFactory(&socket_factory_);
2284
2285 // Add successful TCP data so that TCP job will succeed.
2286 MockWrite http_writes[] = {
2287 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2288 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2289 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2290
2291 MockRead http_reads[] = {
2292 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2293 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2294 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2295 SequencedSocketData http_data(http_reads, http_writes);
2296 socket_factory_.AddSocketDataProvider(&http_data);
2297 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2298
2299 // Add data for the second QUIC connection to fail.
2300 MockQuicData quic_data2;
2301 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2302 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2303 quic_data2.AddSocketDataToFactory(&socket_factory_);
2304
2305 // Resolve the host resolution synchronously.
2306 host_resolver_.set_synchronous_mode(true);
2307 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2308 "");
2309 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2310 AddressList address;
2311 std::unique_ptr<HostResolver::Request> request;
2312 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2313 CompletionOnceCallback(), &request,
2314 net_log_.bound());
2315 EXPECT_THAT(rv, IsOk());
2316
2317 CreateSession();
2318 session_->quic_stream_factory()->set_require_confirmation(true);
2319 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2320 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2321 QuicStreamFactoryPeer::SetAlarmFactory(
2322 session_->quic_stream_factory(),
2323 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2324 &clock_));
2325 // Add alternate protocol mapping to race QUIC and TCP.
2326 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2327 // peer.
2328 AddQuicAlternateProtocolMapping(
2329 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2330
2331 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2332 TestCompletionCallback callback;
2333 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2335
2336 // Pump the message loop to get the request started.
2337 // Request will be served with TCP job.
2338 base::RunLoop().RunUntilIdle();
2339 EXPECT_THAT(callback.WaitForResult(), IsOk());
2340 CheckResponseData(&trans, "TCP succeeds");
2341
2342 // Fire the retransmission alarm, from this point, connection will idle
2343 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062344 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182345 quic_fix_time_of_first_packet_sent_after_receiving)) {
2346 quic_task_runner_->RunNextTask();
2347 }
Zhongyi Shia6b68d112018-09-24 07:49:032348 // Fast forward to idle timeout the original connection. A new connection will
2349 // be kicked off on the alternate network.
2350 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2351 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2352 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2353
2354 // Run the message loop to execute posted tasks, which will report job status.
2355 base::RunLoop().RunUntilIdle();
2356
2357 // Verify that QUIC is marked as broken.
2358 ExpectBrokenAlternateProtocolMapping();
2359
2360 // Deliver a message to notify the new network becomes default, the brokenness
2361 // will not expire as QUIC is broken on both networks.
2362 scoped_mock_change_notifier_->mock_network_change_notifier()
2363 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2364 ExpectBrokenAlternateProtocolMapping();
2365
2366 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2367 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2368}
2369
2370// This test verifies that a new QUIC connection will be attempted on the
2371// alternate network if the original QUIC connection fails with idle timeout
2372// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2373// alternate network, QUIC is marked as broken. The brokenness will expire when
2374// the default network changes.
2375TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2376 SetUpTestForRetryConnectionOnAlternateNetwork();
2377
2378 std::string request_data;
2379 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2380 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2381
2382 // The request will initially go out over QUIC.
2383 MockQuicData quic_data;
2384 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2385 int packet_num = 1;
2386 quic_data.AddWrite(SYNCHRONOUS,
2387 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2388 // Retranmit the handshake messages.
2389 quic_data.AddWrite(SYNCHRONOUS,
2390 client_maker_.MakeDummyCHLOPacket(packet_num++));
2391 quic_data.AddWrite(SYNCHRONOUS,
2392 client_maker_.MakeDummyCHLOPacket(packet_num++));
2393 quic_data.AddWrite(SYNCHRONOUS,
2394 client_maker_.MakeDummyCHLOPacket(packet_num++));
2395 quic_data.AddWrite(SYNCHRONOUS,
2396 client_maker_.MakeDummyCHLOPacket(packet_num++));
2397 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2398 if (version_ <= quic::QUIC_VERSION_39) {
2399 quic_data.AddWrite(SYNCHRONOUS,
2400 client_maker_.MakeDummyCHLOPacket(packet_num++));
2401 }
2402 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2403 quic_data.AddWrite(SYNCHRONOUS,
2404 client_maker_.MakeConnectionClosePacket(
2405 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2406 "No recent network activity."));
2407 quic_data.AddSocketDataToFactory(&socket_factory_);
2408
2409 // Add successful TCP data so that TCP job will succeed.
2410 MockWrite http_writes[] = {
2411 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2412 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2413 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2414
2415 MockRead http_reads[] = {
2416 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2417 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2418 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2419 SequencedSocketData http_data(http_reads, http_writes);
2420 socket_factory_.AddSocketDataProvider(&http_data);
2421 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2422
2423 // Quic connection will be retried on the alternate network after the initial
2424 // one fails on the default network.
2425 MockQuicData quic_data2;
2426 quic::QuicStreamOffset header_stream_offset = 0;
2427 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2428 quic_data2.AddWrite(SYNCHRONOUS,
2429 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2430
2431 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2432 quic_data2.AddWrite(SYNCHRONOUS,
2433 ConstructInitialSettingsPacket(2, &header_stream_offset));
2434 quic_data2.AddSocketDataToFactory(&socket_factory_);
2435
2436 // Resolve the host resolution synchronously.
2437 host_resolver_.set_synchronous_mode(true);
2438 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2439 "");
2440 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2441 AddressList address;
2442 std::unique_ptr<HostResolver::Request> request;
2443 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2444 CompletionOnceCallback(), &request,
2445 net_log_.bound());
2446 EXPECT_THAT(rv, IsOk());
2447
2448 CreateSession();
2449 session_->quic_stream_factory()->set_require_confirmation(true);
2450 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2451 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2452 QuicStreamFactoryPeer::SetAlarmFactory(
2453 session_->quic_stream_factory(),
2454 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2455 &clock_));
2456 // Add alternate protocol mapping to race QUIC and TCP.
2457 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2458 // peer.
2459 AddQuicAlternateProtocolMapping(
2460 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2461
2462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2463 TestCompletionCallback callback;
2464 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2465 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2466
2467 // Pump the message loop to get the request started.
2468 // Request will be served with TCP job.
2469 base::RunLoop().RunUntilIdle();
2470 EXPECT_THAT(callback.WaitForResult(), IsOk());
2471 CheckResponseData(&trans, "TCP succeeds");
2472
2473 // Fire the retransmission alarm, after which connection will idle
2474 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062475 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182476 quic_fix_time_of_first_packet_sent_after_receiving)) {
2477 quic_task_runner_->RunNextTask();
2478 }
Zhongyi Shia6b68d112018-09-24 07:49:032479 // Fast forward to idle timeout the original connection. A new connection will
2480 // be kicked off on the alternate network.
2481 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2482 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2483 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2484
2485 // The second connection hasn't finish handshake, verify that QUIC is not
2486 // marked as broken.
2487 ExpectQuicAlternateProtocolMapping();
2488 // Explicitly confirm the handshake on the second connection.
2489 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2490 quic::QuicSession::HANDSHAKE_CONFIRMED);
2491 // Run message loop to execute posted tasks, which will notify JoController
2492 // about the orphaned job status.
2493 base::RunLoop().RunUntilIdle();
2494
2495 // Verify that QUIC is marked as broken.
2496 ExpectBrokenAlternateProtocolMapping();
2497
2498 // Deliver a message to notify the new network becomes default, the previous
2499 // brokenness will be clear as the brokenness is bond with old default
2500 // network.
2501 scoped_mock_change_notifier_->mock_network_change_notifier()
2502 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2503 ExpectQuicAlternateProtocolMapping();
2504
2505 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2506 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2507}
2508
2509// This test verifies that a new QUIC connection will be attempted on the
2510// alternate network if the original QUIC connection fails with idle timeout
2511// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2512// alternative network succeeds, QUIC is not marked as broken.
2513TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2514 SetUpTestForRetryConnectionOnAlternateNetwork();
2515
2516 std::string request_data;
2517 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2518 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2519
2520 // The request will initially go out over QUIC.
2521 MockQuicData quic_data;
2522 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2523 int packet_num = 1;
2524 quic_data.AddWrite(SYNCHRONOUS,
2525 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2526 // Retranmit the handshake messages.
2527 quic_data.AddWrite(SYNCHRONOUS,
2528 client_maker_.MakeDummyCHLOPacket(packet_num++));
2529 quic_data.AddWrite(SYNCHRONOUS,
2530 client_maker_.MakeDummyCHLOPacket(packet_num++));
2531 quic_data.AddWrite(SYNCHRONOUS,
2532 client_maker_.MakeDummyCHLOPacket(packet_num++));
2533 quic_data.AddWrite(SYNCHRONOUS,
2534 client_maker_.MakeDummyCHLOPacket(packet_num++));
2535 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2536 // quic_fix_has_pending_crypto_data is introduced and enabled.
2537 if (version_ <= quic::QUIC_VERSION_39) {
2538 quic_data.AddWrite(SYNCHRONOUS,
2539 client_maker_.MakeDummyCHLOPacket(packet_num++));
2540 }
2541 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2542 quic_data.AddWrite(SYNCHRONOUS,
2543 client_maker_.MakeConnectionClosePacket(
2544 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2545 "No recent network activity."));
2546 quic_data.AddSocketDataToFactory(&socket_factory_);
2547
2548 // Add hanging TCP data so that TCP job will never succeeded.
2549 AddHangingNonAlternateProtocolSocketData();
2550
2551 // Quic connection will then be retried on the alternate network.
2552 MockQuicData quic_data2;
2553 quic::QuicStreamOffset header_stream_offset = 0;
2554 quic_data2.AddWrite(SYNCHRONOUS,
2555 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2556
Renjief49758b2019-01-11 23:32:412557 const quic::QuicString body = "hello!";
2558 quic::QuicString header = ConstructDataHeader(body.length());
2559
Zhongyi Shia6b68d112018-09-24 07:49:032560 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2561 quic_data2.AddWrite(SYNCHRONOUS,
2562 ConstructInitialSettingsPacket(2, &header_stream_offset));
2563 quic_data2.AddWrite(
2564 SYNCHRONOUS,
2565 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332566 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032567 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032568 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332569 ASYNC, ConstructServerResponseHeadersPacket(
2570 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2571 GetResponseHeaders("200 OK")));
2572 quic_data2.AddRead(
2573 ASYNC, ConstructServerDataPacket(
2574 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412575 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032576 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2577 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2578 quic_data2.AddSocketDataToFactory(&socket_factory_);
2579
2580 // Resolve the host resolution synchronously.
2581 host_resolver_.set_synchronous_mode(true);
2582 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2583 "");
2584 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2585 AddressList address;
2586 std::unique_ptr<HostResolver::Request> request;
2587 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2588 CompletionOnceCallback(), &request,
2589 net_log_.bound());
2590 EXPECT_THAT(rv, IsOk());
2591
2592 CreateSession();
2593 session_->quic_stream_factory()->set_require_confirmation(true);
2594 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2595 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2596 QuicStreamFactoryPeer::SetAlarmFactory(
2597 session_->quic_stream_factory(),
2598 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2599 &clock_));
2600 // Add alternate protocol mapping to race QUIC and TCP.
2601 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2602 // peer.
2603 AddQuicAlternateProtocolMapping(
2604 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2605
2606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2607 TestCompletionCallback callback;
2608 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2610
2611 // Pump the message loop to get the request started.
2612 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062613 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182614 quic_fix_time_of_first_packet_sent_after_receiving)) {
2615 quic_task_runner_->RunNextTask();
2616 }
Zhongyi Shia6b68d112018-09-24 07:49:032617
2618 // Fast forward to idle timeout the original connection. A new connection will
2619 // be kicked off on the alternate network.
2620 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2621 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2622 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2623
2624 // Verify that QUIC is not marked as broken.
2625 ExpectQuicAlternateProtocolMapping();
2626 // Explicitly confirm the handshake on the second connection.
2627 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2628 quic::QuicSession::HANDSHAKE_CONFIRMED);
2629
2630 // Read the response.
2631 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412632 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032633 // Verify that QUIC is not marked as broken.
2634 ExpectQuicAlternateProtocolMapping();
2635
2636 // Deliver a message to notify the new network becomes default.
2637 scoped_mock_change_notifier_->mock_network_change_notifier()
2638 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2639 ExpectQuicAlternateProtocolMapping();
2640 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2641 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2642}
2643
rch9ecde09b2017-04-08 00:18:232644// Verify that if a QUIC connection times out, the QuicHttpStream will
2645// return QUIC_PROTOCOL_ERROR.
2646TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482647 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412648 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232649
2650 // The request will initially go out over QUIC.
2651 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522652 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132653 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232654 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2655
2656 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522657 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2658 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432659 quic_data.AddWrite(SYNCHRONOUS,
2660 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332661 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2662 true, priority, GetRequestHeaders("GET", "https", "/"),
2663 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232664
2665 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522666 quic::QuicStreamOffset settings_offset = header_stream_offset;
2667 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432668 quic_data.AddWrite(SYNCHRONOUS,
2669 client_maker_.MakeInitialSettingsPacketAndSaveData(
2670 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232671 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092672 quic_data.AddWrite(SYNCHRONOUS,
2673 client_maker_.MakeDataPacket(
2674 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2675 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232676 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092677 quic_data.AddWrite(SYNCHRONOUS,
2678 client_maker_.MakeDataPacket(
2679 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2680 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232681 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092682 quic_data.AddWrite(SYNCHRONOUS,
2683 client_maker_.MakeDataPacket(
2684 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2685 false, 0, request_data));
2686 quic_data.AddWrite(SYNCHRONOUS,
2687 client_maker_.MakeDataPacket(
2688 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2689 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232690 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092691 quic_data.AddWrite(SYNCHRONOUS,
2692 client_maker_.MakeDataPacket(
2693 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2694 false, 0, request_data));
2695 quic_data.AddWrite(SYNCHRONOUS,
2696 client_maker_.MakeDataPacket(
2697 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2698 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232699 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092700 quic_data.AddWrite(SYNCHRONOUS,
2701 client_maker_.MakeDataPacket(
2702 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2703 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522704 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092705 SYNCHRONOUS, client_maker_.MakeDataPacket(
2706 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2707 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232708
Zhongyi Shi32f2fd02018-04-16 18:23:432709 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522710 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432711 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222712
rch9ecde09b2017-04-08 00:18:232713 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2714 quic_data.AddRead(ASYNC, OK);
2715 quic_data.AddSocketDataToFactory(&socket_factory_);
2716
2717 // In order for a new QUIC session to be established via alternate-protocol
2718 // without racing an HTTP connection, we need the host resolution to happen
2719 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2720 // connection to the the server, in this test we require confirmation
2721 // before encrypting so the HTTP job will still start.
2722 host_resolver_.set_synchronous_mode(true);
2723 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2724 "");
2725 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2726 AddressList address;
2727 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582728 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2729 CompletionOnceCallback(), &request,
2730 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412731 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232732
2733 CreateSession();
2734 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552735 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232736 QuicStreamFactoryPeer::SetAlarmFactory(
2737 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192738 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552739 &clock_));
rch9ecde09b2017-04-08 00:18:232740
Ryan Hamilton9835e662018-08-02 05:36:272741 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232742
2743 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2744 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412745 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232746 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2747
2748 // Pump the message loop to get the request started.
2749 base::RunLoop().RunUntilIdle();
2750 // Explicitly confirm the handshake.
2751 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522752 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232753
2754 // Run the QUIC session to completion.
2755 quic_task_runner_->RunUntilIdle();
2756
2757 ExpectQuicAlternateProtocolMapping();
2758 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2759 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2760}
2761
2762// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2763// return QUIC_PROTOCOL_ERROR.
2764TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482765 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522766 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232767
2768 // The request will initially go out over QUIC.
2769 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522770 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132771 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232772 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2773
2774 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522775 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2776 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432777 quic_data.AddWrite(SYNCHRONOUS,
2778 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332779 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2780 true, priority, GetRequestHeaders("GET", "https", "/"),
2781 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232782
2783 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522784 quic::QuicStreamOffset settings_offset = header_stream_offset;
2785 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432786 quic_data.AddWrite(SYNCHRONOUS,
2787 client_maker_.MakeInitialSettingsPacketAndSaveData(
2788 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232789 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092790 quic_data.AddWrite(SYNCHRONOUS,
2791 client_maker_.MakeDataPacket(
2792 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2793 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232794 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092795 quic_data.AddWrite(SYNCHRONOUS,
2796 client_maker_.MakeDataPacket(
2797 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2798 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232799 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092800 quic_data.AddWrite(SYNCHRONOUS,
2801 client_maker_.MakeDataPacket(
2802 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2803 false, 0, request_data));
2804 quic_data.AddWrite(SYNCHRONOUS,
2805 client_maker_.MakeDataPacket(
2806 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2807 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232808 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092809 quic_data.AddWrite(SYNCHRONOUS,
2810 client_maker_.MakeDataPacket(
2811 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2812 false, 0, request_data));
2813 quic_data.AddWrite(SYNCHRONOUS,
2814 client_maker_.MakeDataPacket(
2815 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2816 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232817 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092818 quic_data.AddWrite(SYNCHRONOUS,
2819 client_maker_.MakeDataPacket(
2820 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2821 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522822 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092823 SYNCHRONOUS, client_maker_.MakeDataPacket(
2824 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2825 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232826 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522827 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092828 SYNCHRONOUS, client_maker_.MakeDataPacket(
2829 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2830 false, 0, request_data));
2831 quic_data.AddWrite(
2832 SYNCHRONOUS, client_maker_.MakeDataPacket(
2833 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2834 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232835 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432836 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522837 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432838 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232839
2840 quic_data.AddRead(ASYNC, OK);
2841 quic_data.AddSocketDataToFactory(&socket_factory_);
2842
2843 // In order for a new QUIC session to be established via alternate-protocol
2844 // without racing an HTTP connection, we need the host resolution to happen
2845 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2846 // connection to the the server, in this test we require confirmation
2847 // before encrypting so the HTTP job will still start.
2848 host_resolver_.set_synchronous_mode(true);
2849 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2850 "");
2851 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2852 AddressList address;
2853 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582854 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2855 CompletionOnceCallback(), &request,
2856 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412857 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232858
2859 CreateSession();
2860 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552861 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232862 QuicStreamFactoryPeer::SetAlarmFactory(
2863 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192864 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552865 &clock_));
rch9ecde09b2017-04-08 00:18:232866
Ryan Hamilton9835e662018-08-02 05:36:272867 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232868
2869 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2870 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412871 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2873
2874 // Pump the message loop to get the request started.
2875 base::RunLoop().RunUntilIdle();
2876 // Explicitly confirm the handshake.
2877 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522878 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232879
2880 // Run the QUIC session to completion.
2881 quic_task_runner_->RunUntilIdle();
2882
2883 ExpectQuicAlternateProtocolMapping();
2884 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2885 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2886}
2887
2888// Verify that if a QUIC connection RTOs, while there are no active streams
2889// QUIC will not be marked as broken.
2890TEST_P(QuicNetworkTransactionTest,
2891 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522892 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232893
2894 // The request will initially go out over QUIC.
2895 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522896 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132897 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232898 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2899
2900 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522901 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2902 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432903 quic_data.AddWrite(SYNCHRONOUS,
2904 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332905 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2906 true, priority, GetRequestHeaders("GET", "https", "/"),
2907 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232908
2909 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522910 quic::QuicStreamOffset settings_offset = header_stream_offset;
2911 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432912 quic_data.AddWrite(SYNCHRONOUS,
2913 client_maker_.MakeInitialSettingsPacketAndSaveData(
2914 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232915
Fan Yang32c5a112018-12-10 20:06:332916 quic_data.AddWrite(SYNCHRONOUS,
2917 client_maker_.MakeRstPacket(
2918 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2919 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232920 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092921 quic_data.AddWrite(SYNCHRONOUS,
2922 client_maker_.MakeDataPacket(
2923 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2924 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232925 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092926 quic_data.AddWrite(SYNCHRONOUS,
2927 client_maker_.MakeDataPacket(
2928 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2929 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232930 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332931 quic_data.AddWrite(SYNCHRONOUS,
2932 client_maker_.MakeRstPacket(
2933 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2934 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092935 quic_data.AddWrite(SYNCHRONOUS,
2936 client_maker_.MakeDataPacket(
2937 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2938 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232939 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092940 quic_data.AddWrite(SYNCHRONOUS,
2941 client_maker_.MakeDataPacket(
2942 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2943 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332944 quic_data.AddWrite(SYNCHRONOUS,
2945 client_maker_.MakeRstPacket(
2946 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2947 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232948 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522949 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092950 SYNCHRONOUS, client_maker_.MakeDataPacket(
2951 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2952 false, 0, request_data));
2953 quic_data.AddWrite(
2954 SYNCHRONOUS, client_maker_.MakeDataPacket(
2955 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2956 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232957 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432958 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332959 SYNCHRONOUS, client_maker_.MakeRstPacket(
2960 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2961 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522962 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092963 SYNCHRONOUS, client_maker_.MakeDataPacket(
2964 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2965 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232966 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432967 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522968 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432969 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232970
2971 quic_data.AddRead(ASYNC, OK);
2972 quic_data.AddSocketDataToFactory(&socket_factory_);
2973
2974 // In order for a new QUIC session to be established via alternate-protocol
2975 // without racing an HTTP connection, we need the host resolution to happen
2976 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2977 // connection to the the server, in this test we require confirmation
2978 // before encrypting so the HTTP job will still start.
2979 host_resolver_.set_synchronous_mode(true);
2980 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2981 "");
2982 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2983 AddressList address;
2984 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582985 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2986 CompletionOnceCallback(), &request,
2987 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412988 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232989
2990 CreateSession();
2991 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552992 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232993 QuicStreamFactoryPeer::SetAlarmFactory(
2994 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192995 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552996 &clock_));
rch9ecde09b2017-04-08 00:18:232997
Ryan Hamilton9835e662018-08-02 05:36:272998 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232999
Jeremy Roman0579ed62017-08-29 15:56:193000 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233001 session_.get());
3002 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413003 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3005
3006 // Pump the message loop to get the request started.
3007 base::RunLoop().RunUntilIdle();
3008 // Explicitly confirm the handshake.
3009 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523010 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233011
3012 // Now cancel the request.
3013 trans.reset();
3014
3015 // Run the QUIC session to completion.
3016 quic_task_runner_->RunUntilIdle();
3017
3018 ExpectQuicAlternateProtocolMapping();
3019
3020 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3021}
3022
rch2f2991c2017-04-13 19:28:173023// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3024// the request fails with QUIC_PROTOCOL_ERROR.
3025TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:483026 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173027 // The request will initially go out over QUIC.
3028 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523029 quic::QuicStreamOffset header_stream_offset = 0;
3030 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3031 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433032 quic_data.AddWrite(
3033 SYNCHRONOUS,
3034 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333035 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433036 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523037 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433038 quic_data.AddWrite(SYNCHRONOUS,
3039 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173040 // Peer sending data from an non-existing stream causes this end to raise
3041 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333042 quic_data.AddRead(
3043 ASYNC, ConstructServerRstPacket(
3044 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3045 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173046 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433047 quic_data.AddWrite(SYNCHRONOUS,
3048 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523049 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3050 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173051 quic_data.AddSocketDataToFactory(&socket_factory_);
3052
3053 // In order for a new QUIC session to be established via alternate-protocol
3054 // without racing an HTTP connection, we need the host resolution to happen
3055 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3056 // connection to the the server, in this test we require confirmation
3057 // before encrypting so the HTTP job will still start.
3058 host_resolver_.set_synchronous_mode(true);
3059 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3060 "");
3061 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3062 AddressList address;
3063 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583064 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3065 CompletionOnceCallback(), &request,
3066 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413067 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173068
3069 CreateSession();
3070
Ryan Hamilton9835e662018-08-02 05:36:273071 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173072
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());
rch2f2991c2017-04-13 19:28:173076 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);
rch2f2991c2017-04-13 19:28:173083
3084 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3085
3086 // Run the QUIC session to completion.
3087 base::RunLoop().RunUntilIdle();
3088 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3089 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3090
3091 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3092 ExpectQuicAlternateProtocolMapping();
3093 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3094}
3095
rch9ecde09b2017-04-08 00:18:233096// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3097// connection times out, then QUIC will be marked as broken and the request
3098// retried over TCP.
3099TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413100 session_params_.mark_quic_broken_when_network_blackholes = true;
3101 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233102
3103 // The request will initially go out over QUIC.
3104 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523105 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133106 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233107 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3108
3109 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523110 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3111 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433112 quic_data.AddWrite(SYNCHRONOUS,
3113 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333114 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3115 true, priority, GetRequestHeaders("GET", "https", "/"),
3116 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233117
3118 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523119 quic::QuicStreamOffset settings_offset = header_stream_offset;
3120 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433121 quic_data.AddWrite(SYNCHRONOUS,
3122 client_maker_.MakeInitialSettingsPacketAndSaveData(
3123 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233124 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093125 quic_data.AddWrite(SYNCHRONOUS,
3126 client_maker_.MakeDataPacket(
3127 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3128 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233129 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093130 quic_data.AddWrite(SYNCHRONOUS,
3131 client_maker_.MakeDataPacket(
3132 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3133 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233134 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093135 quic_data.AddWrite(SYNCHRONOUS,
3136 client_maker_.MakeDataPacket(
3137 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3138 false, 0, request_data));
3139 quic_data.AddWrite(SYNCHRONOUS,
3140 client_maker_.MakeDataPacket(
3141 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3142 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233143 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093144 quic_data.AddWrite(SYNCHRONOUS,
3145 client_maker_.MakeDataPacket(
3146 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3147 false, 0, request_data));
3148 quic_data.AddWrite(SYNCHRONOUS,
3149 client_maker_.MakeDataPacket(
3150 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3151 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233152 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093153 quic_data.AddWrite(SYNCHRONOUS,
3154 client_maker_.MakeDataPacket(
3155 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3156 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523157 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093158 SYNCHRONOUS, client_maker_.MakeDataPacket(
3159 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3160 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233161
Zhongyi Shi32f2fd02018-04-16 18:23:433162 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523163 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433164 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223165
rch9ecde09b2017-04-08 00:18:233166 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3167 quic_data.AddRead(ASYNC, OK);
3168 quic_data.AddSocketDataToFactory(&socket_factory_);
3169
3170 // After that fails, it will be resent via TCP.
3171 MockWrite http_writes[] = {
3172 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3173 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3174 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3175
3176 MockRead http_reads[] = {
3177 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3178 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3179 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013180 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233181 socket_factory_.AddSocketDataProvider(&http_data);
3182 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3183
3184 // In order for a new QUIC session to be established via alternate-protocol
3185 // without racing an HTTP connection, we need the host resolution to happen
3186 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3187 // connection to the the server, in this test we require confirmation
3188 // before encrypting so the HTTP job will still start.
3189 host_resolver_.set_synchronous_mode(true);
3190 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3191 "");
3192 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3193 AddressList address;
3194 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583195 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3196 CompletionOnceCallback(), &request,
3197 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413198 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233199
3200 CreateSession();
3201 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553202 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233203 QuicStreamFactoryPeer::SetAlarmFactory(
3204 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193205 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553206 &clock_));
rch9ecde09b2017-04-08 00:18:233207
Ryan Hamilton9835e662018-08-02 05:36:273208 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233209
3210 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3211 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413212 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233213 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3214
3215 // Pump the message loop to get the request started.
3216 base::RunLoop().RunUntilIdle();
3217 // Explicitly confirm the handshake.
3218 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523219 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233220
3221 // Run the QUIC session to completion.
3222 quic_task_runner_->RunUntilIdle();
3223 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3224
3225 // Let the transaction proceed which will result in QUIC being marked
3226 // as broken and the request falling back to TCP.
3227 EXPECT_THAT(callback.WaitForResult(), IsOk());
3228
3229 ExpectBrokenAlternateProtocolMapping();
3230 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3231 ASSERT_FALSE(http_data.AllReadDataConsumed());
3232
3233 // Read the response body over TCP.
3234 CheckResponseData(&trans, "hello world");
3235 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3236 ASSERT_TRUE(http_data.AllReadDataConsumed());
3237}
3238
rch2f2991c2017-04-13 19:28:173239// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3240// connection times out, then QUIC will be marked as broken and the request
3241// retried over TCP.
3242TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413243 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173244
3245 // The request will initially go out over QUIC.
3246 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523247 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133248 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173249 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3250
3251 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523252 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3253 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433254 quic_data.AddWrite(SYNCHRONOUS,
3255 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333256 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3257 true, priority, GetRequestHeaders("GET", "https", "/"),
3258 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173259
3260 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523261 quic::QuicStreamOffset settings_offset = header_stream_offset;
3262 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433263 quic_data.AddWrite(SYNCHRONOUS,
3264 client_maker_.MakeInitialSettingsPacketAndSaveData(
3265 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173266 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093267 quic_data.AddWrite(SYNCHRONOUS,
3268 client_maker_.MakeDataPacket(
3269 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3270 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173271 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093272 quic_data.AddWrite(SYNCHRONOUS,
3273 client_maker_.MakeDataPacket(
3274 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3275 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173276 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093277 quic_data.AddWrite(SYNCHRONOUS,
3278 client_maker_.MakeDataPacket(
3279 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3280 false, 0, request_data));
3281 quic_data.AddWrite(SYNCHRONOUS,
3282 client_maker_.MakeDataPacket(
3283 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3284 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173285 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093286 quic_data.AddWrite(SYNCHRONOUS,
3287 client_maker_.MakeDataPacket(
3288 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3289 false, 0, request_data));
3290 quic_data.AddWrite(SYNCHRONOUS,
3291 client_maker_.MakeDataPacket(
3292 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3293 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173294 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093295 quic_data.AddWrite(SYNCHRONOUS,
3296 client_maker_.MakeDataPacket(
3297 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3298 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523299 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093300 SYNCHRONOUS, client_maker_.MakeDataPacket(
3301 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3302 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173303
Zhongyi Shi32f2fd02018-04-16 18:23:433304 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523305 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433306 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223307
rch2f2991c2017-04-13 19:28:173308 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3309 quic_data.AddRead(ASYNC, OK);
3310 quic_data.AddSocketDataToFactory(&socket_factory_);
3311
3312 // After that fails, it will be resent via TCP.
3313 MockWrite http_writes[] = {
3314 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3315 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3316 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3317
3318 MockRead http_reads[] = {
3319 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3320 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3321 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013322 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173323 socket_factory_.AddSocketDataProvider(&http_data);
3324 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3325
3326 // In order for a new QUIC session to be established via alternate-protocol
3327 // without racing an HTTP connection, we need the host resolution to happen
3328 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3329 // connection to the the server, in this test we require confirmation
3330 // before encrypting so the HTTP job will still start.
3331 host_resolver_.set_synchronous_mode(true);
3332 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3333 "");
3334 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3335 AddressList address;
3336 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583337 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3338 CompletionOnceCallback(), &request,
3339 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413340 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173341
3342 CreateSession();
3343 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553344 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173345 QuicStreamFactoryPeer::SetAlarmFactory(
3346 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193347 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553348 &clock_));
rch2f2991c2017-04-13 19:28:173349
Ryan Hamilton9835e662018-08-02 05:36:273350 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173351
3352 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3353 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413354 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3356
3357 // Pump the message loop to get the request started.
3358 base::RunLoop().RunUntilIdle();
3359 // Explicitly confirm the handshake.
3360 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523361 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173362
3363 // Run the QUIC session to completion.
3364 quic_task_runner_->RunUntilIdle();
3365 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3366
3367 ExpectQuicAlternateProtocolMapping();
3368
3369 // Let the transaction proceed which will result in QUIC being marked
3370 // as broken and the request falling back to TCP.
3371 EXPECT_THAT(callback.WaitForResult(), IsOk());
3372
3373 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3374 ASSERT_FALSE(http_data.AllReadDataConsumed());
3375
3376 // Read the response body over TCP.
3377 CheckResponseData(&trans, "hello world");
3378 ExpectBrokenAlternateProtocolMapping();
3379 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3380 ASSERT_TRUE(http_data.AllReadDataConsumed());
3381}
3382
rch9ecde09b2017-04-08 00:18:233383// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3384// connection times out, then QUIC will be marked as broken but the request
3385// will not be retried over TCP.
3386TEST_P(QuicNetworkTransactionTest,
3387 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413388 session_params_.mark_quic_broken_when_network_blackholes = true;
3389 session_params_.quic_idle_connection_timeout_seconds = 5;
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(
Fan Yang32c5a112018-12-10 20:06:333402 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3403 true, priority, GetRequestHeaders("GET", "https", "/"),
3404 0, 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
Zhongyi Shi32f2fd02018-04-16 18:23:433413 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333414 1, GetNthClientInitiatedBidirectionalStreamId(0),
3415 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433416 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523417 quic_data.AddWrite(
3418 SYNCHRONOUS,
3419 ConstructClientAckPacket(3, 1, 1, 1,
3420 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233421
3422 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523423 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093424 SYNCHRONOUS, client_maker_.MakeDataPacket(
3425 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3426 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233427 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093428 quic_data.AddWrite(
3429 SYNCHRONOUS, client_maker_.MakeDataPacket(
3430 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3431 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233432 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523433 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093434 SYNCHRONOUS, client_maker_.MakeDataPacket(
3435 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3436 false, 0, request_data));
3437 quic_data.AddWrite(
3438 SYNCHRONOUS, client_maker_.MakeDataPacket(
3439 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3440 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233441 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523442 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093443 SYNCHRONOUS, client_maker_.MakeDataPacket(
3444 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3445 false, 0, request_data));
3446 quic_data.AddWrite(
3447 SYNCHRONOUS, client_maker_.MakeDataPacket(
3448 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3449 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233450 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523451 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093452 SYNCHRONOUS, client_maker_.MakeDataPacket(
3453 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3454 false, 0, request_data));
3455 quic_data.AddWrite(
3456 SYNCHRONOUS, client_maker_.MakeDataPacket(
3457 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3458 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233459
Michael Warres112212822018-12-26 17:51:063460 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183461 quic_fix_time_of_first_packet_sent_after_receiving)) {
3462 quic_data.AddWrite(
3463 SYNCHRONOUS,
3464 client_maker_.MakeAckAndConnectionClosePacket(
3465 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3466 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3467
3468 } else {
3469 quic_data.AddWrite(
3470 SYNCHRONOUS,
3471 client_maker_.MakeAckAndConnectionClosePacket(
3472 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3473 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3474 }
Fan Yang928f1632017-12-14 18:55:223475
rch9ecde09b2017-04-08 00:18:233476 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3477 quic_data.AddRead(ASYNC, OK);
3478 quic_data.AddSocketDataToFactory(&socket_factory_);
3479
3480 // In order for a new QUIC session to be established via alternate-protocol
3481 // without racing an HTTP connection, we need the host resolution to happen
3482 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3483 // connection to the the server, in this test we require confirmation
3484 // before encrypting so the HTTP job will still start.
3485 host_resolver_.set_synchronous_mode(true);
3486 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3487 "");
3488 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3489 AddressList address;
3490 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583491 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3492 CompletionOnceCallback(), &request,
3493 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413494 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233495
3496 CreateSession();
3497 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553498 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233499 QuicStreamFactoryPeer::SetAlarmFactory(
3500 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193501 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553502 &clock_));
rch9ecde09b2017-04-08 00:18:233503
Ryan Hamilton9835e662018-08-02 05:36:273504 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233505
3506 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3507 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413508 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233509 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3510
3511 // Pump the message loop to get the request started.
3512 base::RunLoop().RunUntilIdle();
3513 // Explicitly confirm the handshake.
3514 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523515 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233516
3517 // Pump the message loop to get the request started.
3518 base::RunLoop().RunUntilIdle();
3519
3520 // Run the QUIC session to completion.
3521 quic_task_runner_->RunUntilIdle();
3522 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3523
3524 // Let the transaction proceed which will result in QUIC being marked
3525 // as broken and the request falling back to TCP.
3526 EXPECT_THAT(callback.WaitForResult(), IsOk());
3527
3528 ExpectBrokenAlternateProtocolMapping();
3529 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3530
3531 std::string response_data;
3532 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3533 IsError(ERR_QUIC_PROTOCOL_ERROR));
3534}
3535
3536// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3537// connection RTOs, then QUIC will be marked as broken and the request retried
3538// over TCP.
3539TEST_P(QuicNetworkTransactionTest,
3540 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413541 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523542 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233543
3544 // The request will initially go out over QUIC.
3545 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523546 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133547 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233548 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3549
3550 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523551 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3552 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433553 quic_data.AddWrite(SYNCHRONOUS,
3554 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333555 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3556 true, priority, GetRequestHeaders("GET", "https", "/"),
3557 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233558
3559 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523560 quic::QuicStreamOffset settings_offset = header_stream_offset;
3561 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433562 quic_data.AddWrite(SYNCHRONOUS,
3563 client_maker_.MakeInitialSettingsPacketAndSaveData(
3564 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233565 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093566 quic_data.AddWrite(SYNCHRONOUS,
3567 client_maker_.MakeDataPacket(
3568 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3569 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233570 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093571 quic_data.AddWrite(SYNCHRONOUS,
3572 client_maker_.MakeDataPacket(
3573 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3574 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233575 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093576 quic_data.AddWrite(SYNCHRONOUS,
3577 client_maker_.MakeDataPacket(
3578 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3579 false, 0, request_data));
3580 quic_data.AddWrite(SYNCHRONOUS,
3581 client_maker_.MakeDataPacket(
3582 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3583 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233584 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093585 quic_data.AddWrite(SYNCHRONOUS,
3586 client_maker_.MakeDataPacket(
3587 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3588 false, 0, request_data));
3589 quic_data.AddWrite(SYNCHRONOUS,
3590 client_maker_.MakeDataPacket(
3591 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3592 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233593 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093594 quic_data.AddWrite(SYNCHRONOUS,
3595 client_maker_.MakeDataPacket(
3596 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3597 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523598 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093599 SYNCHRONOUS, client_maker_.MakeDataPacket(
3600 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3601 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233602 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523603 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093604 SYNCHRONOUS, client_maker_.MakeDataPacket(
3605 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3606 false, 0, request_data));
3607 quic_data.AddWrite(
3608 SYNCHRONOUS, client_maker_.MakeDataPacket(
3609 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3610 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233611
Zhongyi Shi32f2fd02018-04-16 18:23:433612 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523613 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433614 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233615
3616 quic_data.AddRead(ASYNC, OK);
3617 quic_data.AddSocketDataToFactory(&socket_factory_);
3618
3619 // After that fails, it will be resent via TCP.
3620 MockWrite http_writes[] = {
3621 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3622 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3623 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3624
3625 MockRead http_reads[] = {
3626 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3627 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3628 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013629 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233630 socket_factory_.AddSocketDataProvider(&http_data);
3631 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3632
3633 // In order for a new QUIC session to be established via alternate-protocol
3634 // without racing an HTTP connection, we need the host resolution to happen
3635 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3636 // connection to the the server, in this test we require confirmation
3637 // before encrypting so the HTTP job will still start.
3638 host_resolver_.set_synchronous_mode(true);
3639 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3640 "");
3641 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3642 AddressList address;
3643 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583644 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3645 CompletionOnceCallback(), &request,
3646 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413647 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233648
3649 CreateSession();
3650 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553651 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233652 QuicStreamFactoryPeer::SetAlarmFactory(
3653 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193654 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553655 &clock_));
rch9ecde09b2017-04-08 00:18:233656
Ryan Hamilton9835e662018-08-02 05:36:273657 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233658
3659 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3660 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413661 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3663
3664 // Pump the message loop to get the request started.
3665 base::RunLoop().RunUntilIdle();
3666 // Explicitly confirm the handshake.
3667 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523668 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233669
3670 // Run the QUIC session to completion.
3671 quic_task_runner_->RunUntilIdle();
3672 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3673
3674 // Let the transaction proceed which will result in QUIC being marked
3675 // as broken and the request falling back to TCP.
3676 EXPECT_THAT(callback.WaitForResult(), IsOk());
3677
3678 ExpectBrokenAlternateProtocolMapping();
3679 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3680 ASSERT_FALSE(http_data.AllReadDataConsumed());
3681
3682 // Read the response body over TCP.
3683 CheckResponseData(&trans, "hello world");
3684 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3685 ASSERT_TRUE(http_data.AllReadDataConsumed());
3686}
3687
3688// Verify that if a QUIC connection RTOs, while there are no active streams
3689// QUIC will be marked as broken.
3690TEST_P(QuicNetworkTransactionTest,
3691 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413692 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523693 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233694
3695 // The request will initially go out over QUIC.
3696 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523697 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133698 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233699 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3700
3701 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523702 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3703 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433704 quic_data.AddWrite(SYNCHRONOUS,
3705 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333706 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3707 true, priority, GetRequestHeaders("GET", "https", "/"),
3708 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233709
3710 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523711 quic::QuicStreamOffset settings_offset = header_stream_offset;
3712 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433713 quic_data.AddWrite(SYNCHRONOUS,
3714 client_maker_.MakeInitialSettingsPacketAndSaveData(
3715 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233716
Fan Yang32c5a112018-12-10 20:06:333717 quic_data.AddWrite(SYNCHRONOUS,
3718 client_maker_.MakeRstPacket(
3719 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3720 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233721 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093722 quic_data.AddWrite(SYNCHRONOUS,
3723 client_maker_.MakeDataPacket(
3724 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3725 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233726 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093727 quic_data.AddWrite(SYNCHRONOUS,
3728 client_maker_.MakeDataPacket(
3729 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3730 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233731 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333732 quic_data.AddWrite(SYNCHRONOUS,
3733 client_maker_.MakeRstPacket(
3734 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3735 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093736 quic_data.AddWrite(SYNCHRONOUS,
3737 client_maker_.MakeDataPacket(
3738 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3739 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233740 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093741 quic_data.AddWrite(SYNCHRONOUS,
3742 client_maker_.MakeDataPacket(
3743 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3744 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333745 quic_data.AddWrite(SYNCHRONOUS,
3746 client_maker_.MakeRstPacket(
3747 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3748 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233749 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523750 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093751 SYNCHRONOUS, client_maker_.MakeDataPacket(
3752 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3753 false, 0, request_data));
3754 quic_data.AddWrite(
3755 SYNCHRONOUS, client_maker_.MakeDataPacket(
3756 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3757 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233758 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433759 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333760 SYNCHRONOUS, client_maker_.MakeRstPacket(
3761 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3762 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523763 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093764 SYNCHRONOUS, client_maker_.MakeDataPacket(
3765 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3766 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233767 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433768 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523769 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433770 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233771
3772 quic_data.AddRead(ASYNC, OK);
3773 quic_data.AddSocketDataToFactory(&socket_factory_);
3774
3775 // In order for a new QUIC session to be established via alternate-protocol
3776 // without racing an HTTP connection, we need the host resolution to happen
3777 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3778 // connection to the the server, in this test we require confirmation
3779 // before encrypting so the HTTP job will still start.
3780 host_resolver_.set_synchronous_mode(true);
3781 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3782 "");
3783 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3784 AddressList address;
3785 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583786 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3787 CompletionOnceCallback(), &request,
3788 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413789 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233790
3791 CreateSession();
3792 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553793 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233794 QuicStreamFactoryPeer::SetAlarmFactory(
3795 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193796 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553797 &clock_));
rch9ecde09b2017-04-08 00:18:233798
Ryan Hamilton9835e662018-08-02 05:36:273799 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233800
Jeremy Roman0579ed62017-08-29 15:56:193801 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233802 session_.get());
3803 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413804 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3806
3807 // Pump the message loop to get the request started.
3808 base::RunLoop().RunUntilIdle();
3809 // Explicitly confirm the handshake.
3810 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523811 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233812
3813 // Now cancel the request.
3814 trans.reset();
3815
3816 // Run the QUIC session to completion.
3817 quic_task_runner_->RunUntilIdle();
3818
3819 ExpectBrokenAlternateProtocolMapping();
3820
3821 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3822}
3823
rch2f2991c2017-04-13 19:28:173824// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3825// protocol error occurs after the handshake is confirmed, the request
3826// retried over TCP and the QUIC will be marked as broken.
3827TEST_P(QuicNetworkTransactionTest,
3828 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413829 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173830
3831 // The request will initially go out over QUIC.
3832 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523833 quic::QuicStreamOffset header_stream_offset = 0;
3834 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3835 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433836 quic_data.AddWrite(
3837 SYNCHRONOUS,
3838 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333839 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433840 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523841 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433842 quic_data.AddWrite(SYNCHRONOUS,
3843 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173844 // Peer sending data from an non-existing stream causes this end to raise
3845 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333846 quic_data.AddRead(
3847 ASYNC, ConstructServerRstPacket(
3848 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3849 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173850 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433851 quic_data.AddWrite(SYNCHRONOUS,
3852 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523853 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3854 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173855 quic_data.AddSocketDataToFactory(&socket_factory_);
3856
3857 // After that fails, it will be resent via TCP.
3858 MockWrite http_writes[] = {
3859 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3860 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3861 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3862
3863 MockRead http_reads[] = {
3864 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3865 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3866 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013867 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173868 socket_factory_.AddSocketDataProvider(&http_data);
3869 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3870
3871 // In order for a new QUIC session to be established via alternate-protocol
3872 // without racing an HTTP connection, we need the host resolution to happen
3873 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3874 // connection to the the server, in this test we require confirmation
3875 // before encrypting so the HTTP job will still start.
3876 host_resolver_.set_synchronous_mode(true);
3877 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3878 "");
3879 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3880 AddressList address;
3881 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583882 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3883 CompletionOnceCallback(), &request,
3884 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413885 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173886
3887 CreateSession();
3888
Ryan Hamilton9835e662018-08-02 05:36:273889 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173890
3891 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3892 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413893 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3895
3896 // Pump the message loop to get the request started.
3897 base::RunLoop().RunUntilIdle();
3898 // Explicitly confirm the handshake.
3899 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523900 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173901
3902 // Run the QUIC session to completion.
3903 base::RunLoop().RunUntilIdle();
3904 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3905
3906 ExpectQuicAlternateProtocolMapping();
3907
3908 // Let the transaction proceed which will result in QUIC being marked
3909 // as broken and the request falling back to TCP.
3910 EXPECT_THAT(callback.WaitForResult(), IsOk());
3911
3912 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3913 ASSERT_FALSE(http_data.AllReadDataConsumed());
3914
3915 // Read the response body over TCP.
3916 CheckResponseData(&trans, "hello world");
3917 ExpectBrokenAlternateProtocolMapping();
3918 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3919 ASSERT_TRUE(http_data.AllReadDataConsumed());
3920}
3921
rch30943ee2017-06-12 21:28:443922// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3923// request is reset from, then QUIC will be marked as broken and the request
3924// retried over TCP.
3925TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443926 // The request will initially go out over QUIC.
3927 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523928 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133929 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443930 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3931
3932 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523933 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3934 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433935 quic_data.AddWrite(SYNCHRONOUS,
3936 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333937 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3938 true, priority, GetRequestHeaders("GET", "https", "/"),
3939 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443940
3941 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523942 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3943 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433944 quic_data.AddWrite(SYNCHRONOUS,
3945 client_maker_.MakeInitialSettingsPacketAndSaveData(
3946 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443947
Fan Yang32c5a112018-12-10 20:06:333948 quic_data.AddRead(ASYNC,
3949 ConstructServerRstPacket(
3950 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3951 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443952
3953 quic_data.AddRead(ASYNC, OK);
3954 quic_data.AddSocketDataToFactory(&socket_factory_);
3955
3956 // After that fails, it will be resent via TCP.
3957 MockWrite http_writes[] = {
3958 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3959 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3960 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3961
3962 MockRead http_reads[] = {
3963 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3964 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3965 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013966 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443967 socket_factory_.AddSocketDataProvider(&http_data);
3968 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3969
3970 // In order for a new QUIC session to be established via alternate-protocol
3971 // without racing an HTTP connection, we need the host resolution to happen
3972 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3973 // connection to the the server, in this test we require confirmation
3974 // before encrypting so the HTTP job will still start.
3975 host_resolver_.set_synchronous_mode(true);
3976 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3977 "");
3978 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3979 AddressList address;
3980 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583981 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3982 CompletionOnceCallback(), &request,
3983 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413984 EXPECT_THAT(rv, IsOk());
rch30943ee2017-06-12 21:28:443985
3986 CreateSession();
3987
Ryan Hamilton9835e662018-08-02 05:36:273988 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443989
3990 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3991 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413992 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443993 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3994
3995 // Pump the message loop to get the request started.
3996 base::RunLoop().RunUntilIdle();
3997 // Explicitly confirm the handshake.
3998 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523999 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:444000
4001 // Run the QUIC session to completion.
4002 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4003
4004 ExpectQuicAlternateProtocolMapping();
4005
4006 // Let the transaction proceed which will result in QUIC being marked
4007 // as broken and the request falling back to TCP.
4008 EXPECT_THAT(callback.WaitForResult(), IsOk());
4009
4010 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4011 ASSERT_FALSE(http_data.AllReadDataConsumed());
4012
4013 // Read the response body over TCP.
4014 CheckResponseData(&trans, "hello world");
4015 ExpectBrokenAlternateProtocolMapping();
4016 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4017 ASSERT_TRUE(http_data.AllReadDataConsumed());
4018}
4019
Ryan Hamilton6c2a2a82017-12-15 02:06:284020// Verify that when an origin has two alt-svc advertisements, one local and one
4021// remote, that when the local is broken the request will go over QUIC via
4022// the remote Alt-Svc.
4023// This is a regression test for crbug/825646.
4024TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
4025 session_params_.quic_allow_remote_alt_svc = true;
4026
4027 GURL origin1 = request_.url; // mail.example.org
4028 GURL origin2("https://www.example.org/");
4029 ASSERT_NE(origin1.host(), origin2.host());
4030
4031 scoped_refptr<X509Certificate> cert(
4032 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244033 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4034 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284035
4036 ProofVerifyDetailsChromium verify_details;
4037 verify_details.cert_verify_result.verified_cert = cert;
4038 verify_details.cert_verify_result.is_issued_by_known_root = true;
4039 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4040
4041 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524042 quic::QuicStreamOffset request_header_offset(0);
4043 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:284044 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434045 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4046 mock_quic_data.AddWrite(
4047 SYNCHRONOUS,
4048 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334049 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434050 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4051 mock_quic_data.AddRead(
4052 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334053 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434054 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414055 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434056 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334057 ASYNC, ConstructServerDataPacket(
4058 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414059 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434060 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284061 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4062 mock_quic_data.AddRead(ASYNC, 0); // EOF
4063
4064 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4065 MockQuicData mock_quic_data2;
4066 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4067 AddHangingNonAlternateProtocolSocketData();
4068
4069 CreateSession();
4070
4071 // Set up alternative service for |origin1|.
4072 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4073 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4074 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4075 AlternativeServiceInfoVector alternative_services;
4076 alternative_services.push_back(
4077 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4078 local_alternative, expiration,
4079 session_->params().quic_supported_versions));
4080 alternative_services.push_back(
4081 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4082 remote_alternative, expiration,
4083 session_->params().quic_supported_versions));
4084 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
4085 alternative_services);
4086
4087 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
4088
4089 SendRequestAndExpectQuicResponse("hello!");
4090}
4091
rch30943ee2017-06-12 21:28:444092// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4093// request is reset from, then QUIC will be marked as broken and the request
4094// retried over TCP. Then, subsequent requests will go over a new QUIC
4095// connection instead of going back to the broken QUIC connection.
4096// This is a regression tests for crbug/731303.
4097TEST_P(QuicNetworkTransactionTest,
4098 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344099 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444100
4101 GURL origin1 = request_.url;
4102 GURL origin2("https://www.example.org/");
4103 ASSERT_NE(origin1.host(), origin2.host());
4104
4105 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524106 quic::QuicStreamOffset request_header_offset(0);
4107 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444108
4109 scoped_refptr<X509Certificate> cert(
4110 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244111 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4112 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444113
4114 ProofVerifyDetailsChromium verify_details;
4115 verify_details.cert_verify_result.verified_cert = cert;
4116 verify_details.cert_verify_result.is_issued_by_known_root = true;
4117 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4118
4119 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434120 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444121 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434122 mock_quic_data.AddWrite(
4123 SYNCHRONOUS,
4124 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334125 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434126 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4127 mock_quic_data.AddRead(
4128 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334129 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434130 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414131 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434132 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334133 ASYNC, ConstructServerDataPacket(
4134 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414135 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434136 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444137
4138 // Second request will go over the pooled QUIC connection, but will be
4139 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054140 QuicTestPacketMaker client_maker2(
Fan Yang32c5a112018-12-10 20:06:334141 version_, quic::EmptyQuicConnectionId(), &clock_, origin2.host(),
4142 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054143 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:334144 QuicTestPacketMaker server_maker2(version_, quic::EmptyQuicConnectionId(),
4145 &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524146 quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434147 mock_quic_data.AddWrite(
4148 SYNCHRONOUS,
4149 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334150 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434151 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334152 GetNthClientInitiatedBidirectionalStreamId(0),
4153 &request_header_offset));
4154 mock_quic_data.AddRead(
4155 ASYNC, ConstructServerRstPacket(
4156 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4157 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444158 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4159 mock_quic_data.AddRead(ASYNC, 0); // EOF
4160
4161 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4162
4163 // After that fails, it will be resent via TCP.
4164 MockWrite http_writes[] = {
4165 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4166 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4167 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4168
4169 MockRead http_reads[] = {
4170 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4171 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4172 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014173 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444174 socket_factory_.AddSocketDataProvider(&http_data);
4175 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4176
Ryan Hamilton6c2a2a82017-12-15 02:06:284177 // Then the next request to the second origin will be sent over TCP.
4178 socket_factory_.AddSocketDataProvider(&http_data);
4179 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444180
4181 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564182 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4183 QuicStreamFactoryPeer::SetAlarmFactory(
4184 session_->quic_stream_factory(),
4185 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4186 &clock_));
rch30943ee2017-06-12 21:28:444187
4188 // Set up alternative service for |origin1|.
4189 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244190 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214191 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244192 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444193 supported_versions_);
rch30943ee2017-06-12 21:28:444194
4195 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244196 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214197 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244198 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444199 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344200
rch30943ee2017-06-12 21:28:444201 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524202 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444203 SendRequestAndExpectQuicResponse("hello!");
4204
4205 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524206 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444207 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4208 request_.url = origin2;
4209 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284210 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244211 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284212 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244213 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444214
4215 // The third request should use a new QUIC connection, not the broken
4216 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284217 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444218}
4219
bnc8be55ebb2015-10-30 14:12:074220TEST_P(QuicNetworkTransactionTest,
4221 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4222 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444223 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074224 MockRead http_reads[] = {
4225 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4226 MockRead("hello world"),
4227 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4228 MockRead(ASYNC, OK)};
4229
Ryan Sleevib8d7ea02018-05-07 20:01:014230 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074231 socket_factory_.AddSocketDataProvider(&http_data);
4232 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4233 socket_factory_.AddSocketDataProvider(&http_data);
4234 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4235
rch3f4b8452016-02-23 16:59:324236 CreateSession();
bnc8be55ebb2015-10-30 14:12:074237
4238 SendRequestAndExpectHttpResponse("hello world");
4239 SendRequestAndExpectHttpResponse("hello world");
4240}
4241
Xida Chen9bfe0b62018-04-24 19:52:214242// When multiple alternative services are advertised, HttpStreamFactory should
4243// select the alternative service which uses existing QUIC session if available.
4244// If no existing QUIC session can be used, use the first alternative service
4245// from the list.
zhongyi32569c62016-01-08 02:54:304246TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344247 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524248 MockRead http_reads[] = {
4249 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294250 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524251 MockRead("hello world"),
4252 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4253 MockRead(ASYNC, OK)};
4254
Ryan Sleevib8d7ea02018-05-07 20:01:014255 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524256 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084257 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564258 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524259
Ryan Hamilton8d9ee76e2018-05-29 23:52:524260 quic::QuicStreamOffset request_header_offset = 0;
4261 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304262 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294263 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304264 // alternative service list.
bncc958faa2015-07-31 18:14:524265 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364266 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434267 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4268 mock_quic_data.AddWrite(
4269 SYNCHRONOUS,
4270 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334271 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434272 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304273
4274 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294275 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4276 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434277 mock_quic_data.AddRead(
4278 ASYNC,
4279 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334280 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434281 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414282 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434283 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334284 ASYNC, ConstructServerDataPacket(
4285 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414286 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434287 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304288
4289 // Second QUIC request data.
4290 // Connection pooling, using existing session, no need to include version
4291 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584292 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334293 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4294 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4295 true, GetRequestHeaders("GET", "https", "/"),
4296 GetNthClientInitiatedBidirectionalStreamId(0),
4297 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434298 mock_quic_data.AddRead(
4299 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334300 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434301 GetResponseHeaders("200 OK"), &response_header_offset));
4302 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334303 ASYNC, ConstructServerDataPacket(
4304 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414305 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434306 mock_quic_data.AddWrite(
4307 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524308 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594309 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524310
4311 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4312
rtennetib8e80fb2016-05-16 00:12:094313 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324314 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564315 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4316 QuicStreamFactoryPeer::SetAlarmFactory(
4317 session_->quic_stream_factory(),
4318 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4319 &clock_));
bncc958faa2015-07-31 18:14:524320
4321 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304322
bnc359ed2a2016-04-29 20:43:454323 SendRequestAndExpectQuicResponse("hello!");
4324 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304325}
4326
tbansal6490783c2016-09-20 17:55:274327// Check that an existing QUIC connection to an alternative proxy server is
4328// used.
4329TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4330 base::HistogramTester histogram_tester;
4331
Ryan Hamilton8d9ee76e2018-05-29 23:52:524332 quic::QuicStreamOffset request_header_offset = 0;
4333 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274334 // First QUIC request data.
4335 // Open a session to foo.example.org:443 using the first entry of the
4336 // alternative service list.
4337 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364338 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434339 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4340 mock_quic_data.AddWrite(
4341 SYNCHRONOUS,
4342 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334343 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434344 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274345
4346 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434347 mock_quic_data.AddRead(
4348 ASYNC,
4349 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334350 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434351 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414352 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434353 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334354 ASYNC, ConstructServerDataPacket(
4355 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414356 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434357 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274358
4359 // Second QUIC request data.
4360 // Connection pooling, using existing session, no need to include version
4361 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274362 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334363 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4364 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4365 true, GetRequestHeaders("GET", "http", "/"),
4366 GetNthClientInitiatedBidirectionalStreamId(0),
4367 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434368 mock_quic_data.AddRead(
4369 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334370 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434371 GetResponseHeaders("200 OK"), &response_header_offset));
4372 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334373 ASYNC, ConstructServerDataPacket(
4374 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414375 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434376 mock_quic_data.AddWrite(
4377 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274378 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4379 mock_quic_data.AddRead(ASYNC, 0); // EOF
4380
4381 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4382
4383 AddHangingNonAlternateProtocolSocketData();
4384
4385 TestProxyDelegate test_proxy_delegate;
4386
Lily Houghton8c2f97d2018-01-22 05:06:594387 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494388 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274389
4390 test_proxy_delegate.set_alternative_proxy_server(
4391 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524392 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274393
4394 request_.url = GURL("http://mail.example.org/");
4395
4396 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564397 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4398 QuicStreamFactoryPeer::SetAlarmFactory(
4399 session_->quic_stream_factory(),
4400 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4401 &clock_));
tbansal6490783c2016-09-20 17:55:274402
4403 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4404 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4405 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4406 1);
4407
4408 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4409 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4410 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4411 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4412 1);
4413}
4414
Ryan Hamilton8d9ee76e2018-05-29 23:52:524415// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454416// even if alternative service destination is different.
4417TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344418 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304419 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524420 quic::QuicStreamOffset request_header_offset(0);
4421 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454422
rch5cb522462017-04-25 20:18:364423 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434424 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454425 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434426 mock_quic_data.AddWrite(
4427 SYNCHRONOUS,
4428 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334429 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434430 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4431 mock_quic_data.AddRead(
4432 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334433 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434434 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414435 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434436 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334437 ASYNC, ConstructServerDataPacket(
4438 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414439 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434440 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304441
bnc359ed2a2016-04-29 20:43:454442 // Second request.
alyssar2adf3ac2016-05-03 17:12:584443 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334444 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4445 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4446 true, GetRequestHeaders("GET", "https", "/"),
4447 GetNthClientInitiatedBidirectionalStreamId(0),
4448 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434449 mock_quic_data.AddRead(
4450 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334451 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434452 GetResponseHeaders("200 OK"), &response_header_offset));
4453 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334454 ASYNC, ConstructServerDataPacket(
4455 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414456 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434457 mock_quic_data.AddWrite(
4458 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304459 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4460 mock_quic_data.AddRead(ASYNC, 0); // EOF
4461
4462 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454463
4464 AddHangingNonAlternateProtocolSocketData();
4465 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304466
rch3f4b8452016-02-23 16:59:324467 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564468 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4469 QuicStreamFactoryPeer::SetAlarmFactory(
4470 session_->quic_stream_factory(),
4471 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4472 &clock_));
zhongyi32569c62016-01-08 02:54:304473
bnc359ed2a2016-04-29 20:43:454474 const char destination1[] = "first.example.com";
4475 const char destination2[] = "second.example.com";
4476
4477 // Set up alternative service entry to destination1.
4478 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214479 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454480 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214481 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444482 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454483 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524484 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454485 SendRequestAndExpectQuicResponse("hello!");
4486
4487 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214488 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214489 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444490 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524491 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454492 // even though alternative service destination is different.
4493 SendRequestAndExpectQuicResponse("hello!");
4494}
4495
4496// Pool to existing session with matching destination and matching certificate
4497// even if origin is different, and even if the alternative service with
4498// matching destination is not the first one on the list.
4499TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344500 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454501 GURL origin1 = request_.url;
4502 GURL origin2("https://www.example.org/");
4503 ASSERT_NE(origin1.host(), origin2.host());
4504
4505 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524506 quic::QuicStreamOffset request_header_offset(0);
4507 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454508
rch5cb522462017-04-25 20:18:364509 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434510 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454511 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434512 mock_quic_data.AddWrite(
4513 SYNCHRONOUS,
4514 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334515 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434516 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4517 mock_quic_data.AddRead(
4518 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334519 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434520 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414521 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434522 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334523 ASYNC, ConstructServerDataPacket(
4524 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414525 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434526 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454527
4528 // Second request.
Yixin Wang079ad542018-01-11 04:06:054529 QuicTestPacketMaker client_maker2(
Fan Yang32c5a112018-12-10 20:06:334530 version_, quic::EmptyQuicConnectionId(), &clock_, origin2.host(),
4531 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054532 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:334533 QuicTestPacketMaker server_maker2(version_, quic::EmptyQuicConnectionId(),
4534 &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524535 quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584536 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434537 SYNCHRONOUS,
4538 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334539 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434540 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334541 GetNthClientInitiatedBidirectionalStreamId(0),
4542 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434543 mock_quic_data.AddRead(
4544 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334545 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434546 GetResponseHeaders("200 OK"), &response_header_offset));
4547 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334548 ASYNC, ConstructServerDataPacket(
4549 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414550 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434551 mock_quic_data.AddWrite(
4552 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454553 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4554 mock_quic_data.AddRead(ASYNC, 0); // EOF
4555
4556 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4557
4558 AddHangingNonAlternateProtocolSocketData();
4559 AddHangingNonAlternateProtocolSocketData();
4560
4561 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564562 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4563 QuicStreamFactoryPeer::SetAlarmFactory(
4564 session_->quic_stream_factory(),
4565 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4566 &clock_));
bnc359ed2a2016-04-29 20:43:454567
4568 const char destination1[] = "first.example.com";
4569 const char destination2[] = "second.example.com";
4570
4571 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214572 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454573 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214574 http_server_properties_.SetQuicAlternativeService(
4575 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444576 supported_versions_);
bnc359ed2a2016-04-29 20:43:454577
4578 // Set up multiple alternative service entries for |origin2|,
4579 // the first one with a different destination as for |origin1|,
4580 // the second one with the same. The second one should be used,
4581 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214582 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454583 AlternativeServiceInfoVector alternative_services;
4584 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214585 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4586 alternative_service2, expiration,
4587 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454588 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214589 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4590 alternative_service1, expiration,
4591 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454592 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4593 alternative_services);
bnc359ed2a2016-04-29 20:43:454594 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524595 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454596 SendRequestAndExpectQuicResponse("hello!");
4597
4598 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524599 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454600 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584601
bnc359ed2a2016-04-29 20:43:454602 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304603}
4604
4605// Multiple origins have listed the same alternative services. When there's a
4606// existing QUIC session opened by a request to other origin,
4607// if the cert is valid, should select this QUIC session to make the request
4608// if this is also the first existing QUIC session.
4609TEST_P(QuicNetworkTransactionTest,
4610 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344611 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294612 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304613
rch9ae5b3b2016-02-11 00:36:294614 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304615 MockRead http_reads[] = {
4616 MockRead("HTTP/1.1 200 OK\r\n"),
4617 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294618 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304619 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4620 MockRead(ASYNC, OK)};
4621
Ryan Sleevib8d7ea02018-05-07 20:01:014622 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304623 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084624 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304625 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4626
4627 // HTTP data for request to mail.example.org.
4628 MockRead http_reads2[] = {
4629 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294630 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304631 MockRead("hello world from mail.example.org"),
4632 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4633 MockRead(ASYNC, OK)};
4634
Ryan Sleevib8d7ea02018-05-07 20:01:014635 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304636 socket_factory_.AddSocketDataProvider(&http_data2);
4637 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4638
Ryan Hamilton8d9ee76e2018-05-29 23:52:524639 quic::QuicStreamOffset request_header_offset = 0;
4640 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304641
Yixin Wang079ad542018-01-11 04:06:054642 QuicTestPacketMaker client_maker(
Fan Yang32c5a112018-12-10 20:06:334643 version_, quic::EmptyQuicConnectionId(), &clock_, "mail.example.org",
4644 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054645 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584646 server_maker_.set_hostname("www.example.org");
4647 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304648 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364649 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434650 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304651 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584652 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434653 SYNCHRONOUS,
4654 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334655 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434656 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4657
4658 mock_quic_data.AddRead(
4659 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334660 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434661 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414662 quic::QuicString header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334663 mock_quic_data.AddRead(
4664 ASYNC, ConstructServerDataPacket(
4665 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414666 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434667 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4668 // Second QUIC request data.
4669 mock_quic_data.AddWrite(
4670 SYNCHRONOUS,
4671 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334672 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434673 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334674 GetNthClientInitiatedBidirectionalStreamId(0),
4675 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434676 mock_quic_data.AddRead(
4677 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334678 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434679 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334680 mock_quic_data.AddRead(
4681 ASYNC, ConstructServerDataPacket(
4682 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414683 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434684 mock_quic_data.AddWrite(
4685 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304686 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4687 mock_quic_data.AddRead(ASYNC, 0); // EOF
4688
4689 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304690
rtennetib8e80fb2016-05-16 00:12:094691 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324692 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564693 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4694 QuicStreamFactoryPeer::SetAlarmFactory(
4695 session_->quic_stream_factory(),
4696 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4697 &clock_));
zhongyi32569c62016-01-08 02:54:304698
4699 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294700 request_.url = GURL("https://www.example.org/");
4701 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304702 request_.url = GURL("https://mail.example.org/");
4703 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4704
rch9ae5b3b2016-02-11 00:36:294705 // Open a QUIC session to mail.example.org:443 when making request
4706 // to mail.example.org.
4707 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454708 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304709
rch9ae5b3b2016-02-11 00:36:294710 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304711 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454712 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524713}
4714
4715TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524716 MockRead http_reads[] = {
4717 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564718 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524719 MockRead("hello world"),
4720 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4721 MockRead(ASYNC, OK)};
4722
Ryan Sleevib8d7ea02018-05-07 20:01:014723 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524724 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084725 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564726 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524727
rtennetib8e80fb2016-05-16 00:12:094728 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324729 CreateSession();
bncc958faa2015-07-31 18:14:524730
4731 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454732
4733 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344734 AlternativeServiceInfoVector alternative_service_info_vector =
4735 http_server_properties_.GetAlternativeServiceInfos(http_server);
4736 ASSERT_EQ(1u, alternative_service_info_vector.size());
4737 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544738 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344739 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4740 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4741 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524742}
4743
4744TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524745 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564746 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4747 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524748 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4749 MockRead(ASYNC, OK)};
4750
Ryan Sleevib8d7ea02018-05-07 20:01:014751 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524752 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084753 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564754 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524755
4756 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524757 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364758 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434759 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4760 mock_quic_data.AddWrite(
4761 SYNCHRONOUS,
4762 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334763 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434764 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434765 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334766 ASYNC, ConstructServerResponseHeadersPacket(
4767 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4768 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414769 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334770 mock_quic_data.AddRead(
4771 ASYNC, ConstructServerDataPacket(
4772 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414773 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434774 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524775 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4776 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524777
4778 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4779
rtennetib8e80fb2016-05-16 00:12:094780 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324781 CreateSession();
bncc958faa2015-07-31 18:14:524782
bnc3472afd2016-11-17 15:27:214783 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524784 HostPortPair::FromURL(request_.url));
4785 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4786 alternative_service);
4787 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4788 alternative_service));
4789
4790 SendRequestAndExpectHttpResponse("hello world");
4791 SendRequestAndExpectQuicResponse("hello!");
4792
mmenkee24011922015-12-17 22:12:594793 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524794
4795 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4796 alternative_service));
rchac7f35e2017-03-15 20:42:304797 EXPECT_NE(nullptr,
4798 http_server_properties_.GetServerNetworkStats(
4799 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524800}
4801
bncc958faa2015-07-31 18:14:524802TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524803 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564804 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4805 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524806 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4807 MockRead(ASYNC, OK)};
4808
Ryan Sleevib8d7ea02018-05-07 20:01:014809 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524810 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564811 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524812
4813 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524814 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364815 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434816 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4817 mock_quic_data.AddWrite(
4818 SYNCHRONOUS,
4819 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334820 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434821 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434822 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334823 ASYNC, ConstructServerResponseHeadersPacket(
4824 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4825 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414826 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334827 mock_quic_data.AddRead(
4828 ASYNC, ConstructServerDataPacket(
4829 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414830 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434831 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524832 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4833
4834 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4835
4836 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324837 CreateSession();
bncc958faa2015-07-31 18:14:524838
4839 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4840 SendRequestAndExpectHttpResponse("hello world");
4841}
4842
tbansalc3308d72016-08-27 10:25:044843// Tests that the connection to an HTTPS proxy is raced with an available
4844// alternative proxy server.
4845TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274846 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594847 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494848 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044849
4850 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524851 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364852 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434853 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4854 mock_quic_data.AddWrite(
4855 SYNCHRONOUS,
4856 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334857 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434858 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434859 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334860 ASYNC, ConstructServerResponseHeadersPacket(
4861 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4862 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414863 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334864 mock_quic_data.AddRead(
4865 ASYNC, ConstructServerDataPacket(
4866 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414867 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434868 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044869 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4870 mock_quic_data.AddRead(ASYNC, 0); // EOF
4871
4872 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4873
4874 // There is no need to set up main job, because no attempt will be made to
4875 // speak to the proxy over TCP.
4876 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044877 TestProxyDelegate test_proxy_delegate;
4878 const HostPortPair host_port_pair("mail.example.org", 443);
4879
4880 test_proxy_delegate.set_alternative_proxy_server(
4881 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524882 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044883 CreateSession();
4884 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4885
4886 // The main job needs to hang in order to guarantee that the alternative
4887 // proxy server job will "win".
4888 AddHangingNonAlternateProtocolSocketData();
4889
4890 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4891
4892 // Verify that the alternative proxy server is not marked as broken.
4893 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4894
4895 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594896 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274897
4898 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4899 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4900 1);
tbansalc3308d72016-08-27 10:25:044901}
4902
bnc1c196c6e2016-05-28 13:51:484903TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304904 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274905 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304906
4907 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564908 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294909 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564910 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304911
4912 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564913 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484914 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564915 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304916
Ryan Sleevib8d7ea02018-05-07 20:01:014917 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504918 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084919 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504920 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304921
4922 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454923 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304924 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454925 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304926 };
Ryan Sleevib8d7ea02018-05-07 20:01:014927 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504928 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304929
4930 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014931 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504932 socket_factory_.AddSocketDataProvider(&http_data2);
4933 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304934
bnc912a04b2016-04-20 14:19:504935 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304936
4937 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304938 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174939 ASSERT_TRUE(http_data.AllReadDataConsumed());
4940 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304941
4942 // Now run the second request in which the QUIC socket hangs,
4943 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304944 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454945 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304946
rch37de576c2015-05-17 20:28:174947 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4948 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454949 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304950}
4951
[email protected]1e960032013-12-20 19:00:204952TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204953 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524954 quic::QuicStreamOffset header_stream_offset = 0;
4955 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4956 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434957 mock_quic_data.AddWrite(
4958 SYNCHRONOUS,
4959 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334960 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434961 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434962 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334963 ASYNC, ConstructServerResponseHeadersPacket(
4964 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4965 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414966 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334967 mock_quic_data.AddRead(
4968 ASYNC, ConstructServerDataPacket(
4969 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414970 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434971 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504972 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594973 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484974
rcha5399e02015-04-21 19:32:044975 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484976
rtennetib8e80fb2016-05-16 00:12:094977 // The non-alternate protocol job needs to hang in order to guarantee that
4978 // the alternate-protocol job will "win".
4979 AddHangingNonAlternateProtocolSocketData();
4980
rch3f4b8452016-02-23 16:59:324981 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274982 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194983 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304984
4985 EXPECT_EQ(nullptr,
4986 http_server_properties_.GetServerNetworkStats(
4987 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484988}
4989
[email protected]1e960032013-12-20 19:00:204990TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204991 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524992 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4993 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Fan Yang32c5a112018-12-10 20:06:334994 mock_quic_data.AddWrite(
4995 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4996 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4997 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434998 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334999 ASYNC, ConstructServerResponseHeadersPacket(
5000 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5001 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415002 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335003 mock_quic_data.AddRead(
5004 ASYNC, ConstructServerDataPacket(
5005 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415006 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435007 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:505008 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595009 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045010 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275011
5012 // In order for a new QUIC session to be established via alternate-protocol
5013 // without racing an HTTP connection, we need the host resolution to happen
5014 // synchronously.
5015 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295016 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565017 "");
rch9ae5b3b2016-02-11 00:36:295018 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]3a120a6b2013-06-25 01:08:275019 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105020 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585021 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5022 CompletionOnceCallback(), &request,
5023 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415024 EXPECT_THAT(rv, IsOk());
[email protected]3a120a6b2013-06-25 01:08:275025
rtennetib8e80fb2016-05-16 00:12:095026 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325027 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275028 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275029 SendRequestAndExpectQuicResponse("hello!");
5030}
5031
[email protected]0fc924b2014-03-31 04:34:155032TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495033 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5034 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155035
5036 // Since we are using a proxy, the QUIC job will not succeed.
5037 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295038 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5039 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565040 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155041
5042 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565043 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485044 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565045 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155046
Ryan Sleevib8d7ea02018-05-07 20:01:015047 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155048 socket_factory_.AddSocketDataProvider(&http_data);
5049
5050 // In order for a new QUIC session to be established via alternate-protocol
5051 // without racing an HTTP connection, we need the host resolution to happen
5052 // synchronously.
5053 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295054 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565055 "");
rch9ae5b3b2016-02-11 00:36:295056 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]0fc924b2014-03-31 04:34:155057 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105058 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585059 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5060 CompletionOnceCallback(), &request,
5061 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415062 EXPECT_THAT(rv, IsOk());
[email protected]0fc924b2014-03-31 04:34:155063
rch9ae5b3b2016-02-11 00:36:295064 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325065 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275066 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155067 SendRequestAndExpectHttpResponse("hello world");
5068}
5069
[email protected]1e960032013-12-20 19:00:205070TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:205071 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525072 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365073 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435074 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5075 mock_quic_data.AddWrite(
5076 SYNCHRONOUS,
5077 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335078 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435079 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435080 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335081 ASYNC, ConstructServerResponseHeadersPacket(
5082 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5083 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415084 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335085 mock_quic_data.AddRead(
5086 ASYNC, ConstructServerDataPacket(
5087 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415088 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435089 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595090 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045091 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125092
rtennetib8e80fb2016-05-16 00:12:095093 // The non-alternate protocol job needs to hang in order to guarantee that
5094 // the alternate-protocol job will "win".
5095 AddHangingNonAlternateProtocolSocketData();
5096
[email protected]11c05872013-08-20 02:04:125097 // In order for a new QUIC session to be established via alternate-protocol
5098 // without racing an HTTP connection, we need the host resolution to happen
5099 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5100 // connection to the the server, in this test we require confirmation
5101 // before encrypting so the HTTP job will still start.
5102 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295103 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565104 "");
rch9ae5b3b2016-02-11 00:36:295105 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]11c05872013-08-20 02:04:125106 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105107 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585108 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5109 CompletionOnceCallback(), &request,
5110 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415111 EXPECT_THAT(rv, IsOk());
[email protected]11c05872013-08-20 02:04:125112
rch3f4b8452016-02-23 16:59:325113 CreateSession();
[email protected]11c05872013-08-20 02:04:125114 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275115 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125116
bnc691fda62016-08-12 00:43:165117 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125118 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415119 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125121
5122 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525123 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015124 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505125
bnc691fda62016-08-12 00:43:165126 CheckWasQuicResponse(&trans);
5127 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125128}
5129
Steven Valdez58097ec32018-07-16 18:29:045130TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5131 MockQuicData mock_quic_data;
5132 quic::QuicStreamOffset client_header_stream_offset = 0;
5133 quic::QuicStreamOffset server_header_stream_offset = 0;
5134 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5135 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045136 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335137 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5138 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5139 true, GetRequestHeaders("GET", "https", "/"),
5140 &client_header_stream_offset));
5141 mock_quic_data.AddRead(
5142 ASYNC,
5143 ConstructServerResponseHeadersPacket(
5144 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5145 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5146 mock_quic_data.AddWrite(SYNCHRONOUS,
5147 ConstructClientAckAndRstPacket(
5148 2, GetNthClientInitiatedBidirectionalStreamId(0),
5149 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045150
5151 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5152
5153 spdy::SpdySettingsIR settings_frame;
5154 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5155 quic::kDefaultMaxUncompressedHeaderSize);
5156 spdy::SpdySerializedFrame spdy_frame(
5157 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5158 mock_quic_data.AddWrite(
5159 SYNCHRONOUS,
5160 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385161 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5162 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045163 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5164 client_header_stream_offset += spdy_frame.size();
5165
5166 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335167 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5168 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5169 true, GetRequestHeaders("GET", "https", "/"),
5170 GetNthClientInitiatedBidirectionalStreamId(0),
5171 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045172 mock_quic_data.AddRead(
5173 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335174 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045175 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjief49758b2019-01-11 23:32:415176 quic::QuicString header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045177 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335178 ASYNC, ConstructServerDataPacket(
5179 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415180 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045181 mock_quic_data.AddWrite(
5182 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5183 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5184 mock_quic_data.AddRead(ASYNC, 0); // EOF
5185
5186 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5187
5188 // In order for a new QUIC session to be established via alternate-protocol
5189 // without racing an HTTP connection, we need the host resolution to happen
5190 // synchronously.
5191 host_resolver_.set_synchronous_mode(true);
5192 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5193 "");
5194 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5195 AddressList address;
5196 std::unique_ptr<HostResolver::Request> request;
5197 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5198 CompletionOnceCallback(), &request, net_log_.bound());
5199
5200 AddHangingNonAlternateProtocolSocketData();
5201 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275202 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565203 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5204 QuicStreamFactoryPeer::SetAlarmFactory(
5205 session_->quic_stream_factory(),
5206 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5207 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045208
5209 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5210 TestCompletionCallback callback;
5211 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5212 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5213
5214 // Confirm the handshake after the 425 Too Early.
5215 base::RunLoop().RunUntilIdle();
5216
5217 // The handshake hasn't been confirmed yet, so the retry should not have
5218 // succeeded.
5219 EXPECT_FALSE(callback.have_result());
5220
5221 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5222 quic::QuicSession::HANDSHAKE_CONFIRMED);
5223
5224 EXPECT_THAT(callback.WaitForResult(), IsOk());
5225 CheckWasQuicResponse(&trans);
5226 CheckResponseData(&trans, "hello!");
5227}
5228
5229TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5230 MockQuicData mock_quic_data;
5231 quic::QuicStreamOffset client_header_stream_offset = 0;
5232 quic::QuicStreamOffset server_header_stream_offset = 0;
5233 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5234 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045235 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335236 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5237 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5238 true, GetRequestHeaders("GET", "https", "/"),
5239 &client_header_stream_offset));
5240 mock_quic_data.AddRead(
5241 ASYNC,
5242 ConstructServerResponseHeadersPacket(
5243 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5244 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5245 mock_quic_data.AddWrite(SYNCHRONOUS,
5246 ConstructClientAckAndRstPacket(
5247 2, GetNthClientInitiatedBidirectionalStreamId(0),
5248 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045249
5250 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5251
5252 spdy::SpdySettingsIR settings_frame;
5253 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5254 quic::kDefaultMaxUncompressedHeaderSize);
5255 spdy::SpdySerializedFrame spdy_frame(
5256 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5257 mock_quic_data.AddWrite(
5258 SYNCHRONOUS,
5259 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385260 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5261 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045262 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5263 client_header_stream_offset += spdy_frame.size();
5264
5265 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335266 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5267 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5268 true, GetRequestHeaders("GET", "https", "/"),
5269 GetNthClientInitiatedBidirectionalStreamId(0),
5270 &client_header_stream_offset));
5271 mock_quic_data.AddRead(
5272 ASYNC,
5273 ConstructServerResponseHeadersPacket(
5274 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5275 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5276 mock_quic_data.AddWrite(SYNCHRONOUS,
5277 ConstructClientAckAndRstPacket(
5278 5, GetNthClientInitiatedBidirectionalStreamId(1),
5279 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045280 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5281 mock_quic_data.AddRead(ASYNC, 0); // EOF
5282
5283 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5284
5285 // In order for a new QUIC session to be established via alternate-protocol
5286 // without racing an HTTP connection, we need the host resolution to happen
5287 // synchronously.
5288 host_resolver_.set_synchronous_mode(true);
5289 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5290 "");
5291 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5292 AddressList address;
5293 std::unique_ptr<HostResolver::Request> request;
5294 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5295 CompletionOnceCallback(), &request, net_log_.bound());
5296
5297 AddHangingNonAlternateProtocolSocketData();
5298 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275299 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565300 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5301 QuicStreamFactoryPeer::SetAlarmFactory(
5302 session_->quic_stream_factory(),
5303 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5304 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045305
5306 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5307 TestCompletionCallback callback;
5308 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5309 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5310
5311 // Confirm the handshake after the 425 Too Early.
5312 base::RunLoop().RunUntilIdle();
5313
5314 // The handshake hasn't been confirmed yet, so the retry should not have
5315 // succeeded.
5316 EXPECT_FALSE(callback.have_result());
5317
5318 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5319 quic::QuicSession::HANDSHAKE_CONFIRMED);
5320
5321 EXPECT_THAT(callback.WaitForResult(), IsOk());
5322 const HttpResponseInfo* response = trans.GetResponseInfo();
5323 ASSERT_TRUE(response != nullptr);
5324 ASSERT_TRUE(response->headers.get() != nullptr);
5325 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5326 EXPECT_TRUE(response->was_fetched_via_spdy);
5327 EXPECT_TRUE(response->was_alpn_negotiated);
5328 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5329 response->connection_info);
5330}
5331
zhongyica364fbb2015-12-12 03:39:125332TEST_P(QuicNetworkTransactionTest,
5333 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485334 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125335 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525336 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365337 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435338 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5339 mock_quic_data.AddWrite(
5340 SYNCHRONOUS,
5341 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335342 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435343 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125344 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525345 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435346 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125347 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5348
5349 // The non-alternate protocol job needs to hang in order to guarantee that
5350 // the alternate-protocol job will "win".
5351 AddHangingNonAlternateProtocolSocketData();
5352
5353 // In order for a new QUIC session to be established via alternate-protocol
5354 // without racing an HTTP connection, we need the host resolution to happen
5355 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5356 // connection to the the server, in this test we require confirmation
5357 // before encrypting so the HTTP job will still start.
5358 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295359 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125360 "");
rch9ae5b3b2016-02-11 00:36:295361 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125362 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105363 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585364 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5365 CompletionOnceCallback(), &request,
5366 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415367 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125368
rch3f4b8452016-02-23 16:59:325369 CreateSession();
zhongyica364fbb2015-12-12 03:39:125370 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275371 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125372
bnc691fda62016-08-12 00:43:165373 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125374 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415375 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125377
5378 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525379 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015380 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125381
5382 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525383 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125384
bnc691fda62016-08-12 00:43:165385 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125386 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525387 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5388 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125389}
5390
5391TEST_P(QuicNetworkTransactionTest,
5392 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485393 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125394 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525395 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365396 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435397 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5398 mock_quic_data.AddWrite(
5399 SYNCHRONOUS,
5400 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335401 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435402 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215403 // Peer sending data from an non-existing stream causes this end to raise
5404 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335405 mock_quic_data.AddRead(
5406 ASYNC, ConstructServerRstPacket(
5407 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5408 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215409 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525410 mock_quic_data.AddWrite(
5411 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5412 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5413 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125414 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5415
5416 // The non-alternate protocol job needs to hang in order to guarantee that
5417 // the alternate-protocol job will "win".
5418 AddHangingNonAlternateProtocolSocketData();
5419
5420 // In order for a new QUIC session to be established via alternate-protocol
5421 // without racing an HTTP connection, we need the host resolution to happen
5422 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5423 // connection to the the server, in this test we require confirmation
5424 // before encrypting so the HTTP job will still start.
5425 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295426 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125427 "");
rch9ae5b3b2016-02-11 00:36:295428 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125429 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105430 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585431 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5432 CompletionOnceCallback(), &request,
5433 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415434 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125435
rch3f4b8452016-02-23 16:59:325436 CreateSession();
zhongyica364fbb2015-12-12 03:39:125437 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275438 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125439
bnc691fda62016-08-12 00:43:165440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125441 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415442 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125444
5445 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525446 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015447 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125448 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525449 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125450
bnc691fda62016-08-12 00:43:165451 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525452 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125453}
5454
rchcd5f1c62016-06-23 02:43:485455TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5456 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525457 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365458 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435459 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5460 mock_quic_data.AddWrite(
5461 SYNCHRONOUS,
5462 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335463 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435464 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485465 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335466 mock_quic_data.AddRead(
5467 ASYNC, ConstructServerResponseHeadersPacket(
5468 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5469 GetResponseHeaders("200 OK")));
5470 mock_quic_data.AddRead(
5471 ASYNC, ConstructServerRstPacket(
5472 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5473 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435474 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485475 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5476 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5477
5478 // The non-alternate protocol job needs to hang in order to guarantee that
5479 // the alternate-protocol job will "win".
5480 AddHangingNonAlternateProtocolSocketData();
5481
5482 // In order for a new QUIC session to be established via alternate-protocol
5483 // without racing an HTTP connection, we need the host resolution to happen
5484 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5485 // connection to the the server, in this test we require confirmation
5486 // before encrypting so the HTTP job will still start.
5487 host_resolver_.set_synchronous_mode(true);
5488 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5489 "");
5490 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5491 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105492 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585493 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5494 CompletionOnceCallback(), &request,
5495 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415496 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485497
5498 CreateSession();
5499 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275500 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485501
bnc691fda62016-08-12 00:43:165502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485503 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415504 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015505 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485506
5507 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525508 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485509 // Read the headers.
robpercival214763f2016-07-01 23:27:015510 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485511
bnc691fda62016-08-12 00:43:165512 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485513 ASSERT_TRUE(response != nullptr);
5514 ASSERT_TRUE(response->headers.get() != nullptr);
5515 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5516 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525517 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445518 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5519 response->connection_info);
rchcd5f1c62016-06-23 02:43:485520
5521 std::string response_data;
bnc691fda62016-08-12 00:43:165522 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485523}
5524
5525TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485526 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485527 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525528 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365529 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435530 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5531 mock_quic_data.AddWrite(
5532 SYNCHRONOUS,
5533 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335534 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435535 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335536 mock_quic_data.AddRead(
5537 ASYNC, ConstructServerRstPacket(
5538 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5539 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485540 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5541 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5542
5543 // The non-alternate protocol job needs to hang in order to guarantee that
5544 // the alternate-protocol job will "win".
5545 AddHangingNonAlternateProtocolSocketData();
5546
5547 // In order for a new QUIC session to be established via alternate-protocol
5548 // without racing an HTTP connection, we need the host resolution to happen
5549 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5550 // connection to the the server, in this test we require confirmation
5551 // before encrypting so the HTTP job will still start.
5552 host_resolver_.set_synchronous_mode(true);
5553 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5554 "");
5555 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5556 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105557 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585558 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5559 CompletionOnceCallback(), &request,
5560 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415561 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485562
5563 CreateSession();
5564 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275565 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485566
bnc691fda62016-08-12 00:43:165567 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485568 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415569 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015570 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485571
5572 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525573 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485574 // Read the headers.
robpercival214763f2016-07-01 23:27:015575 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485576}
5577
[email protected]1e960032013-12-20 19:00:205578TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305579 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525580 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585581 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305582 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505583 MockRead(ASYNC, close->data(), close->length()),
5584 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5585 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305586 };
Ryan Sleevib8d7ea02018-05-07 20:01:015587 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305588 socket_factory_.AddSocketDataProvider(&quic_data);
5589
5590 // Main job which will succeed even though the alternate job fails.
5591 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025592 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5593 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5594 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305595
Ryan Sleevib8d7ea02018-05-07 20:01:015596 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305597 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565598 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305599
rch3f4b8452016-02-23 16:59:325600 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275601 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195602 SendRequestAndExpectHttpResponse("hello from http");
5603 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305604}
5605
[email protected]1e960032013-12-20 19:00:205606TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595607 // Alternate-protocol job
5608 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025609 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595610 };
Ryan Sleevib8d7ea02018-05-07 20:01:015611 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595612 socket_factory_.AddSocketDataProvider(&quic_data);
5613
5614 // Main job which will succeed even though the alternate job fails.
5615 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025616 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5617 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5618 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595619
Ryan Sleevib8d7ea02018-05-07 20:01:015620 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595621 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565622 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595623
rch3f4b8452016-02-23 16:59:325624 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595625
Ryan Hamilton9835e662018-08-02 05:36:275626 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195627 SendRequestAndExpectHttpResponse("hello from http");
5628 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595629}
5630
[email protected]00c159f2014-05-21 22:38:165631TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535632 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165633 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025634 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165635 };
Ryan Sleevib8d7ea02018-05-07 20:01:015636 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165637 socket_factory_.AddSocketDataProvider(&quic_data);
5638
[email protected]eb71ab62014-05-23 07:57:535639 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165640 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025641 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165642 };
5643
Ryan Sleevib8d7ea02018-05-07 20:01:015644 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165645 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5646 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565647 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165648
rtennetib8e80fb2016-05-16 00:12:095649 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325650 CreateSession();
[email protected]00c159f2014-05-21 22:38:165651
Ryan Hamilton9835e662018-08-02 05:36:275652 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165653 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165654 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165655 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5657 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165658 ExpectQuicAlternateProtocolMapping();
5659}
5660
Zhongyi Shia0cef1082017-08-25 01:49:505661TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5662 // Tests that TCP job is delayed and QUIC job does not require confirmation
5663 // if QUIC was recently supported on the same IP on start.
5664
5665 // Set QUIC support on the last IP address, which is same with the local IP
5666 // address. Require confirmation mode will be turned off immediately when
5667 // local IP address is sorted out after we configure the UDP socket.
5668 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5669
5670 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525671 quic::QuicStreamOffset header_stream_offset = 0;
5672 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5673 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:435674 mock_quic_data.AddWrite(
5675 SYNCHRONOUS,
5676 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335677 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435678 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435679 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335680 ASYNC, ConstructServerResponseHeadersPacket(
5681 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5682 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415683 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335684 mock_quic_data.AddRead(
5685 ASYNC, ConstructServerDataPacket(
5686 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415687 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435688 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505689 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5690 mock_quic_data.AddRead(ASYNC, 0); // EOF
5691
5692 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5693 // No HTTP data is mocked as TCP job never starts in this case.
5694
5695 CreateSession();
5696 // QuicStreamFactory by default requires confirmation on construction.
5697 session_->quic_stream_factory()->set_require_confirmation(true);
5698
Ryan Hamilton9835e662018-08-02 05:36:275699 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505700
5701 // Stall host resolution so that QUIC job will not succeed synchronously.
5702 // Socket will not be configured immediately and QUIC support is not sorted
5703 // out, TCP job will still be delayed as server properties indicates QUIC
5704 // support on last IP address.
5705 host_resolver_.set_synchronous_mode(false);
5706
5707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5708 TestCompletionCallback callback;
5709 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5710 IsError(ERR_IO_PENDING));
5711 // Complete host resolution in next message loop so that QUIC job could
5712 // proceed.
5713 base::RunLoop().RunUntilIdle();
5714 EXPECT_THAT(callback.WaitForResult(), IsOk());
5715
5716 CheckWasQuicResponse(&trans);
5717 CheckResponseData(&trans, "hello!");
5718}
5719
5720TEST_P(QuicNetworkTransactionTest,
5721 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5722 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5723 // was recently supported on a different IP address on start.
5724
5725 // Set QUIC support on the last IP address, which is different with the local
5726 // IP address. Require confirmation mode will remain when local IP address is
5727 // sorted out after we configure the UDP socket.
5728 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5729
5730 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525731 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505732 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435733 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5734 mock_quic_data.AddWrite(
5735 SYNCHRONOUS,
5736 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335737 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435738 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435739 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335740 ASYNC, ConstructServerResponseHeadersPacket(
5741 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5742 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415743 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335744 mock_quic_data.AddRead(
5745 ASYNC, ConstructServerDataPacket(
5746 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415747 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435748 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505749 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5750 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5751 // No HTTP data is mocked as TCP job will be delayed and never starts.
5752
5753 CreateSession();
5754 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275755 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505756
5757 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5758 // Socket will not be configured immediately and QUIC support is not sorted
5759 // out, TCP job will still be delayed as server properties indicates QUIC
5760 // support on last IP address.
5761 host_resolver_.set_synchronous_mode(false);
5762
5763 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5764 TestCompletionCallback callback;
5765 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5766 IsError(ERR_IO_PENDING));
5767
5768 // Complete host resolution in next message loop so that QUIC job could
5769 // proceed.
5770 base::RunLoop().RunUntilIdle();
5771 // Explicitly confirm the handshake so that QUIC job could succeed.
5772 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525773 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505774 EXPECT_THAT(callback.WaitForResult(), IsOk());
5775
5776 CheckWasQuicResponse(&trans);
5777 CheckResponseData(&trans, "hello!");
5778}
5779
Ryan Hamilton75f197262017-08-17 14:00:075780TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5781 // Test that NetErrorDetails is correctly populated, even if the
5782 // handshake has not yet been confirmed and no stream has been created.
5783
5784 // QUIC job will pause. When resumed, it will fail.
5785 MockQuicData mock_quic_data;
5786 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5787 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5788 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5789
5790 // Main job will also fail.
5791 MockRead http_reads[] = {
5792 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5793 };
5794
Ryan Sleevib8d7ea02018-05-07 20:01:015795 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075796 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5797 socket_factory_.AddSocketDataProvider(&http_data);
5798 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5799
5800 AddHangingNonAlternateProtocolSocketData();
5801 CreateSession();
5802 // Require handshake confirmation to ensure that no QUIC streams are
5803 // created, and to ensure that the TCP job does not wait for the QUIC
5804 // job to fail before it starts.
5805 session_->quic_stream_factory()->set_require_confirmation(true);
5806
Ryan Hamilton9835e662018-08-02 05:36:275807 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075808 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5809 TestCompletionCallback callback;
5810 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5812 // Allow the TCP job to fail.
5813 base::RunLoop().RunUntilIdle();
5814 // Now let the QUIC job fail.
5815 mock_quic_data.Resume();
5816 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5817 ExpectQuicAlternateProtocolMapping();
5818 NetErrorDetails details;
5819 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525820 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075821}
5822
[email protected]1e960032013-12-20 19:00:205823TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455824 // Alternate-protocol job
5825 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025826 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455827 };
Ryan Sleevib8d7ea02018-05-07 20:01:015828 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455829 socket_factory_.AddSocketDataProvider(&quic_data);
5830
[email protected]c92c1b52014-05-31 04:16:065831 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015832 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065833 socket_factory_.AddSocketDataProvider(&quic_data2);
5834
[email protected]4d283b32013-10-17 12:57:275835 // Final job that will proceed when the QUIC job fails.
5836 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025837 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5838 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5839 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275840
Ryan Sleevib8d7ea02018-05-07 20:01:015841 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275842 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565843 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275844
rtennetiafccbc062016-05-16 18:21:145845 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325846 CreateSession();
[email protected]77c6c162013-08-17 02:57:455847
Ryan Hamilton9835e662018-08-02 05:36:275848 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455849
[email protected]4d283b32013-10-17 12:57:275850 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455851
5852 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275853
rch37de576c2015-05-17 20:28:175854 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5855 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455856}
5857
[email protected]93b31772014-06-19 08:03:355858TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035859 // Alternate-protocol job
5860 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595861 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035862 };
Ryan Sleevib8d7ea02018-05-07 20:01:015863 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035864 socket_factory_.AddSocketDataProvider(&quic_data);
5865
5866 // Main job that will proceed when the QUIC job fails.
5867 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025868 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5869 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5870 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035871
Ryan Sleevib8d7ea02018-05-07 20:01:015872 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035873 socket_factory_.AddSocketDataProvider(&http_data);
5874
rtennetib8e80fb2016-05-16 00:12:095875 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325876 CreateSession();
[email protected]65768442014-06-06 23:37:035877
Ryan Hamilton9835e662018-08-02 05:36:275878 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035879
5880 SendRequestAndExpectHttpResponse("hello from http");
5881}
5882
[email protected]eb71ab62014-05-23 07:57:535883TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335884 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015885 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495886 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335887 socket_factory_.AddSocketDataProvider(&quic_data);
5888
5889 // Main job which will succeed even though the alternate job fails.
5890 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025891 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5892 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5893 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335894
Ryan Sleevib8d7ea02018-05-07 20:01:015895 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335896 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565897 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335898
rch3f4b8452016-02-23 16:59:325899 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275900 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335901 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535902
5903 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335904}
5905
[email protected]4fee9672014-01-08 14:47:155906TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155907 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435908 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335909 mock_quic_data.AddWrite(
5910 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5911 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5912 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435913 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
rcha5399e02015-04-21 19:32:045914 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155915
5916 // When the QUIC connection fails, we will try the request again over HTTP.
5917 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485918 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565919 MockRead("hello world"),
5920 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5921 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155922
Ryan Sleevib8d7ea02018-05-07 20:01:015923 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155924 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565925 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155926
5927 // In order for a new QUIC session to be established via alternate-protocol
5928 // without racing an HTTP connection, we need the host resolution to happen
5929 // synchronously.
5930 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295931 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565932 "");
rch9ae5b3b2016-02-11 00:36:295933 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]4fee9672014-01-08 14:47:155934 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105935 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585936 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5937 CompletionOnceCallback(), &request,
5938 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415939 EXPECT_THAT(rv, IsOk());
[email protected]4fee9672014-01-08 14:47:155940
rch3f4b8452016-02-23 16:59:325941 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275942 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]4fee9672014-01-08 14:47:155943 SendRequestAndExpectHttpResponse("hello world");
5944}
5945
tbansalc3308d72016-08-27 10:25:045946// For an alternative proxy that supports QUIC, test that the request is
5947// successfully fetched by the main job when the alternate proxy job encounters
5948// an error.
5949TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5950 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5951}
5952TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5953 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5954}
5955TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5956 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5957}
5958TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5959 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5960}
5961TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5962 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5963}
5964TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5965 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5966}
5967TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5968 TestAlternativeProxy(ERR_IO_PENDING);
5969}
5970TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5971 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5972}
5973
5974TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5975 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435976 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335977 mock_quic_data.AddWrite(
5978 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5979 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5980 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435981 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045982 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5983
5984 // When the QUIC connection fails, we will try the request again over HTTP.
5985 MockRead http_reads[] = {
5986 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5987 MockRead("hello world"),
5988 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5989 MockRead(ASYNC, OK)};
5990
Ryan Sleevib8d7ea02018-05-07 20:01:015991 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045992 socket_factory_.AddSocketDataProvider(&http_data);
5993 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5994
5995 TestProxyDelegate test_proxy_delegate;
5996 const HostPortPair host_port_pair("myproxy.org", 443);
5997 test_proxy_delegate.set_alternative_proxy_server(
5998 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5999 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6000
Ramin Halavatica8d5252018-03-12 05:33:496001 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
6002 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526003 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046004 request_.url = GURL("http://mail.example.org/");
6005
6006 // In order for a new QUIC session to be established via alternate-protocol
6007 // without racing an HTTP connection, we need the host resolution to happen
6008 // synchronously.
6009 host_resolver_.set_synchronous_mode(true);
6010 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
6011 HostResolver::RequestInfo info(HostPortPair("myproxy.org", 443));
6012 AddressList address;
6013 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:586014 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
6015 CompletionOnceCallback(), &request,
6016 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:416017 EXPECT_THAT(rv, IsOk());
tbansalc3308d72016-08-27 10:25:046018
6019 CreateSession();
6020 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596021 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166022 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046023}
6024
bnc508835902015-05-12 20:10:296025TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586026 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386027 EXPECT_FALSE(
6028 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296029 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526030 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366031 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436032 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6033 mock_quic_data.AddWrite(
6034 SYNCHRONOUS,
6035 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336036 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436037 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436038 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336039 ASYNC, ConstructServerResponseHeadersPacket(
6040 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6041 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416042 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336043 mock_quic_data.AddRead(
6044 ASYNC, ConstructServerDataPacket(
6045 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416046 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436047 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:506048 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296049 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6050
bncb07c05532015-05-14 19:07:206051 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096052 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326053 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276054 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296055 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386056 EXPECT_TRUE(
6057 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296058}
6059
zhongyi363c91c2017-03-23 23:16:086060// TODO(zhongyi): disabled this broken test as it was not testing the correct
6061// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6062TEST_P(QuicNetworkTransactionTest,
6063 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276064 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596065 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496066 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046067
6068 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046069
6070 test_proxy_delegate.set_alternative_proxy_server(
6071 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526072 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046073
6074 request_.url = GURL("http://mail.example.org/");
6075
6076 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6077 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016078 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046079 socket_factory_.AddSocketDataProvider(&socket_data);
6080
6081 // The non-alternate protocol job needs to hang in order to guarantee that
6082 // the alternate-protocol job will "win".
6083 AddHangingNonAlternateProtocolSocketData();
6084
6085 CreateSession();
6086 request_.method = "POST";
6087 ChunkedUploadDataStream upload_data(0);
6088 upload_data.AppendData("1", 1, true);
6089
6090 request_.upload_data_stream = &upload_data;
6091
6092 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6093 TestCompletionCallback callback;
6094 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6095 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6096 EXPECT_NE(OK, callback.WaitForResult());
6097
6098 // Verify that the alternative proxy server is not marked as broken.
6099 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6100
6101 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596102 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276103
6104 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6105 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6106 1);
tbansalc3308d72016-08-27 10:25:046107}
6108
rtenneti56977812016-01-15 19:26:566109TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:416110 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576111 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566112
6113 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6114 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016115 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:566116 socket_factory_.AddSocketDataProvider(&socket_data);
6117
rtennetib8e80fb2016-05-16 00:12:096118 // The non-alternate protocol job needs to hang in order to guarantee that
6119 // the alternate-protocol job will "win".
6120 AddHangingNonAlternateProtocolSocketData();
6121
rtenneti56977812016-01-15 19:26:566122 CreateSession();
6123 request_.method = "POST";
6124 ChunkedUploadDataStream upload_data(0);
6125 upload_data.AppendData("1", 1, true);
6126
6127 request_.upload_data_stream = &upload_data;
6128
bnc691fda62016-08-12 00:43:166129 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566130 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166131 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566133 EXPECT_NE(OK, callback.WaitForResult());
6134}
6135
rche11300ef2016-09-02 01:44:286136TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:486137 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286138 ScopedMockNetworkChangeNotifier network_change_notifier;
6139 MockNetworkChangeNotifier* mock_ncn =
6140 network_change_notifier.mock_network_change_notifier();
6141 mock_ncn->ForceNetworkHandlesSupported();
6142 mock_ncn->SetConnectedNetworksList(
6143 {kDefaultNetworkForTests, kNewNetworkForTests});
6144
mmenke6ddfbea2017-05-31 21:48:416145 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286146 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:316147 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286148
6149 MockQuicData socket_data;
6150 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526151 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436152 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:336153 socket_data.AddWrite(
6154 SYNCHRONOUS,
6155 ConstructClientRequestHeadersPacket(
6156 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6157 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286158 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6159 socket_data.AddSocketDataToFactory(&socket_factory_);
6160
6161 MockQuicData socket_data2;
6162 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6163 socket_data2.AddSocketDataToFactory(&socket_factory_);
6164
6165 // The non-alternate protocol job needs to hang in order to guarantee that
6166 // the alternate-protocol job will "win".
6167 AddHangingNonAlternateProtocolSocketData();
6168
6169 CreateSession();
6170 request_.method = "POST";
6171 ChunkedUploadDataStream upload_data(0);
6172
6173 request_.upload_data_stream = &upload_data;
6174
rdsmith1d343be52016-10-21 20:37:506175 std::unique_ptr<HttpNetworkTransaction> trans(
6176 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286177 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506178 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286179 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6180
6181 base::RunLoop().RunUntilIdle();
6182 upload_data.AppendData("1", 1, true);
6183 base::RunLoop().RunUntilIdle();
6184
6185 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506186 trans.reset();
rche11300ef2016-09-02 01:44:286187 session_.reset();
6188}
6189
Ryan Hamilton4b3574532017-10-30 20:17:256190TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6191 session_params_.origins_to_force_quic_on.insert(
6192 HostPortPair::FromString("mail.example.org:443"));
6193
6194 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526195 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436196 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256197 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336198 socket_data.AddWrite(
6199 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6200 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6201 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436202 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336203 ASYNC, ConstructServerResponseHeadersPacket(
6204 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6205 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416206 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336207 socket_data.AddRead(
6208 ASYNC, ConstructServerDataPacket(
6209 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416210 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436211 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256212 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166213 socket_data.AddWrite(
6214 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6215 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6216 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256217
6218 socket_data.AddSocketDataToFactory(&socket_factory_);
6219
6220 CreateSession();
6221
6222 SendRequestAndExpectQuicResponse("hello!");
6223 session_.reset();
6224}
6225
6226TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6227 session_params_.origins_to_force_quic_on.insert(
6228 HostPortPair::FromString("mail.example.org:443"));
6229
6230 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526231 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436232 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256233 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336234 socket_data.AddWrite(
6235 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6236 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6237 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436238 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336239 ASYNC, ConstructServerResponseHeadersPacket(
6240 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6241 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416242 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336243 socket_data.AddRead(
6244 ASYNC, ConstructServerDataPacket(
6245 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416246 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436247 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256248 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166249 socket_data.AddWrite(
6250 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6251 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6252 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256253
6254 socket_data.AddSocketDataToFactory(&socket_factory_);
6255
6256 CreateSession();
6257
6258 SendRequestAndExpectQuicResponse("hello!");
6259 session_.reset();
6260}
6261
Ryan Hamilton9edcf1a2017-11-22 05:55:176262TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486263 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256264 session_params_.origins_to_force_quic_on.insert(
6265 HostPortPair::FromString("mail.example.org:443"));
6266
6267 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526268 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256269 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436270 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176271 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256272 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6273 }
6274 socket_data.AddSocketDataToFactory(&socket_factory_);
6275
6276 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176277 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6278 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6279 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6280 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256281
Ryan Hamilton8d9ee76e2018-05-29 23:52:526282 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6284 TestCompletionCallback callback;
6285 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6286 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176287 while (!callback.have_result()) {
6288 base::RunLoop().RunUntilIdle();
6289 quic_task_runner_->RunUntilIdle();
6290 }
6291 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256292 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176293 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6294 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6295 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526296 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6297 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256298}
6299
Ryan Hamilton9edcf1a2017-11-22 05:55:176300TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486301 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256302 session_params_.origins_to_force_quic_on.insert(
6303 HostPortPair::FromString("mail.example.org:443"));
6304
6305 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526306 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256307 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436308 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176309 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256310 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6311 }
6312 socket_data.AddSocketDataToFactory(&socket_factory_);
6313
6314 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176315 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6316 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6317 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6318 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256319
Ryan Hamilton8d9ee76e2018-05-29 23:52:526320 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256321 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6322 TestCompletionCallback callback;
6323 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176325 while (!callback.have_result()) {
6326 base::RunLoop().RunUntilIdle();
6327 quic_task_runner_->RunUntilIdle();
6328 }
6329 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256330 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176331 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6332 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6333 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526334 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6335 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256336}
6337
Cherie Shi7596de632018-02-22 07:28:186338TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486339 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186340 session_params_.origins_to_force_quic_on.insert(
6341 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526342 const quic::QuicString error_details =
6343 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6344 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186345
6346 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526347 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186348 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436349 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186350 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6351 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526352 socket_data.AddWrite(
6353 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6354 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186355 socket_data.AddSocketDataToFactory(&socket_factory_);
6356
6357 CreateSession();
6358
6359 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6360 TestCompletionCallback callback;
6361 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6362 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6363 base::RunLoop().RunUntilIdle();
6364 ASSERT_TRUE(callback.have_result());
6365 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6366 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6367 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6368}
6369
ckrasic769733c2016-06-30 00:42:136370// Adds coverage to catch regression such as https://crbug.com/622043
6371TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416372 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136373 HostPortPair::FromString("mail.example.org:443"));
6374
6375 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526376 quic::QuicStreamOffset header_stream_offset = 0;
6377 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436378 mock_quic_data.AddWrite(
6379 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6380 &header_stream_offset));
6381 mock_quic_data.AddWrite(
6382 SYNCHRONOUS,
6383 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336384 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6385 true, true, GetRequestHeaders("GET", "https", "/"),
6386 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526387 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436388 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336389 ASYNC, ConstructServerPushPromisePacket(
6390 1, GetNthClientInitiatedBidirectionalStreamId(0),
6391 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6392 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6393 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576394 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266395 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336396 mock_quic_data.AddWrite(SYNCHRONOUS,
6397 ConstructClientPriorityPacket(
6398 client_packet_number++, false,
6399 GetNthServerInitiatedUnidirectionalStreamId(0),
6400 GetNthClientInitiatedBidirectionalStreamId(0),
6401 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576402 }
Zhongyi Shi32f2fd02018-04-16 18:23:436403 mock_quic_data.AddRead(
6404 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336405 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436406 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576407 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436408 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6409 mock_quic_data.AddRead(
6410 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336411 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6412 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416413 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436414 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336415 ASYNC, ConstructServerDataPacket(
6416 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416417 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576418 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436419 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416420 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436421 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336422 ASYNC, ConstructServerDataPacket(
6423 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416424 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336425 mock_quic_data.AddWrite(SYNCHRONOUS,
6426 ConstructClientAckAndRstPacket(
6427 client_packet_number++,
6428 GetNthServerInitiatedUnidirectionalStreamId(0),
6429 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136430 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6431 mock_quic_data.AddRead(ASYNC, 0); // EOF
6432 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6433
6434 // The non-alternate protocol job needs to hang in order to guarantee that
6435 // the alternate-protocol job will "win".
6436 AddHangingNonAlternateProtocolSocketData();
6437
6438 CreateSession();
6439
6440 // PUSH_PROMISE handling in the http layer gets exercised here.
6441 SendRequestAndExpectQuicResponse("hello!");
6442
6443 request_.url = GURL("https://mail.example.org/pushed.jpg");
6444 SendRequestAndExpectQuicResponse("and hello!");
6445
6446 // Check that the NetLog was filled reasonably.
6447 TestNetLogEntry::List entries;
6448 net_log_.GetEntries(&entries);
6449 EXPECT_LT(0u, entries.size());
6450
6451 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6452 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006453 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6454 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136455 EXPECT_LT(0, pos);
6456}
6457
rch56ec40a2017-06-23 14:48:446458// Regression test for http://crbug.com/719461 in which a promised stream
6459// is closed before the pushed headers arrive, but after the connection
6460// is closed and before the callbacks are executed.
6461TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486462 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446463 session_params_.origins_to_force_quic_on.insert(
6464 HostPortPair::FromString("mail.example.org:443"));
6465
6466 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526467 quic::QuicStreamOffset header_stream_offset = 0;
6468 quic::QuicPacketNumber client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446469 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436470 mock_quic_data.AddWrite(
6471 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6472 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446473 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436474 mock_quic_data.AddWrite(
6475 SYNCHRONOUS,
6476 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336477 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6478 true, true, GetRequestHeaders("GET", "https", "/"),
6479 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526480 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446481 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436482 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336483 ASYNC, ConstructServerPushPromisePacket(
6484 1, GetNthClientInitiatedBidirectionalStreamId(0),
6485 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6486 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6487 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576488 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266489 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336490 mock_quic_data.AddWrite(SYNCHRONOUS,
6491 ConstructClientPriorityPacket(
6492 client_packet_number++, false,
6493 GetNthServerInitiatedUnidirectionalStreamId(0),
6494 GetNthClientInitiatedBidirectionalStreamId(0),
6495 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576496 }
rch56ec40a2017-06-23 14:48:446497 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436498 mock_quic_data.AddRead(
6499 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336500 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436501 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446502 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576503 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436504 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446505 // Response body for first request.
Renjief49758b2019-01-11 23:32:416506 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436507 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336508 ASYNC, ConstructServerDataPacket(
6509 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416510 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446511 // Write error for the third request.
6512 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6513 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6514 mock_quic_data.AddRead(ASYNC, 0); // EOF
6515 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6516
6517 CreateSession();
6518
6519 // Send a request which triggers a push promise from the server.
6520 SendRequestAndExpectQuicResponse("hello!");
6521
6522 // Start a push transaction that will be cancelled after the connection
6523 // is closed, but before the callback is executed.
6524 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196525 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446526 session_.get());
6527 TestCompletionCallback callback2;
6528 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6529 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6530 base::RunLoop().RunUntilIdle();
6531
6532 // Cause the connection to close on a write error.
6533 HttpRequestInfo request3;
6534 request3.method = "GET";
6535 request3.url = GURL("https://mail.example.org/");
6536 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106537 request3.traffic_annotation =
6538 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446539 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6540 TestCompletionCallback callback3;
6541 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6542 IsError(ERR_IO_PENDING));
6543
6544 base::RunLoop().RunUntilIdle();
6545
6546 // When |trans2| is destroyed, the underlying stream will be closed.
6547 EXPECT_FALSE(callback2.have_result());
6548 trans2 = nullptr;
6549
6550 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6551}
6552
ckrasicda193a82016-07-09 00:39:366553TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416554 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366555 HostPortPair::FromString("mail.example.org:443"));
6556
6557 MockQuicData mock_quic_data;
6558
Ryan Hamilton8d9ee76e2018-05-29 23:52:526559 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416560 int write_packet_index = 1;
6561 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6562 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366563
Renjief49758b2019-01-11 23:32:416564 quic::QuicString header = ConstructDataHeader(1);
6565 if (version_ != quic::QUIC_VERSION_99) {
6566 mock_quic_data.AddWrite(
6567 SYNCHRONOUS,
6568 ConstructClientRequestHeadersAndDataFramesPacket(
6569 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6570 true, true, DEFAULT_PRIORITY,
6571 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6572 {"1"}));
6573 } else {
6574 mock_quic_data.AddWrite(
6575 SYNCHRONOUS,
6576 ConstructClientRequestHeadersAndDataFramesPacket(
6577 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6578 true, true, DEFAULT_PRIORITY,
6579 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6580 {header, "1"}));
6581 }
ckrasicda193a82016-07-09 00:39:366582
Zhongyi Shi32f2fd02018-04-16 18:23:436583 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336584 ASYNC, ConstructServerResponseHeadersPacket(
6585 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6586 GetResponseHeaders("200 OK")));
6587
Renjief49758b2019-01-11 23:32:416588 quic::QuicString header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336589 mock_quic_data.AddRead(
6590 ASYNC, ConstructServerDataPacket(
6591 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416592 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366593
Renjief49758b2019-01-11 23:32:416594 mock_quic_data.AddWrite(
6595 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366596
6597 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6598 mock_quic_data.AddRead(ASYNC, 0); // EOF
6599 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6600
6601 // The non-alternate protocol job needs to hang in order to guarantee that
6602 // the alternate-protocol job will "win".
6603 AddHangingNonAlternateProtocolSocketData();
6604
6605 CreateSession();
6606 request_.method = "POST";
6607 ChunkedUploadDataStream upload_data(0);
6608 upload_data.AppendData("1", 1, true);
6609
6610 request_.upload_data_stream = &upload_data;
6611
6612 SendRequestAndExpectQuicResponse("hello!");
6613}
6614
allada71b2efb2016-09-09 04:57:486615class QuicURLRequestContext : public URLRequestContext {
6616 public:
6617 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6618 MockClientSocketFactory* socket_factory)
6619 : storage_(this) {
6620 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076621 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046622 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486623 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046624 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596625 storage_.set_proxy_resolution_service(
6626 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076627 storage_.set_ssl_config_service(
6628 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486629 storage_.set_http_auth_handler_factory(
6630 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6631 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076632 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046633 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486634 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046635 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6636 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6637 false));
allada71b2efb2016-09-09 04:57:486638 }
6639
6640 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6641
6642 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6643
6644 private:
6645 MockClientSocketFactory* socket_factory_;
6646 URLRequestContextStorage storage_;
6647};
6648
6649TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416650 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486651 HostPortPair::FromString("mail.example.org:443"));
6652
6653 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526654 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366655 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436656 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136657 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486658 headers["user-agent"] = "";
6659 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336660 mock_quic_data.AddWrite(
6661 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6662 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6663 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486664
Ryan Hamilton8d9ee76e2018-05-29 23:52:526665 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336666 mock_quic_data.AddRead(
6667 ASYNC,
6668 ConstructServerResponseHeadersPacket(
6669 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6670 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486671
Renjief49758b2019-01-11 23:32:416672 quic::QuicString header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366673 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336674 ASYNC, ConstructServerDataPacket(
6675 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6676 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436677 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486678
6679 mock_quic_data.AddRead(ASYNC, 0); // EOF
6680
6681 CreateSession();
6682
6683 TestDelegate delegate;
6684 QuicURLRequestContext quic_url_request_context(std::move(session_),
6685 &socket_factory_);
6686
6687 mock_quic_data.AddSocketDataToFactory(
6688 &quic_url_request_context.socket_factory());
6689 TestNetworkDelegate network_delegate;
6690 quic_url_request_context.set_network_delegate(&network_delegate);
6691
6692 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296693 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6694 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486695 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6696 &ssl_data_);
6697
6698 request->Start();
Wez2a31b222018-06-07 22:07:156699 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486700
6701 EXPECT_LT(0, request->GetTotalSentBytes());
6702 EXPECT_LT(0, request->GetTotalReceivedBytes());
6703 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6704 request->GetTotalSentBytes());
6705 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6706 request->GetTotalReceivedBytes());
6707 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6708 request->raw_header_size());
Wez0e717112018-06-18 23:09:226709
6710 // Pump the message loop to allow all data to be consumed.
6711 base::RunLoop().RunUntilIdle();
6712
allada71b2efb2016-09-09 04:57:486713 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6714 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6715}
6716
6717TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416718 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486719 HostPortPair::FromString("mail.example.org:443"));
6720
6721 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526722 quic::QuicStreamOffset header_stream_offset = 0;
6723 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436724 mock_quic_data.AddWrite(
6725 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6726 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136727 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486728 headers["user-agent"] = "";
6729 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436730 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336731 SYNCHRONOUS,
6732 ConstructClientRequestHeadersPacket(
6733 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6734 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486735
Ryan Hamilton8d9ee76e2018-05-29 23:52:526736 quic::QuicStreamOffset server_header_offset = 0;
6737 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486738
Zhongyi Shi32f2fd02018-04-16 18:23:436739 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336740 ASYNC, ConstructServerPushPromisePacket(
6741 1, GetNthClientInitiatedBidirectionalStreamId(0),
6742 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6743 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6744 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486745
Yixin Wangb470bc882018-02-15 18:43:576746 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266747 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336748 mock_quic_data.AddWrite(SYNCHRONOUS,
6749 ConstructClientPriorityPacket(
6750 client_packet_number++, false,
6751 GetNthServerInitiatedUnidirectionalStreamId(0),
6752 GetNthClientInitiatedBidirectionalStreamId(0),
6753 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576754 }
6755
allada71b2efb2016-09-09 04:57:486756 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436757 mock_quic_data.AddRead(
6758 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336759 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436760 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486761 expected_raw_header_response_size =
6762 server_header_offset - expected_raw_header_response_size;
6763
Yixin Wangb470bc882018-02-15 18:43:576764 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436765 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486766
ckrasicbf2f59c2017-05-04 23:54:366767 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436768 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336769 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6770 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416771 quic::QuicString header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436772 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336773 ASYNC, ConstructServerDataPacket(
6774 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416775 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486776
Yixin Wangb470bc882018-02-15 18:43:576777 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436778 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416779 quic::QuicString header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366780 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336781 ASYNC, ConstructServerDataPacket(
6782 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416783 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486784
Zhongyi Shi32f2fd02018-04-16 18:23:436785 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486786
6787 CreateSession();
6788
6789 TestDelegate delegate;
6790 QuicURLRequestContext quic_url_request_context(std::move(session_),
6791 &socket_factory_);
6792
6793 mock_quic_data.AddSocketDataToFactory(
6794 &quic_url_request_context.socket_factory());
6795 TestNetworkDelegate network_delegate;
6796 quic_url_request_context.set_network_delegate(&network_delegate);
6797
6798 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296799 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6800 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486801 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6802 &ssl_data_);
6803
6804 request->Start();
Wez2a31b222018-06-07 22:07:156805 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486806
6807 EXPECT_LT(0, request->GetTotalSentBytes());
6808 EXPECT_LT(0, request->GetTotalReceivedBytes());
6809 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6810 request->GetTotalSentBytes());
6811 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6812 request->GetTotalReceivedBytes());
6813 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6814 request->raw_header_size());
Wez0e717112018-06-18 23:09:226815
6816 // Pump the message loop to allow all data to be consumed.
6817 base::RunLoop().RunUntilIdle();
6818
allada71b2efb2016-09-09 04:57:486819 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6820 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6821}
6822
Yixin Wang10f477ed2017-11-21 04:20:206823TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6824 session_params_.quic_host_whitelist.insert("mail.example.org");
6825
6826 MockRead http_reads[] = {
6827 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6828 MockRead("hello world"),
6829 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6830 MockRead(ASYNC, OK)};
6831
Ryan Sleevib8d7ea02018-05-07 20:01:016832 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206833 socket_factory_.AddSocketDataProvider(&http_data);
6834 AddCertificate(&ssl_data_);
6835 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6836
6837 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526838 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206839 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436840 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6841 mock_quic_data.AddWrite(
6842 SYNCHRONOUS,
6843 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336844 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436845 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436846 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336847 ASYNC, ConstructServerResponseHeadersPacket(
6848 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6849 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416850 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336851 mock_quic_data.AddRead(
6852 ASYNC, ConstructServerDataPacket(
6853 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416854 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436855 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206856 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6857 mock_quic_data.AddRead(ASYNC, 0); // EOF
6858
6859 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6860
6861 AddHangingNonAlternateProtocolSocketData();
6862 CreateSession();
6863
6864 SendRequestAndExpectHttpResponse("hello world");
6865 SendRequestAndExpectQuicResponse("hello!");
6866}
6867
6868TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6869 session_params_.quic_host_whitelist.insert("mail.example.com");
6870
6871 MockRead http_reads[] = {
6872 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6873 MockRead("hello world"),
6874 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6875 MockRead(ASYNC, OK)};
6876
Ryan Sleevib8d7ea02018-05-07 20:01:016877 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206878 socket_factory_.AddSocketDataProvider(&http_data);
6879 AddCertificate(&ssl_data_);
6880 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6881 socket_factory_.AddSocketDataProvider(&http_data);
6882 AddCertificate(&ssl_data_);
6883 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6884
6885 AddHangingNonAlternateProtocolSocketData();
6886 CreateSession();
6887
6888 SendRequestAndExpectHttpResponse("hello world");
6889 SendRequestAndExpectHttpResponse("hello world");
6890}
6891
bnc359ed2a2016-04-29 20:43:456892class QuicNetworkTransactionWithDestinationTest
6893 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016894 public ::testing::WithParamInterface<PoolingTestParams>,
6895 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456896 protected:
6897 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556898 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056899 client_headers_include_h2_stream_dependency_(
6900 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526901 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456902 destination_type_(GetParam().destination_type),
6903 cert_transparency_verifier_(new MultiLogCTVerifier()),
6904 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596905 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456906 auth_handler_factory_(
6907 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6908 random_generator_(0),
6909 ssl_data_(ASYNC, OK) {}
6910
6911 void SetUp() override {
6912 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556913 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456914
mmenke6ddfbea2017-05-31 21:48:416915 HttpNetworkSession::Params session_params;
6916 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346917 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446918 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056919 session_params.quic_headers_include_h2_stream_dependency =
6920 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416921
6922 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456923
Ryan Hamilton8d9ee76e2018-05-29 23:52:526924 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416925 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456926
6927 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276928 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416929 session_context.quic_crypto_client_stream_factory =
6930 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456931
mmenke6ddfbea2017-05-31 21:48:416932 session_context.quic_random = &random_generator_;
6933 session_context.client_socket_factory = &socket_factory_;
6934 session_context.host_resolver = &host_resolver_;
6935 session_context.cert_verifier = &cert_verifier_;
6936 session_context.transport_security_state = &transport_security_state_;
6937 session_context.cert_transparency_verifier =
6938 cert_transparency_verifier_.get();
6939 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6940 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456941 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416942 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596943 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416944 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6945 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456946
mmenke6ddfbea2017-05-31 21:48:416947 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456948 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456949 }
6950
6951 void TearDown() override {
6952 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6953 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556954 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456955 PlatformTest::TearDown();
6956 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556957 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406958 session_.reset();
bnc359ed2a2016-04-29 20:43:456959 }
6960
zhongyie537a002017-06-27 16:48:216961 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456962 HostPortPair destination;
6963 switch (destination_type_) {
6964 case SAME_AS_FIRST:
6965 destination = HostPortPair(origin1_, 443);
6966 break;
6967 case SAME_AS_SECOND:
6968 destination = HostPortPair(origin2_, 443);
6969 break;
6970 case DIFFERENT:
6971 destination = HostPortPair(kDifferentHostname, 443);
6972 break;
6973 }
bnc3472afd2016-11-17 15:27:216974 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456975 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216976 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456977 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446978 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456979 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526980 std::unique_ptr<quic::QuicEncryptedPacket>
6981 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6982 quic::QuicStreamId stream_id,
6983 bool should_include_version,
6984 quic::QuicStreamOffset* offset,
6985 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486986 return ConstructClientRequestHeadersPacket(
6987 packet_number, stream_id, should_include_version, 0, offset, maker);
6988 }
bnc359ed2a2016-04-29 20:43:456989
Ryan Hamilton8d9ee76e2018-05-29 23:52:526990 std::unique_ptr<quic::QuicEncryptedPacket>
6991 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6992 quic::QuicStreamId stream_id,
6993 bool should_include_version,
6994 quic::QuicStreamId parent_stream_id,
6995 quic::QuicStreamOffset* offset,
6996 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136997 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456998 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136999 spdy::SpdyHeaderBlock headers(
7000 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:457001 return maker->MakeRequestHeadersPacketWithOffsetTracking(
7002 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:487003 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:457004 }
7005
Ryan Hamilton8d9ee76e2018-05-29 23:52:527006 std::unique_ptr<quic::QuicEncryptedPacket>
7007 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
7008 quic::QuicStreamId stream_id,
7009 bool should_include_version,
7010 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587011 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457012 packet_number, stream_id, should_include_version, nullptr, maker);
7013 }
7014
Ryan Hamilton8d9ee76e2018-05-29 23:52:527015 std::unique_ptr<quic::QuicEncryptedPacket>
7016 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
7017 quic::QuicStreamId stream_id,
7018 quic::QuicStreamOffset* offset,
7019 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137020 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:457021 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:267022 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:457023 }
7024
Ryan Hamilton8d9ee76e2018-05-29 23:52:527025 std::unique_ptr<quic::QuicEncryptedPacket>
7026 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
7027 quic::QuicStreamId stream_id,
7028 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587029 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
7030 nullptr, maker);
bnc359ed2a2016-04-29 20:43:457031 }
7032
Ryan Hamilton8d9ee76e2018-05-29 23:52:527033 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
7034 quic::QuicPacketNumber packet_number,
7035 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457036 QuicTestPacketMaker* maker) {
Renjief49758b2019-01-11 23:32:417037 quic::QuicString header = "";
7038 if (version_ == quic::QUIC_VERSION_99) {
7039 quic::HttpEncoder encoder;
7040 std::unique_ptr<char[]> buffer;
7041 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
7042 header = quic::QuicString(buffer.get(), header_length);
7043 }
bnc359ed2a2016-04-29 20:43:457044 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:417045 header + "hello");
bnc359ed2a2016-04-29 20:43:457046 }
7047
Ryan Hamilton8d9ee76e2018-05-29 23:52:527048 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
7049 quic::QuicPacketNumber packet_number,
7050 quic::QuicPacketNumber largest_received,
7051 quic::QuicPacketNumber smallest_received,
7052 quic::QuicPacketNumber least_unacked,
bnc359ed2a2016-04-29 20:43:457053 QuicTestPacketMaker* maker) {
7054 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497055 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457056 }
7057
Ryan Hamilton8d9ee76e2018-05-29 23:52:527058 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
7059 quic::QuicPacketNumber packet_number,
7060 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:377061 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:367062 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:377063 }
7064
bnc359ed2a2016-04-29 20:43:457065 void AddRefusedSocketData() {
7066 std::unique_ptr<StaticSocketDataProvider> refused_data(
7067 new StaticSocketDataProvider());
7068 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7069 refused_data->set_connect_data(refused_connect);
7070 socket_factory_.AddSocketDataProvider(refused_data.get());
7071 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7072 }
7073
7074 void AddHangingSocketData() {
7075 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7076 new StaticSocketDataProvider());
7077 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7078 hanging_data->set_connect_data(hanging_connect);
7079 socket_factory_.AddSocketDataProvider(hanging_data.get());
7080 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7081 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7082 }
7083
7084 bool AllDataConsumed() {
7085 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7086 if (!socket_data_ptr->AllReadDataConsumed() ||
7087 !socket_data_ptr->AllWriteDataConsumed()) {
7088 return false;
7089 }
7090 }
7091 return true;
7092 }
7093
7094 void SendRequestAndExpectQuicResponse(const std::string& host) {
7095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7096 HttpRequestInfo request;
7097 std::string url("https://");
7098 url.append(host);
7099 request.url = GURL(url);
7100 request.load_flags = 0;
7101 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107102 request.traffic_annotation =
7103 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457104 TestCompletionCallback callback;
7105 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017106 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457107
7108 std::string response_data;
robpercival214763f2016-07-01 23:27:017109 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457110 EXPECT_EQ("hello", response_data);
7111
7112 const HttpResponseInfo* response = trans.GetResponseInfo();
7113 ASSERT_TRUE(response != nullptr);
7114 ASSERT_TRUE(response->headers.get() != nullptr);
7115 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7116 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527117 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:447118 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457119 response->connection_info);
7120 EXPECT_EQ(443, response->socket_address.port());
7121 }
7122
Fan Yang32c5a112018-12-10 20:06:337123 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
7124 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:367125 }
7126
Ryan Hamilton8d9ee76e2018-05-29 23:52:527127 quic::MockClock clock_;
7128 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:057129 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527130 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457131 DestinationType destination_type_;
7132 std::string origin1_;
7133 std::string origin2_;
7134 std::unique_ptr<HttpNetworkSession> session_;
7135 MockClientSocketFactory socket_factory_;
7136 MockHostResolver host_resolver_;
7137 MockCertVerifier cert_verifier_;
7138 TransportSecurityState transport_security_state_;
7139 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237140 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457141 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077142 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597143 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457144 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527145 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:457146 HttpServerPropertiesImpl http_server_properties_;
7147 BoundTestNetLog net_log_;
7148 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7149 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7150 static_socket_data_provider_vector_;
7151 SSLSocketDataProvider ssl_data_;
7152};
7153
Bence Békyce380cb2018-04-26 23:39:557154INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
bnc359ed2a2016-04-29 20:43:457155 QuicNetworkTransactionWithDestinationTest,
7156 ::testing::ValuesIn(GetPoolingTestParams()));
7157
7158// A single QUIC request fails because the certificate does not match the origin
7159// hostname, regardless of whether it matches the alternative service hostname.
7160TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7161 if (destination_type_ == DIFFERENT)
7162 return;
7163
7164 GURL url("https://mail.example.com/");
7165 origin1_ = url.host();
7166
7167 // Not used for requests, but this provides a test case where the certificate
7168 // is valid for the hostname of the alternative service.
7169 origin2_ = "mail.example.org";
7170
zhongyie537a002017-06-27 16:48:217171 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457172
7173 scoped_refptr<X509Certificate> cert(
7174 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247175 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7176 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457177
7178 ProofVerifyDetailsChromium verify_details;
7179 verify_details.cert_verify_result.verified_cert = cert;
7180 verify_details.cert_verify_result.is_issued_by_known_root = true;
7181 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7182
7183 MockQuicData mock_quic_data;
7184 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7185 mock_quic_data.AddRead(ASYNC, 0);
7186
7187 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7188
7189 AddRefusedSocketData();
7190
7191 HttpRequestInfo request;
7192 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107193 request.traffic_annotation =
7194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457195
7196 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7197 TestCompletionCallback callback;
7198 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017199 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457200
7201 EXPECT_TRUE(AllDataConsumed());
7202}
7203
7204// First request opens QUIC session to alternative service. Second request
7205// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527206// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457207TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7208 origin1_ = "mail.example.org";
7209 origin2_ = "news.example.org";
7210
zhongyie537a002017-06-27 16:48:217211 SetQuicAlternativeService(origin1_);
7212 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457213
7214 scoped_refptr<X509Certificate> cert(
7215 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247216 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7217 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7218 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457219
7220 ProofVerifyDetailsChromium verify_details;
7221 verify_details.cert_verify_result.verified_cert = cert;
7222 verify_details.cert_verify_result.is_issued_by_known_root = true;
7223 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7224
Yixin Wang079ad542018-01-11 04:06:057225 QuicTestPacketMaker client_maker(
Fan Yang32c5a112018-12-10 20:06:337226 version_, quic::EmptyQuicConnectionId(), &clock_, origin1_,
7227 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057228 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:337229 QuicTestPacketMaker server_maker(version_, quic::EmptyQuicConnectionId(),
7230 &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527231 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457232
Ryan Hamilton8d9ee76e2018-05-29 23:52:527233 quic::QuicStreamOffset request_header_offset(0);
7234 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457235
7236 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057237 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437238 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057239 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337240 mock_quic_data.AddWrite(
7241 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7242 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7243 &request_header_offset, &client_maker));
7244 mock_quic_data.AddRead(ASYNC,
7245 ConstructServerResponseHeadersPacket(
7246 1, GetNthClientInitiatedBidirectionalStreamId(0),
7247 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437248 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337249 ASYNC,
7250 ConstructServerDataPacket(
7251 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437252 mock_quic_data.AddWrite(SYNCHRONOUS,
7253 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457254
Yixin Wang079ad542018-01-11 04:06:057255 client_maker.set_hostname(origin2_);
7256 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457257
Zhongyi Shi32f2fd02018-04-16 18:23:437258 mock_quic_data.AddWrite(
7259 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337260 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7261 GetNthClientInitiatedBidirectionalStreamId(0),
7262 &request_header_offset, &client_maker));
7263 mock_quic_data.AddRead(ASYNC,
7264 ConstructServerResponseHeadersPacket(
7265 3, GetNthClientInitiatedBidirectionalStreamId(1),
7266 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437267 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337268 ASYNC,
7269 ConstructServerDataPacket(
7270 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437271 mock_quic_data.AddWrite(SYNCHRONOUS,
7272 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457273 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7274 mock_quic_data.AddRead(ASYNC, 0); // EOF
7275
7276 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7277
7278 AddHangingSocketData();
7279 AddHangingSocketData();
7280
Fan Yangc9e00dc2018-10-09 14:17:567281 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7282 QuicStreamFactoryPeer::SetAlarmFactory(
7283 session_->quic_stream_factory(),
7284 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7285 &clock_));
7286
bnc359ed2a2016-04-29 20:43:457287 SendRequestAndExpectQuicResponse(origin1_);
7288 SendRequestAndExpectQuicResponse(origin2_);
7289
7290 EXPECT_TRUE(AllDataConsumed());
7291}
7292
7293// First request opens QUIC session to alternative service. Second request does
7294// not pool to it, even though destination matches, because certificate is not
7295// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527296// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457297TEST_P(QuicNetworkTransactionWithDestinationTest,
7298 DoNotPoolIfCertificateInvalid) {
7299 origin1_ = "news.example.org";
7300 origin2_ = "mail.example.com";
7301
zhongyie537a002017-06-27 16:48:217302 SetQuicAlternativeService(origin1_);
7303 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457304
7305 scoped_refptr<X509Certificate> cert1(
7306 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247307 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7308 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7309 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457310
7311 scoped_refptr<X509Certificate> cert2(
7312 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247313 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7314 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457315
7316 ProofVerifyDetailsChromium verify_details1;
7317 verify_details1.cert_verify_result.verified_cert = cert1;
7318 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7319 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7320
7321 ProofVerifyDetailsChromium verify_details2;
7322 verify_details2.cert_verify_result.verified_cert = cert2;
7323 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7324 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7325
Yixin Wang079ad542018-01-11 04:06:057326 QuicTestPacketMaker client_maker1(
Fan Yang32c5a112018-12-10 20:06:337327 version_, quic::EmptyQuicConnectionId(), &clock_, origin1_,
7328 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057329 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:337330 QuicTestPacketMaker server_maker1(version_, quic::EmptyQuicConnectionId(),
7331 &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527332 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457333
7334 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527335 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457336 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437337 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7338 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337339 mock_quic_data1.AddWrite(
7340 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7341 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7342 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437343 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337344 ASYNC,
7345 ConstructServerResponseHeadersPacket(
7346 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437347 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337348 ASYNC,
7349 ConstructServerDataPacket(
7350 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437351 mock_quic_data1.AddWrite(
7352 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457353 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7354 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7355
7356 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7357
Yixin Wang079ad542018-01-11 04:06:057358 QuicTestPacketMaker client_maker2(
Fan Yang32c5a112018-12-10 20:06:337359 version_, quic::EmptyQuicConnectionId(), &clock_, origin2_,
7360 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057361 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:337362 QuicTestPacketMaker server_maker2(version_, quic::EmptyQuicConnectionId(),
7363 &clock_, origin2_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527364 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457365
7366 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527367 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457368 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437369 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7370 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337371 mock_quic_data2.AddWrite(
7372 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7373 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7374 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437375 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337376 ASYNC,
7377 ConstructServerResponseHeadersPacket(
7378 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437379 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337380 ASYNC,
7381 ConstructServerDataPacket(
7382 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437383 mock_quic_data2.AddWrite(
7384 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457385 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7386 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7387
7388 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7389
bnc359ed2a2016-04-29 20:43:457390 SendRequestAndExpectQuicResponse(origin1_);
7391 SendRequestAndExpectQuicResponse(origin2_);
7392
7393 EXPECT_TRUE(AllDataConsumed());
7394}
7395
ckrasicdee37572017-04-06 22:42:277396// crbug.com/705109 - this confirms that matching request with a body
7397// triggers a crash (pre-fix).
7398TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417399 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277400 HostPortPair::FromString("mail.example.org:443"));
7401
7402 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527403 quic::QuicStreamOffset header_stream_offset = 0;
7404 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437405 mock_quic_data.AddWrite(
7406 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7407 &header_stream_offset));
7408 mock_quic_data.AddWrite(
7409 SYNCHRONOUS,
7410 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337411 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7412 true, true, GetRequestHeaders("GET", "https", "/"),
7413 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527414 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437415 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337416 ASYNC, ConstructServerPushPromisePacket(
7417 1, GetNthClientInitiatedBidirectionalStreamId(0),
7418 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7419 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7420 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577421 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267422 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337423 mock_quic_data.AddWrite(SYNCHRONOUS,
7424 ConstructClientPriorityPacket(
7425 client_packet_number++, false,
7426 GetNthServerInitiatedUnidirectionalStreamId(0),
7427 GetNthClientInitiatedBidirectionalStreamId(0),
7428 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577429 }
Zhongyi Shi32f2fd02018-04-16 18:23:437430 mock_quic_data.AddRead(
7431 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337432 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437433 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577434 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437435 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7436 mock_quic_data.AddRead(
7437 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337438 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7439 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417440 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437441 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337442 ASYNC, ConstructServerDataPacket(
7443 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417444 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577445 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437446 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417447
7448 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437449 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337450 ASYNC, ConstructServerDataPacket(
7451 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417452 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277453
7454 // Because the matching request has a body, we will see the push
7455 // stream get cancelled, and the matching request go out on the
7456 // wire.
Fan Yang32c5a112018-12-10 20:06:337457 mock_quic_data.AddWrite(SYNCHRONOUS,
7458 ConstructClientAckAndRstPacket(
7459 client_packet_number++,
7460 GetNthServerInitiatedUnidirectionalStreamId(0),
7461 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277462 const char kBody[] = "1";
Renjief49758b2019-01-11 23:32:417463 quic::QuicString header3 = ConstructDataHeader(1);
7464 if (version_ != quic::QUIC_VERSION_99) {
7465 mock_quic_data.AddWrite(
7466 SYNCHRONOUS,
7467 ConstructClientRequestHeadersAndDataFramesPacket(
7468 client_packet_number++,
7469 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7470 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7471 GetNthServerInitiatedUnidirectionalStreamId(0),
7472 &header_stream_offset, nullptr, {kBody}));
7473 } else {
7474 mock_quic_data.AddWrite(
7475 SYNCHRONOUS,
7476 ConstructClientRequestHeadersAndDataFramesPacket(
7477 client_packet_number++,
7478 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7479 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7480 GetNthServerInitiatedUnidirectionalStreamId(0),
7481 &header_stream_offset, nullptr, {header3, kBody}));
7482 }
ckrasicdee37572017-04-06 22:42:277483
7484 // We see the same response as for the earlier pushed and cancelled
7485 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437486 mock_quic_data.AddRead(
7487 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337488 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437489 GetResponseHeaders("200 OK"), &server_header_offset));
7490 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337491 ASYNC, ConstructServerDataPacket(
7492 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417493 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277494
Yixin Wangb470bc882018-02-15 18:43:577495 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437496 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277497 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7498 mock_quic_data.AddRead(ASYNC, 0); // EOF
7499 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7500
7501 // The non-alternate protocol job needs to hang in order to guarantee that
7502 // the alternate-protocol job will "win".
7503 AddHangingNonAlternateProtocolSocketData();
7504
7505 CreateSession();
7506
7507 // PUSH_PROMISE handling in the http layer gets exercised here.
7508 SendRequestAndExpectQuicResponse("hello!");
7509
7510 request_.url = GURL("https://mail.example.org/pushed.jpg");
7511 ChunkedUploadDataStream upload_data(0);
7512 upload_data.AppendData("1", 1, true);
7513 request_.upload_data_stream = &upload_data;
7514 SendRequestAndExpectQuicResponse("and hello!");
7515}
7516
Bence Béky7538a952018-02-01 16:59:527517// Regression test for https://crbug.com/797825: If pushed headers describe a
7518// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7519// not be called (otherwise a DCHECK fails).
7520TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137521 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527522 pushed_request_headers[":authority"] = "";
7523 pushed_request_headers[":method"] = "GET";
7524 pushed_request_headers[":path"] = "/";
7525 pushed_request_headers[":scheme"] = "nosuchscheme";
7526
7527 session_params_.origins_to_force_quic_on.insert(
7528 HostPortPair::FromString("mail.example.org:443"));
7529
7530 MockQuicData mock_quic_data;
7531
Ryan Hamilton8d9ee76e2018-05-29 23:52:527532 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527533 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437534 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7535 mock_quic_data.AddWrite(
7536 SYNCHRONOUS,
7537 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337538 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437539 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527540
Ryan Hamilton8d9ee76e2018-05-29 23:52:527541 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337542 mock_quic_data.AddRead(
7543 ASYNC, ConstructServerPushPromisePacket(
7544 1, GetNthClientInitiatedBidirectionalStreamId(0),
7545 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7546 std::move(pushed_request_headers), &server_header_offset,
7547 &server_maker_));
7548 mock_quic_data.AddWrite(SYNCHRONOUS,
7549 ConstructClientRstPacket(
7550 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7551 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527552
Zhongyi Shi32f2fd02018-04-16 18:23:437553 mock_quic_data.AddRead(
7554 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337555 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437556 GetResponseHeaders("200 OK"), &server_header_offset));
7557 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527558
Zhongyi Shi32f2fd02018-04-16 18:23:437559 mock_quic_data.AddRead(
7560 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337561 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7562 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417563 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437564 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337565 ASYNC, ConstructServerDataPacket(
7566 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417567 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437568 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527569
7570 mock_quic_data.AddRead(ASYNC, 0);
7571 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7572
7573 // The non-alternate protocol job needs to hang in order to guarantee that
7574 // the alternate-protocol job will "win".
7575 AddHangingNonAlternateProtocolSocketData();
7576
7577 CreateSession();
7578
7579 // PUSH_PROMISE handling in the http layer gets exercised here.
7580 SendRequestAndExpectQuicResponse("hello!");
7581
7582 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7583 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7584}
7585
Yixin Wang46a273ec302018-01-23 17:59:567586// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147587TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567588 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147589 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567590 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497591 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567592
7593 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527594 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567595 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357596 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337597 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357598 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7599 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7600 false, ConnectRequestHeaders("mail.example.org:443"),
7601 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337602 mock_quic_data.AddRead(
7603 ASYNC, ConstructServerResponseHeadersPacket(
7604 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7605 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567606
7607 const char get_request[] =
7608 "GET / HTTP/1.1\r\n"
7609 "Host: mail.example.org\r\n"
7610 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417611 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7612 if (version_ != quic::QUIC_VERSION_99) {
7613 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357614 SYNCHRONOUS,
7615 ConstructClientAckAndDataPacket(
7616 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7617 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417618 } else {
7619 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417620 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357621 ConstructClientAckAndMultipleDataFramesPacket(
7622 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7623 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417624 }
7625
Yixin Wang46a273ec302018-01-23 17:59:567626 const char get_response[] =
7627 "HTTP/1.1 200 OK\r\n"
7628 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417629 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437630 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337631 ASYNC, ConstructServerDataPacket(
7632 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417633 0, header2 + quic::QuicString(get_response)));
7634 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337635 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417636 SYNCHRONOUS, ConstructServerDataPacket(
7637 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7638 false, strlen(get_response) + header2.length(),
7639 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:357640 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567641 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7642
7643 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417644 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357645 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7646 quic::QUIC_STREAM_CANCELLED,
7647 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567648
7649 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7650
7651 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7652
7653 CreateSession();
7654
7655 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097656 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567657 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7658 HeadersHandler headers_handler;
7659 trans.SetBeforeHeadersSentCallback(
7660 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7661 base::Unretained(&headers_handler)));
7662 RunTransaction(&trans);
7663 CheckWasHttpResponse(&trans);
7664 CheckResponsePort(&trans, 70);
7665 CheckResponseData(&trans, "0123456789");
7666 EXPECT_TRUE(headers_handler.was_proxied());
7667 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7668
7669 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7670 // proxy socket to disconnect.
7671 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7672
7673 base::RunLoop().RunUntilIdle();
7674 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7675 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7676}
7677
7678// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147679TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567680 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147681 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567682 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497683 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567684
7685 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527686 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567687 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357688 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337689 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357690 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7691 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7692 false, ConnectRequestHeaders("mail.example.org:443"),
7693 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337694 mock_quic_data.AddRead(
7695 ASYNC, ConstructServerResponseHeadersPacket(
7696 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7697 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567698
7699 SpdyTestUtil spdy_util;
7700
Ryan Hamilton0239aac2018-05-19 00:03:137701 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567702 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417703 quic::QuicString header = ConstructDataHeader(get_frame.size());
7704 if (version_ != quic::QUIC_VERSION_99) {
7705 mock_quic_data.AddWrite(
7706 SYNCHRONOUS,
7707 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357708 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7709 false, 0,
Renjief49758b2019-01-11 23:32:417710 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7711 } else {
7712 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417713 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357714 ConstructClientAckAndMultipleDataFramesPacket(
7715 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7716 false, 0,
7717 {header, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417718 }
Ryan Hamilton0239aac2018-05-19 00:03:137719 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567720 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417721 quic::QuicString header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437722 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337723 ASYNC,
7724 ConstructServerDataPacket(
7725 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Renjief49758b2019-01-11 23:32:417726 header2 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567727
Ryan Hamilton0239aac2018-05-19 00:03:137728 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197729 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Renjief49758b2019-01-11 23:32:417730 quic::QuicString header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437731 mock_quic_data.AddRead(
7732 SYNCHRONOUS,
7733 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337734 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417735 resp_frame.size() + header2.length(),
7736 header3 + quic::QuicString(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357737 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567738 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7739
7740 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437741 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357742 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7743 quic::QUIC_STREAM_CANCELLED,
7744 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567745
7746 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7747
7748 SSLSocketDataProvider ssl_data(ASYNC, OK);
7749 ssl_data.next_proto = kProtoHTTP2;
7750 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7751
7752 CreateSession();
7753
7754 request_.url = GURL("https://mail.example.org/");
7755 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7756 HeadersHandler headers_handler;
7757 trans.SetBeforeHeadersSentCallback(
7758 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7759 base::Unretained(&headers_handler)));
7760 RunTransaction(&trans);
7761 CheckWasSpdyResponse(&trans);
7762 CheckResponsePort(&trans, 70);
7763 CheckResponseData(&trans, "0123456789");
7764 EXPECT_TRUE(headers_handler.was_proxied());
7765 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7766
Wez0e717112018-06-18 23:09:227767 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7768 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567769 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7770
7771 base::RunLoop().RunUntilIdle();
7772 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7773 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7774}
7775
7776// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7777// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147778TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567779 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147780 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567781 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497782 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567783
7784 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527785 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417786 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567787 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417788 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7789 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337790 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417791 SYNCHRONOUS,
7792 ConstructClientRequestHeadersPacket(
7793 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7794 true, false, ConnectRequestHeaders("mail.example.org:443"),
7795 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337796 mock_quic_data.AddRead(
7797 ASYNC, ConstructServerResponseHeadersPacket(
7798 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7799 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567800
Ryan Hamilton8d9ee76e2018-05-29 23:52:527801 quic::QuicStreamOffset client_data_offset = 0;
7802 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567803 const char get_request_1[] =
7804 "GET / HTTP/1.1\r\n"
7805 "Host: mail.example.org\r\n"
7806 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417807 quic::QuicString header = ConstructDataHeader(strlen(get_request_1));
7808 if (version_ != quic::QUIC_VERSION_99) {
7809 mock_quic_data.AddWrite(
7810 SYNCHRONOUS,
7811 ConstructClientAckAndDataPacket(
7812 write_packet_index++, false,
7813 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7814 client_data_offset, quic::QuicStringPiece(get_request_1)));
7815 } else {
7816 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417817 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357818 ConstructClientAckAndMultipleDataFramesPacket(
7819 write_packet_index++, false,
7820 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7821 client_data_offset, {header, quic::QuicString(get_request_1)}));
Renjief49758b2019-01-11 23:32:417822 }
7823
7824 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567825
7826 const char get_response_1[] =
7827 "HTTP/1.1 200 OK\r\n"
7828 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417829 quic::QuicString header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437830 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417831 ASYNC,
7832 ConstructServerDataPacket(
7833 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7834 server_data_offset, header2 + quic::QuicString(get_response_1)));
7835 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567836
Renjief49758b2019-01-11 23:32:417837 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337838 mock_quic_data.AddRead(
7839 SYNCHRONOUS,
7840 ConstructServerDataPacket(
7841 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417842 server_data_offset, header3 + quic::QuicString("0123456789")));
7843 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567844
Renjief49758b2019-01-11 23:32:417845 mock_quic_data.AddWrite(
7846 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567847
7848 const char get_request_2[] =
7849 "GET /2 HTTP/1.1\r\n"
7850 "Host: mail.example.org\r\n"
7851 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417852 quic::QuicString header4 = ConstructDataHeader(strlen(get_request_2));
7853 if (version_ == quic::QUIC_VERSION_99) {
7854 mock_quic_data.AddWrite(
7855 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357856 ConstructClientMultipleDataFramesPacket(
7857 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7858 false, false, client_data_offset,
7859 {header4, quic::QuicString(get_request_2)}));
7860 client_data_offset += header4.length() + strlen(get_request_2);
7861 } else {
7862 mock_quic_data.AddWrite(
7863 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417864 ConstructClientDataPacket(write_packet_index++,
7865 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357866 false, false, client_data_offset,
7867 quic::QuicStringPiece(get_request_2)));
7868 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417869 }
Yixin Wang46a273ec302018-01-23 17:59:567870
7871 const char get_response_2[] =
7872 "HTTP/1.1 200 OK\r\n"
7873 "Content-Length: 7\r\n\r\n";
Renjief49758b2019-01-11 23:32:417874 quic::QuicString header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437875 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417876 ASYNC,
7877 ConstructServerDataPacket(
7878 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7879 server_data_offset, header5 + quic::QuicString(get_response_2)));
7880 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567881
Renjief49758b2019-01-11 23:32:417882 quic::QuicString header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527883 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337884 SYNCHRONOUS,
7885 ConstructServerDataPacket(
7886 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417887 server_data_offset, header6 + quic::QuicString("0123456")));
7888 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567889
Renjief49758b2019-01-11 23:32:417890 mock_quic_data.AddWrite(
7891 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567892 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7893
Renjief49758b2019-01-11 23:32:417894 mock_quic_data.AddWrite(
7895 SYNCHRONOUS,
7896 ConstructClientRstPacket(
7897 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7898 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567899
7900 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7901
7902 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7903
7904 CreateSession();
7905
7906 request_.url = GURL("https://mail.example.org/");
7907 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7908 HeadersHandler headers_handler_1;
7909 trans_1.SetBeforeHeadersSentCallback(
7910 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7911 base::Unretained(&headers_handler_1)));
7912 RunTransaction(&trans_1);
7913 CheckWasHttpResponse(&trans_1);
7914 CheckResponsePort(&trans_1, 70);
7915 CheckResponseData(&trans_1, "0123456789");
7916 EXPECT_TRUE(headers_handler_1.was_proxied());
7917 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7918
7919 request_.url = GURL("https://mail.example.org/2");
7920 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7921 HeadersHandler headers_handler_2;
7922 trans_2.SetBeforeHeadersSentCallback(
7923 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7924 base::Unretained(&headers_handler_2)));
7925 RunTransaction(&trans_2);
7926 CheckWasHttpResponse(&trans_2);
7927 CheckResponsePort(&trans_2, 70);
7928 CheckResponseData(&trans_2, "0123456");
7929 EXPECT_TRUE(headers_handler_2.was_proxied());
7930 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7931
7932 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7933 // proxy socket to disconnect.
7934 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7935
7936 base::RunLoop().RunUntilIdle();
7937 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7938 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7939}
7940
7941// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7942// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7943// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147944TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567945 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147946 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567947 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497948 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567949
7950 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527951 quic::QuicStreamOffset client_header_stream_offset = 0;
7952 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357953 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7954 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567955
7956 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337957 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357958 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7959 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7960 false, ConnectRequestHeaders("mail.example.org:443"),
7961 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437962 mock_quic_data.AddRead(
7963 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337964 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437965 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567966
7967 // GET request, response, and data over QUIC tunnel for first request
7968 const char get_request[] =
7969 "GET / HTTP/1.1\r\n"
7970 "Host: mail.example.org\r\n"
7971 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417972 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7973 if (version_ != quic::QUIC_VERSION_99) {
7974 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357975 SYNCHRONOUS,
7976 ConstructClientAckAndDataPacket(
7977 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7978 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417979 } else {
7980 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417981 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357982 ConstructClientAckAndMultipleDataFramesPacket(
7983 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7984 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417985 }
7986
Yixin Wang46a273ec302018-01-23 17:59:567987 const char get_response[] =
7988 "HTTP/1.1 200 OK\r\n"
7989 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417990 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567991 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337992 ASYNC, ConstructServerDataPacket(
7993 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417994 0, header2 + quic::QuicString(get_response)));
7995 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337996 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417997 SYNCHRONOUS, ConstructServerDataPacket(
7998 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7999 false, strlen(get_response) + header2.length(),
8000 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:358001 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568002
8003 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438004 mock_quic_data.AddWrite(
8005 SYNCHRONOUS,
8006 ConstructClientRequestHeadersPacket(
Renjied172e812019-01-16 05:12:358007 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8008 ConnectRequestHeaders("different.example.org:443"),
Fan Yang32c5a112018-12-10 20:06:338009 GetNthClientInitiatedBidirectionalStreamId(0),
8010 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438011 mock_quic_data.AddRead(
8012 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338013 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438014 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568015
8016 // GET request, response, and data over QUIC tunnel for second request
8017 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138018 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568019 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:418020 quic::QuicString header4 = ConstructDataHeader(get_frame.size());
8021 if (version_ != quic::QUIC_VERSION_99) {
8022 mock_quic_data.AddWrite(
8023 SYNCHRONOUS,
8024 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:358025 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
8026 false, 0,
Renjief49758b2019-01-11 23:32:418027 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
8028 } else {
8029 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418030 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358031 ConstructClientAckAndMultipleDataFramesPacket(
8032 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
8033 false, 0,
8034 {header4, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418035 }
Yixin Wang46a273ec302018-01-23 17:59:568036
Ryan Hamilton0239aac2018-05-19 00:03:138037 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568038 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:418039 quic::QuicString header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438040 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338041 ASYNC,
8042 ConstructServerDataPacket(
8043 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Renjief49758b2019-01-11 23:32:418044 header5 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568045
Ryan Hamilton0239aac2018-05-19 00:03:138046 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198047 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Renjief49758b2019-01-11 23:32:418048 quic::QuicString header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438049 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418050 ASYNC,
8051 ConstructServerDataPacket(
8052 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8053 resp_frame.size() + header5.length(),
8054 header6 + quic::QuicString(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568055
Renjied172e812019-01-16 05:12:358056 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568057 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8058
8059 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418060 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358061 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
8062 quic::QUIC_STREAM_CANCELLED,
8063 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568064 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438065 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358066 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
8067 quic::QUIC_STREAM_CANCELLED,
8068 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:568069
8070 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8071
8072 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8073
8074 SSLSocketDataProvider ssl_data(ASYNC, OK);
8075 ssl_data.next_proto = kProtoHTTP2;
8076 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8077
8078 CreateSession();
8079
8080 request_.url = GURL("https://mail.example.org/");
8081 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8082 HeadersHandler headers_handler_1;
8083 trans_1.SetBeforeHeadersSentCallback(
8084 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8085 base::Unretained(&headers_handler_1)));
8086 RunTransaction(&trans_1);
8087 CheckWasHttpResponse(&trans_1);
8088 CheckResponsePort(&trans_1, 70);
8089 CheckResponseData(&trans_1, "0123456789");
8090 EXPECT_TRUE(headers_handler_1.was_proxied());
8091 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8092
8093 request_.url = GURL("https://different.example.org/");
8094 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8095 HeadersHandler headers_handler_2;
8096 trans_2.SetBeforeHeadersSentCallback(
8097 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8098 base::Unretained(&headers_handler_2)));
8099 RunTransaction(&trans_2);
8100 CheckWasSpdyResponse(&trans_2);
8101 CheckResponsePort(&trans_2, 70);
8102 CheckResponseData(&trans_2, "0123456");
8103 EXPECT_TRUE(headers_handler_2.was_proxied());
8104 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8105
8106 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8107 // proxy socket to disconnect.
8108 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8109
8110 base::RunLoop().RunUntilIdle();
8111 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8112 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8113}
8114
8115// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148116TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568117 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148118 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568119 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498120 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568121
8122 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528123 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568124 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438125 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528126 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338127 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8128 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8129 false, ConnectRequestHeaders("mail.example.org:443"),
8130 &header_stream_offset));
8131 mock_quic_data.AddRead(
8132 ASYNC, ConstructServerResponseHeadersPacket(
8133 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8134 GetResponseHeaders("500")));
8135 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8136 mock_quic_data.AddWrite(SYNCHRONOUS,
8137 ConstructClientAckAndRstPacket(
8138 3, GetNthClientInitiatedBidirectionalStreamId(0),
8139 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568140
8141 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8142
8143 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8144
8145 CreateSession();
8146
8147 request_.url = GURL("https://mail.example.org/");
8148 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8149 HeadersHandler headers_handler;
8150 trans.SetBeforeHeadersSentCallback(
8151 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8152 base::Unretained(&headers_handler)));
8153 TestCompletionCallback callback;
8154 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8155 EXPECT_EQ(ERR_IO_PENDING, rv);
8156 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8157 EXPECT_EQ(false, headers_handler.was_proxied());
8158
8159 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8160 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8161}
8162
8163// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148164TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568165 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148166 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568167 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498168 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568169
8170 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528171 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568172 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438173 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338174 mock_quic_data.AddWrite(
8175 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8176 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8177 false, ConnectRequestHeaders("mail.example.org:443"),
8178 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568179 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8180
8181 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8182
8183 CreateSession();
8184
8185 request_.url = GURL("https://mail.example.org/");
8186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8187 HeadersHandler headers_handler;
8188 trans.SetBeforeHeadersSentCallback(
8189 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8190 base::Unretained(&headers_handler)));
8191 TestCompletionCallback callback;
8192 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8193 EXPECT_EQ(ERR_IO_PENDING, rv);
8194 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8195
8196 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8197 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8198}
8199
8200// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8201// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148202TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568203 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148204 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568205 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498206 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568207
8208 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528209 quic::QuicStreamOffset client_header_stream_offset = 0;
8210 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358211 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8212 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338213 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358214 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8215 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8216 false, ConnectRequestHeaders("mail.example.org:443"),
8217 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438218 mock_quic_data.AddRead(
8219 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338220 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438221 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358222 mock_quic_data.AddWrite(SYNCHRONOUS,
8223 ConstructClientAckAndRstPacket(
8224 3, GetNthClientInitiatedBidirectionalStreamId(0),
8225 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568226
Zhongyi Shi32f2fd02018-04-16 18:23:438227 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358228 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8229 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8230 false, ConnectRequestHeaders("mail.example.org:443"),
8231 GetNthClientInitiatedBidirectionalStreamId(0),
8232 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438233 mock_quic_data.AddRead(
8234 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338235 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438236 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568237
8238 const char get_request[] =
8239 "GET / HTTP/1.1\r\n"
8240 "Host: mail.example.org\r\n"
8241 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:418242 quic::QuicString header = ConstructDataHeader(strlen(get_request));
8243 if (version_ != quic::QUIC_VERSION_99) {
8244 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358245 SYNCHRONOUS,
8246 ConstructClientAckAndDataPacket(
8247 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8248 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418249 } else {
8250 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418251 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358252 ConstructClientAckAndMultipleDataFramesPacket(
8253 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8254 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:418255 }
Yixin Wang46a273ec302018-01-23 17:59:568256 const char get_response[] =
8257 "HTTP/1.1 200 OK\r\n"
8258 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:418259 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438260 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338261 ASYNC, ConstructServerDataPacket(
8262 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Renjief49758b2019-01-11 23:32:418263 0, header2 + quic::QuicString(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528264
Renjief49758b2019-01-11 23:32:418265 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338266 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418267 SYNCHRONOUS, ConstructServerDataPacket(
8268 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8269 false, strlen(get_response) + header2.length(),
8270 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:358271 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568272 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8273
8274 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418275 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358276 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8277 quic::QUIC_STREAM_CANCELLED,
8278 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568279
8280 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8281
8282 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8283 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8284
8285 SSLSocketDataProvider ssl_data(ASYNC, OK);
8286 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8287
8288 CreateSession();
8289
8290 request_.url = GURL("https://mail.example.org/");
8291 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8292 HeadersHandler headers_handler;
8293 trans.SetBeforeHeadersSentCallback(
8294 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8295 base::Unretained(&headers_handler)));
8296 TestCompletionCallback callback;
8297 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8298 EXPECT_EQ(ERR_IO_PENDING, rv);
8299 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8300
8301 rv = trans.RestartIgnoringLastError(callback.callback());
8302 EXPECT_EQ(ERR_IO_PENDING, rv);
8303 EXPECT_EQ(OK, callback.WaitForResult());
8304
8305 CheckWasHttpResponse(&trans);
8306 CheckResponsePort(&trans, 70);
8307 CheckResponseData(&trans, "0123456789");
8308 EXPECT_EQ(true, headers_handler.was_proxied());
8309 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8310
8311 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8312 // proxy socket to disconnect.
8313 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8314
8315 base::RunLoop().RunUntilIdle();
8316 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8317 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8318}
8319
8320// Checks if a request's specified "user-agent" header shows up correctly in the
8321// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148322TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Yixin Wang46a273ec302018-01-23 17:59:568323 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148324 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568325 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498326 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568327
8328 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528329 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568330 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438331 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568332
Ryan Hamilton0239aac2018-05-19 00:03:138333 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568334 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Fan Yang32c5a112018-12-10 20:06:338335 mock_quic_data.AddWrite(
8336 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8337 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8338 false, std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568339 // Return an error, so the transaction stops here (this test isn't interested
8340 // in the rest).
8341 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8342
8343 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8344
8345 CreateSession();
8346
8347 request_.url = GURL("https://mail.example.org/");
8348 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8349 "Chromium Ultra Awesome X Edition");
8350 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8351 HeadersHandler headers_handler;
8352 trans.SetBeforeHeadersSentCallback(
8353 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8354 base::Unretained(&headers_handler)));
8355 TestCompletionCallback callback;
8356 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8357 EXPECT_EQ(ERR_IO_PENDING, rv);
8358 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8359
8360 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8361 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8362}
8363
Yixin Wang00fc44c2018-01-23 21:12:208364// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8365// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148366TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208367 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148368 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208369 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498370 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208371
8372 const RequestPriority request_priority = MEDIUM;
8373
8374 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528375 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208376 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438377 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8378 mock_quic_data.AddWrite(
8379 SYNCHRONOUS,
8380 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338381 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8382 request_priority, ConnectRequestHeaders("mail.example.org:443"), 0,
Zhongyi Shi32f2fd02018-04-16 18:23:438383 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208384 // Return an error, so the transaction stops here (this test isn't interested
8385 // in the rest).
8386 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8387
8388 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8389
8390 CreateSession();
8391
8392 request_.url = GURL("https://mail.example.org/");
8393 HttpNetworkTransaction trans(request_priority, session_.get());
8394 TestCompletionCallback callback;
8395 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8396 EXPECT_EQ(ERR_IO_PENDING, rv);
8397 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8398
8399 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8400 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8401}
8402
Yixin Wang46a273ec302018-01-23 17:59:568403// Test the request-challenge-retry sequence for basic auth, over a QUIC
8404// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148405TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568406 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8407 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138408 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568409 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8410
8411 std::unique_ptr<QuicTestPacketMaker> client_maker;
8412 std::unique_ptr<QuicTestPacketMaker> server_maker;
8413
8414 // On the second pass, the body read of the auth challenge is synchronous, so
8415 // IsConnectedAndIdle returns false. The socket should still be drained and
8416 // reused. See http://crbug.com/544255.
8417 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338418 client_maker.reset(new QuicTestPacketMaker(
8419 version_, quic::EmptyQuicConnectionId(), &clock_,
8420 kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8421 client_headers_include_h2_stream_dependency_));
8422 server_maker.reset(new QuicTestPacketMaker(
8423 version_, quic::EmptyQuicConnectionId(), &clock_,
8424 kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568425
8426 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148427 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568428 proxy_resolution_service_ =
8429 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498430 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568431
8432 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528433 quic::QuicStreamOffset client_header_stream_offset = 0;
8434 quic::QuicStreamOffset server_header_stream_offset = 0;
8435 quic::QuicStreamOffset client_data_offset = 0;
8436 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568437
Zhongyi Shi32f2fd02018-04-16 18:23:438438 mock_quic_data.AddWrite(SYNCHRONOUS,
8439 client_maker->MakeInitialSettingsPacket(
8440 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568441
8442 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438443 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568444 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338445 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8446 default_priority,
Yixin Wang46a273ec302018-01-23 17:59:568447 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8448 &client_header_stream_offset));
8449
Ryan Hamilton0239aac2018-05-19 00:03:138450 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568451 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8452 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8453 headers["content-length"] = "10";
8454 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438455 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338456 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8457 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568458
8459 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438460 mock_quic_data.AddRead(
8461 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338462 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8463 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568464 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438465 mock_quic_data.AddRead(
8466 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338467 2, GetNthClientInitiatedBidirectionalStreamId(0),
8468 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568469 }
8470 server_data_offset += 10;
8471
Zhongyi Shi32f2fd02018-04-16 18:23:438472 mock_quic_data.AddWrite(SYNCHRONOUS,
8473 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568474
8475 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338476 SYNCHRONOUS,
8477 client_maker->MakeRstPacket(
8478 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
8479 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:568480
8481 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8482 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8483 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338484 SYNCHRONOUS, client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8485 5, GetNthClientInitiatedBidirectionalStreamId(1),
8486 false, false, default_priority, std::move(headers),
8487 GetNthClientInitiatedBidirectionalStreamId(0),
8488 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568489
8490 // Response to wrong password
8491 headers =
8492 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8493 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8494 headers["content-length"] = "10";
8495 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438496 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338497 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8498 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568499 mock_quic_data.AddRead(SYNCHRONOUS,
8500 ERR_IO_PENDING); // No more data to read
8501
Fan Yang32c5a112018-12-10 20:06:338502 mock_quic_data.AddWrite(
8503 SYNCHRONOUS,
8504 client_maker->MakeAckAndRstPacket(
8505 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8506 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568507
8508 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8509 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8510
8511 CreateSession();
8512
8513 request_.url = GURL("https://mail.example.org/");
8514 // Ensure that proxy authentication is attempted even
8515 // when the no authentication data flag is set.
8516 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8517 {
8518 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8519 HeadersHandler headers_handler;
8520 trans.SetBeforeHeadersSentCallback(
8521 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8522 base::Unretained(&headers_handler)));
8523 RunTransaction(&trans);
8524
8525 const HttpResponseInfo* response = trans.GetResponseInfo();
8526 ASSERT_TRUE(response != nullptr);
8527 ASSERT_TRUE(response->headers.get() != nullptr);
8528 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8529 response->headers->GetStatusLine());
8530 EXPECT_TRUE(response->headers->IsKeepAlive());
8531 EXPECT_EQ(407, response->headers->response_code());
8532 EXPECT_EQ(10, response->headers->GetContentLength());
8533 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8534 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8535 ASSERT_TRUE(auth_challenge != nullptr);
8536 EXPECT_TRUE(auth_challenge->is_proxy);
8537 EXPECT_EQ("https://proxy.example.org:70",
8538 auth_challenge->challenger.Serialize());
8539 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8540 EXPECT_EQ("basic", auth_challenge->scheme);
8541
8542 TestCompletionCallback callback;
8543 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8544 callback.callback());
8545 EXPECT_EQ(ERR_IO_PENDING, rv);
8546 EXPECT_EQ(OK, callback.WaitForResult());
8547
8548 response = trans.GetResponseInfo();
8549 ASSERT_TRUE(response != nullptr);
8550 ASSERT_TRUE(response->headers.get() != nullptr);
8551 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8552 response->headers->GetStatusLine());
8553 EXPECT_TRUE(response->headers->IsKeepAlive());
8554 EXPECT_EQ(407, response->headers->response_code());
8555 EXPECT_EQ(10, response->headers->GetContentLength());
8556 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8557 auth_challenge = response->auth_challenge.get();
8558 ASSERT_TRUE(auth_challenge != nullptr);
8559 EXPECT_TRUE(auth_challenge->is_proxy);
8560 EXPECT_EQ("https://proxy.example.org:70",
8561 auth_challenge->challenger.Serialize());
8562 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8563 EXPECT_EQ("basic", auth_challenge->scheme);
8564 }
8565 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8566 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8567 // reused because it's not connected).
8568 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8569 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8570 }
8571}
8572
Yixin Wang385652a2018-02-16 02:37:238573TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8574 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8575 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268576 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238577 !client_headers_include_h2_stream_dependency_) {
8578 return;
8579 }
8580
8581 session_params_.origins_to_force_quic_on.insert(
8582 HostPortPair::FromString("mail.example.org:443"));
8583
Fan Yang32c5a112018-12-10 20:06:338584 const quic::QuicStreamId client_stream_0 =
8585 GetNthClientInitiatedBidirectionalStreamId(0);
8586 const quic::QuicStreamId client_stream_1 =
8587 GetNthClientInitiatedBidirectionalStreamId(1);
8588 const quic::QuicStreamId client_stream_2 =
8589 GetNthClientInitiatedBidirectionalStreamId(2);
8590 const quic::QuicStreamId push_stream_0 =
8591 GetNthServerInitiatedUnidirectionalStreamId(0);
8592 const quic::QuicStreamId push_stream_1 =
8593 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238594
8595 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528596 quic::QuicStreamOffset header_stream_offset = 0;
8597 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238598 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438599 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238600
8601 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438602 mock_quic_data.AddWrite(SYNCHRONOUS,
8603 ConstructClientRequestHeadersPacket(
8604 2, client_stream_0, true, true, HIGHEST,
8605 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8606 &header_stream_offset));
8607 mock_quic_data.AddWrite(SYNCHRONOUS,
8608 ConstructClientRequestHeadersPacket(
8609 3, client_stream_1, true, true, MEDIUM,
8610 GetRequestHeaders("GET", "https", "/1.jpg"),
8611 client_stream_0, &header_stream_offset));
8612 mock_quic_data.AddWrite(SYNCHRONOUS,
8613 ConstructClientRequestHeadersPacket(
8614 4, client_stream_2, true, true, MEDIUM,
8615 GetRequestHeaders("GET", "https", "/2.jpg"),
8616 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238617
8618 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438619 mock_quic_data.AddRead(
8620 ASYNC, ConstructServerResponseHeadersPacket(
8621 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8622 &server_header_offset));
8623 mock_quic_data.AddRead(
8624 ASYNC, ConstructServerResponseHeadersPacket(
8625 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8626 &server_header_offset));
8627 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8628 mock_quic_data.AddRead(
8629 ASYNC, ConstructServerResponseHeadersPacket(
8630 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8631 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238632
8633 // Server sends two push promises associated with |client_stream_0|; client
8634 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8635 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438636 mock_quic_data.AddRead(ASYNC,
8637 ConstructServerPushPromisePacket(
8638 4, client_stream_0, push_stream_0, false,
8639 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8640 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238641 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438642 SYNCHRONOUS,
8643 ConstructClientAckAndPriorityFramesPacket(
8644 6, false, 4, 3, 1,
8645 {{push_stream_0, client_stream_2,
8646 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8647 &header_stream_offset));
8648 mock_quic_data.AddRead(ASYNC,
8649 ConstructServerPushPromisePacket(
8650 5, client_stream_0, push_stream_1, false,
8651 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8652 &server_header_offset, &server_maker_));
8653 mock_quic_data.AddWrite(
8654 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238655 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8656 DEFAULT_PRIORITY, &header_stream_offset));
8657
8658 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438659 mock_quic_data.AddRead(
8660 ASYNC, ConstructServerResponseHeadersPacket(
8661 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8662 &server_header_offset));
8663 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8664 mock_quic_data.AddRead(
8665 ASYNC, ConstructServerResponseHeadersPacket(
8666 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8667 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238668
8669 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8670 // priority updates to match the request's priority. Client sends PRIORITY
8671 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438672 mock_quic_data.AddWrite(
8673 SYNCHRONOUS,
8674 ConstructClientAckAndPriorityFramesPacket(
8675 9, false, 7, 7, 1,
8676 {{push_stream_1, client_stream_2,
8677 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8678 {push_stream_0, client_stream_0,
8679 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8680 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238681
8682 // Server sends data for the three requests and the two push promises.
Renjief49758b2019-01-11 23:32:418683 quic::QuicString header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438684 mock_quic_data.AddRead(
8685 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418686 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438687 mock_quic_data.AddRead(
8688 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418689 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438690 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8691 mock_quic_data.AddRead(
8692 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418693 header + "hello 2!"));
8694 quic::QuicString header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438695 mock_quic_data.AddRead(
8696 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418697 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438698 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8699 mock_quic_data.AddRead(
8700 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418701 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238702
Yixin Wang385652a2018-02-16 02:37:238703 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8704 mock_quic_data.AddRead(ASYNC, 0); // EOF
8705 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8706
8707 // The non-alternate protocol job needs to hang in order to guarantee that
8708 // the alternate-protocol job will "win".
8709 AddHangingNonAlternateProtocolSocketData();
8710
8711 CreateSession();
8712
8713 request_.url = GURL("https://mail.example.org/0.jpg");
8714 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8715 TestCompletionCallback callback_0;
8716 EXPECT_EQ(ERR_IO_PENDING,
8717 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8718 base::RunLoop().RunUntilIdle();
8719
8720 request_.url = GURL("https://mail.example.org/1.jpg");
8721 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8722 TestCompletionCallback callback_1;
8723 EXPECT_EQ(ERR_IO_PENDING,
8724 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8725 base::RunLoop().RunUntilIdle();
8726
8727 request_.url = GURL("https://mail.example.org/2.jpg");
8728 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8729 TestCompletionCallback callback_2;
8730 EXPECT_EQ(ERR_IO_PENDING,
8731 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8732 base::RunLoop().RunUntilIdle();
8733
8734 // Client makes request that matches resource pushed in |pushed_stream_0|.
8735 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8736 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8737 TestCompletionCallback callback_3;
8738 EXPECT_EQ(ERR_IO_PENDING,
8739 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8740 base::RunLoop().RunUntilIdle();
8741
8742 EXPECT_TRUE(callback_0.have_result());
8743 EXPECT_EQ(OK, callback_0.WaitForResult());
8744 EXPECT_TRUE(callback_1.have_result());
8745 EXPECT_EQ(OK, callback_1.WaitForResult());
8746 EXPECT_TRUE(callback_2.have_result());
8747 EXPECT_EQ(OK, callback_2.WaitForResult());
8748
8749 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8750 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8751 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8752 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8753
8754 mock_quic_data.Resume();
8755 base::RunLoop().RunUntilIdle();
8756 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8757 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8758}
8759
[email protected]61a527782013-02-21 03:58:008760} // namespace test
8761} // namespace net