blob: f533f745dff8d3b478eb596c34d3e1478c39cf9f [file] [log] [blame]
[email protected]61a527782013-02-21 03:58:001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rchbd089ab2017-05-26 23:05:045#include <algorithm>
bnc359ed2a2016-04-29 20:43:456#include <ostream>
bnc912a04b2016-04-20 14:19:507#include <string>
8#include <utility>
[email protected]1e960032013-12-20 19:00:209#include <vector>
10
[email protected]61a527782013-02-21 03:58:0011#include "base/compiler_specific.h"
Avi Drissman13fc8932015-12-20 04:40:4612#include "base/macros.h"
mmenke651bae7f2015-12-18 21:26:4513#include "base/run_loop.h"
[email protected]98b20ce2013-05-10 05:55:2614#include "base/stl_util.h"
zhongyie537a002017-06-27 16:48:2115#include "base/strings/string_number_conversions.h"
Bence Békyd74f4382018-02-20 18:26:1916#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0717#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4718#include "base/test/metrics/histogram_tester.h"
rtenneti56977812016-01-15 19:26:5619#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5820#include "net/base/completion_once_callback.h"
mgershaf9a9232017-04-13 20:19:0321#include "net/base/mock_network_change_notifier.h"
[email protected]61a527782013-02-21 03:58:0022#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0423#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2024#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1125#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1226#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5327#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0028#include "net/http/http_auth_handler_factory.h"
29#include "net/http/http_network_session.h"
30#include "net/http/http_network_transaction.h"
31#include "net/http/http_server_properties_impl.h"
32#include "net/http/http_stream.h"
33#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1934#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1135#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0036#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5137#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4638#include "net/log/test_net_log_entry.h"
39#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4040#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0341#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4042#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0843#include "net/quic/crypto/proof_verifier_chromium.h"
44#include "net/quic/mock_crypto_client_stream_factory.h"
45#include "net/quic/mock_quic_data.h"
46#include "net/quic/quic_chromium_alarm_factory.h"
47#include "net/quic/quic_http_stream.h"
48#include "net/quic/quic_http_utils.h"
49#include "net/quic/quic_stream_factory_peer.h"
50#include "net/quic/quic_test_packet_maker.h"
51#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0052#include "net/socket/client_socket_factory.h"
53#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2154#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2855#include "net/socket/socket_performance_watcher.h"
56#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0057#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5858#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5759#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2960#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0161#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4362#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0163#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1664#include "net/third_party/quic/core/crypto/quic_decrypter.h"
65#include "net/third_party/quic/core/crypto/quic_encrypter.h"
66#include "net/third_party/quic/core/quic_framer.h"
Ryan Hamilton47cf9d12018-10-17 04:33:0967#include "net/third_party/quic/core/quic_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1668#include "net/third_party/quic/platform/api/quic_str_cat.h"
69#include "net/third_party/quic/platform/api/quic_string_piece.h"
70#include "net/third_party/quic/platform/api/quic_test.h"
71#include "net/third_party/quic/test_tools/crypto_test_utils.h"
72#include "net/third_party/quic/test_tools/mock_clock.h"
73#include "net/third_party/quic/test_tools/mock_random.h"
74#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
75#include "net/third_party/quic/test_tools/quic_test_utils.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2976#include "net/third_party/spdy/core/spdy_frame_builder.h"
77#include "net/third_party/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2978#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
allada71b2efb2016-09-09 04:57:4879#include "net/url_request/url_request.h"
80#include "net/url_request/url_request_job_factory_impl.h"
81#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0182#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0083#include "testing/gtest/include/gtest/gtest.h"
84#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4685#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0086
Reilly Grant89a7e512018-01-20 01:57:1687using ::testing::ElementsAre;
88using ::testing::Key;
89
bnc508835902015-05-12 20:10:2990namespace net {
91namespace test {
[email protected]61a527782013-02-21 03:58:0092
93namespace {
94
bnc359ed2a2016-04-29 20:43:4595enum DestinationType {
96 // In pooling tests with two requests for different origins to the same
97 // destination, the destination should be
98 SAME_AS_FIRST, // the same as the first origin,
99 SAME_AS_SECOND, // the same as the second origin, or
100 DIFFERENT, // different from both.
101};
102
rchf114d982015-10-21 01:34:56103static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52104 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12105static const char kQuicAlternativeServiceWithProbabilityHeader[] =
106 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56107static const char kQuicAlternativeServiceDifferentPortHeader[] =
108 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20109
rch9ae5b3b2016-02-11 00:36:29110const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45111const char kDifferentHostname[] = "different.example.com";
112
113// Run QuicNetworkTransactionWithDestinationTest instances with all value
114// combinations of version and destination_type.
115struct PoolingTestParams {
116 friend std::ostream& operator<<(std::ostream& os,
117 const PoolingTestParams& p) {
118 os << "{ version: " << QuicVersionToString(p.version)
119 << ", destination_type: ";
120 switch (p.destination_type) {
121 case SAME_AS_FIRST:
122 os << "SAME_AS_FIRST";
123 break;
124 case SAME_AS_SECOND:
125 os << "SAME_AS_SECOND";
126 break;
127 case DIFFERENT:
128 os << "DIFFERENT";
129 break;
130 }
Yixin Wang079ad542018-01-11 04:06:05131 os << ", client_headers_include_h2_stream_dependency: "
132 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45133 os << " }";
134 return os;
135 }
136
Ryan Hamilton8d9ee76e2018-05-29 23:52:52137 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45138 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05139 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45140};
141
zhongyie537a002017-06-27 16:48:21142std::string GenerateQuicVersionsListForAltSvcHeader(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52143 const quic::QuicTransportVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21144 std::string result = "";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52145 for (const quic::QuicTransportVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21146 if (!result.empty())
147 result.append(",");
148 result.append(base::IntToString(version));
149 }
150 return result;
151}
152
bnc359ed2a2016-04-29 20:43:45153std::vector<PoolingTestParams> GetPoolingTestParams() {
154 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52155 quic::QuicTransportVersionVector all_supported_versions =
156 quic::AllSupportedTransportVersions();
157 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05158 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
159 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
160 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
161 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
162 params.push_back(PoolingTestParams{version, DIFFERENT, false});
163 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45164 }
165 return params;
166}
bncb07c05532015-05-14 19:07:20167
[email protected]61a527782013-02-21 03:58:00168} // namespace
169
ryansturm49a8cb12016-06-15 16:51:09170class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12171 public:
ryansturm49a8cb12016-06-15 16:51:09172 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12173
ryansturm49a8cb12016-06-15 16:51:09174 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12175
ryansturm49a8cb12016-06-15 16:51:09176 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
177 HttpRequestHeaders* request_headers) {
178 if (!proxy_info.is_http() && !proxy_info.is_https() &&
179 !proxy_info.is_quic()) {
180 return;
181 }
182 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12183 }
184
185 private:
ryansturm49a8cb12016-06-15 16:51:09186 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12187};
188
tbansal0f56a39a2016-04-07 22:03:38189class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40190 public:
tbansal180587c2017-02-16 15:13:23191 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
192 bool* rtt_notification_received)
193 : should_notify_updated_rtt_(should_notify_updated_rtt),
194 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38195 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40196
tbansal180587c2017-02-16 15:13:23197 bool ShouldNotifyUpdatedRTT() const override {
198 return *should_notify_updated_rtt_;
199 }
tbansalfdf5665b2015-09-21 22:46:40200
tbansal0f56a39a2016-04-07 22:03:38201 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
202 *rtt_notification_received_ = true;
203 }
204
205 void OnConnectionChanged() override {}
206
207 private:
tbansal180587c2017-02-16 15:13:23208 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38209 bool* rtt_notification_received_;
210
211 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
212};
213
214class TestSocketPerformanceWatcherFactory
215 : public SocketPerformanceWatcherFactory {
216 public:
217 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23218 : watcher_count_(0u),
219 should_notify_updated_rtt_(true),
220 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38221 ~TestSocketPerformanceWatcherFactory() override {}
222
223 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42224 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41225 const Protocol protocol,
226 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51227 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38228 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51229 }
230 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42231 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23232 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
233 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40234 }
235
tbansalc8a94ea2015-11-02 23:58:51236 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40237
tbansalc8a94ea2015-11-02 23:58:51238 bool rtt_notification_received() const { return rtt_notification_received_; }
239
tbansal180587c2017-02-16 15:13:23240 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
241 should_notify_updated_rtt_ = should_notify_updated_rtt;
242 }
243
tbansalc8a94ea2015-11-02 23:58:51244 private:
tbansal0f56a39a2016-04-07 22:03:38245 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23246 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51247 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38248
249 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51250};
251
Ryan Hamilton8d9ee76e2018-05-29 23:52:52252class QuicNetworkTransactionTest
253 : public PlatformTest,
254 public ::testing::WithParamInterface<
255 std::tuple<quic::QuicTransportVersion, bool>>,
256 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00257 protected:
[email protected]1c04f9522013-02-21 20:32:43258 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05259 : version_(std::get<0>(GetParam())),
260 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52261 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc90be5dd782016-11-09 16:28:44262 client_maker_(version_,
Fan Yang32c5a112018-12-10 20:06:33263 quic::EmptyQuicConnectionId(),
rchbf4c26d2017-04-16 23:17:55264 &clock_,
alyssar2adf3ac2016-05-03 17:12:58265 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52266 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05267 client_headers_include_h2_stream_dependency_),
bnc90be5dd782016-11-09 16:28:44268 server_maker_(version_,
Fan Yang32c5a112018-12-10 20:06:33269 quic::EmptyQuicConnectionId(),
rchbf4c26d2017-04-16 23:17:55270 &clock_,
alyssar2adf3ac2016-05-03 17:12:58271 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52272 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05273 false),
rtenneti052774e2015-11-24 21:00:12274 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43275 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59276 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
[email protected]1c04f9522013-02-21 20:32:43277 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30278 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
[email protected]457d6952013-12-13 09:24:58279 random_generator_(0),
rchf114d982015-10-21 01:34:56280 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19281 request_.method = "GET";
rchf114d982015-10-21 01:34:56282 std::string url("https://");
bncb07c05532015-05-14 19:07:20283 url.append(kDefaultServerHostName);
284 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19285 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10286 request_.traffic_annotation =
287 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52288 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56289
290 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29291 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56292 verify_details_.cert_verify_result.verified_cert = cert;
293 verify_details_.cert_verify_result.is_issued_by_known_root = true;
294 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43295 }
[email protected]61a527782013-02-21 03:58:00296
dcheng67be2b1f2014-10-27 21:47:29297 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00298 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55299 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00300 }
301
dcheng67be2b1f2014-10-27 21:47:29302 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00303 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
304 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55305 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00306 PlatformTest::TearDown();
307 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55308 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40309 session_.reset();
[email protected]61a527782013-02-21 03:58:00310 }
311
Ryan Hamilton8d9ee76e2018-05-29 23:52:52312 std::unique_ptr<quic::QuicEncryptedPacket>
313 ConstructClientConnectionClosePacket(quic::QuicPacketNumber num) {
Bin Wu5311aca2018-01-22 01:19:03314 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52315 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30316 }
317
Ryan Hamilton8d9ee76e2018-05-29 23:52:52318 std::unique_ptr<quic::QuicEncryptedPacket>
319 ConstructServerConnectionClosePacket(quic::QuicPacketNumber num) {
Bin Wu5311aca2018-01-22 01:19:03320 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52321 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58322 }
323
Ryan Hamilton8d9ee76e2018-05-29 23:52:52324 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
325 quic::QuicPacketNumber num,
326 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20327 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58328 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20329 }
330
Ryan Hamilton8d9ee76e2018-05-29 23:52:52331 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
332 quic::QuicPacketNumber packet_number,
333 quic::QuicPacketNumber largest_received,
334 quic::QuicPacketNumber smallest_received,
335 quic::QuicPacketNumber least_unacked) {
fayang3bcb8b502016-12-07 21:44:37336 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49337 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37338 }
339
Ryan Hamilton8d9ee76e2018-05-29 23:52:52340 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
341 quic::QuicPacketNumber packet_number,
342 quic::QuicPacketNumber largest_received,
343 quic::QuicPacketNumber smallest_received,
344 quic::QuicPacketNumber least_unacked,
345 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23346 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49347 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23348 ack_delay_time);
349 }
350
Ryan Hamilton8d9ee76e2018-05-29 23:52:52351 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
352 quic::QuicPacketNumber num,
353 quic::QuicStreamId stream_id,
354 quic::QuicRstStreamErrorCode error_code,
355 quic::QuicPacketNumber largest_received,
356 quic::QuicPacketNumber smallest_received,
357 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58358 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49359 num, false, stream_id, error_code, largest_received, smallest_received,
360 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20361 }
362
Ryan Hamilton8d9ee76e2018-05-29 23:52:52363 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
364 quic::QuicPacketNumber num,
365 quic::QuicStreamId stream_id,
366 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56367 size_t bytes_written) {
368 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
369 bytes_written);
370 }
371
Ryan Hamilton8d9ee76e2018-05-29 23:52:52372 std::unique_ptr<quic::QuicEncryptedPacket>
373 ConstructClientAckAndConnectionClosePacket(
374 quic::QuicPacketNumber packet_number,
375 quic::QuicPacketNumber largest_received,
376 quic::QuicPacketNumber smallest_received,
377 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58378 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49379 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20380 }
[email protected]61a527782013-02-21 03:58:00381
Ryan Hamilton8d9ee76e2018-05-29 23:52:52382 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58383 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 quic::QuicPacketNumber num,
385 quic::QuicTime::Delta delta_time_largest_observed,
386 quic::QuicPacketNumber largest_received,
387 quic::QuicPacketNumber smallest_received,
388 quic::QuicPacketNumber least_unacked,
389 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50390 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58391 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12392 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49393 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12394 }
395
Ryan Hamilton8d9ee76e2018-05-29 23:52:52396 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
397 quic::QuicPacketNumber num,
zhongyica364fbb2015-12-12 03:39:12398 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52399 quic::QuicStreamId stream_id,
400 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58401 return server_maker_.MakeRstPacket(num, include_version, stream_id,
402 error_code);
zhongyica364fbb2015-12-12 03:39:12403 }
404
Ryan Hamilton8d9ee76e2018-05-29 23:52:52405 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
406 quic::QuicPacketNumber packet_number,
407 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36408 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37409 }
410
Ryan Hamilton8d9ee76e2018-05-29 23:52:52411 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
412 quic::QuicPacketNumber packet_number,
413 quic::QuicPacketNumber largest_received,
414 quic::QuicPacketNumber smallest_received,
415 quic::QuicPacketNumber least_unacked) {
fayang3bcb8b502016-12-07 21:44:37416 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49417 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37418 }
419
Ryan Hamilton8d9ee76e2018-05-29 23:52:52420 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
421 quic::QuicPacketNumber packet_number,
Yixin Wangb470bc882018-02-15 18:43:57422 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 quic::QuicStreamId id,
424 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57425 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52426 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57427 return client_maker_.MakePriorityPacket(
428 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23429 ConvertRequestPriorityToQuicPriority(request_priority), offset);
430 }
431
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25433 ConstructClientAckAndPriorityFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52434 quic::QuicPacketNumber packet_number,
Yixin Wang385652a2018-02-16 02:37:23435 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52436 quic::QuicPacketNumber largest_received,
437 quic::QuicPacketNumber smallest_received,
438 quic::QuicPacketNumber least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25439 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
440 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52441 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25442 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23443 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25444 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57445 }
446
zhongyi32569c62016-01-08 02:54:30447 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13448 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
449 const std::string& scheme,
450 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58451 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30452 }
453
454 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13455 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
456 const std::string& scheme,
457 const std::string& path,
458 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50459 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00460 }
461
Ryan Hamilton0239aac2018-05-19 00:03:13462 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56463 return client_maker_.ConnectRequestHeaders(host_port);
464 }
465
Ryan Hamilton0239aac2018-05-19 00:03:13466 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58467 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00468 }
469
zhongyi32569c62016-01-08 02:54:30470 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13471 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
472 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58473 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30474 }
475
Ryan Hamilton8d9ee76e2018-05-29 23:52:52476 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
477 quic::QuicPacketNumber packet_number,
478 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05479 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00480 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52481 quic::QuicStreamOffset offset,
482 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58483 return server_maker_.MakeDataPacket(
484 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00485 }
486
Ryan Hamilton8d9ee76e2018-05-29 23:52:52487 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
488 quic::QuicPacketNumber packet_number,
489 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36490 bool should_include_version,
491 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52492 quic::QuicStreamOffset offset,
493 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36494 return client_maker_.MakeDataPacket(
495 packet_number, stream_id, should_include_version, fin, offset, data);
496 }
497
Ryan Hamilton8d9ee76e2018-05-29 23:52:52498 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
499 quic::QuicPacketNumber packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56500 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52501 quic::QuicStreamId stream_id,
502 quic::QuicPacketNumber largest_received,
503 quic::QuicPacketNumber smallest_received,
504 quic::QuicPacketNumber least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56505 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52506 quic::QuicStreamOffset offset,
507 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56508 return client_maker_.MakeAckAndDataPacket(
509 packet_number, include_version, stream_id, largest_received,
510 smallest_received, least_unacked, fin, offset, data);
511 }
512
Ryan Hamilton8d9ee76e2018-05-29 23:52:52513 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
514 quic::QuicPacketNumber packet_number,
515 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36516 bool should_include_version,
517 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52518 quic::QuicStreamOffset* offset,
519 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36520 return client_maker_.MakeForceHolDataPacket(
521 packet_number, stream_id, should_include_version, fin, offset, data);
522 }
523
Ryan Hamilton8d9ee76e2018-05-29 23:52:52524 std::unique_ptr<quic::QuicEncryptedPacket>
525 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
526 quic::QuicStreamId stream_id,
527 bool should_include_version,
528 bool fin,
529 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56530 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
531 should_include_version, fin,
532 std::move(headers), nullptr);
533 }
534
Ryan Hamilton8d9ee76e2018-05-29 23:52:52535 std::unique_ptr<quic::QuicEncryptedPacket>
536 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
537 quic::QuicStreamId stream_id,
538 bool should_include_version,
539 bool fin,
540 spdy::SpdyHeaderBlock headers,
541 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48542 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
543 should_include_version, fin,
544 std::move(headers), 0, offset);
545 }
546
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 std::unique_ptr<quic::QuicEncryptedPacket>
548 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
549 quic::QuicStreamId stream_id,
550 bool should_include_version,
551 bool fin,
552 spdy::SpdyHeaderBlock headers,
553 quic::QuicStreamId parent_stream_id,
554 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56555 return ConstructClientRequestHeadersPacket(
556 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48557 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30558 }
559
Ryan Hamilton8d9ee76e2018-05-29 23:52:52560 std::unique_ptr<quic::QuicEncryptedPacket>
561 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
562 quic::QuicStreamId stream_id,
563 bool should_include_version,
564 bool fin,
565 RequestPriority request_priority,
566 spdy::SpdyHeaderBlock headers,
567 quic::QuicStreamId parent_stream_id,
568 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13569 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56570 ConvertRequestPriorityToQuicPriority(request_priority);
571 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
572 packet_number, stream_id, should_include_version, fin, priority,
573 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00574 }
575
Ryan Hamilton8d9ee76e2018-05-29 23:52:52576 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25577 ConstructClientRequestHeadersAndDataFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52578 quic::QuicPacketNumber packet_number,
579 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25580 bool should_include_version,
581 bool fin,
582 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13583 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52584 quic::QuicStreamId parent_stream_id,
585 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25586 size_t* spdy_headers_frame_length,
587 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13588 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25589 ConvertRequestPriorityToQuicPriority(request_priority);
590 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
591 packet_number, stream_id, should_include_version, fin, priority,
592 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
593 data_writes);
594 }
595
Ryan Hamilton8d9ee76e2018-05-29 23:52:52596 std::unique_ptr<quic::QuicEncryptedPacket>
597 ConstructClientMultipleDataFramesPacket(quic::QuicPacketNumber packet_number,
598 quic::QuicStreamId stream_id,
599 bool should_include_version,
600 bool fin,
601 const std::vector<std::string>& data,
602 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27603 return client_maker_.MakeMultipleDataFramesPacket(
604 packet_number, stream_id, should_include_version, fin, offset, data);
605 }
606
Ryan Hamilton8d9ee76e2018-05-29 23:52:52607 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
608 quic::QuicPacketNumber packet_number,
609 quic::QuicStreamId stream_id,
610 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13611 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13612 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52613 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13614 QuicTestPacketMaker* maker) {
615 return maker->MakePushPromisePacket(
616 packet_number, stream_id, promised_stream_id, should_include_version,
617 false, std::move(headers), nullptr, offset);
618 }
619
Ryan Hamilton8d9ee76e2018-05-29 23:52:52620 std::unique_ptr<quic::QuicEncryptedPacket>
621 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
622 quic::QuicStreamId stream_id,
623 bool should_include_version,
624 bool fin,
625 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27626 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
627 should_include_version, fin,
628 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30629 }
630
Ryan Hamilton8d9ee76e2018-05-29 23:52:52631 std::unique_ptr<quic::QuicEncryptedPacket>
632 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
633 quic::QuicStreamId stream_id,
634 bool should_include_version,
635 bool fin,
636 spdy::SpdyHeaderBlock headers,
637 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58638 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25639 packet_number, stream_id, should_include_version, fin,
640 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30641 }
642
Renjief49758b2019-01-11 23:32:41643 quic::QuicString ConstructDataHeader(size_t body_len) {
644 if (version_ != quic::QUIC_VERSION_99) {
645 return "";
646 }
647 quic::HttpEncoder encoder;
648 std::unique_ptr<char[]> buffer;
649 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
650 return quic::QuicString(buffer.get(), header_length);
651 }
652
Ryan Hamilton8d9ee76e2018-05-29 23:52:52653 void CreateSession(
654 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41655 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21656 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05657 session_params_.quic_headers_include_h2_stream_dependency =
658 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00659
mmenke6ddfbea2017-05-31 21:48:41660 session_context_.quic_clock = &clock_;
661 session_context_.quic_random = &random_generator_;
662 session_context_.client_socket_factory = &socket_factory_;
663 session_context_.quic_crypto_client_stream_factory =
664 &crypto_client_stream_factory_;
665 session_context_.host_resolver = &host_resolver_;
666 session_context_.cert_verifier = &cert_verifier_;
667 session_context_.transport_security_state = &transport_security_state_;
668 session_context_.cert_transparency_verifier =
669 cert_transparency_verifier_.get();
670 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
671 session_context_.socket_performance_watcher_factory =
672 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59673 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41674 session_context_.ssl_config_service = ssl_config_service_.get();
675 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
676 session_context_.http_server_properties = &http_server_properties_;
677 session_context_.net_log = net_log_.bound().net_log();
678
679 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12680 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56681 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
682 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00683 }
684
zhongyi86838d52017-06-30 01:19:44685 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21686
bnc691fda62016-08-12 00:43:16687 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19688 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42689 ASSERT_TRUE(response != nullptr);
690 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19691 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
692 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52693 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44694 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19695 response->connection_info);
696 }
697
bnc691fda62016-08-12 00:43:16698 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41699 const HttpResponseInfo* response = trans->GetResponseInfo();
700 ASSERT_TRUE(response != nullptr);
701 EXPECT_EQ(port, response->socket_address.port());
702 }
703
bnc691fda62016-08-12 00:43:16704 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19705 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42706 ASSERT_TRUE(response != nullptr);
707 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19708 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
709 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52710 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52711 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19712 response->connection_info);
713 }
714
Yixin Wang46a273ec302018-01-23 17:59:56715 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
716 const HttpResponseInfo* response = trans->GetResponseInfo();
717 ASSERT_TRUE(response != nullptr);
718 ASSERT_TRUE(response->headers.get() != nullptr);
719 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
720 EXPECT_TRUE(response->was_fetched_via_spdy);
721 EXPECT_TRUE(response->was_alpn_negotiated);
722 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
723 response->connection_info);
724 }
725
bnc691fda62016-08-12 00:43:16726 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19727 const std::string& expected) {
728 std::string response_data;
bnc691fda62016-08-12 00:43:16729 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19730 EXPECT_EQ(expected, response_data);
731 }
732
bnc691fda62016-08-12 00:43:16733 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19734 TestCompletionCallback callback;
735 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
737 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19738 }
739
740 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16741 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
742 RunTransaction(&trans);
743 CheckWasHttpResponse(&trans);
744 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19745 }
746
tbansalc3308d72016-08-27 10:25:04747 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
748 bool used_proxy,
749 uint16_t port) {
750 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
751 HeadersHandler headers_handler;
752 trans.SetBeforeHeadersSentCallback(
753 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
754 base::Unretained(&headers_handler)));
755 RunTransaction(&trans);
756 CheckWasHttpResponse(&trans);
757 CheckResponsePort(&trans, port);
758 CheckResponseData(&trans, expected);
759 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47760 if (used_proxy) {
761 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
762 } else {
763 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
764 }
tbansalc3308d72016-08-27 10:25:04765 }
766
[email protected]aa9b14d2013-05-10 23:45:19767 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56768 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12769 }
770
bnc62a44f022015-04-02 15:59:41771 void SendRequestAndExpectQuicResponseFromProxyOnPort(
772 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46773 uint16_t port) {
bnc62a44f022015-04-02 15:59:41774 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19775 }
776
777 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27778 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19779 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46780 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21781 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12782 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21783 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44784 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19785 }
786
rchbe69cb902016-02-11 01:10:48787 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27788 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48789 const HostPortPair& alternative) {
790 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46791 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21792 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48793 alternative.port());
794 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21795 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44796 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48797 }
798
[email protected]aa9b14d2013-05-10 23:45:19799 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46800 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34801 const AlternativeServiceInfoVector alternative_service_info_vector =
802 http_server_properties_.GetAlternativeServiceInfos(server);
803 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07804 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54805 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19806 }
807
[email protected]4d590c9c2014-05-02 05:14:33808 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46809 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34810 const AlternativeServiceInfoVector alternative_service_info_vector =
811 http_server_properties_.GetAlternativeServiceInfos(server);
812 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54813 EXPECT_EQ(
814 kProtoQUIC,
815 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23816 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54817 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33818 }
819
[email protected]aa9b14d2013-05-10 23:45:19820 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42821 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30822 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30823 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30824 hanging_data->set_connect_data(hanging_connect);
825 hanging_data_.push_back(std::move(hanging_data));
826 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56827 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19828 }
829
Zhongyi Shia6b68d112018-09-24 07:49:03830 void SetUpTestForRetryConnectionOnAlternateNetwork() {
831 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
832 session_params_.quic_migrate_sessions_early_v2 = true;
833 session_params_.quic_retry_on_alternate_network_before_handshake = true;
834 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
835 MockNetworkChangeNotifier* mock_ncn =
836 scoped_mock_change_notifier_->mock_network_change_notifier();
837 mock_ncn->ForceNetworkHandlesSupported();
838 mock_ncn->SetConnectedNetworksList(
839 {kDefaultNetworkForTests, kNewNetworkForTests});
840 }
841
tbansalc3308d72016-08-27 10:25:04842 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
843 // alternative proxy. Verifies that if the alternative proxy job returns
844 // |error_code|, the request is fetched successfully by the main job.
845 void TestAlternativeProxy(int error_code) {
846 // Use a non-cryptographic scheme for the request URL since this request
847 // will be fetched via proxy with QUIC as the alternative service.
848 request_.url = GURL("http://example.org/");
849 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27850 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04851 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27852 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04853 };
854
Ryan Sleevib8d7ea02018-05-07 20:01:01855 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04856 socket_factory_.AddSocketDataProvider(&quic_data);
857
858 // Main job succeeds and the alternative job fails.
859 // Add data for two requests that will be read by the main job.
860 MockRead http_reads_1[] = {
861 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
862 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
863 MockRead(ASYNC, OK)};
864
865 MockRead http_reads_2[] = {
866 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
867 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
868 MockRead(ASYNC, OK)};
869
Ryan Sleevib8d7ea02018-05-07 20:01:01870 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
871 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04872 socket_factory_.AddSocketDataProvider(&http_data_1);
873 socket_factory_.AddSocketDataProvider(&http_data_2);
874 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
875 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
876
877 TestProxyDelegate test_proxy_delegate;
878 // Proxy URL is different from the request URL.
879 test_proxy_delegate.set_alternative_proxy_server(
880 ProxyServer::FromPacString("QUIC myproxy.org:443"));
881
Lily Houghton8c2f97d2018-01-22 05:06:59882 proxy_resolution_service_ =
883 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49884 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52885 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04886
887 CreateSession();
888 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
889
890 // The first request should be fetched via the HTTPS proxy.
891 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
892
Reilly Grant89a7e512018-01-20 01:57:16893 // Since the main job succeeded only the alternative proxy server should be
894 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59895 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16896 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04897
898 // Verify that the second request completes successfully, and the
899 // alternative proxy server job is not started.
900 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
901 }
902
Fan Yang32c5a112018-12-10 20:06:33903 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
904 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36905 }
906
Fan Yang32c5a112018-12-10 20:06:33907 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
908 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36909 }
910
Bence Béky230ac612017-08-30 19:17:08911 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49912 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08913 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49914 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08915 }
916
Ryan Hamilton8d9ee76e2018-05-29 23:52:52917 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05918 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52919 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01920 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52921 quic::MockClock clock_;
alyssar2adf3ac2016-05-03 17:12:58922 QuicTestPacketMaker client_maker_;
923 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42924 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00925 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56926 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05927 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43928 MockHostResolver host_resolver_;
929 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11930 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42931 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23932 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38933 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07934 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59935 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42936 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52937 quic::test::MockRandom random_generator_;
bnc6be245c12015-05-15 11:24:07938 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41939 HttpNetworkSession::Params session_params_;
940 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19941 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51942 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42943 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56944 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03945 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12946
947 private:
948 void SendRequestAndExpectQuicResponseMaybeFromProxy(
949 const std::string& expected,
bnc62a44f022015-04-02 15:59:41950 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46951 uint16_t port) {
bnc691fda62016-08-12 00:43:16952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09953 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16954 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09955 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
956 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16957 RunTransaction(&trans);
958 CheckWasQuicResponse(&trans);
959 CheckResponsePort(&trans, port);
960 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09961 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47962 if (used_proxy) {
963 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
964 } else {
965 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
966 }
tbansal7cec3812015-02-05 21:25:12967 }
[email protected]61a527782013-02-21 03:58:00968};
969
Yixin Wang079ad542018-01-11 04:06:05970INSTANTIATE_TEST_CASE_P(
Yixin Wang385652a2018-02-16 02:37:23971 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05972 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52973 ::testing::Combine(
974 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
975 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20976
Ryan Hamiltona64a5bcf2017-11-30 07:35:28977TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:48978 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28979 base::HistogramTester histograms;
980 session_params_.origins_to_force_quic_on.insert(
981 HostPortPair::FromString("mail.example.org:443"));
982 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27983 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:28984
985 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52986 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28987 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43988 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:28989 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
990 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
991 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
992
993 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
994
995 CreateSession();
996
997 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
998 TestCompletionCallback callback;
999 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1001 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1002
1003 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1004 -ERR_INTERNET_DISCONNECTED, 1);
1005 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1006 -ERR_INTERNET_DISCONNECTED, 1);
1007}
1008
1009TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481010 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281011 base::HistogramTester histograms;
1012 session_params_.origins_to_force_quic_on.insert(
1013 HostPortPair::FromString("mail.example.org:443"));
1014 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271015 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281016
1017 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521018 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281019 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431020 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281021 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1022 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1023 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1024
1025 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1026
1027 CreateSession();
1028
1029 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1030 TestCompletionCallback callback;
1031 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1032 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1033 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1034
1035 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1036 -ERR_INTERNET_DISCONNECTED, 1);
1037 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1038 -ERR_INTERNET_DISCONNECTED, 1);
1039}
1040
tbansal180587c2017-02-16 15:13:231041TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411042 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231043 HostPortPair::FromString("mail.example.org:443"));
1044
1045 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521046 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361047 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431048 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1049 mock_quic_data.AddWrite(
1050 SYNCHRONOUS,
1051 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331052 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431053 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431054 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331055 ASYNC, ConstructServerResponseHeadersPacket(
1056 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1057 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411058 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331059 mock_quic_data.AddRead(
1060 ASYNC, ConstructServerDataPacket(
1061 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411062 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431063 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231064 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1065
1066 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1067
1068 CreateSession();
1069 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1070
1071 EXPECT_FALSE(
1072 test_socket_performance_watcher_factory_.rtt_notification_received());
1073 SendRequestAndExpectQuicResponse("hello!");
1074 EXPECT_TRUE(
1075 test_socket_performance_watcher_factory_.rtt_notification_received());
1076}
1077
1078TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411079 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231080 HostPortPair::FromString("mail.example.org:443"));
1081
1082 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521083 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361084 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431085 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1086 mock_quic_data.AddWrite(
1087 SYNCHRONOUS,
1088 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331089 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431090 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431091 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331092 ASYNC, ConstructServerResponseHeadersPacket(
1093 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1094 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411095 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331096 mock_quic_data.AddRead(
1097 ASYNC, ConstructServerDataPacket(
1098 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411099 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431100 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231101 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1102
1103 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1104
1105 CreateSession();
1106 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1107
1108 EXPECT_FALSE(
1109 test_socket_performance_watcher_factory_.rtt_notification_received());
1110 SendRequestAndExpectQuicResponse("hello!");
1111 EXPECT_FALSE(
1112 test_socket_performance_watcher_factory_.rtt_notification_received());
1113}
1114
[email protected]1e960032013-12-20 19:00:201115TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411116 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571117 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471118
[email protected]1e960032013-12-20 19:00:201119 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521120 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361121 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431122 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1123 mock_quic_data.AddWrite(
1124 SYNCHRONOUS,
1125 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331126 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431127 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431128 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331129 ASYNC, ConstructServerResponseHeadersPacket(
1130 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1131 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411132 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331133 mock_quic_data.AddRead(
1134 ASYNC, ConstructServerDataPacket(
1135 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411136 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431137 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591138 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471139
rcha5399e02015-04-21 19:32:041140 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471141
[email protected]4dca587c2013-03-07 16:54:471142 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471143
[email protected]aa9b14d2013-05-10 23:45:191144 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471145
[email protected]98b20ce2013-05-10 05:55:261146 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461147 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191148 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261149 EXPECT_LT(0u, entries.size());
1150
1151 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291152 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001153 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1154 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261155 EXPECT_LT(0, pos);
1156
rchfd527212015-08-25 00:41:261157 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291158 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261159 entries, 0,
mikecirone8b85c432016-09-08 19:11:001160 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1161 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261162 EXPECT_LT(0, pos);
1163
Eric Romanaefc98c2018-12-18 21:38:011164 int packet_number;
1165 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1166 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261167
rchfd527212015-08-25 00:41:261168 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1169 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001170 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1171 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261172 EXPECT_LT(0, pos);
1173
[email protected]98b20ce2013-05-10 05:55:261174 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291175 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001176 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1177 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261178 EXPECT_LT(0, pos);
1179
1180 int log_stream_id;
1181 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381182 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1183 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471184}
1185
rchbd089ab2017-05-26 23:05:041186TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411187 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041188 HostPortPair::FromString("mail.example.org:443"));
1189
1190 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521191 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041192 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431193 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1194 mock_quic_data.AddWrite(
1195 SYNCHRONOUS,
1196 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331197 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431198 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131199 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041200 response_headers["key1"] = std::string(30000, 'A');
1201 response_headers["key2"] = std::string(30000, 'A');
1202 response_headers["key3"] = std::string(30000, 'A');
1203 response_headers["key4"] = std::string(30000, 'A');
1204 response_headers["key5"] = std::string(30000, 'A');
1205 response_headers["key6"] = std::string(30000, 'A');
1206 response_headers["key7"] = std::string(30000, 'A');
1207 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331208 spdy::SpdyHeadersIR headers_frame(
1209 GetNthClientInitiatedBidirectionalStreamId(0),
1210 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131211 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1212 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041213 response_framer.SerializeFrame(headers_frame);
1214
Ryan Hamilton8d9ee76e2018-05-29 23:52:521215 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041216 size_t chunk_size = 1200;
1217 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1218 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431219 mock_quic_data.AddRead(
1220 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091221 packet_number++,
1222 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521223 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041224 }
1225
Renjief49758b2019-01-11 23:32:411226 quic::QuicString header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041227 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331228 ASYNC, ConstructServerDataPacket(
1229 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411230 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041231 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431232 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1233 mock_quic_data.AddWrite(ASYNC,
1234 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041235
1236 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1237
1238 CreateSession();
1239
1240 SendRequestAndExpectQuicResponse("hello!");
1241}
1242
1243TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481244 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411245 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041246 HostPortPair::FromString("mail.example.org:443"));
1247
1248 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521249 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041250 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431251 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1252 mock_quic_data.AddWrite(
1253 SYNCHRONOUS,
1254 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331255 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431256 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131257 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041258 response_headers["key1"] = std::string(30000, 'A');
1259 response_headers["key2"] = std::string(30000, 'A');
1260 response_headers["key3"] = std::string(30000, 'A');
1261 response_headers["key4"] = std::string(30000, 'A');
1262 response_headers["key5"] = std::string(30000, 'A');
1263 response_headers["key6"] = std::string(30000, 'A');
1264 response_headers["key7"] = std::string(30000, 'A');
1265 response_headers["key8"] = std::string(30000, 'A');
1266 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331267 spdy::SpdyHeadersIR headers_frame(
1268 GetNthClientInitiatedBidirectionalStreamId(0),
1269 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131270 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1271 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041272 response_framer.SerializeFrame(headers_frame);
1273
Ryan Hamilton8d9ee76e2018-05-29 23:52:521274 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041275 size_t chunk_size = 1200;
1276 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1277 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431278 mock_quic_data.AddRead(
1279 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091280 packet_number++,
1281 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521282 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041283 }
1284
Renjief49758b2019-01-11 23:32:411285 quic::QuicString header = ConstructDataHeader(6);
1286
rchbd089ab2017-05-26 23:05:041287 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331288 ASYNC, ConstructServerDataPacket(
1289 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411290 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041291 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431292 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1293 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331294 ASYNC, ConstructClientAckAndRstPacket(
1295 4, GetNthClientInitiatedBidirectionalStreamId(0),
1296 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041297
1298 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1299
1300 CreateSession();
1301
1302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1303 TestCompletionCallback callback;
1304 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1306 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1307}
1308
rcha2bd44b2016-07-02 00:42:551309TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411310 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551311
Ryan Hamilton9835e662018-08-02 05:36:271312 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551313
1314 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521315 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361316 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431317 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1318 mock_quic_data.AddWrite(
1319 SYNCHRONOUS,
1320 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331321 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431322 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431323 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331324 ASYNC, ConstructServerResponseHeadersPacket(
1325 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1326 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411327 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331328 mock_quic_data.AddRead(
1329 ASYNC, ConstructServerDataPacket(
1330 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411331 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431332 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551333 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1334
1335 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1336
1337 CreateSession();
1338
1339 SendRequestAndExpectQuicResponse("hello!");
1340 EXPECT_TRUE(
1341 test_socket_performance_watcher_factory_.rtt_notification_received());
1342}
1343
[email protected]cf3e3cd62014-02-05 16:16:161344TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411345 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591346 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491347 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161348
[email protected]cf3e3cd62014-02-05 16:16:161349 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521350 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361351 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431352 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1353 mock_quic_data.AddWrite(
1354 SYNCHRONOUS,
1355 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331356 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431357 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431358 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331359 ASYNC, ConstructServerResponseHeadersPacket(
1360 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1361 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411362 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331363 mock_quic_data.AddRead(
1364 ASYNC, ConstructServerDataPacket(
1365 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411366 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431367 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501368 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591369 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161370
rcha5399e02015-04-21 19:32:041371 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161372
tbansal0f56a39a2016-04-07 22:03:381373 EXPECT_FALSE(
1374 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161375 // There is no need to set up an alternate protocol job, because
1376 // no attempt will be made to speak to the proxy over TCP.
1377
rch9ae5b3b2016-02-11 00:36:291378 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161379 CreateSession();
1380
bnc62a44f022015-04-02 15:59:411381 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381382 EXPECT_TRUE(
1383 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161384}
1385
bnc313ba9c2015-06-11 15:42:311386// Regression test for https://crbug.com/492458. Test that for an HTTP
1387// connection through a QUIC proxy, the certificate exhibited by the proxy is
1388// checked against the proxy hostname, not the origin hostname.
1389TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291390 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311391 const std::string proxy_host = "www.example.org";
1392
mmenke6ddfbea2017-05-31 21:48:411393 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591394 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491395 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311396
alyssar2adf3ac2016-05-03 17:12:581397 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311398 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521399 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361400 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431401 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1402 mock_quic_data.AddWrite(
1403 SYNCHRONOUS,
1404 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331405 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431406 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431407 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331408 ASYNC, ConstructServerResponseHeadersPacket(
1409 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1410 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411411 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331412 mock_quic_data.AddRead(
1413 ASYNC, ConstructServerDataPacket(
1414 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411415 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431416 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501417 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591418 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311419 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1420
1421 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291422 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311423 ASSERT_TRUE(cert.get());
1424 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241425 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1426 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311427 ProofVerifyDetailsChromium verify_details;
1428 verify_details.cert_verify_result.verified_cert = cert;
1429 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561430 ProofVerifyDetailsChromium verify_details2;
1431 verify_details2.cert_verify_result.verified_cert = cert;
1432 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311433
1434 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091435 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321436 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271437 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311438 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1439}
1440
rchbe69cb902016-02-11 01:10:481441TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341442 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481443 HostPortPair origin("www.example.org", 443);
1444 HostPortPair alternative("mail.example.org", 443);
1445
1446 base::FilePath certs_dir = GetTestCertsDirectory();
1447 scoped_refptr<X509Certificate> cert(
1448 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1449 ASSERT_TRUE(cert.get());
1450 // TODO(rch): the connection should be "to" the origin, so if the cert is
1451 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241452 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1453 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481454 ProofVerifyDetailsChromium verify_details;
1455 verify_details.cert_verify_result.verified_cert = cert;
1456 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1457
alyssar2adf3ac2016-05-03 17:12:581458 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481459 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521460 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361461 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431462 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1463 mock_quic_data.AddWrite(
1464 SYNCHRONOUS,
1465 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331466 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431467 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431468 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331469 ASYNC, ConstructServerResponseHeadersPacket(
1470 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1471 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411472 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331473 mock_quic_data.AddRead(
1474 ASYNC, ConstructServerDataPacket(
1475 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411476 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431477 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481478 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1479 mock_quic_data.AddRead(ASYNC, 0);
1480 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1481
1482 request_.url = GURL("https://" + origin.host());
1483 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271484 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091485 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321486 CreateSession();
rchbe69cb902016-02-11 01:10:481487
1488 SendRequestAndExpectQuicResponse("hello!");
1489}
1490
zhongyief3f4ce52017-07-05 23:53:281491TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521492 quic::QuicTransportVersion unsupported_version =
1493 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281494 // Add support for another QUIC version besides |version_|. Also find a
1495 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521496 for (const quic::QuicTransportVersion& version :
1497 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281498 if (version == version_)
1499 continue;
1500 if (supported_versions_.size() != 2) {
1501 supported_versions_.push_back(version);
1502 continue;
1503 }
1504 unsupported_version = version;
1505 break;
1506 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521507 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281508
1509 // Set up alternative service to use QUIC with a version that is not
1510 // supported.
1511 url::SchemeHostPort server(request_.url);
1512 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1513 443);
1514 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1515 http_server_properties_.SetQuicAlternativeService(
1516 server, alternative_service, expiration, {unsupported_version});
1517
1518 AlternativeServiceInfoVector alt_svc_info_vector =
1519 http_server_properties_.GetAlternativeServiceInfos(server);
1520 EXPECT_EQ(1u, alt_svc_info_vector.size());
1521 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1522 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1523 EXPECT_EQ(unsupported_version,
1524 alt_svc_info_vector[0].advertised_versions()[0]);
1525
1526 // First request should still be sent via TCP as the QUIC version advertised
1527 // in the stored AlternativeService is not supported by the client. However,
1528 // the response from the server will advertise new Alt-Svc with supported
1529 // versions.
1530 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521531 GenerateQuicVersionsListForAltSvcHeader(
1532 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281533 std::string altsvc_header =
1534 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1535 advertised_versions_list_str.c_str());
1536 MockRead http_reads[] = {
1537 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1538 MockRead("hello world"),
1539 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1540 MockRead(ASYNC, OK)};
1541
Ryan Sleevib8d7ea02018-05-07 20:01:011542 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281543 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081544 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281545 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1546
1547 // Second request should be sent via QUIC as a new list of verions supported
1548 // by the client has been advertised by the server.
1549 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521550 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281551 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431552 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1553 mock_quic_data.AddWrite(
1554 SYNCHRONOUS,
1555 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331556 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431557 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431558 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331559 ASYNC, ConstructServerResponseHeadersPacket(
1560 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1561 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411562 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331563 mock_quic_data.AddRead(
1564 ASYNC, ConstructServerDataPacket(
1565 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411566 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431567 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281568 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1569 mock_quic_data.AddRead(ASYNC, 0); // EOF
1570
1571 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1572
1573 AddHangingNonAlternateProtocolSocketData();
1574
1575 CreateSession(supported_versions_);
1576
1577 SendRequestAndExpectHttpResponse("hello world");
1578 SendRequestAndExpectQuicResponse("hello!");
1579
1580 // Check alternative service list is updated with new versions.
1581 alt_svc_info_vector =
1582 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1583 EXPECT_EQ(1u, alt_svc_info_vector.size());
1584 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1585 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1586 // Advertised versions will be lised in a sorted order.
1587 std::sort(supported_versions_.begin(), supported_versions_.end());
1588 EXPECT_EQ(supported_versions_[0],
1589 alt_svc_info_vector[0].advertised_versions()[0]);
1590 EXPECT_EQ(supported_versions_[1],
1591 alt_svc_info_vector[0].advertised_versions()[1]);
1592}
1593
bncaccd4962017-04-06 21:00:261594// Regression test for https://crbug.com/546991.
1595// The server might not be able to serve a request on an alternative connection,
1596// and might send a 421 Misdirected Request response status to indicate this.
1597// HttpNetworkTransaction should reset the request and retry without using
1598// alternative services.
1599TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1600 // Set up alternative service to use QUIC.
1601 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1602 // that overrides |enable_alternative_services|.
1603 url::SchemeHostPort server(request_.url);
1604 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1605 443);
1606 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211607 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441608 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261609
davidbena4449722017-05-05 23:30:531610 // First try: The alternative job uses QUIC and reports an HTTP 421
1611 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1612 // paused at Connect(), so it will never exit the socket pool. This ensures
1613 // that the alternate job always wins the race and keeps whether the
1614 // |http_data| exits the socket pool before the main job is aborted
1615 // deterministic. The first main job gets aborted without the socket pool ever
1616 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261617 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521618 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361619 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431620 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1621 mock_quic_data.AddWrite(
1622 SYNCHRONOUS,
1623 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331624 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431625 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331626 mock_quic_data.AddRead(
1627 ASYNC, ConstructServerResponseHeadersPacket(
1628 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1629 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261630 mock_quic_data.AddRead(ASYNC, OK);
1631 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1632
davidbena4449722017-05-05 23:30:531633 // Second try: The main job uses TCP, and there is no alternate job. Once the
1634 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1635 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261636 // Note that if there was an alternative QUIC Job created for the second try,
1637 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1638 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531639 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1640 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1641 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1642 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1643 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1644 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011645 reads, writes);
bncaccd4962017-04-06 21:00:261646 socket_factory_.AddSocketDataProvider(&http_data);
1647 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1648
bncaccd4962017-04-06 21:00:261649 CreateSession();
1650 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531651
1652 // Run until |mock_quic_data| has failed and |http_data| has paused.
1653 TestCompletionCallback callback;
1654 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1656 base::RunLoop().RunUntilIdle();
1657
1658 // |mock_quic_data| must have run to completion.
1659 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1660 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1661
1662 // Now that the QUIC data has been consumed, unblock |http_data|.
1663 http_data.socket()->OnConnectComplete(MockConnect());
1664
1665 // The retry logic must hide the 421 status. The transaction succeeds on
1666 // |http_data|.
1667 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261668 CheckWasHttpResponse(&trans);
1669 CheckResponsePort(&trans, 443);
1670 CheckResponseData(&trans, "hello!");
1671}
1672
[email protected]1e960032013-12-20 19:00:201673TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411674 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571675 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301676
tbansalfdf5665b2015-09-21 22:46:401677 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521678 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361679 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431680 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401681 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401682 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371683 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361684 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431685 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301686 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401687 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431688 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401689
1690 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1691 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301692
1693 CreateSession();
1694
tbansal0f56a39a2016-04-07 22:03:381695 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401696 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161697 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401698 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161699 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1701 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381702 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531703
1704 NetErrorDetails details;
1705 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521706 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401707 }
[email protected]cebe3282013-05-22 23:49:301708}
1709
tbansalc8a94ea2015-11-02 23:58:511710TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1711 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411712 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571713 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511714
1715 MockRead http_reads[] = {
1716 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1717 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1718 MockRead(ASYNC, OK)};
1719
Ryan Sleevib8d7ea02018-05-07 20:01:011720 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511721 socket_factory_.AddSocketDataProvider(&data);
1722 SSLSocketDataProvider ssl(ASYNC, OK);
1723 socket_factory_.AddSSLSocketDataProvider(&ssl);
1724
1725 CreateSession();
1726
1727 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381728 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511729}
1730
bncc958faa2015-07-31 18:14:521731TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521732 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561733 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1734 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521735 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1736 MockRead(ASYNC, OK)};
1737
Ryan Sleevib8d7ea02018-05-07 20:01:011738 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521739 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081740 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561741 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521742
1743 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521744 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361745 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431746 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1747 mock_quic_data.AddWrite(
1748 SYNCHRONOUS,
1749 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331750 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431751 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431752 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331753 ASYNC, ConstructServerResponseHeadersPacket(
1754 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1755 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411756 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331757 mock_quic_data.AddRead(
1758 ASYNC, ConstructServerDataPacket(
1759 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411760 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431761 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521762 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591763 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521764
1765 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1766
rtennetib8e80fb2016-05-16 00:12:091767 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321768 CreateSession();
bncc958faa2015-07-31 18:14:521769
1770 SendRequestAndExpectHttpResponse("hello world");
1771 SendRequestAndExpectQuicResponse("hello!");
1772}
1773
zhongyia00ca012017-07-06 23:36:391774TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1775 // Both server advertises and client supports two QUIC versions.
1776 // Only |version_| is advertised and supported.
1777 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1778 // PacketMakers are using |version_|.
1779
1780 // Add support for another QUIC version besides |version_| on the client side.
1781 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521782 quic::QuicTransportVersion advertised_version_2 =
1783 quic::QUIC_VERSION_UNSUPPORTED;
1784 for (const quic::QuicTransportVersion& version :
1785 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391786 if (version == version_)
1787 continue;
1788 if (supported_versions_.size() != 2) {
1789 supported_versions_.push_back(version);
1790 continue;
1791 }
1792 advertised_version_2 = version;
1793 break;
1794 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521795 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391796
1797 std::string QuicAltSvcWithVersionHeader =
1798 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1799 advertised_version_2, version_);
1800
1801 MockRead http_reads[] = {
1802 MockRead("HTTP/1.1 200 OK\r\n"),
1803 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1804 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1805 MockRead(ASYNC, OK)};
1806
Ryan Sleevib8d7ea02018-05-07 20:01:011807 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391808 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081809 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391810 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1811
1812 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521813 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391814 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431815 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1816 mock_quic_data.AddWrite(
1817 SYNCHRONOUS,
1818 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331819 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431820 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431821 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331822 ASYNC, ConstructServerResponseHeadersPacket(
1823 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1824 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411825 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331826 mock_quic_data.AddRead(
1827 ASYNC, ConstructServerDataPacket(
1828 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411829 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431830 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391831 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1832 mock_quic_data.AddRead(ASYNC, 0); // EOF
1833
1834 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1835
1836 AddHangingNonAlternateProtocolSocketData();
1837 CreateSession(supported_versions_);
1838
1839 SendRequestAndExpectHttpResponse("hello world");
1840 SendRequestAndExpectQuicResponse("hello!");
1841}
1842
1843TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1844 // Client and server mutually support more than one QUIC_VERSION.
1845 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1846 // which is verified as the PacketMakers are using |version_|.
1847
Ryan Hamilton8d9ee76e2018-05-29 23:52:521848 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1849 for (const quic::QuicTransportVersion& version :
1850 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391851 if (version == version_)
1852 continue;
1853 common_version_2 = version;
1854 break;
1855 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521856 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391857
1858 supported_versions_.push_back(
1859 common_version_2); // Supported but unpreferred.
1860
1861 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1862 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1863
1864 MockRead http_reads[] = {
1865 MockRead("HTTP/1.1 200 OK\r\n"),
1866 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1867 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1868 MockRead(ASYNC, OK)};
1869
Ryan Sleevib8d7ea02018-05-07 20:01:011870 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391871 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081872 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391873 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1874
1875 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521876 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391877 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431878 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1879 mock_quic_data.AddWrite(
1880 SYNCHRONOUS,
1881 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331882 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431883 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431884 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331885 ASYNC, ConstructServerResponseHeadersPacket(
1886 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1887 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411888 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331889 mock_quic_data.AddRead(
1890 ASYNC, ConstructServerDataPacket(
1891 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411892 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431893 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391894 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1895 mock_quic_data.AddRead(ASYNC, 0); // EOF
1896
1897 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1898
1899 AddHangingNonAlternateProtocolSocketData();
1900 CreateSession(supported_versions_);
1901
1902 SendRequestAndExpectHttpResponse("hello world");
1903 SendRequestAndExpectQuicResponse("hello!");
1904}
1905
rchf47265dc2016-03-21 21:33:121906TEST_P(QuicNetworkTransactionTest,
1907 UseAlternativeServiceWithProbabilityForQuic) {
1908 MockRead http_reads[] = {
1909 MockRead("HTTP/1.1 200 OK\r\n"),
1910 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1911 MockRead("hello world"),
1912 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1913 MockRead(ASYNC, OK)};
1914
Ryan Sleevib8d7ea02018-05-07 20:01:011915 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121916 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081917 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121918 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1919
1920 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521921 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361922 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431923 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1924 mock_quic_data.AddWrite(
1925 SYNCHRONOUS,
1926 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331927 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431928 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431929 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331930 ASYNC, ConstructServerResponseHeadersPacket(
1931 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1932 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411933 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331934 mock_quic_data.AddRead(
1935 ASYNC, ConstructServerDataPacket(
1936 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411937 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431938 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121939 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1940 mock_quic_data.AddRead(ASYNC, 0); // EOF
1941
1942 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1943
rtennetib8e80fb2016-05-16 00:12:091944 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121945 CreateSession();
1946
1947 SendRequestAndExpectHttpResponse("hello world");
1948 SendRequestAndExpectQuicResponse("hello!");
1949}
1950
zhongyi3d4a55e72016-04-22 20:36:461951TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1952 MockRead http_reads[] = {
1953 MockRead("HTTP/1.1 200 OK\r\n"),
1954 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1955 MockRead("hello world"),
1956 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1957 MockRead(ASYNC, OK)};
1958
Ryan Sleevib8d7ea02018-05-07 20:01:011959 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461960 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081961 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461962 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1963
1964 CreateSession();
bncb26024382016-06-29 02:39:451965 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461966 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:451967 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:461968 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401969 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461970 session_->http_server_properties();
1971 url::SchemeHostPort http_server("http", "mail.example.org", 443);
1972 url::SchemeHostPort https_server("https", "mail.example.org", 443);
1973 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:461974 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:341975 2u,
1976 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:451977 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:341978 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:461979}
1980
1981TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
1982 MockRead http_reads[] = {
1983 MockRead("HTTP/1.1 200 OK\r\n"),
1984 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1985 MockRead("hello world"),
1986 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1987 MockRead(ASYNC, OK)};
1988
Ryan Sleevib8d7ea02018-05-07 20:01:011989 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:081990 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461991
1992 socket_factory_.AddSocketDataProvider(&http_data);
1993 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1994 socket_factory_.AddSocketDataProvider(&http_data);
1995 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1996
1997 CreateSession();
1998
1999 // Send https request and set alternative services if response header
2000 // advertises alternative service for mail.example.org.
2001 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402002 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462003 session_->http_server_properties();
2004
2005 const url::SchemeHostPort https_server(request_.url);
2006 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342007 EXPECT_EQ(
2008 2u,
2009 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462010
2011 // Send http request to the same origin but with diffrent scheme, should not
2012 // use QUIC.
2013 request_.url = GURL("http://mail.example.org:443");
2014 SendRequestAndExpectHttpResponse("hello world");
2015}
2016
zhongyie537a002017-06-27 16:48:212017TEST_P(QuicNetworkTransactionTest,
2018 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442019 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522020 for (const quic::QuicTransportVersion& version :
2021 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:442022 if (version == version_)
2023 continue;
2024 supported_versions_.push_back(version);
2025 break;
2026 }
2027
zhongyie537a002017-06-27 16:48:212028 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:522029 GenerateQuicVersionsListForAltSvcHeader(
2030 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:212031 std::string altsvc_header =
2032 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2033 advertised_versions_list_str.c_str());
2034 MockRead http_reads[] = {
2035 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2036 MockRead("hello world"),
2037 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2038 MockRead(ASYNC, OK)};
2039
Ryan Sleevib8d7ea02018-05-07 20:01:012040 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212041 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082042 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212043 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2044
2045 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522046 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212047 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432048 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2049 mock_quic_data.AddWrite(
2050 SYNCHRONOUS,
2051 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332052 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432053 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432054 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332055 ASYNC, ConstructServerResponseHeadersPacket(
2056 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2057 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412058 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332059 mock_quic_data.AddRead(
2060 ASYNC, ConstructServerDataPacket(
2061 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412062 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432063 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212064 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2065 mock_quic_data.AddRead(ASYNC, 0); // EOF
2066
2067 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2068
2069 AddHangingNonAlternateProtocolSocketData();
2070
zhongyi86838d52017-06-30 01:19:442071 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212072
2073 SendRequestAndExpectHttpResponse("hello world");
2074 SendRequestAndExpectQuicResponse("hello!");
2075
2076 // Check alternative service is set with only mutually supported versions.
2077 const url::SchemeHostPort https_server(request_.url);
2078 const AlternativeServiceInfoVector alt_svc_info_vector =
2079 session_->http_server_properties()->GetAlternativeServiceInfos(
2080 https_server);
2081 EXPECT_EQ(1u, alt_svc_info_vector.size());
2082 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2083 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2084 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442085 std::sort(supported_versions_.begin(), supported_versions_.end());
2086 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212087 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442088 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212089 alt_svc_info_vector[0].advertised_versions()[1]);
2090}
2091
danzh3134c2562016-08-12 14:07:522092TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442093 std::string altsvc_header =
2094 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072095 MockRead http_reads[] = {
2096 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2097 MockRead("hello world"),
2098 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2099 MockRead(ASYNC, OK)};
2100
Ryan Sleevib8d7ea02018-05-07 20:01:012101 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072102 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082103 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072104 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2105
2106 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522107 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362108 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432109 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2110 mock_quic_data.AddWrite(
2111 SYNCHRONOUS,
2112 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332113 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432114 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432115 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332116 ASYNC, ConstructServerResponseHeadersPacket(
2117 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2118 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412119 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332120 mock_quic_data.AddRead(
2121 ASYNC, ConstructServerDataPacket(
2122 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412123 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432124 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072125 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592126 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072127
2128 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2129
rtennetib8e80fb2016-05-16 00:12:092130 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322131 CreateSession();
bnc8be55ebb2015-10-30 14:12:072132
2133 SendRequestAndExpectHttpResponse("hello world");
2134 SendRequestAndExpectQuicResponse("hello!");
2135}
2136
zhongyi6b5a3892016-03-12 04:46:202137TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092138 if (version_ == quic::QUIC_VERSION_99) {
2139 // Not available under version 99
2140 return;
2141 }
zhongyi6b5a3892016-03-12 04:46:202142 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522143 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362144 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432145 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2146 mock_quic_data.AddWrite(
2147 SYNCHRONOUS,
2148 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332149 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432150 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332151 mock_quic_data.AddRead(
2152 ASYNC, ConstructServerResponseHeadersPacket(
2153 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2154 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202155 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522156 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432157 mock_quic_data.AddRead(SYNCHRONOUS,
2158 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522159 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432160 "connection migration with port change only"));
2161 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:412162 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332163 mock_quic_data.AddRead(
2164 SYNCHRONOUS, ConstructServerDataPacket(
2165 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412166 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332167 mock_quic_data.AddWrite(SYNCHRONOUS,
2168 ConstructClientAckAndRstPacket(
2169 4, GetNthClientInitiatedBidirectionalStreamId(0),
2170 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202171 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2172 mock_quic_data.AddRead(ASYNC, 0); // EOF
2173
2174 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2175
2176 // The non-alternate protocol job needs to hang in order to guarantee that
2177 // the alternate-protocol job will "win".
2178 AddHangingNonAlternateProtocolSocketData();
2179
2180 // In order for a new QUIC session to be established via alternate-protocol
2181 // without racing an HTTP connection, we need the host resolution to happen
2182 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2183 // connection to the the server, in this test we require confirmation
2184 // before encrypting so the HTTP job will still start.
2185 host_resolver_.set_synchronous_mode(true);
2186 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2187 "");
2188 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2189 AddressList address;
maksim.sisov31452af2016-07-27 06:38:102190 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582191 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2192 CompletionOnceCallback(), &request,
2193 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412194 EXPECT_THAT(rv, IsOk());
zhongyi6b5a3892016-03-12 04:46:202195
2196 CreateSession();
2197 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272198 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202199
bnc691fda62016-08-12 00:43:162200 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202201 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412202 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202204
2205 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522206 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012207 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202208
2209 // Check whether this transaction is correctly marked as received a go-away
2210 // because of migrating port.
2211 NetErrorDetails details;
2212 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162213 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202214 EXPECT_TRUE(details.quic_port_migration_detected);
2215}
2216
Zhongyi Shia6b68d112018-09-24 07:49:032217// This test verifies that a new QUIC connection will be attempted on the
2218// alternate network if the original QUIC connection fails with idle timeout
2219// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2220// alternate network as well, QUIC is marked as broken and the brokenness will
2221// not expire when default network changes.
2222TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2223 SetUpTestForRetryConnectionOnAlternateNetwork();
2224
2225 std::string request_data;
2226 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2227 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2228
2229 // The request will initially go out over QUIC.
2230 MockQuicData quic_data;
2231 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2232 int packet_num = 1;
2233 quic_data.AddWrite(SYNCHRONOUS,
2234 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2235 // Retranmit the handshake messages.
2236 quic_data.AddWrite(SYNCHRONOUS,
2237 client_maker_.MakeDummyCHLOPacket(packet_num++));
2238 quic_data.AddWrite(SYNCHRONOUS,
2239 client_maker_.MakeDummyCHLOPacket(packet_num++));
2240 quic_data.AddWrite(SYNCHRONOUS,
2241 client_maker_.MakeDummyCHLOPacket(packet_num++));
2242 quic_data.AddWrite(SYNCHRONOUS,
2243 client_maker_.MakeDummyCHLOPacket(packet_num++));
2244 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2245 if (version_ <= quic::QUIC_VERSION_39) {
2246 quic_data.AddWrite(SYNCHRONOUS,
2247 client_maker_.MakeDummyCHLOPacket(packet_num++));
2248 }
2249 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2250 quic_data.AddWrite(SYNCHRONOUS,
2251 client_maker_.MakeConnectionClosePacket(
2252 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2253 "No recent network activity."));
2254 quic_data.AddSocketDataToFactory(&socket_factory_);
2255
2256 // Add successful TCP data so that TCP job will succeed.
2257 MockWrite http_writes[] = {
2258 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2259 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2260 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2261
2262 MockRead http_reads[] = {
2263 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2264 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2265 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2266 SequencedSocketData http_data(http_reads, http_writes);
2267 socket_factory_.AddSocketDataProvider(&http_data);
2268 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2269
2270 // Add data for the second QUIC connection to fail.
2271 MockQuicData quic_data2;
2272 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2273 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2274 quic_data2.AddSocketDataToFactory(&socket_factory_);
2275
2276 // Resolve the host resolution synchronously.
2277 host_resolver_.set_synchronous_mode(true);
2278 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2279 "");
2280 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2281 AddressList address;
2282 std::unique_ptr<HostResolver::Request> request;
2283 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2284 CompletionOnceCallback(), &request,
2285 net_log_.bound());
2286 EXPECT_THAT(rv, IsOk());
2287
2288 CreateSession();
2289 session_->quic_stream_factory()->set_require_confirmation(true);
2290 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2291 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2292 QuicStreamFactoryPeer::SetAlarmFactory(
2293 session_->quic_stream_factory(),
2294 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2295 &clock_));
2296 // Add alternate protocol mapping to race QUIC and TCP.
2297 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2298 // peer.
2299 AddQuicAlternateProtocolMapping(
2300 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2301
2302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2303 TestCompletionCallback callback;
2304 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2306
2307 // Pump the message loop to get the request started.
2308 // Request will be served with TCP job.
2309 base::RunLoop().RunUntilIdle();
2310 EXPECT_THAT(callback.WaitForResult(), IsOk());
2311 CheckResponseData(&trans, "TCP succeeds");
2312
2313 // Fire the retransmission alarm, from this point, connection will idle
2314 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062315 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182316 quic_fix_time_of_first_packet_sent_after_receiving)) {
2317 quic_task_runner_->RunNextTask();
2318 }
Zhongyi Shia6b68d112018-09-24 07:49:032319 // Fast forward to idle timeout the original connection. A new connection will
2320 // be kicked off on the alternate network.
2321 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2322 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2323 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2324
2325 // Run the message loop to execute posted tasks, which will report job status.
2326 base::RunLoop().RunUntilIdle();
2327
2328 // Verify that QUIC is marked as broken.
2329 ExpectBrokenAlternateProtocolMapping();
2330
2331 // Deliver a message to notify the new network becomes default, the brokenness
2332 // will not expire as QUIC is broken on both networks.
2333 scoped_mock_change_notifier_->mock_network_change_notifier()
2334 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2335 ExpectBrokenAlternateProtocolMapping();
2336
2337 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2338 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2339}
2340
2341// This test verifies that a new QUIC connection will be attempted on the
2342// alternate network if the original QUIC connection fails with idle timeout
2343// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2344// alternate network, QUIC is marked as broken. The brokenness will expire when
2345// the default network changes.
2346TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2347 SetUpTestForRetryConnectionOnAlternateNetwork();
2348
2349 std::string request_data;
2350 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2351 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2352
2353 // The request will initially go out over QUIC.
2354 MockQuicData quic_data;
2355 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2356 int packet_num = 1;
2357 quic_data.AddWrite(SYNCHRONOUS,
2358 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2359 // Retranmit the handshake messages.
2360 quic_data.AddWrite(SYNCHRONOUS,
2361 client_maker_.MakeDummyCHLOPacket(packet_num++));
2362 quic_data.AddWrite(SYNCHRONOUS,
2363 client_maker_.MakeDummyCHLOPacket(packet_num++));
2364 quic_data.AddWrite(SYNCHRONOUS,
2365 client_maker_.MakeDummyCHLOPacket(packet_num++));
2366 quic_data.AddWrite(SYNCHRONOUS,
2367 client_maker_.MakeDummyCHLOPacket(packet_num++));
2368 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2369 if (version_ <= quic::QUIC_VERSION_39) {
2370 quic_data.AddWrite(SYNCHRONOUS,
2371 client_maker_.MakeDummyCHLOPacket(packet_num++));
2372 }
2373 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2374 quic_data.AddWrite(SYNCHRONOUS,
2375 client_maker_.MakeConnectionClosePacket(
2376 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2377 "No recent network activity."));
2378 quic_data.AddSocketDataToFactory(&socket_factory_);
2379
2380 // Add successful TCP data so that TCP job will succeed.
2381 MockWrite http_writes[] = {
2382 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2383 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2384 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2385
2386 MockRead http_reads[] = {
2387 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2388 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2389 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2390 SequencedSocketData http_data(http_reads, http_writes);
2391 socket_factory_.AddSocketDataProvider(&http_data);
2392 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2393
2394 // Quic connection will be retried on the alternate network after the initial
2395 // one fails on the default network.
2396 MockQuicData quic_data2;
2397 quic::QuicStreamOffset header_stream_offset = 0;
2398 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2399 quic_data2.AddWrite(SYNCHRONOUS,
2400 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2401
2402 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2403 quic_data2.AddWrite(SYNCHRONOUS,
2404 ConstructInitialSettingsPacket(2, &header_stream_offset));
2405 quic_data2.AddSocketDataToFactory(&socket_factory_);
2406
2407 // Resolve the host resolution synchronously.
2408 host_resolver_.set_synchronous_mode(true);
2409 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2410 "");
2411 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2412 AddressList address;
2413 std::unique_ptr<HostResolver::Request> request;
2414 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2415 CompletionOnceCallback(), &request,
2416 net_log_.bound());
2417 EXPECT_THAT(rv, IsOk());
2418
2419 CreateSession();
2420 session_->quic_stream_factory()->set_require_confirmation(true);
2421 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2422 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2423 QuicStreamFactoryPeer::SetAlarmFactory(
2424 session_->quic_stream_factory(),
2425 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2426 &clock_));
2427 // Add alternate protocol mapping to race QUIC and TCP.
2428 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2429 // peer.
2430 AddQuicAlternateProtocolMapping(
2431 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2432
2433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2434 TestCompletionCallback callback;
2435 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2437
2438 // Pump the message loop to get the request started.
2439 // Request will be served with TCP job.
2440 base::RunLoop().RunUntilIdle();
2441 EXPECT_THAT(callback.WaitForResult(), IsOk());
2442 CheckResponseData(&trans, "TCP succeeds");
2443
2444 // Fire the retransmission alarm, after which connection will idle
2445 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062446 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182447 quic_fix_time_of_first_packet_sent_after_receiving)) {
2448 quic_task_runner_->RunNextTask();
2449 }
Zhongyi Shia6b68d112018-09-24 07:49:032450 // Fast forward to idle timeout the original connection. A new connection will
2451 // be kicked off on the alternate network.
2452 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2453 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2454 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2455
2456 // The second connection hasn't finish handshake, verify that QUIC is not
2457 // marked as broken.
2458 ExpectQuicAlternateProtocolMapping();
2459 // Explicitly confirm the handshake on the second connection.
2460 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2461 quic::QuicSession::HANDSHAKE_CONFIRMED);
2462 // Run message loop to execute posted tasks, which will notify JoController
2463 // about the orphaned job status.
2464 base::RunLoop().RunUntilIdle();
2465
2466 // Verify that QUIC is marked as broken.
2467 ExpectBrokenAlternateProtocolMapping();
2468
2469 // Deliver a message to notify the new network becomes default, the previous
2470 // brokenness will be clear as the brokenness is bond with old default
2471 // network.
2472 scoped_mock_change_notifier_->mock_network_change_notifier()
2473 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2474 ExpectQuicAlternateProtocolMapping();
2475
2476 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2477 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2478}
2479
2480// This test verifies that a new QUIC connection will be attempted on the
2481// alternate network if the original QUIC connection fails with idle timeout
2482// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2483// alternative network succeeds, QUIC is not marked as broken.
2484TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2485 SetUpTestForRetryConnectionOnAlternateNetwork();
2486
2487 std::string request_data;
2488 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2489 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2490
2491 // The request will initially go out over QUIC.
2492 MockQuicData quic_data;
2493 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2494 int packet_num = 1;
2495 quic_data.AddWrite(SYNCHRONOUS,
2496 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2497 // Retranmit the handshake messages.
2498 quic_data.AddWrite(SYNCHRONOUS,
2499 client_maker_.MakeDummyCHLOPacket(packet_num++));
2500 quic_data.AddWrite(SYNCHRONOUS,
2501 client_maker_.MakeDummyCHLOPacket(packet_num++));
2502 quic_data.AddWrite(SYNCHRONOUS,
2503 client_maker_.MakeDummyCHLOPacket(packet_num++));
2504 quic_data.AddWrite(SYNCHRONOUS,
2505 client_maker_.MakeDummyCHLOPacket(packet_num++));
2506 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2507 // quic_fix_has_pending_crypto_data is introduced and enabled.
2508 if (version_ <= quic::QUIC_VERSION_39) {
2509 quic_data.AddWrite(SYNCHRONOUS,
2510 client_maker_.MakeDummyCHLOPacket(packet_num++));
2511 }
2512 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2513 quic_data.AddWrite(SYNCHRONOUS,
2514 client_maker_.MakeConnectionClosePacket(
2515 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2516 "No recent network activity."));
2517 quic_data.AddSocketDataToFactory(&socket_factory_);
2518
2519 // Add hanging TCP data so that TCP job will never succeeded.
2520 AddHangingNonAlternateProtocolSocketData();
2521
2522 // Quic connection will then be retried on the alternate network.
2523 MockQuicData quic_data2;
2524 quic::QuicStreamOffset header_stream_offset = 0;
2525 quic_data2.AddWrite(SYNCHRONOUS,
2526 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2527
Renjief49758b2019-01-11 23:32:412528 const quic::QuicString body = "hello!";
2529 quic::QuicString header = ConstructDataHeader(body.length());
2530
Zhongyi Shia6b68d112018-09-24 07:49:032531 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2532 quic_data2.AddWrite(SYNCHRONOUS,
2533 ConstructInitialSettingsPacket(2, &header_stream_offset));
2534 quic_data2.AddWrite(
2535 SYNCHRONOUS,
2536 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332537 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032538 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032539 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332540 ASYNC, ConstructServerResponseHeadersPacket(
2541 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2542 GetResponseHeaders("200 OK")));
2543 quic_data2.AddRead(
2544 ASYNC, ConstructServerDataPacket(
2545 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412546 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032547 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2548 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2549 quic_data2.AddSocketDataToFactory(&socket_factory_);
2550
2551 // Resolve the host resolution synchronously.
2552 host_resolver_.set_synchronous_mode(true);
2553 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2554 "");
2555 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2556 AddressList address;
2557 std::unique_ptr<HostResolver::Request> request;
2558 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2559 CompletionOnceCallback(), &request,
2560 net_log_.bound());
2561 EXPECT_THAT(rv, IsOk());
2562
2563 CreateSession();
2564 session_->quic_stream_factory()->set_require_confirmation(true);
2565 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2566 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2567 QuicStreamFactoryPeer::SetAlarmFactory(
2568 session_->quic_stream_factory(),
2569 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2570 &clock_));
2571 // Add alternate protocol mapping to race QUIC and TCP.
2572 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2573 // peer.
2574 AddQuicAlternateProtocolMapping(
2575 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2576
2577 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2578 TestCompletionCallback callback;
2579 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2581
2582 // Pump the message loop to get the request started.
2583 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062584 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182585 quic_fix_time_of_first_packet_sent_after_receiving)) {
2586 quic_task_runner_->RunNextTask();
2587 }
Zhongyi Shia6b68d112018-09-24 07:49:032588
2589 // Fast forward to idle timeout the original connection. A new connection will
2590 // be kicked off on the alternate network.
2591 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2592 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2593 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2594
2595 // Verify that QUIC is not marked as broken.
2596 ExpectQuicAlternateProtocolMapping();
2597 // Explicitly confirm the handshake on the second connection.
2598 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2599 quic::QuicSession::HANDSHAKE_CONFIRMED);
2600
2601 // Read the response.
2602 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412603 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032604 // Verify that QUIC is not marked as broken.
2605 ExpectQuicAlternateProtocolMapping();
2606
2607 // Deliver a message to notify the new network becomes default.
2608 scoped_mock_change_notifier_->mock_network_change_notifier()
2609 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2610 ExpectQuicAlternateProtocolMapping();
2611 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2612 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2613}
2614
rch9ecde09b2017-04-08 00:18:232615// Verify that if a QUIC connection times out, the QuicHttpStream will
2616// return QUIC_PROTOCOL_ERROR.
2617TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482618 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412619 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232620
2621 // The request will initially go out over QUIC.
2622 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522623 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132624 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232625 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2626
2627 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522628 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2629 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432630 quic_data.AddWrite(SYNCHRONOUS,
2631 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332632 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2633 true, priority, GetRequestHeaders("GET", "https", "/"),
2634 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232635
2636 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522637 quic::QuicStreamOffset settings_offset = header_stream_offset;
2638 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432639 quic_data.AddWrite(SYNCHRONOUS,
2640 client_maker_.MakeInitialSettingsPacketAndSaveData(
2641 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232642 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092643 quic_data.AddWrite(SYNCHRONOUS,
2644 client_maker_.MakeDataPacket(
2645 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2646 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232647 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092648 quic_data.AddWrite(SYNCHRONOUS,
2649 client_maker_.MakeDataPacket(
2650 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2651 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232652 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092653 quic_data.AddWrite(SYNCHRONOUS,
2654 client_maker_.MakeDataPacket(
2655 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2656 false, 0, request_data));
2657 quic_data.AddWrite(SYNCHRONOUS,
2658 client_maker_.MakeDataPacket(
2659 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2660 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232661 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092662 quic_data.AddWrite(SYNCHRONOUS,
2663 client_maker_.MakeDataPacket(
2664 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2665 false, 0, request_data));
2666 quic_data.AddWrite(SYNCHRONOUS,
2667 client_maker_.MakeDataPacket(
2668 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2669 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232670 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092671 quic_data.AddWrite(SYNCHRONOUS,
2672 client_maker_.MakeDataPacket(
2673 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2674 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522675 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092676 SYNCHRONOUS, client_maker_.MakeDataPacket(
2677 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2678 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232679
Zhongyi Shi32f2fd02018-04-16 18:23:432680 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522681 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432682 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222683
rch9ecde09b2017-04-08 00:18:232684 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2685 quic_data.AddRead(ASYNC, OK);
2686 quic_data.AddSocketDataToFactory(&socket_factory_);
2687
2688 // In order for a new QUIC session to be established via alternate-protocol
2689 // without racing an HTTP connection, we need the host resolution to happen
2690 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2691 // connection to the the server, in this test we require confirmation
2692 // before encrypting so the HTTP job will still start.
2693 host_resolver_.set_synchronous_mode(true);
2694 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2695 "");
2696 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2697 AddressList address;
2698 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582699 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2700 CompletionOnceCallback(), &request,
2701 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412702 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232703
2704 CreateSession();
2705 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552706 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232707 QuicStreamFactoryPeer::SetAlarmFactory(
2708 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192709 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552710 &clock_));
rch9ecde09b2017-04-08 00:18:232711
Ryan Hamilton9835e662018-08-02 05:36:272712 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232713
2714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2715 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412716 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2718
2719 // Pump the message loop to get the request started.
2720 base::RunLoop().RunUntilIdle();
2721 // Explicitly confirm the handshake.
2722 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522723 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232724
2725 // Run the QUIC session to completion.
2726 quic_task_runner_->RunUntilIdle();
2727
2728 ExpectQuicAlternateProtocolMapping();
2729 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2730 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2731}
2732
2733// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2734// return QUIC_PROTOCOL_ERROR.
2735TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482736 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522737 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232738
2739 // The request will initially go out over QUIC.
2740 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522741 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132742 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232743 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2744
2745 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522746 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2747 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432748 quic_data.AddWrite(SYNCHRONOUS,
2749 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332750 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2751 true, priority, GetRequestHeaders("GET", "https", "/"),
2752 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232753
2754 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522755 quic::QuicStreamOffset settings_offset = header_stream_offset;
2756 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432757 quic_data.AddWrite(SYNCHRONOUS,
2758 client_maker_.MakeInitialSettingsPacketAndSaveData(
2759 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232760 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092761 quic_data.AddWrite(SYNCHRONOUS,
2762 client_maker_.MakeDataPacket(
2763 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2764 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232765 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092766 quic_data.AddWrite(SYNCHRONOUS,
2767 client_maker_.MakeDataPacket(
2768 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2769 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232770 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092771 quic_data.AddWrite(SYNCHRONOUS,
2772 client_maker_.MakeDataPacket(
2773 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2774 false, 0, request_data));
2775 quic_data.AddWrite(SYNCHRONOUS,
2776 client_maker_.MakeDataPacket(
2777 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2778 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232779 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092780 quic_data.AddWrite(SYNCHRONOUS,
2781 client_maker_.MakeDataPacket(
2782 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2783 false, 0, request_data));
2784 quic_data.AddWrite(SYNCHRONOUS,
2785 client_maker_.MakeDataPacket(
2786 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2787 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232788 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092789 quic_data.AddWrite(SYNCHRONOUS,
2790 client_maker_.MakeDataPacket(
2791 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2792 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522793 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092794 SYNCHRONOUS, client_maker_.MakeDataPacket(
2795 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2796 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232797 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522798 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092799 SYNCHRONOUS, client_maker_.MakeDataPacket(
2800 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2801 false, 0, request_data));
2802 quic_data.AddWrite(
2803 SYNCHRONOUS, client_maker_.MakeDataPacket(
2804 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2805 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232806 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432807 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522808 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432809 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232810
2811 quic_data.AddRead(ASYNC, OK);
2812 quic_data.AddSocketDataToFactory(&socket_factory_);
2813
2814 // In order for a new QUIC session to be established via alternate-protocol
2815 // without racing an HTTP connection, we need the host resolution to happen
2816 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2817 // connection to the the server, in this test we require confirmation
2818 // before encrypting so the HTTP job will still start.
2819 host_resolver_.set_synchronous_mode(true);
2820 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2821 "");
2822 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2823 AddressList address;
2824 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582825 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2826 CompletionOnceCallback(), &request,
2827 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412828 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232829
2830 CreateSession();
2831 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552832 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232833 QuicStreamFactoryPeer::SetAlarmFactory(
2834 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192835 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552836 &clock_));
rch9ecde09b2017-04-08 00:18:232837
Ryan Hamilton9835e662018-08-02 05:36:272838 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232839
2840 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2841 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412842 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2844
2845 // Pump the message loop to get the request started.
2846 base::RunLoop().RunUntilIdle();
2847 // Explicitly confirm the handshake.
2848 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522849 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232850
2851 // Run the QUIC session to completion.
2852 quic_task_runner_->RunUntilIdle();
2853
2854 ExpectQuicAlternateProtocolMapping();
2855 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2856 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2857}
2858
2859// Verify that if a QUIC connection RTOs, while there are no active streams
2860// QUIC will not be marked as broken.
2861TEST_P(QuicNetworkTransactionTest,
2862 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522863 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232864
2865 // The request will initially go out over QUIC.
2866 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522867 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132868 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232869 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2870
2871 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522872 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2873 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432874 quic_data.AddWrite(SYNCHRONOUS,
2875 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332876 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2877 true, priority, GetRequestHeaders("GET", "https", "/"),
2878 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232879
2880 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522881 quic::QuicStreamOffset settings_offset = header_stream_offset;
2882 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432883 quic_data.AddWrite(SYNCHRONOUS,
2884 client_maker_.MakeInitialSettingsPacketAndSaveData(
2885 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232886
Fan Yang32c5a112018-12-10 20:06:332887 quic_data.AddWrite(SYNCHRONOUS,
2888 client_maker_.MakeRstPacket(
2889 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2890 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232891 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092892 quic_data.AddWrite(SYNCHRONOUS,
2893 client_maker_.MakeDataPacket(
2894 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2895 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232896 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092897 quic_data.AddWrite(SYNCHRONOUS,
2898 client_maker_.MakeDataPacket(
2899 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2900 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232901 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332902 quic_data.AddWrite(SYNCHRONOUS,
2903 client_maker_.MakeRstPacket(
2904 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2905 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092906 quic_data.AddWrite(SYNCHRONOUS,
2907 client_maker_.MakeDataPacket(
2908 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2909 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232910 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092911 quic_data.AddWrite(SYNCHRONOUS,
2912 client_maker_.MakeDataPacket(
2913 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2914 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332915 quic_data.AddWrite(SYNCHRONOUS,
2916 client_maker_.MakeRstPacket(
2917 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2918 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232919 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522920 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092921 SYNCHRONOUS, client_maker_.MakeDataPacket(
2922 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2923 false, 0, request_data));
2924 quic_data.AddWrite(
2925 SYNCHRONOUS, client_maker_.MakeDataPacket(
2926 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2927 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232928 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432929 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332930 SYNCHRONOUS, client_maker_.MakeRstPacket(
2931 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2932 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522933 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092934 SYNCHRONOUS, client_maker_.MakeDataPacket(
2935 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2936 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232937 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432938 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522939 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432940 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232941
2942 quic_data.AddRead(ASYNC, OK);
2943 quic_data.AddSocketDataToFactory(&socket_factory_);
2944
2945 // In order for a new QUIC session to be established via alternate-protocol
2946 // without racing an HTTP connection, we need the host resolution to happen
2947 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2948 // connection to the the server, in this test we require confirmation
2949 // before encrypting so the HTTP job will still start.
2950 host_resolver_.set_synchronous_mode(true);
2951 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2952 "");
2953 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2954 AddressList address;
2955 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582956 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2957 CompletionOnceCallback(), &request,
2958 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412959 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232960
2961 CreateSession();
2962 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552963 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232964 QuicStreamFactoryPeer::SetAlarmFactory(
2965 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192966 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552967 &clock_));
rch9ecde09b2017-04-08 00:18:232968
Ryan Hamilton9835e662018-08-02 05:36:272969 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232970
Jeremy Roman0579ed62017-08-29 15:56:192971 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232972 session_.get());
2973 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412974 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232975 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2976
2977 // Pump the message loop to get the request started.
2978 base::RunLoop().RunUntilIdle();
2979 // Explicitly confirm the handshake.
2980 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522981 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232982
2983 // Now cancel the request.
2984 trans.reset();
2985
2986 // Run the QUIC session to completion.
2987 quic_task_runner_->RunUntilIdle();
2988
2989 ExpectQuicAlternateProtocolMapping();
2990
2991 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2992}
2993
rch2f2991c2017-04-13 19:28:172994// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2995// the request fails with QUIC_PROTOCOL_ERROR.
2996TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482997 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172998 // The request will initially go out over QUIC.
2999 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523000 quic::QuicStreamOffset header_stream_offset = 0;
3001 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3002 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433003 quic_data.AddWrite(
3004 SYNCHRONOUS,
3005 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333006 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433007 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523008 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433009 quic_data.AddWrite(SYNCHRONOUS,
3010 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173011 // Peer sending data from an non-existing stream causes this end to raise
3012 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333013 quic_data.AddRead(
3014 ASYNC, ConstructServerRstPacket(
3015 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3016 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173017 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433018 quic_data.AddWrite(SYNCHRONOUS,
3019 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523020 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3021 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173022 quic_data.AddSocketDataToFactory(&socket_factory_);
3023
3024 // In order for a new QUIC session to be established via alternate-protocol
3025 // without racing an HTTP connection, we need the host resolution to happen
3026 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3027 // connection to the the server, in this test we require confirmation
3028 // before encrypting so the HTTP job will still start.
3029 host_resolver_.set_synchronous_mode(true);
3030 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3031 "");
3032 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3033 AddressList address;
3034 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583035 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3036 CompletionOnceCallback(), &request,
3037 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413038 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173039
3040 CreateSession();
3041
Ryan Hamilton9835e662018-08-02 05:36:273042 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173043
3044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3045 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413046 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3048
3049 // Pump the message loop to get the request started.
3050 base::RunLoop().RunUntilIdle();
3051 // Explicitly confirm the handshake.
3052 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523053 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173054
3055 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3056
3057 // Run the QUIC session to completion.
3058 base::RunLoop().RunUntilIdle();
3059 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3060 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3061
3062 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3063 ExpectQuicAlternateProtocolMapping();
3064 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3065}
3066
rch9ecde09b2017-04-08 00:18:233067// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3068// connection times out, then QUIC will be marked as broken and the request
3069// retried over TCP.
3070TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413071 session_params_.mark_quic_broken_when_network_blackholes = true;
3072 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233073
3074 // The request will initially go out over QUIC.
3075 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523076 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133077 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233078 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3079
3080 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523081 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3082 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433083 quic_data.AddWrite(SYNCHRONOUS,
3084 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333085 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3086 true, priority, GetRequestHeaders("GET", "https", "/"),
3087 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233088
3089 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523090 quic::QuicStreamOffset settings_offset = header_stream_offset;
3091 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433092 quic_data.AddWrite(SYNCHRONOUS,
3093 client_maker_.MakeInitialSettingsPacketAndSaveData(
3094 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233095 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093096 quic_data.AddWrite(SYNCHRONOUS,
3097 client_maker_.MakeDataPacket(
3098 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3099 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233100 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093101 quic_data.AddWrite(SYNCHRONOUS,
3102 client_maker_.MakeDataPacket(
3103 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3104 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233105 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093106 quic_data.AddWrite(SYNCHRONOUS,
3107 client_maker_.MakeDataPacket(
3108 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3109 false, 0, request_data));
3110 quic_data.AddWrite(SYNCHRONOUS,
3111 client_maker_.MakeDataPacket(
3112 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3113 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233114 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093115 quic_data.AddWrite(SYNCHRONOUS,
3116 client_maker_.MakeDataPacket(
3117 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3118 false, 0, request_data));
3119 quic_data.AddWrite(SYNCHRONOUS,
3120 client_maker_.MakeDataPacket(
3121 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3122 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233123 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093124 quic_data.AddWrite(SYNCHRONOUS,
3125 client_maker_.MakeDataPacket(
3126 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3127 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523128 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093129 SYNCHRONOUS, client_maker_.MakeDataPacket(
3130 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3131 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233132
Zhongyi Shi32f2fd02018-04-16 18:23:433133 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523134 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433135 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223136
rch9ecde09b2017-04-08 00:18:233137 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3138 quic_data.AddRead(ASYNC, OK);
3139 quic_data.AddSocketDataToFactory(&socket_factory_);
3140
3141 // After that fails, it will be resent via TCP.
3142 MockWrite http_writes[] = {
3143 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3144 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3145 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3146
3147 MockRead http_reads[] = {
3148 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3149 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3150 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013151 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233152 socket_factory_.AddSocketDataProvider(&http_data);
3153 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3154
3155 // In order for a new QUIC session to be established via alternate-protocol
3156 // without racing an HTTP connection, we need the host resolution to happen
3157 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3158 // connection to the the server, in this test we require confirmation
3159 // before encrypting so the HTTP job will still start.
3160 host_resolver_.set_synchronous_mode(true);
3161 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3162 "");
3163 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3164 AddressList address;
3165 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583166 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3167 CompletionOnceCallback(), &request,
3168 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413169 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233170
3171 CreateSession();
3172 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553173 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233174 QuicStreamFactoryPeer::SetAlarmFactory(
3175 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193176 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553177 &clock_));
rch9ecde09b2017-04-08 00:18:233178
Ryan Hamilton9835e662018-08-02 05:36:273179 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233180
3181 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3182 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413183 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233184 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3185
3186 // Pump the message loop to get the request started.
3187 base::RunLoop().RunUntilIdle();
3188 // Explicitly confirm the handshake.
3189 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523190 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233191
3192 // Run the QUIC session to completion.
3193 quic_task_runner_->RunUntilIdle();
3194 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3195
3196 // Let the transaction proceed which will result in QUIC being marked
3197 // as broken and the request falling back to TCP.
3198 EXPECT_THAT(callback.WaitForResult(), IsOk());
3199
3200 ExpectBrokenAlternateProtocolMapping();
3201 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3202 ASSERT_FALSE(http_data.AllReadDataConsumed());
3203
3204 // Read the response body over TCP.
3205 CheckResponseData(&trans, "hello world");
3206 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3207 ASSERT_TRUE(http_data.AllReadDataConsumed());
3208}
3209
rch2f2991c2017-04-13 19:28:173210// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3211// connection times out, then QUIC will be marked as broken and the request
3212// retried over TCP.
3213TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413214 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173215
3216 // The request will initially go out over QUIC.
3217 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523218 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133219 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173220 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3221
3222 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523223 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3224 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433225 quic_data.AddWrite(SYNCHRONOUS,
3226 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333227 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3228 true, priority, GetRequestHeaders("GET", "https", "/"),
3229 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173230
3231 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523232 quic::QuicStreamOffset settings_offset = header_stream_offset;
3233 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433234 quic_data.AddWrite(SYNCHRONOUS,
3235 client_maker_.MakeInitialSettingsPacketAndSaveData(
3236 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173237 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093238 quic_data.AddWrite(SYNCHRONOUS,
3239 client_maker_.MakeDataPacket(
3240 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3241 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173242 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093243 quic_data.AddWrite(SYNCHRONOUS,
3244 client_maker_.MakeDataPacket(
3245 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3246 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173247 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093248 quic_data.AddWrite(SYNCHRONOUS,
3249 client_maker_.MakeDataPacket(
3250 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3251 false, 0, request_data));
3252 quic_data.AddWrite(SYNCHRONOUS,
3253 client_maker_.MakeDataPacket(
3254 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3255 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173256 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093257 quic_data.AddWrite(SYNCHRONOUS,
3258 client_maker_.MakeDataPacket(
3259 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3260 false, 0, request_data));
3261 quic_data.AddWrite(SYNCHRONOUS,
3262 client_maker_.MakeDataPacket(
3263 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3264 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173265 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093266 quic_data.AddWrite(SYNCHRONOUS,
3267 client_maker_.MakeDataPacket(
3268 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3269 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523270 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093271 SYNCHRONOUS, client_maker_.MakeDataPacket(
3272 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3273 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173274
Zhongyi Shi32f2fd02018-04-16 18:23:433275 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523276 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433277 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223278
rch2f2991c2017-04-13 19:28:173279 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3280 quic_data.AddRead(ASYNC, OK);
3281 quic_data.AddSocketDataToFactory(&socket_factory_);
3282
3283 // After that fails, it will be resent via TCP.
3284 MockWrite http_writes[] = {
3285 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3286 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3287 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3288
3289 MockRead http_reads[] = {
3290 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3291 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3292 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013293 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173294 socket_factory_.AddSocketDataProvider(&http_data);
3295 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3296
3297 // In order for a new QUIC session to be established via alternate-protocol
3298 // without racing an HTTP connection, we need the host resolution to happen
3299 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3300 // connection to the the server, in this test we require confirmation
3301 // before encrypting so the HTTP job will still start.
3302 host_resolver_.set_synchronous_mode(true);
3303 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3304 "");
3305 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3306 AddressList address;
3307 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583308 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3309 CompletionOnceCallback(), &request,
3310 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413311 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173312
3313 CreateSession();
3314 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553315 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173316 QuicStreamFactoryPeer::SetAlarmFactory(
3317 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193318 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553319 &clock_));
rch2f2991c2017-04-13 19:28:173320
Ryan Hamilton9835e662018-08-02 05:36:273321 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173322
3323 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3324 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413325 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173326 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3327
3328 // Pump the message loop to get the request started.
3329 base::RunLoop().RunUntilIdle();
3330 // Explicitly confirm the handshake.
3331 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523332 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173333
3334 // Run the QUIC session to completion.
3335 quic_task_runner_->RunUntilIdle();
3336 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3337
3338 ExpectQuicAlternateProtocolMapping();
3339
3340 // Let the transaction proceed which will result in QUIC being marked
3341 // as broken and the request falling back to TCP.
3342 EXPECT_THAT(callback.WaitForResult(), IsOk());
3343
3344 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3345 ASSERT_FALSE(http_data.AllReadDataConsumed());
3346
3347 // Read the response body over TCP.
3348 CheckResponseData(&trans, "hello world");
3349 ExpectBrokenAlternateProtocolMapping();
3350 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3351 ASSERT_TRUE(http_data.AllReadDataConsumed());
3352}
3353
rch9ecde09b2017-04-08 00:18:233354// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3355// connection times out, then QUIC will be marked as broken but the request
3356// will not be retried over TCP.
3357TEST_P(QuicNetworkTransactionTest,
3358 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413359 session_params_.mark_quic_broken_when_network_blackholes = true;
3360 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233361
3362 // The request will initially go out over QUIC.
3363 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523364 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133365 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233366 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3367
3368 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523369 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3370 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433371 quic_data.AddWrite(SYNCHRONOUS,
3372 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333373 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3374 true, priority, GetRequestHeaders("GET", "https", "/"),
3375 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233376
3377 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523378 quic::QuicStreamOffset settings_offset = header_stream_offset;
3379 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433380 quic_data.AddWrite(SYNCHRONOUS,
3381 client_maker_.MakeInitialSettingsPacketAndSaveData(
3382 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233383
Zhongyi Shi32f2fd02018-04-16 18:23:433384 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333385 1, GetNthClientInitiatedBidirectionalStreamId(0),
3386 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433387 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523388 quic_data.AddWrite(
3389 SYNCHRONOUS,
3390 ConstructClientAckPacket(3, 1, 1, 1,
3391 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233392
3393 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523394 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093395 SYNCHRONOUS, client_maker_.MakeDataPacket(
3396 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3397 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233398 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093399 quic_data.AddWrite(
3400 SYNCHRONOUS, client_maker_.MakeDataPacket(
3401 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3402 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233403 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523404 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093405 SYNCHRONOUS, client_maker_.MakeDataPacket(
3406 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3407 false, 0, request_data));
3408 quic_data.AddWrite(
3409 SYNCHRONOUS, client_maker_.MakeDataPacket(
3410 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3411 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233412 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523413 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093414 SYNCHRONOUS, client_maker_.MakeDataPacket(
3415 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3416 false, 0, request_data));
3417 quic_data.AddWrite(
3418 SYNCHRONOUS, client_maker_.MakeDataPacket(
3419 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3420 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233421 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523422 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093423 SYNCHRONOUS, client_maker_.MakeDataPacket(
3424 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3425 false, 0, request_data));
3426 quic_data.AddWrite(
3427 SYNCHRONOUS, client_maker_.MakeDataPacket(
3428 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3429 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233430
Michael Warres112212822018-12-26 17:51:063431 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183432 quic_fix_time_of_first_packet_sent_after_receiving)) {
3433 quic_data.AddWrite(
3434 SYNCHRONOUS,
3435 client_maker_.MakeAckAndConnectionClosePacket(
3436 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3437 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3438
3439 } else {
3440 quic_data.AddWrite(
3441 SYNCHRONOUS,
3442 client_maker_.MakeAckAndConnectionClosePacket(
3443 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3444 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3445 }
Fan Yang928f1632017-12-14 18:55:223446
rch9ecde09b2017-04-08 00:18:233447 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3448 quic_data.AddRead(ASYNC, OK);
3449 quic_data.AddSocketDataToFactory(&socket_factory_);
3450
3451 // In order for a new QUIC session to be established via alternate-protocol
3452 // without racing an HTTP connection, we need the host resolution to happen
3453 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3454 // connection to the the server, in this test we require confirmation
3455 // before encrypting so the HTTP job will still start.
3456 host_resolver_.set_synchronous_mode(true);
3457 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3458 "");
3459 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3460 AddressList address;
3461 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583462 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3463 CompletionOnceCallback(), &request,
3464 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413465 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233466
3467 CreateSession();
3468 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553469 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233470 QuicStreamFactoryPeer::SetAlarmFactory(
3471 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193472 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553473 &clock_));
rch9ecde09b2017-04-08 00:18:233474
Ryan Hamilton9835e662018-08-02 05:36:273475 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233476
3477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3478 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413479 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3481
3482 // Pump the message loop to get the request started.
3483 base::RunLoop().RunUntilIdle();
3484 // Explicitly confirm the handshake.
3485 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523486 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233487
3488 // Pump the message loop to get the request started.
3489 base::RunLoop().RunUntilIdle();
3490
3491 // Run the QUIC session to completion.
3492 quic_task_runner_->RunUntilIdle();
3493 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3494
3495 // Let the transaction proceed which will result in QUIC being marked
3496 // as broken and the request falling back to TCP.
3497 EXPECT_THAT(callback.WaitForResult(), IsOk());
3498
3499 ExpectBrokenAlternateProtocolMapping();
3500 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3501
3502 std::string response_data;
3503 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3504 IsError(ERR_QUIC_PROTOCOL_ERROR));
3505}
3506
3507// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3508// connection RTOs, then QUIC will be marked as broken and the request retried
3509// over TCP.
3510TEST_P(QuicNetworkTransactionTest,
3511 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413512 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523513 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233514
3515 // The request will initially go out over QUIC.
3516 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523517 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133518 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233519 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3520
3521 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523522 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3523 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433524 quic_data.AddWrite(SYNCHRONOUS,
3525 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333526 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3527 true, priority, GetRequestHeaders("GET", "https", "/"),
3528 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233529
3530 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523531 quic::QuicStreamOffset settings_offset = header_stream_offset;
3532 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433533 quic_data.AddWrite(SYNCHRONOUS,
3534 client_maker_.MakeInitialSettingsPacketAndSaveData(
3535 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233536 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093537 quic_data.AddWrite(SYNCHRONOUS,
3538 client_maker_.MakeDataPacket(
3539 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3540 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233541 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093542 quic_data.AddWrite(SYNCHRONOUS,
3543 client_maker_.MakeDataPacket(
3544 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3545 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233546 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093547 quic_data.AddWrite(SYNCHRONOUS,
3548 client_maker_.MakeDataPacket(
3549 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3550 false, 0, request_data));
3551 quic_data.AddWrite(SYNCHRONOUS,
3552 client_maker_.MakeDataPacket(
3553 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3554 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233555 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093556 quic_data.AddWrite(SYNCHRONOUS,
3557 client_maker_.MakeDataPacket(
3558 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3559 false, 0, request_data));
3560 quic_data.AddWrite(SYNCHRONOUS,
3561 client_maker_.MakeDataPacket(
3562 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3563 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233564 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093565 quic_data.AddWrite(SYNCHRONOUS,
3566 client_maker_.MakeDataPacket(
3567 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3568 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523569 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093570 SYNCHRONOUS, client_maker_.MakeDataPacket(
3571 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3572 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233573 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523574 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093575 SYNCHRONOUS, client_maker_.MakeDataPacket(
3576 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3577 false, 0, request_data));
3578 quic_data.AddWrite(
3579 SYNCHRONOUS, client_maker_.MakeDataPacket(
3580 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3581 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233582
Zhongyi Shi32f2fd02018-04-16 18:23:433583 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523584 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433585 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233586
3587 quic_data.AddRead(ASYNC, OK);
3588 quic_data.AddSocketDataToFactory(&socket_factory_);
3589
3590 // After that fails, it will be resent via TCP.
3591 MockWrite http_writes[] = {
3592 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3593 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3594 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3595
3596 MockRead http_reads[] = {
3597 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3598 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3599 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013600 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233601 socket_factory_.AddSocketDataProvider(&http_data);
3602 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3603
3604 // In order for a new QUIC session to be established via alternate-protocol
3605 // without racing an HTTP connection, we need the host resolution to happen
3606 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3607 // connection to the the server, in this test we require confirmation
3608 // before encrypting so the HTTP job will still start.
3609 host_resolver_.set_synchronous_mode(true);
3610 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3611 "");
3612 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3613 AddressList address;
3614 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583615 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3616 CompletionOnceCallback(), &request,
3617 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413618 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233619
3620 CreateSession();
3621 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553622 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233623 QuicStreamFactoryPeer::SetAlarmFactory(
3624 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193625 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553626 &clock_));
rch9ecde09b2017-04-08 00:18:233627
Ryan Hamilton9835e662018-08-02 05:36:273628 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233629
3630 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3631 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413632 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3634
3635 // Pump the message loop to get the request started.
3636 base::RunLoop().RunUntilIdle();
3637 // Explicitly confirm the handshake.
3638 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523639 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233640
3641 // Run the QUIC session to completion.
3642 quic_task_runner_->RunUntilIdle();
3643 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3644
3645 // Let the transaction proceed which will result in QUIC being marked
3646 // as broken and the request falling back to TCP.
3647 EXPECT_THAT(callback.WaitForResult(), IsOk());
3648
3649 ExpectBrokenAlternateProtocolMapping();
3650 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3651 ASSERT_FALSE(http_data.AllReadDataConsumed());
3652
3653 // Read the response body over TCP.
3654 CheckResponseData(&trans, "hello world");
3655 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3656 ASSERT_TRUE(http_data.AllReadDataConsumed());
3657}
3658
3659// Verify that if a QUIC connection RTOs, while there are no active streams
3660// QUIC will be marked as broken.
3661TEST_P(QuicNetworkTransactionTest,
3662 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413663 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523664 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233665
3666 // The request will initially go out over QUIC.
3667 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523668 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133669 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233670 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3671
3672 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523673 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3674 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433675 quic_data.AddWrite(SYNCHRONOUS,
3676 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333677 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3678 true, priority, GetRequestHeaders("GET", "https", "/"),
3679 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233680
3681 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523682 quic::QuicStreamOffset settings_offset = header_stream_offset;
3683 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433684 quic_data.AddWrite(SYNCHRONOUS,
3685 client_maker_.MakeInitialSettingsPacketAndSaveData(
3686 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233687
Fan Yang32c5a112018-12-10 20:06:333688 quic_data.AddWrite(SYNCHRONOUS,
3689 client_maker_.MakeRstPacket(
3690 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3691 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233692 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093693 quic_data.AddWrite(SYNCHRONOUS,
3694 client_maker_.MakeDataPacket(
3695 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3696 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233697 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093698 quic_data.AddWrite(SYNCHRONOUS,
3699 client_maker_.MakeDataPacket(
3700 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3701 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233702 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333703 quic_data.AddWrite(SYNCHRONOUS,
3704 client_maker_.MakeRstPacket(
3705 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3706 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093707 quic_data.AddWrite(SYNCHRONOUS,
3708 client_maker_.MakeDataPacket(
3709 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3710 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233711 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093712 quic_data.AddWrite(SYNCHRONOUS,
3713 client_maker_.MakeDataPacket(
3714 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3715 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333716 quic_data.AddWrite(SYNCHRONOUS,
3717 client_maker_.MakeRstPacket(
3718 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3719 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233720 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523721 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093722 SYNCHRONOUS, client_maker_.MakeDataPacket(
3723 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3724 false, 0, request_data));
3725 quic_data.AddWrite(
3726 SYNCHRONOUS, client_maker_.MakeDataPacket(
3727 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3728 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233729 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433730 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333731 SYNCHRONOUS, client_maker_.MakeRstPacket(
3732 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3733 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523734 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093735 SYNCHRONOUS, client_maker_.MakeDataPacket(
3736 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3737 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233738 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433739 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523740 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433741 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233742
3743 quic_data.AddRead(ASYNC, OK);
3744 quic_data.AddSocketDataToFactory(&socket_factory_);
3745
3746 // In order for a new QUIC session to be established via alternate-protocol
3747 // without racing an HTTP connection, we need the host resolution to happen
3748 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3749 // connection to the the server, in this test we require confirmation
3750 // before encrypting so the HTTP job will still start.
3751 host_resolver_.set_synchronous_mode(true);
3752 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3753 "");
3754 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3755 AddressList address;
3756 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583757 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3758 CompletionOnceCallback(), &request,
3759 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413760 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233761
3762 CreateSession();
3763 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553764 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233765 QuicStreamFactoryPeer::SetAlarmFactory(
3766 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193767 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553768 &clock_));
rch9ecde09b2017-04-08 00:18:233769
Ryan Hamilton9835e662018-08-02 05:36:273770 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233771
Jeremy Roman0579ed62017-08-29 15:56:193772 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233773 session_.get());
3774 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413775 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3777
3778 // Pump the message loop to get the request started.
3779 base::RunLoop().RunUntilIdle();
3780 // Explicitly confirm the handshake.
3781 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523782 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233783
3784 // Now cancel the request.
3785 trans.reset();
3786
3787 // Run the QUIC session to completion.
3788 quic_task_runner_->RunUntilIdle();
3789
3790 ExpectBrokenAlternateProtocolMapping();
3791
3792 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3793}
3794
rch2f2991c2017-04-13 19:28:173795// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3796// protocol error occurs after the handshake is confirmed, the request
3797// retried over TCP and the QUIC will be marked as broken.
3798TEST_P(QuicNetworkTransactionTest,
3799 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413800 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173801
3802 // The request will initially go out over QUIC.
3803 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523804 quic::QuicStreamOffset header_stream_offset = 0;
3805 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3806 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433807 quic_data.AddWrite(
3808 SYNCHRONOUS,
3809 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333810 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433811 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523812 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433813 quic_data.AddWrite(SYNCHRONOUS,
3814 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173815 // Peer sending data from an non-existing stream causes this end to raise
3816 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333817 quic_data.AddRead(
3818 ASYNC, ConstructServerRstPacket(
3819 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3820 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173821 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433822 quic_data.AddWrite(SYNCHRONOUS,
3823 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523824 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3825 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173826 quic_data.AddSocketDataToFactory(&socket_factory_);
3827
3828 // After that fails, it will be resent via TCP.
3829 MockWrite http_writes[] = {
3830 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3831 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3832 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3833
3834 MockRead http_reads[] = {
3835 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3836 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3837 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013838 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173839 socket_factory_.AddSocketDataProvider(&http_data);
3840 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3841
3842 // In order for a new QUIC session to be established via alternate-protocol
3843 // without racing an HTTP connection, we need the host resolution to happen
3844 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3845 // connection to the the server, in this test we require confirmation
3846 // before encrypting so the HTTP job will still start.
3847 host_resolver_.set_synchronous_mode(true);
3848 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3849 "");
3850 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3851 AddressList address;
3852 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583853 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3854 CompletionOnceCallback(), &request,
3855 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413856 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173857
3858 CreateSession();
3859
Ryan Hamilton9835e662018-08-02 05:36:273860 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173861
3862 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3863 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413864 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3866
3867 // Pump the message loop to get the request started.
3868 base::RunLoop().RunUntilIdle();
3869 // Explicitly confirm the handshake.
3870 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523871 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173872
3873 // Run the QUIC session to completion.
3874 base::RunLoop().RunUntilIdle();
3875 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3876
3877 ExpectQuicAlternateProtocolMapping();
3878
3879 // Let the transaction proceed which will result in QUIC being marked
3880 // as broken and the request falling back to TCP.
3881 EXPECT_THAT(callback.WaitForResult(), IsOk());
3882
3883 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3884 ASSERT_FALSE(http_data.AllReadDataConsumed());
3885
3886 // Read the response body over TCP.
3887 CheckResponseData(&trans, "hello world");
3888 ExpectBrokenAlternateProtocolMapping();
3889 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3890 ASSERT_TRUE(http_data.AllReadDataConsumed());
3891}
3892
rch30943ee2017-06-12 21:28:443893// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3894// request is reset from, then QUIC will be marked as broken and the request
3895// retried over TCP.
3896TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443897 // The request will initially go out over QUIC.
3898 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523899 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133900 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443901 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3902
3903 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523904 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3905 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433906 quic_data.AddWrite(SYNCHRONOUS,
3907 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333908 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3909 true, priority, GetRequestHeaders("GET", "https", "/"),
3910 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443911
3912 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523913 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3914 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433915 quic_data.AddWrite(SYNCHRONOUS,
3916 client_maker_.MakeInitialSettingsPacketAndSaveData(
3917 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443918
Fan Yang32c5a112018-12-10 20:06:333919 quic_data.AddRead(ASYNC,
3920 ConstructServerRstPacket(
3921 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3922 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443923
3924 quic_data.AddRead(ASYNC, OK);
3925 quic_data.AddSocketDataToFactory(&socket_factory_);
3926
3927 // After that fails, it will be resent via TCP.
3928 MockWrite http_writes[] = {
3929 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3930 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3931 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3932
3933 MockRead http_reads[] = {
3934 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3935 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3936 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013937 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443938 socket_factory_.AddSocketDataProvider(&http_data);
3939 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3940
3941 // In order for a new QUIC session to be established via alternate-protocol
3942 // without racing an HTTP connection, we need the host resolution to happen
3943 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3944 // connection to the the server, in this test we require confirmation
3945 // before encrypting so the HTTP job will still start.
3946 host_resolver_.set_synchronous_mode(true);
3947 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3948 "");
3949 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3950 AddressList address;
3951 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583952 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3953 CompletionOnceCallback(), &request,
3954 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413955 EXPECT_THAT(rv, IsOk());
rch30943ee2017-06-12 21:28:443956
3957 CreateSession();
3958
Ryan Hamilton9835e662018-08-02 05:36:273959 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443960
3961 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3962 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413963 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3965
3966 // Pump the message loop to get the request started.
3967 base::RunLoop().RunUntilIdle();
3968 // Explicitly confirm the handshake.
3969 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523970 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443971
3972 // Run the QUIC session to completion.
3973 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3974
3975 ExpectQuicAlternateProtocolMapping();
3976
3977 // Let the transaction proceed which will result in QUIC being marked
3978 // as broken and the request falling back to TCP.
3979 EXPECT_THAT(callback.WaitForResult(), IsOk());
3980
3981 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3982 ASSERT_FALSE(http_data.AllReadDataConsumed());
3983
3984 // Read the response body over TCP.
3985 CheckResponseData(&trans, "hello world");
3986 ExpectBrokenAlternateProtocolMapping();
3987 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3988 ASSERT_TRUE(http_data.AllReadDataConsumed());
3989}
3990
Ryan Hamilton6c2a2a82017-12-15 02:06:283991// Verify that when an origin has two alt-svc advertisements, one local and one
3992// remote, that when the local is broken the request will go over QUIC via
3993// the remote Alt-Svc.
3994// This is a regression test for crbug/825646.
3995TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3996 session_params_.quic_allow_remote_alt_svc = true;
3997
3998 GURL origin1 = request_.url; // mail.example.org
3999 GURL origin2("https://www.example.org/");
4000 ASSERT_NE(origin1.host(), origin2.host());
4001
4002 scoped_refptr<X509Certificate> cert(
4003 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244004 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4005 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284006
4007 ProofVerifyDetailsChromium verify_details;
4008 verify_details.cert_verify_result.verified_cert = cert;
4009 verify_details.cert_verify_result.is_issued_by_known_root = true;
4010 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4011
4012 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524013 quic::QuicStreamOffset request_header_offset(0);
4014 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:284015 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434016 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4017 mock_quic_data.AddWrite(
4018 SYNCHRONOUS,
4019 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334020 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434021 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4022 mock_quic_data.AddRead(
4023 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334024 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434025 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414026 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434027 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334028 ASYNC, ConstructServerDataPacket(
4029 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414030 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434031 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284032 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4033 mock_quic_data.AddRead(ASYNC, 0); // EOF
4034
4035 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4036 MockQuicData mock_quic_data2;
4037 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4038 AddHangingNonAlternateProtocolSocketData();
4039
4040 CreateSession();
4041
4042 // Set up alternative service for |origin1|.
4043 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4044 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4045 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4046 AlternativeServiceInfoVector alternative_services;
4047 alternative_services.push_back(
4048 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4049 local_alternative, expiration,
4050 session_->params().quic_supported_versions));
4051 alternative_services.push_back(
4052 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4053 remote_alternative, expiration,
4054 session_->params().quic_supported_versions));
4055 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
4056 alternative_services);
4057
4058 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
4059
4060 SendRequestAndExpectQuicResponse("hello!");
4061}
4062
rch30943ee2017-06-12 21:28:444063// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4064// request is reset from, then QUIC will be marked as broken and the request
4065// retried over TCP. Then, subsequent requests will go over a new QUIC
4066// connection instead of going back to the broken QUIC connection.
4067// This is a regression tests for crbug/731303.
4068TEST_P(QuicNetworkTransactionTest,
4069 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344070 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444071
4072 GURL origin1 = request_.url;
4073 GURL origin2("https://www.example.org/");
4074 ASSERT_NE(origin1.host(), origin2.host());
4075
4076 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524077 quic::QuicStreamOffset request_header_offset(0);
4078 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444079
4080 scoped_refptr<X509Certificate> cert(
4081 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244082 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4083 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444084
4085 ProofVerifyDetailsChromium verify_details;
4086 verify_details.cert_verify_result.verified_cert = cert;
4087 verify_details.cert_verify_result.is_issued_by_known_root = true;
4088 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4089
4090 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434091 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444092 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434093 mock_quic_data.AddWrite(
4094 SYNCHRONOUS,
4095 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334096 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434097 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4098 mock_quic_data.AddRead(
4099 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334100 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434101 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414102 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434103 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334104 ASYNC, ConstructServerDataPacket(
4105 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414106 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434107 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444108
4109 // Second request will go over the pooled QUIC connection, but will be
4110 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054111 QuicTestPacketMaker client_maker2(
Fan Yang32c5a112018-12-10 20:06:334112 version_, quic::EmptyQuicConnectionId(), &clock_, origin2.host(),
4113 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054114 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:334115 QuicTestPacketMaker server_maker2(version_, quic::EmptyQuicConnectionId(),
4116 &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524117 quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434118 mock_quic_data.AddWrite(
4119 SYNCHRONOUS,
4120 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334121 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434122 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334123 GetNthClientInitiatedBidirectionalStreamId(0),
4124 &request_header_offset));
4125 mock_quic_data.AddRead(
4126 ASYNC, ConstructServerRstPacket(
4127 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4128 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444129 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4130 mock_quic_data.AddRead(ASYNC, 0); // EOF
4131
4132 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4133
4134 // After that fails, it will be resent via TCP.
4135 MockWrite http_writes[] = {
4136 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4137 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4138 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4139
4140 MockRead http_reads[] = {
4141 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4142 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4143 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014144 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444145 socket_factory_.AddSocketDataProvider(&http_data);
4146 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4147
Ryan Hamilton6c2a2a82017-12-15 02:06:284148 // Then the next request to the second origin will be sent over TCP.
4149 socket_factory_.AddSocketDataProvider(&http_data);
4150 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444151
4152 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564153 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4154 QuicStreamFactoryPeer::SetAlarmFactory(
4155 session_->quic_stream_factory(),
4156 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4157 &clock_));
rch30943ee2017-06-12 21:28:444158
4159 // Set up alternative service for |origin1|.
4160 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244161 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214162 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244163 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444164 supported_versions_);
rch30943ee2017-06-12 21:28:444165
4166 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244167 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214168 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244169 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444170 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344171
rch30943ee2017-06-12 21:28:444172 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524173 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444174 SendRequestAndExpectQuicResponse("hello!");
4175
4176 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524177 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444178 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4179 request_.url = origin2;
4180 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284181 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244182 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284183 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244184 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444185
4186 // The third request should use a new QUIC connection, not the broken
4187 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284188 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444189}
4190
bnc8be55ebb2015-10-30 14:12:074191TEST_P(QuicNetworkTransactionTest,
4192 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4193 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444194 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074195 MockRead http_reads[] = {
4196 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4197 MockRead("hello world"),
4198 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4199 MockRead(ASYNC, OK)};
4200
Ryan Sleevib8d7ea02018-05-07 20:01:014201 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074202 socket_factory_.AddSocketDataProvider(&http_data);
4203 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4204 socket_factory_.AddSocketDataProvider(&http_data);
4205 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4206
rch3f4b8452016-02-23 16:59:324207 CreateSession();
bnc8be55ebb2015-10-30 14:12:074208
4209 SendRequestAndExpectHttpResponse("hello world");
4210 SendRequestAndExpectHttpResponse("hello world");
4211}
4212
Xida Chen9bfe0b62018-04-24 19:52:214213// When multiple alternative services are advertised, HttpStreamFactory should
4214// select the alternative service which uses existing QUIC session if available.
4215// If no existing QUIC session can be used, use the first alternative service
4216// from the list.
zhongyi32569c62016-01-08 02:54:304217TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344218 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524219 MockRead http_reads[] = {
4220 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294221 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524222 MockRead("hello world"),
4223 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4224 MockRead(ASYNC, OK)};
4225
Ryan Sleevib8d7ea02018-05-07 20:01:014226 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524227 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084228 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564229 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524230
Ryan Hamilton8d9ee76e2018-05-29 23:52:524231 quic::QuicStreamOffset request_header_offset = 0;
4232 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304233 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294234 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304235 // alternative service list.
bncc958faa2015-07-31 18:14:524236 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364237 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434238 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4239 mock_quic_data.AddWrite(
4240 SYNCHRONOUS,
4241 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334242 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434243 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304244
4245 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294246 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4247 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434248 mock_quic_data.AddRead(
4249 ASYNC,
4250 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334251 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434252 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414253 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434254 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334255 ASYNC, ConstructServerDataPacket(
4256 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414257 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434258 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304259
4260 // Second QUIC request data.
4261 // Connection pooling, using existing session, no need to include version
4262 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584263 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334264 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4265 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4266 true, GetRequestHeaders("GET", "https", "/"),
4267 GetNthClientInitiatedBidirectionalStreamId(0),
4268 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434269 mock_quic_data.AddRead(
4270 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334271 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434272 GetResponseHeaders("200 OK"), &response_header_offset));
4273 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334274 ASYNC, ConstructServerDataPacket(
4275 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414276 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434277 mock_quic_data.AddWrite(
4278 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524279 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594280 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524281
4282 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4283
rtennetib8e80fb2016-05-16 00:12:094284 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324285 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564286 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4287 QuicStreamFactoryPeer::SetAlarmFactory(
4288 session_->quic_stream_factory(),
4289 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4290 &clock_));
bncc958faa2015-07-31 18:14:524291
4292 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304293
bnc359ed2a2016-04-29 20:43:454294 SendRequestAndExpectQuicResponse("hello!");
4295 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304296}
4297
tbansal6490783c2016-09-20 17:55:274298// Check that an existing QUIC connection to an alternative proxy server is
4299// used.
4300TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4301 base::HistogramTester histogram_tester;
4302
Ryan Hamilton8d9ee76e2018-05-29 23:52:524303 quic::QuicStreamOffset request_header_offset = 0;
4304 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274305 // First QUIC request data.
4306 // Open a session to foo.example.org:443 using the first entry of the
4307 // alternative service list.
4308 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364309 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434310 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4311 mock_quic_data.AddWrite(
4312 SYNCHRONOUS,
4313 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334314 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434315 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274316
4317 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434318 mock_quic_data.AddRead(
4319 ASYNC,
4320 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334321 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434322 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414323 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434324 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334325 ASYNC, ConstructServerDataPacket(
4326 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414327 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434328 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274329
4330 // Second QUIC request data.
4331 // Connection pooling, using existing session, no need to include version
4332 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274333 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334334 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4335 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4336 true, GetRequestHeaders("GET", "http", "/"),
4337 GetNthClientInitiatedBidirectionalStreamId(0),
4338 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434339 mock_quic_data.AddRead(
4340 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334341 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434342 GetResponseHeaders("200 OK"), &response_header_offset));
4343 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334344 ASYNC, ConstructServerDataPacket(
4345 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414346 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434347 mock_quic_data.AddWrite(
4348 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274349 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4350 mock_quic_data.AddRead(ASYNC, 0); // EOF
4351
4352 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4353
4354 AddHangingNonAlternateProtocolSocketData();
4355
4356 TestProxyDelegate test_proxy_delegate;
4357
Lily Houghton8c2f97d2018-01-22 05:06:594358 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494359 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274360
4361 test_proxy_delegate.set_alternative_proxy_server(
4362 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524363 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274364
4365 request_.url = GURL("http://mail.example.org/");
4366
4367 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564368 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4369 QuicStreamFactoryPeer::SetAlarmFactory(
4370 session_->quic_stream_factory(),
4371 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4372 &clock_));
tbansal6490783c2016-09-20 17:55:274373
4374 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4375 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4376 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4377 1);
4378
4379 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4380 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4381 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4382 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4383 1);
4384}
4385
Ryan Hamilton8d9ee76e2018-05-29 23:52:524386// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454387// even if alternative service destination is different.
4388TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344389 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304390 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524391 quic::QuicStreamOffset request_header_offset(0);
4392 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454393
rch5cb522462017-04-25 20:18:364394 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434395 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454396 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434397 mock_quic_data.AddWrite(
4398 SYNCHRONOUS,
4399 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334400 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434401 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4402 mock_quic_data.AddRead(
4403 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334404 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434405 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414406 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434407 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334408 ASYNC, ConstructServerDataPacket(
4409 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414410 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434411 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304412
bnc359ed2a2016-04-29 20:43:454413 // Second request.
alyssar2adf3ac2016-05-03 17:12:584414 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334415 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4416 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4417 true, GetRequestHeaders("GET", "https", "/"),
4418 GetNthClientInitiatedBidirectionalStreamId(0),
4419 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434420 mock_quic_data.AddRead(
4421 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334422 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434423 GetResponseHeaders("200 OK"), &response_header_offset));
4424 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334425 ASYNC, ConstructServerDataPacket(
4426 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414427 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434428 mock_quic_data.AddWrite(
4429 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304430 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4431 mock_quic_data.AddRead(ASYNC, 0); // EOF
4432
4433 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454434
4435 AddHangingNonAlternateProtocolSocketData();
4436 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304437
rch3f4b8452016-02-23 16:59:324438 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564439 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4440 QuicStreamFactoryPeer::SetAlarmFactory(
4441 session_->quic_stream_factory(),
4442 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4443 &clock_));
zhongyi32569c62016-01-08 02:54:304444
bnc359ed2a2016-04-29 20:43:454445 const char destination1[] = "first.example.com";
4446 const char destination2[] = "second.example.com";
4447
4448 // Set up alternative service entry to destination1.
4449 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214450 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454451 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214452 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444453 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454454 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524455 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454456 SendRequestAndExpectQuicResponse("hello!");
4457
4458 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214459 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214460 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444461 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524462 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454463 // even though alternative service destination is different.
4464 SendRequestAndExpectQuicResponse("hello!");
4465}
4466
4467// Pool to existing session with matching destination and matching certificate
4468// even if origin is different, and even if the alternative service with
4469// matching destination is not the first one on the list.
4470TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344471 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454472 GURL origin1 = request_.url;
4473 GURL origin2("https://www.example.org/");
4474 ASSERT_NE(origin1.host(), origin2.host());
4475
4476 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524477 quic::QuicStreamOffset request_header_offset(0);
4478 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454479
rch5cb522462017-04-25 20:18:364480 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434481 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454482 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434483 mock_quic_data.AddWrite(
4484 SYNCHRONOUS,
4485 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334486 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434487 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4488 mock_quic_data.AddRead(
4489 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334490 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434491 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414492 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434493 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334494 ASYNC, ConstructServerDataPacket(
4495 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414496 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434497 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454498
4499 // Second request.
Yixin Wang079ad542018-01-11 04:06:054500 QuicTestPacketMaker client_maker2(
Fan Yang32c5a112018-12-10 20:06:334501 version_, quic::EmptyQuicConnectionId(), &clock_, origin2.host(),
4502 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054503 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:334504 QuicTestPacketMaker server_maker2(version_, quic::EmptyQuicConnectionId(),
4505 &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524506 quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584507 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434508 SYNCHRONOUS,
4509 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334510 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434511 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334512 GetNthClientInitiatedBidirectionalStreamId(0),
4513 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434514 mock_quic_data.AddRead(
4515 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334516 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434517 GetResponseHeaders("200 OK"), &response_header_offset));
4518 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334519 ASYNC, ConstructServerDataPacket(
4520 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414521 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434522 mock_quic_data.AddWrite(
4523 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454524 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4525 mock_quic_data.AddRead(ASYNC, 0); // EOF
4526
4527 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4528
4529 AddHangingNonAlternateProtocolSocketData();
4530 AddHangingNonAlternateProtocolSocketData();
4531
4532 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564533 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4534 QuicStreamFactoryPeer::SetAlarmFactory(
4535 session_->quic_stream_factory(),
4536 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4537 &clock_));
bnc359ed2a2016-04-29 20:43:454538
4539 const char destination1[] = "first.example.com";
4540 const char destination2[] = "second.example.com";
4541
4542 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214543 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454544 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214545 http_server_properties_.SetQuicAlternativeService(
4546 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444547 supported_versions_);
bnc359ed2a2016-04-29 20:43:454548
4549 // Set up multiple alternative service entries for |origin2|,
4550 // the first one with a different destination as for |origin1|,
4551 // the second one with the same. The second one should be used,
4552 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214553 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454554 AlternativeServiceInfoVector alternative_services;
4555 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214556 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4557 alternative_service2, expiration,
4558 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454559 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214560 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4561 alternative_service1, expiration,
4562 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454563 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4564 alternative_services);
bnc359ed2a2016-04-29 20:43:454565 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524566 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454567 SendRequestAndExpectQuicResponse("hello!");
4568
4569 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524570 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454571 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584572
bnc359ed2a2016-04-29 20:43:454573 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304574}
4575
4576// Multiple origins have listed the same alternative services. When there's a
4577// existing QUIC session opened by a request to other origin,
4578// if the cert is valid, should select this QUIC session to make the request
4579// if this is also the first existing QUIC session.
4580TEST_P(QuicNetworkTransactionTest,
4581 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344582 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294583 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304584
rch9ae5b3b2016-02-11 00:36:294585 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304586 MockRead http_reads[] = {
4587 MockRead("HTTP/1.1 200 OK\r\n"),
4588 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294589 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304590 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4591 MockRead(ASYNC, OK)};
4592
Ryan Sleevib8d7ea02018-05-07 20:01:014593 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304594 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084595 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304596 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4597
4598 // HTTP data for request to mail.example.org.
4599 MockRead http_reads2[] = {
4600 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294601 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304602 MockRead("hello world from mail.example.org"),
4603 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4604 MockRead(ASYNC, OK)};
4605
Ryan Sleevib8d7ea02018-05-07 20:01:014606 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304607 socket_factory_.AddSocketDataProvider(&http_data2);
4608 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4609
Ryan Hamilton8d9ee76e2018-05-29 23:52:524610 quic::QuicStreamOffset request_header_offset = 0;
4611 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304612
Yixin Wang079ad542018-01-11 04:06:054613 QuicTestPacketMaker client_maker(
Fan Yang32c5a112018-12-10 20:06:334614 version_, quic::EmptyQuicConnectionId(), &clock_, "mail.example.org",
4615 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054616 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584617 server_maker_.set_hostname("www.example.org");
4618 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304619 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364620 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434621 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304622 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584623 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434624 SYNCHRONOUS,
4625 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334626 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434627 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4628
4629 mock_quic_data.AddRead(
4630 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334631 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434632 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414633 quic::QuicString header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334634 mock_quic_data.AddRead(
4635 ASYNC, ConstructServerDataPacket(
4636 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414637 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434638 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4639 // Second QUIC request data.
4640 mock_quic_data.AddWrite(
4641 SYNCHRONOUS,
4642 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334643 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434644 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334645 GetNthClientInitiatedBidirectionalStreamId(0),
4646 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434647 mock_quic_data.AddRead(
4648 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334649 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434650 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334651 mock_quic_data.AddRead(
4652 ASYNC, ConstructServerDataPacket(
4653 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414654 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434655 mock_quic_data.AddWrite(
4656 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304657 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4658 mock_quic_data.AddRead(ASYNC, 0); // EOF
4659
4660 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304661
rtennetib8e80fb2016-05-16 00:12:094662 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324663 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564664 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4665 QuicStreamFactoryPeer::SetAlarmFactory(
4666 session_->quic_stream_factory(),
4667 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4668 &clock_));
zhongyi32569c62016-01-08 02:54:304669
4670 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294671 request_.url = GURL("https://www.example.org/");
4672 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304673 request_.url = GURL("https://mail.example.org/");
4674 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4675
rch9ae5b3b2016-02-11 00:36:294676 // Open a QUIC session to mail.example.org:443 when making request
4677 // to mail.example.org.
4678 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454679 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304680
rch9ae5b3b2016-02-11 00:36:294681 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304682 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454683 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524684}
4685
4686TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524687 MockRead http_reads[] = {
4688 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564689 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524690 MockRead("hello world"),
4691 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4692 MockRead(ASYNC, OK)};
4693
Ryan Sleevib8d7ea02018-05-07 20:01:014694 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524695 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084696 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564697 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524698
rtennetib8e80fb2016-05-16 00:12:094699 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324700 CreateSession();
bncc958faa2015-07-31 18:14:524701
4702 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454703
4704 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344705 AlternativeServiceInfoVector alternative_service_info_vector =
4706 http_server_properties_.GetAlternativeServiceInfos(http_server);
4707 ASSERT_EQ(1u, alternative_service_info_vector.size());
4708 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544709 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344710 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4711 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4712 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524713}
4714
4715TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524716 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564717 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4718 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524719 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4720 MockRead(ASYNC, OK)};
4721
Ryan Sleevib8d7ea02018-05-07 20:01:014722 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524723 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084724 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564725 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524726
4727 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524728 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364729 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434730 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4731 mock_quic_data.AddWrite(
4732 SYNCHRONOUS,
4733 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334734 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434735 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434736 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334737 ASYNC, ConstructServerResponseHeadersPacket(
4738 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4739 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414740 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334741 mock_quic_data.AddRead(
4742 ASYNC, ConstructServerDataPacket(
4743 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414744 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434745 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524746 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4747 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524748
4749 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4750
rtennetib8e80fb2016-05-16 00:12:094751 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324752 CreateSession();
bncc958faa2015-07-31 18:14:524753
bnc3472afd2016-11-17 15:27:214754 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524755 HostPortPair::FromURL(request_.url));
4756 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4757 alternative_service);
4758 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4759 alternative_service));
4760
4761 SendRequestAndExpectHttpResponse("hello world");
4762 SendRequestAndExpectQuicResponse("hello!");
4763
mmenkee24011922015-12-17 22:12:594764 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524765
4766 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4767 alternative_service));
rchac7f35e2017-03-15 20:42:304768 EXPECT_NE(nullptr,
4769 http_server_properties_.GetServerNetworkStats(
4770 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524771}
4772
bncc958faa2015-07-31 18:14:524773TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524774 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564775 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4776 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524777 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4778 MockRead(ASYNC, OK)};
4779
Ryan Sleevib8d7ea02018-05-07 20:01:014780 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524781 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564782 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524783
4784 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524785 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364786 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434787 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4788 mock_quic_data.AddWrite(
4789 SYNCHRONOUS,
4790 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334791 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434792 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434793 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334794 ASYNC, ConstructServerResponseHeadersPacket(
4795 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4796 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414797 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334798 mock_quic_data.AddRead(
4799 ASYNC, ConstructServerDataPacket(
4800 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414801 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434802 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524803 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4804
4805 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4806
4807 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324808 CreateSession();
bncc958faa2015-07-31 18:14:524809
4810 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4811 SendRequestAndExpectHttpResponse("hello world");
4812}
4813
tbansalc3308d72016-08-27 10:25:044814// Tests that the connection to an HTTPS proxy is raced with an available
4815// alternative proxy server.
4816TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274817 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594818 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494819 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044820
4821 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524822 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364823 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434824 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4825 mock_quic_data.AddWrite(
4826 SYNCHRONOUS,
4827 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334828 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434829 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434830 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334831 ASYNC, ConstructServerResponseHeadersPacket(
4832 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4833 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414834 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334835 mock_quic_data.AddRead(
4836 ASYNC, ConstructServerDataPacket(
4837 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414838 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434839 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044840 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4841 mock_quic_data.AddRead(ASYNC, 0); // EOF
4842
4843 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4844
4845 // There is no need to set up main job, because no attempt will be made to
4846 // speak to the proxy over TCP.
4847 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044848 TestProxyDelegate test_proxy_delegate;
4849 const HostPortPair host_port_pair("mail.example.org", 443);
4850
4851 test_proxy_delegate.set_alternative_proxy_server(
4852 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524853 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044854 CreateSession();
4855 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4856
4857 // The main job needs to hang in order to guarantee that the alternative
4858 // proxy server job will "win".
4859 AddHangingNonAlternateProtocolSocketData();
4860
4861 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4862
4863 // Verify that the alternative proxy server is not marked as broken.
4864 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4865
4866 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594867 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274868
4869 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4870 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4871 1);
tbansalc3308d72016-08-27 10:25:044872}
4873
bnc1c196c6e2016-05-28 13:51:484874TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304875 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274876 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304877
4878 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564879 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294880 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564881 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304882
4883 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564884 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484885 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564886 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304887
Ryan Sleevib8d7ea02018-05-07 20:01:014888 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504889 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084890 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504891 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304892
4893 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454894 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304895 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454896 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304897 };
Ryan Sleevib8d7ea02018-05-07 20:01:014898 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504899 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304900
4901 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014902 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504903 socket_factory_.AddSocketDataProvider(&http_data2);
4904 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304905
bnc912a04b2016-04-20 14:19:504906 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304907
4908 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304909 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174910 ASSERT_TRUE(http_data.AllReadDataConsumed());
4911 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304912
4913 // Now run the second request in which the QUIC socket hangs,
4914 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304915 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454916 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304917
rch37de576c2015-05-17 20:28:174918 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4919 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454920 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304921}
4922
[email protected]1e960032013-12-20 19:00:204923TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204924 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524925 quic::QuicStreamOffset header_stream_offset = 0;
4926 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4927 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434928 mock_quic_data.AddWrite(
4929 SYNCHRONOUS,
4930 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334931 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434932 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434933 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334934 ASYNC, ConstructServerResponseHeadersPacket(
4935 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4936 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414937 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334938 mock_quic_data.AddRead(
4939 ASYNC, ConstructServerDataPacket(
4940 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414941 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434942 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504943 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594944 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484945
rcha5399e02015-04-21 19:32:044946 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484947
rtennetib8e80fb2016-05-16 00:12:094948 // The non-alternate protocol job needs to hang in order to guarantee that
4949 // the alternate-protocol job will "win".
4950 AddHangingNonAlternateProtocolSocketData();
4951
rch3f4b8452016-02-23 16:59:324952 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274953 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194954 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304955
4956 EXPECT_EQ(nullptr,
4957 http_server_properties_.GetServerNetworkStats(
4958 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484959}
4960
[email protected]1e960032013-12-20 19:00:204961TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204962 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524963 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4964 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Fan Yang32c5a112018-12-10 20:06:334965 mock_quic_data.AddWrite(
4966 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4967 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4968 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434969 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334970 ASYNC, ConstructServerResponseHeadersPacket(
4971 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4972 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414973 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334974 mock_quic_data.AddRead(
4975 ASYNC, ConstructServerDataPacket(
4976 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414977 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434978 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504979 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594980 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044981 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274982
4983 // In order for a new QUIC session to be established via alternate-protocol
4984 // without racing an HTTP connection, we need the host resolution to happen
4985 // synchronously.
4986 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294987 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564988 "");
rch9ae5b3b2016-02-11 00:36:294989 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]3a120a6b2013-06-25 01:08:274990 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104991 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584992 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4993 CompletionOnceCallback(), &request,
4994 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414995 EXPECT_THAT(rv, IsOk());
[email protected]3a120a6b2013-06-25 01:08:274996
rtennetib8e80fb2016-05-16 00:12:094997 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324998 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274999 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275000 SendRequestAndExpectQuicResponse("hello!");
5001}
5002
[email protected]0fc924b2014-03-31 04:34:155003TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495004 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5005 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155006
5007 // Since we are using a proxy, the QUIC job will not succeed.
5008 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295009 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5010 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565011 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155012
5013 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565014 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485015 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565016 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155017
Ryan Sleevib8d7ea02018-05-07 20:01:015018 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155019 socket_factory_.AddSocketDataProvider(&http_data);
5020
5021 // In order for a new QUIC session to be established via alternate-protocol
5022 // without racing an HTTP connection, we need the host resolution to happen
5023 // synchronously.
5024 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295025 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565026 "");
rch9ae5b3b2016-02-11 00:36:295027 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]0fc924b2014-03-31 04:34:155028 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105029 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585030 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5031 CompletionOnceCallback(), &request,
5032 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415033 EXPECT_THAT(rv, IsOk());
[email protected]0fc924b2014-03-31 04:34:155034
rch9ae5b3b2016-02-11 00:36:295035 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325036 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275037 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155038 SendRequestAndExpectHttpResponse("hello world");
5039}
5040
[email protected]1e960032013-12-20 19:00:205041TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:205042 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525043 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365044 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435045 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5046 mock_quic_data.AddWrite(
5047 SYNCHRONOUS,
5048 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335049 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435050 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435051 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335052 ASYNC, ConstructServerResponseHeadersPacket(
5053 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5054 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415055 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335056 mock_quic_data.AddRead(
5057 ASYNC, ConstructServerDataPacket(
5058 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415059 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435060 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595061 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045062 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125063
rtennetib8e80fb2016-05-16 00:12:095064 // The non-alternate protocol job needs to hang in order to guarantee that
5065 // the alternate-protocol job will "win".
5066 AddHangingNonAlternateProtocolSocketData();
5067
[email protected]11c05872013-08-20 02:04:125068 // In order for a new QUIC session to be established via alternate-protocol
5069 // without racing an HTTP connection, we need the host resolution to happen
5070 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5071 // connection to the the server, in this test we require confirmation
5072 // before encrypting so the HTTP job will still start.
5073 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295074 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565075 "");
rch9ae5b3b2016-02-11 00:36:295076 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]11c05872013-08-20 02:04:125077 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105078 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585079 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5080 CompletionOnceCallback(), &request,
5081 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415082 EXPECT_THAT(rv, IsOk());
[email protected]11c05872013-08-20 02:04:125083
rch3f4b8452016-02-23 16:59:325084 CreateSession();
[email protected]11c05872013-08-20 02:04:125085 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275086 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125087
bnc691fda62016-08-12 00:43:165088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125089 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415090 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125092
5093 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525094 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015095 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505096
bnc691fda62016-08-12 00:43:165097 CheckWasQuicResponse(&trans);
5098 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125099}
5100
Steven Valdez58097ec32018-07-16 18:29:045101TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5102 MockQuicData mock_quic_data;
5103 quic::QuicStreamOffset client_header_stream_offset = 0;
5104 quic::QuicStreamOffset server_header_stream_offset = 0;
5105 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5106 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045107 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335108 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5109 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5110 true, GetRequestHeaders("GET", "https", "/"),
5111 &client_header_stream_offset));
5112 mock_quic_data.AddRead(
5113 ASYNC,
5114 ConstructServerResponseHeadersPacket(
5115 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5116 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5117 mock_quic_data.AddWrite(SYNCHRONOUS,
5118 ConstructClientAckAndRstPacket(
5119 2, GetNthClientInitiatedBidirectionalStreamId(0),
5120 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045121
5122 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5123
5124 spdy::SpdySettingsIR settings_frame;
5125 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5126 quic::kDefaultMaxUncompressedHeaderSize);
5127 spdy::SpdySerializedFrame spdy_frame(
5128 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5129 mock_quic_data.AddWrite(
5130 SYNCHRONOUS,
5131 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385132 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5133 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045134 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5135 client_header_stream_offset += spdy_frame.size();
5136
5137 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335138 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5139 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5140 true, GetRequestHeaders("GET", "https", "/"),
5141 GetNthClientInitiatedBidirectionalStreamId(0),
5142 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045143 mock_quic_data.AddRead(
5144 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335145 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045146 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjief49758b2019-01-11 23:32:415147 quic::QuicString header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045148 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335149 ASYNC, ConstructServerDataPacket(
5150 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415151 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045152 mock_quic_data.AddWrite(
5153 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5154 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5155 mock_quic_data.AddRead(ASYNC, 0); // EOF
5156
5157 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5158
5159 // In order for a new QUIC session to be established via alternate-protocol
5160 // without racing an HTTP connection, we need the host resolution to happen
5161 // synchronously.
5162 host_resolver_.set_synchronous_mode(true);
5163 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5164 "");
5165 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5166 AddressList address;
5167 std::unique_ptr<HostResolver::Request> request;
5168 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5169 CompletionOnceCallback(), &request, net_log_.bound());
5170
5171 AddHangingNonAlternateProtocolSocketData();
5172 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275173 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565174 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5175 QuicStreamFactoryPeer::SetAlarmFactory(
5176 session_->quic_stream_factory(),
5177 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5178 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045179
5180 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5181 TestCompletionCallback callback;
5182 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5183 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5184
5185 // Confirm the handshake after the 425 Too Early.
5186 base::RunLoop().RunUntilIdle();
5187
5188 // The handshake hasn't been confirmed yet, so the retry should not have
5189 // succeeded.
5190 EXPECT_FALSE(callback.have_result());
5191
5192 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5193 quic::QuicSession::HANDSHAKE_CONFIRMED);
5194
5195 EXPECT_THAT(callback.WaitForResult(), IsOk());
5196 CheckWasQuicResponse(&trans);
5197 CheckResponseData(&trans, "hello!");
5198}
5199
5200TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5201 MockQuicData mock_quic_data;
5202 quic::QuicStreamOffset client_header_stream_offset = 0;
5203 quic::QuicStreamOffset server_header_stream_offset = 0;
5204 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5205 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045206 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335207 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5208 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5209 true, GetRequestHeaders("GET", "https", "/"),
5210 &client_header_stream_offset));
5211 mock_quic_data.AddRead(
5212 ASYNC,
5213 ConstructServerResponseHeadersPacket(
5214 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5215 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5216 mock_quic_data.AddWrite(SYNCHRONOUS,
5217 ConstructClientAckAndRstPacket(
5218 2, GetNthClientInitiatedBidirectionalStreamId(0),
5219 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045220
5221 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5222
5223 spdy::SpdySettingsIR settings_frame;
5224 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5225 quic::kDefaultMaxUncompressedHeaderSize);
5226 spdy::SpdySerializedFrame spdy_frame(
5227 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5228 mock_quic_data.AddWrite(
5229 SYNCHRONOUS,
5230 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385231 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5232 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045233 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5234 client_header_stream_offset += spdy_frame.size();
5235
5236 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335237 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5238 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5239 true, GetRequestHeaders("GET", "https", "/"),
5240 GetNthClientInitiatedBidirectionalStreamId(0),
5241 &client_header_stream_offset));
5242 mock_quic_data.AddRead(
5243 ASYNC,
5244 ConstructServerResponseHeadersPacket(
5245 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5246 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5247 mock_quic_data.AddWrite(SYNCHRONOUS,
5248 ConstructClientAckAndRstPacket(
5249 5, GetNthClientInitiatedBidirectionalStreamId(1),
5250 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045251 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5252 mock_quic_data.AddRead(ASYNC, 0); // EOF
5253
5254 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5255
5256 // In order for a new QUIC session to be established via alternate-protocol
5257 // without racing an HTTP connection, we need the host resolution to happen
5258 // synchronously.
5259 host_resolver_.set_synchronous_mode(true);
5260 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5261 "");
5262 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5263 AddressList address;
5264 std::unique_ptr<HostResolver::Request> request;
5265 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5266 CompletionOnceCallback(), &request, net_log_.bound());
5267
5268 AddHangingNonAlternateProtocolSocketData();
5269 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275270 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565271 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5272 QuicStreamFactoryPeer::SetAlarmFactory(
5273 session_->quic_stream_factory(),
5274 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5275 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045276
5277 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5278 TestCompletionCallback callback;
5279 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5281
5282 // Confirm the handshake after the 425 Too Early.
5283 base::RunLoop().RunUntilIdle();
5284
5285 // The handshake hasn't been confirmed yet, so the retry should not have
5286 // succeeded.
5287 EXPECT_FALSE(callback.have_result());
5288
5289 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5290 quic::QuicSession::HANDSHAKE_CONFIRMED);
5291
5292 EXPECT_THAT(callback.WaitForResult(), IsOk());
5293 const HttpResponseInfo* response = trans.GetResponseInfo();
5294 ASSERT_TRUE(response != nullptr);
5295 ASSERT_TRUE(response->headers.get() != nullptr);
5296 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5297 EXPECT_TRUE(response->was_fetched_via_spdy);
5298 EXPECT_TRUE(response->was_alpn_negotiated);
5299 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5300 response->connection_info);
5301}
5302
zhongyica364fbb2015-12-12 03:39:125303TEST_P(QuicNetworkTransactionTest,
5304 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485305 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125306 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525307 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365308 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435309 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5310 mock_quic_data.AddWrite(
5311 SYNCHRONOUS,
5312 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335313 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435314 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125315 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525316 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435317 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125318 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5319
5320 // The non-alternate protocol job needs to hang in order to guarantee that
5321 // the alternate-protocol job will "win".
5322 AddHangingNonAlternateProtocolSocketData();
5323
5324 // In order for a new QUIC session to be established via alternate-protocol
5325 // without racing an HTTP connection, we need the host resolution to happen
5326 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5327 // connection to the the server, in this test we require confirmation
5328 // before encrypting so the HTTP job will still start.
5329 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295330 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125331 "");
rch9ae5b3b2016-02-11 00:36:295332 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125333 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105334 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585335 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5336 CompletionOnceCallback(), &request,
5337 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415338 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125339
rch3f4b8452016-02-23 16:59:325340 CreateSession();
zhongyica364fbb2015-12-12 03:39:125341 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275342 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125343
bnc691fda62016-08-12 00:43:165344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125345 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415346 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125348
5349 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525350 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015351 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125352
5353 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525354 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125355
bnc691fda62016-08-12 00:43:165356 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125357 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525358 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5359 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125360}
5361
5362TEST_P(QuicNetworkTransactionTest,
5363 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485364 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125365 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525366 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365367 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435368 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5369 mock_quic_data.AddWrite(
5370 SYNCHRONOUS,
5371 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335372 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435373 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215374 // Peer sending data from an non-existing stream causes this end to raise
5375 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335376 mock_quic_data.AddRead(
5377 ASYNC, ConstructServerRstPacket(
5378 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5379 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215380 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525381 mock_quic_data.AddWrite(
5382 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5383 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5384 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125385 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5386
5387 // The non-alternate protocol job needs to hang in order to guarantee that
5388 // the alternate-protocol job will "win".
5389 AddHangingNonAlternateProtocolSocketData();
5390
5391 // In order for a new QUIC session to be established via alternate-protocol
5392 // without racing an HTTP connection, we need the host resolution to happen
5393 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5394 // connection to the the server, in this test we require confirmation
5395 // before encrypting so the HTTP job will still start.
5396 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295397 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125398 "");
rch9ae5b3b2016-02-11 00:36:295399 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125400 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105401 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585402 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5403 CompletionOnceCallback(), &request,
5404 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415405 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125406
rch3f4b8452016-02-23 16:59:325407 CreateSession();
zhongyica364fbb2015-12-12 03:39:125408 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275409 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125410
bnc691fda62016-08-12 00:43:165411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125412 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415413 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015414 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125415
5416 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525417 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015418 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125419 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525420 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125421
bnc691fda62016-08-12 00:43:165422 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525423 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125424}
5425
rchcd5f1c62016-06-23 02:43:485426TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5427 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525428 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365429 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435430 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5431 mock_quic_data.AddWrite(
5432 SYNCHRONOUS,
5433 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335434 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435435 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485436 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335437 mock_quic_data.AddRead(
5438 ASYNC, ConstructServerResponseHeadersPacket(
5439 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5440 GetResponseHeaders("200 OK")));
5441 mock_quic_data.AddRead(
5442 ASYNC, ConstructServerRstPacket(
5443 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5444 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435445 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485446 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5447 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5448
5449 // The non-alternate protocol job needs to hang in order to guarantee that
5450 // the alternate-protocol job will "win".
5451 AddHangingNonAlternateProtocolSocketData();
5452
5453 // In order for a new QUIC session to be established via alternate-protocol
5454 // without racing an HTTP connection, we need the host resolution to happen
5455 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5456 // connection to the the server, in this test we require confirmation
5457 // before encrypting so the HTTP job will still start.
5458 host_resolver_.set_synchronous_mode(true);
5459 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5460 "");
5461 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5462 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105463 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585464 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5465 CompletionOnceCallback(), &request,
5466 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415467 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485468
5469 CreateSession();
5470 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275471 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485472
bnc691fda62016-08-12 00:43:165473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485474 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415475 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485477
5478 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525479 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485480 // Read the headers.
robpercival214763f2016-07-01 23:27:015481 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485482
bnc691fda62016-08-12 00:43:165483 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485484 ASSERT_TRUE(response != nullptr);
5485 ASSERT_TRUE(response->headers.get() != nullptr);
5486 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5487 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525488 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445489 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5490 response->connection_info);
rchcd5f1c62016-06-23 02:43:485491
5492 std::string response_data;
bnc691fda62016-08-12 00:43:165493 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485494}
5495
5496TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485497 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485498 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525499 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365500 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435501 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5502 mock_quic_data.AddWrite(
5503 SYNCHRONOUS,
5504 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335505 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435506 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335507 mock_quic_data.AddRead(
5508 ASYNC, ConstructServerRstPacket(
5509 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5510 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485511 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5512 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5513
5514 // The non-alternate protocol job needs to hang in order to guarantee that
5515 // the alternate-protocol job will "win".
5516 AddHangingNonAlternateProtocolSocketData();
5517
5518 // In order for a new QUIC session to be established via alternate-protocol
5519 // without racing an HTTP connection, we need the host resolution to happen
5520 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5521 // connection to the the server, in this test we require confirmation
5522 // before encrypting so the HTTP job will still start.
5523 host_resolver_.set_synchronous_mode(true);
5524 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5525 "");
5526 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5527 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105528 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585529 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5530 CompletionOnceCallback(), &request,
5531 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415532 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485533
5534 CreateSession();
5535 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275536 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485537
bnc691fda62016-08-12 00:43:165538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485539 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415540 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485542
5543 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525544 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485545 // Read the headers.
robpercival214763f2016-07-01 23:27:015546 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485547}
5548
[email protected]1e960032013-12-20 19:00:205549TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305550 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525551 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585552 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305553 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505554 MockRead(ASYNC, close->data(), close->length()),
5555 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5556 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305557 };
Ryan Sleevib8d7ea02018-05-07 20:01:015558 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305559 socket_factory_.AddSocketDataProvider(&quic_data);
5560
5561 // Main job which will succeed even though the alternate job fails.
5562 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025563 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5564 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5565 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305566
Ryan Sleevib8d7ea02018-05-07 20:01:015567 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305568 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565569 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305570
rch3f4b8452016-02-23 16:59:325571 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275572 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195573 SendRequestAndExpectHttpResponse("hello from http");
5574 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305575}
5576
[email protected]1e960032013-12-20 19:00:205577TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595578 // Alternate-protocol job
5579 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025580 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595581 };
Ryan Sleevib8d7ea02018-05-07 20:01:015582 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595583 socket_factory_.AddSocketDataProvider(&quic_data);
5584
5585 // Main job which will succeed even though the alternate job fails.
5586 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025587 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5588 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5589 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595590
Ryan Sleevib8d7ea02018-05-07 20:01:015591 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595592 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565593 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595594
rch3f4b8452016-02-23 16:59:325595 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595596
Ryan Hamilton9835e662018-08-02 05:36:275597 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195598 SendRequestAndExpectHttpResponse("hello from http");
5599 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595600}
5601
[email protected]00c159f2014-05-21 22:38:165602TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535603 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165604 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025605 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165606 };
Ryan Sleevib8d7ea02018-05-07 20:01:015607 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165608 socket_factory_.AddSocketDataProvider(&quic_data);
5609
[email protected]eb71ab62014-05-23 07:57:535610 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165611 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025612 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165613 };
5614
Ryan Sleevib8d7ea02018-05-07 20:01:015615 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165616 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5617 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565618 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165619
rtennetib8e80fb2016-05-16 00:12:095620 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325621 CreateSession();
[email protected]00c159f2014-05-21 22:38:165622
Ryan Hamilton9835e662018-08-02 05:36:275623 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165624 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165625 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165626 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015627 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5628 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165629 ExpectQuicAlternateProtocolMapping();
5630}
5631
Zhongyi Shia0cef1082017-08-25 01:49:505632TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5633 // Tests that TCP job is delayed and QUIC job does not require confirmation
5634 // if QUIC was recently supported on the same IP on start.
5635
5636 // Set QUIC support on the last IP address, which is same with the local IP
5637 // address. Require confirmation mode will be turned off immediately when
5638 // local IP address is sorted out after we configure the UDP socket.
5639 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5640
5641 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525642 quic::QuicStreamOffset header_stream_offset = 0;
5643 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5644 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:435645 mock_quic_data.AddWrite(
5646 SYNCHRONOUS,
5647 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335648 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435649 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435650 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335651 ASYNC, ConstructServerResponseHeadersPacket(
5652 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5653 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415654 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335655 mock_quic_data.AddRead(
5656 ASYNC, ConstructServerDataPacket(
5657 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415658 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435659 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505660 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5661 mock_quic_data.AddRead(ASYNC, 0); // EOF
5662
5663 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5664 // No HTTP data is mocked as TCP job never starts in this case.
5665
5666 CreateSession();
5667 // QuicStreamFactory by default requires confirmation on construction.
5668 session_->quic_stream_factory()->set_require_confirmation(true);
5669
Ryan Hamilton9835e662018-08-02 05:36:275670 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505671
5672 // Stall host resolution so that QUIC job will not succeed synchronously.
5673 // Socket will not be configured immediately and QUIC support is not sorted
5674 // out, TCP job will still be delayed as server properties indicates QUIC
5675 // support on last IP address.
5676 host_resolver_.set_synchronous_mode(false);
5677
5678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5679 TestCompletionCallback callback;
5680 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5681 IsError(ERR_IO_PENDING));
5682 // Complete host resolution in next message loop so that QUIC job could
5683 // proceed.
5684 base::RunLoop().RunUntilIdle();
5685 EXPECT_THAT(callback.WaitForResult(), IsOk());
5686
5687 CheckWasQuicResponse(&trans);
5688 CheckResponseData(&trans, "hello!");
5689}
5690
5691TEST_P(QuicNetworkTransactionTest,
5692 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5693 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5694 // was recently supported on a different IP address on start.
5695
5696 // Set QUIC support on the last IP address, which is different with the local
5697 // IP address. Require confirmation mode will remain when local IP address is
5698 // sorted out after we configure the UDP socket.
5699 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5700
5701 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525702 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505703 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435704 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5705 mock_quic_data.AddWrite(
5706 SYNCHRONOUS,
5707 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335708 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435709 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435710 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335711 ASYNC, ConstructServerResponseHeadersPacket(
5712 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5713 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415714 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335715 mock_quic_data.AddRead(
5716 ASYNC, ConstructServerDataPacket(
5717 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415718 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435719 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505720 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5721 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5722 // No HTTP data is mocked as TCP job will be delayed and never starts.
5723
5724 CreateSession();
5725 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275726 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505727
5728 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5729 // Socket will not be configured immediately and QUIC support is not sorted
5730 // out, TCP job will still be delayed as server properties indicates QUIC
5731 // support on last IP address.
5732 host_resolver_.set_synchronous_mode(false);
5733
5734 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5735 TestCompletionCallback callback;
5736 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5737 IsError(ERR_IO_PENDING));
5738
5739 // Complete host resolution in next message loop so that QUIC job could
5740 // proceed.
5741 base::RunLoop().RunUntilIdle();
5742 // Explicitly confirm the handshake so that QUIC job could succeed.
5743 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525744 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505745 EXPECT_THAT(callback.WaitForResult(), IsOk());
5746
5747 CheckWasQuicResponse(&trans);
5748 CheckResponseData(&trans, "hello!");
5749}
5750
Ryan Hamilton75f197262017-08-17 14:00:075751TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5752 // Test that NetErrorDetails is correctly populated, even if the
5753 // handshake has not yet been confirmed and no stream has been created.
5754
5755 // QUIC job will pause. When resumed, it will fail.
5756 MockQuicData mock_quic_data;
5757 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5758 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5759 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5760
5761 // Main job will also fail.
5762 MockRead http_reads[] = {
5763 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5764 };
5765
Ryan Sleevib8d7ea02018-05-07 20:01:015766 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075767 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5768 socket_factory_.AddSocketDataProvider(&http_data);
5769 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5770
5771 AddHangingNonAlternateProtocolSocketData();
5772 CreateSession();
5773 // Require handshake confirmation to ensure that no QUIC streams are
5774 // created, and to ensure that the TCP job does not wait for the QUIC
5775 // job to fail before it starts.
5776 session_->quic_stream_factory()->set_require_confirmation(true);
5777
Ryan Hamilton9835e662018-08-02 05:36:275778 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075779 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5780 TestCompletionCallback callback;
5781 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5782 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5783 // Allow the TCP job to fail.
5784 base::RunLoop().RunUntilIdle();
5785 // Now let the QUIC job fail.
5786 mock_quic_data.Resume();
5787 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5788 ExpectQuicAlternateProtocolMapping();
5789 NetErrorDetails details;
5790 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525791 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075792}
5793
[email protected]1e960032013-12-20 19:00:205794TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455795 // Alternate-protocol job
5796 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025797 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455798 };
Ryan Sleevib8d7ea02018-05-07 20:01:015799 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455800 socket_factory_.AddSocketDataProvider(&quic_data);
5801
[email protected]c92c1b52014-05-31 04:16:065802 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015803 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065804 socket_factory_.AddSocketDataProvider(&quic_data2);
5805
[email protected]4d283b32013-10-17 12:57:275806 // Final job that will proceed when the QUIC job fails.
5807 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025808 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5809 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5810 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275811
Ryan Sleevib8d7ea02018-05-07 20:01:015812 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275813 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565814 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275815
rtennetiafccbc062016-05-16 18:21:145816 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325817 CreateSession();
[email protected]77c6c162013-08-17 02:57:455818
Ryan Hamilton9835e662018-08-02 05:36:275819 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455820
[email protected]4d283b32013-10-17 12:57:275821 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455822
5823 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275824
rch37de576c2015-05-17 20:28:175825 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5826 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455827}
5828
[email protected]93b31772014-06-19 08:03:355829TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035830 // Alternate-protocol job
5831 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595832 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035833 };
Ryan Sleevib8d7ea02018-05-07 20:01:015834 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035835 socket_factory_.AddSocketDataProvider(&quic_data);
5836
5837 // Main job that will proceed when the QUIC job fails.
5838 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025839 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5840 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5841 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035842
Ryan Sleevib8d7ea02018-05-07 20:01:015843 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035844 socket_factory_.AddSocketDataProvider(&http_data);
5845
rtennetib8e80fb2016-05-16 00:12:095846 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325847 CreateSession();
[email protected]65768442014-06-06 23:37:035848
Ryan Hamilton9835e662018-08-02 05:36:275849 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035850
5851 SendRequestAndExpectHttpResponse("hello from http");
5852}
5853
[email protected]eb71ab62014-05-23 07:57:535854TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335855 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015856 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495857 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335858 socket_factory_.AddSocketDataProvider(&quic_data);
5859
5860 // Main job which will succeed even though the alternate job fails.
5861 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025862 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5863 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5864 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335865
Ryan Sleevib8d7ea02018-05-07 20:01:015866 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335867 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565868 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335869
rch3f4b8452016-02-23 16:59:325870 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275871 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335872 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535873
5874 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335875}
5876
[email protected]4fee9672014-01-08 14:47:155877TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155878 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435879 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335880 mock_quic_data.AddWrite(
5881 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5882 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5883 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435884 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
rcha5399e02015-04-21 19:32:045885 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155886
5887 // When the QUIC connection fails, we will try the request again over HTTP.
5888 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485889 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565890 MockRead("hello world"),
5891 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5892 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155893
Ryan Sleevib8d7ea02018-05-07 20:01:015894 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155895 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565896 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155897
5898 // In order for a new QUIC session to be established via alternate-protocol
5899 // without racing an HTTP connection, we need the host resolution to happen
5900 // synchronously.
5901 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295902 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565903 "");
rch9ae5b3b2016-02-11 00:36:295904 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]4fee9672014-01-08 14:47:155905 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105906 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585907 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5908 CompletionOnceCallback(), &request,
5909 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415910 EXPECT_THAT(rv, IsOk());
[email protected]4fee9672014-01-08 14:47:155911
rch3f4b8452016-02-23 16:59:325912 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275913 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]4fee9672014-01-08 14:47:155914 SendRequestAndExpectHttpResponse("hello world");
5915}
5916
tbansalc3308d72016-08-27 10:25:045917// For an alternative proxy that supports QUIC, test that the request is
5918// successfully fetched by the main job when the alternate proxy job encounters
5919// an error.
5920TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5921 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5922}
5923TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5924 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5925}
5926TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5927 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5928}
5929TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5930 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5931}
5932TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5933 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5934}
5935TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5936 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5937}
5938TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5939 TestAlternativeProxy(ERR_IO_PENDING);
5940}
5941TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5942 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5943}
5944
5945TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5946 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435947 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335948 mock_quic_data.AddWrite(
5949 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5950 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5951 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435952 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045953 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5954
5955 // When the QUIC connection fails, we will try the request again over HTTP.
5956 MockRead http_reads[] = {
5957 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5958 MockRead("hello world"),
5959 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5960 MockRead(ASYNC, OK)};
5961
Ryan Sleevib8d7ea02018-05-07 20:01:015962 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045963 socket_factory_.AddSocketDataProvider(&http_data);
5964 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5965
5966 TestProxyDelegate test_proxy_delegate;
5967 const HostPortPair host_port_pair("myproxy.org", 443);
5968 test_proxy_delegate.set_alternative_proxy_server(
5969 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5970 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5971
Ramin Halavatica8d5252018-03-12 05:33:495972 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5973 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525974 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045975 request_.url = GURL("http://mail.example.org/");
5976
5977 // In order for a new QUIC session to be established via alternate-protocol
5978 // without racing an HTTP connection, we need the host resolution to happen
5979 // synchronously.
5980 host_resolver_.set_synchronous_mode(true);
5981 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
5982 HostResolver::RequestInfo info(HostPortPair("myproxy.org", 443));
5983 AddressList address;
5984 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585985 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5986 CompletionOnceCallback(), &request,
5987 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415988 EXPECT_THAT(rv, IsOk());
tbansalc3308d72016-08-27 10:25:045989
5990 CreateSession();
5991 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595992 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165993 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045994}
5995
bnc508835902015-05-12 20:10:295996TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585997 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385998 EXPECT_FALSE(
5999 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296000 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526001 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366002 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436003 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6004 mock_quic_data.AddWrite(
6005 SYNCHRONOUS,
6006 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336007 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436008 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436009 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336010 ASYNC, ConstructServerResponseHeadersPacket(
6011 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6012 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416013 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336014 mock_quic_data.AddRead(
6015 ASYNC, ConstructServerDataPacket(
6016 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416017 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436018 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:506019 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296020 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6021
bncb07c05532015-05-14 19:07:206022 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096023 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326024 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276025 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296026 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386027 EXPECT_TRUE(
6028 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296029}
6030
zhongyi363c91c2017-03-23 23:16:086031// TODO(zhongyi): disabled this broken test as it was not testing the correct
6032// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6033TEST_P(QuicNetworkTransactionTest,
6034 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276035 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596036 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496037 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046038
6039 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046040
6041 test_proxy_delegate.set_alternative_proxy_server(
6042 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526043 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046044
6045 request_.url = GURL("http://mail.example.org/");
6046
6047 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6048 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016049 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046050 socket_factory_.AddSocketDataProvider(&socket_data);
6051
6052 // The non-alternate protocol job needs to hang in order to guarantee that
6053 // the alternate-protocol job will "win".
6054 AddHangingNonAlternateProtocolSocketData();
6055
6056 CreateSession();
6057 request_.method = "POST";
6058 ChunkedUploadDataStream upload_data(0);
6059 upload_data.AppendData("1", 1, true);
6060
6061 request_.upload_data_stream = &upload_data;
6062
6063 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6064 TestCompletionCallback callback;
6065 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6066 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6067 EXPECT_NE(OK, callback.WaitForResult());
6068
6069 // Verify that the alternative proxy server is not marked as broken.
6070 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6071
6072 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596073 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276074
6075 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6076 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6077 1);
tbansalc3308d72016-08-27 10:25:046078}
6079
rtenneti56977812016-01-15 19:26:566080TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:416081 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576082 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566083
6084 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6085 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016086 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:566087 socket_factory_.AddSocketDataProvider(&socket_data);
6088
rtennetib8e80fb2016-05-16 00:12:096089 // The non-alternate protocol job needs to hang in order to guarantee that
6090 // the alternate-protocol job will "win".
6091 AddHangingNonAlternateProtocolSocketData();
6092
rtenneti56977812016-01-15 19:26:566093 CreateSession();
6094 request_.method = "POST";
6095 ChunkedUploadDataStream upload_data(0);
6096 upload_data.AppendData("1", 1, true);
6097
6098 request_.upload_data_stream = &upload_data;
6099
bnc691fda62016-08-12 00:43:166100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566101 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166102 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566104 EXPECT_NE(OK, callback.WaitForResult());
6105}
6106
rche11300ef2016-09-02 01:44:286107TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:486108 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286109 ScopedMockNetworkChangeNotifier network_change_notifier;
6110 MockNetworkChangeNotifier* mock_ncn =
6111 network_change_notifier.mock_network_change_notifier();
6112 mock_ncn->ForceNetworkHandlesSupported();
6113 mock_ncn->SetConnectedNetworksList(
6114 {kDefaultNetworkForTests, kNewNetworkForTests});
6115
mmenke6ddfbea2017-05-31 21:48:416116 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286117 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:316118 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286119
6120 MockQuicData socket_data;
6121 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526122 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436123 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:336124 socket_data.AddWrite(
6125 SYNCHRONOUS,
6126 ConstructClientRequestHeadersPacket(
6127 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6128 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286129 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6130 socket_data.AddSocketDataToFactory(&socket_factory_);
6131
6132 MockQuicData socket_data2;
6133 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6134 socket_data2.AddSocketDataToFactory(&socket_factory_);
6135
6136 // The non-alternate protocol job needs to hang in order to guarantee that
6137 // the alternate-protocol job will "win".
6138 AddHangingNonAlternateProtocolSocketData();
6139
6140 CreateSession();
6141 request_.method = "POST";
6142 ChunkedUploadDataStream upload_data(0);
6143
6144 request_.upload_data_stream = &upload_data;
6145
rdsmith1d343be52016-10-21 20:37:506146 std::unique_ptr<HttpNetworkTransaction> trans(
6147 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286148 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506149 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286150 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6151
6152 base::RunLoop().RunUntilIdle();
6153 upload_data.AppendData("1", 1, true);
6154 base::RunLoop().RunUntilIdle();
6155
6156 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506157 trans.reset();
rche11300ef2016-09-02 01:44:286158 session_.reset();
6159}
6160
Ryan Hamilton4b3574532017-10-30 20:17:256161TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6162 session_params_.origins_to_force_quic_on.insert(
6163 HostPortPair::FromString("mail.example.org:443"));
6164
6165 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526166 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436167 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256168 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336169 socket_data.AddWrite(
6170 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6171 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6172 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436173 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336174 ASYNC, ConstructServerResponseHeadersPacket(
6175 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6176 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416177 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336178 socket_data.AddRead(
6179 ASYNC, ConstructServerDataPacket(
6180 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416181 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436182 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256183 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166184 socket_data.AddWrite(
6185 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6186 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6187 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256188
6189 socket_data.AddSocketDataToFactory(&socket_factory_);
6190
6191 CreateSession();
6192
6193 SendRequestAndExpectQuicResponse("hello!");
6194 session_.reset();
6195}
6196
6197TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6198 session_params_.origins_to_force_quic_on.insert(
6199 HostPortPair::FromString("mail.example.org:443"));
6200
6201 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526202 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436203 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256204 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336205 socket_data.AddWrite(
6206 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6207 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6208 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436209 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336210 ASYNC, ConstructServerResponseHeadersPacket(
6211 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6212 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416213 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336214 socket_data.AddRead(
6215 ASYNC, ConstructServerDataPacket(
6216 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416217 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436218 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256219 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166220 socket_data.AddWrite(
6221 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6222 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6223 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256224
6225 socket_data.AddSocketDataToFactory(&socket_factory_);
6226
6227 CreateSession();
6228
6229 SendRequestAndExpectQuicResponse("hello!");
6230 session_.reset();
6231}
6232
Ryan Hamilton9edcf1a2017-11-22 05:55:176233TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486234 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256235 session_params_.origins_to_force_quic_on.insert(
6236 HostPortPair::FromString("mail.example.org:443"));
6237
6238 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526239 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256240 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436241 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176242 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256243 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6244 }
6245 socket_data.AddSocketDataToFactory(&socket_factory_);
6246
6247 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176248 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6249 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6250 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6251 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256252
Ryan Hamilton8d9ee76e2018-05-29 23:52:526253 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6255 TestCompletionCallback callback;
6256 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176258 while (!callback.have_result()) {
6259 base::RunLoop().RunUntilIdle();
6260 quic_task_runner_->RunUntilIdle();
6261 }
6262 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256263 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176264 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6265 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6266 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526267 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6268 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256269}
6270
Ryan Hamilton9edcf1a2017-11-22 05:55:176271TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486272 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256273 session_params_.origins_to_force_quic_on.insert(
6274 HostPortPair::FromString("mail.example.org:443"));
6275
6276 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526277 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256278 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436279 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176280 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256281 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6282 }
6283 socket_data.AddSocketDataToFactory(&socket_factory_);
6284
6285 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176286 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6287 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6288 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6289 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256290
Ryan Hamilton8d9ee76e2018-05-29 23:52:526291 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256292 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6293 TestCompletionCallback callback;
6294 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6295 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176296 while (!callback.have_result()) {
6297 base::RunLoop().RunUntilIdle();
6298 quic_task_runner_->RunUntilIdle();
6299 }
6300 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256301 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176302 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6303 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6304 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526305 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6306 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256307}
6308
Cherie Shi7596de632018-02-22 07:28:186309TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486310 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186311 session_params_.origins_to_force_quic_on.insert(
6312 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526313 const quic::QuicString error_details =
6314 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6315 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186316
6317 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526318 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186319 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436320 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186321 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6322 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526323 socket_data.AddWrite(
6324 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6325 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186326 socket_data.AddSocketDataToFactory(&socket_factory_);
6327
6328 CreateSession();
6329
6330 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6331 TestCompletionCallback callback;
6332 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6334 base::RunLoop().RunUntilIdle();
6335 ASSERT_TRUE(callback.have_result());
6336 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6337 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6338 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6339}
6340
ckrasic769733c2016-06-30 00:42:136341// Adds coverage to catch regression such as https://crbug.com/622043
6342TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416343 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136344 HostPortPair::FromString("mail.example.org:443"));
6345
6346 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526347 quic::QuicStreamOffset header_stream_offset = 0;
6348 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436349 mock_quic_data.AddWrite(
6350 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6351 &header_stream_offset));
6352 mock_quic_data.AddWrite(
6353 SYNCHRONOUS,
6354 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336355 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6356 true, true, GetRequestHeaders("GET", "https", "/"),
6357 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526358 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436359 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336360 ASYNC, ConstructServerPushPromisePacket(
6361 1, GetNthClientInitiatedBidirectionalStreamId(0),
6362 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6363 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6364 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576365 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266366 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336367 mock_quic_data.AddWrite(SYNCHRONOUS,
6368 ConstructClientPriorityPacket(
6369 client_packet_number++, false,
6370 GetNthServerInitiatedUnidirectionalStreamId(0),
6371 GetNthClientInitiatedBidirectionalStreamId(0),
6372 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576373 }
Zhongyi Shi32f2fd02018-04-16 18:23:436374 mock_quic_data.AddRead(
6375 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336376 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436377 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576378 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436379 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6380 mock_quic_data.AddRead(
6381 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336382 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6383 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416384 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436385 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336386 ASYNC, ConstructServerDataPacket(
6387 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416388 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576389 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436390 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416391 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436392 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336393 ASYNC, ConstructServerDataPacket(
6394 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416395 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336396 mock_quic_data.AddWrite(SYNCHRONOUS,
6397 ConstructClientAckAndRstPacket(
6398 client_packet_number++,
6399 GetNthServerInitiatedUnidirectionalStreamId(0),
6400 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136401 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6402 mock_quic_data.AddRead(ASYNC, 0); // EOF
6403 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6404
6405 // The non-alternate protocol job needs to hang in order to guarantee that
6406 // the alternate-protocol job will "win".
6407 AddHangingNonAlternateProtocolSocketData();
6408
6409 CreateSession();
6410
6411 // PUSH_PROMISE handling in the http layer gets exercised here.
6412 SendRequestAndExpectQuicResponse("hello!");
6413
6414 request_.url = GURL("https://mail.example.org/pushed.jpg");
6415 SendRequestAndExpectQuicResponse("and hello!");
6416
6417 // Check that the NetLog was filled reasonably.
6418 TestNetLogEntry::List entries;
6419 net_log_.GetEntries(&entries);
6420 EXPECT_LT(0u, entries.size());
6421
6422 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6423 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006424 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6425 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136426 EXPECT_LT(0, pos);
6427}
6428
rch56ec40a2017-06-23 14:48:446429// Regression test for http://crbug.com/719461 in which a promised stream
6430// is closed before the pushed headers arrive, but after the connection
6431// is closed and before the callbacks are executed.
6432TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486433 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446434 session_params_.origins_to_force_quic_on.insert(
6435 HostPortPair::FromString("mail.example.org:443"));
6436
6437 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526438 quic::QuicStreamOffset header_stream_offset = 0;
6439 quic::QuicPacketNumber client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446440 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436441 mock_quic_data.AddWrite(
6442 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6443 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446444 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436445 mock_quic_data.AddWrite(
6446 SYNCHRONOUS,
6447 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336448 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6449 true, true, GetRequestHeaders("GET", "https", "/"),
6450 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526451 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446452 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436453 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336454 ASYNC, ConstructServerPushPromisePacket(
6455 1, GetNthClientInitiatedBidirectionalStreamId(0),
6456 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6457 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6458 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576459 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266460 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336461 mock_quic_data.AddWrite(SYNCHRONOUS,
6462 ConstructClientPriorityPacket(
6463 client_packet_number++, false,
6464 GetNthServerInitiatedUnidirectionalStreamId(0),
6465 GetNthClientInitiatedBidirectionalStreamId(0),
6466 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576467 }
rch56ec40a2017-06-23 14:48:446468 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436469 mock_quic_data.AddRead(
6470 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336471 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436472 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446473 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576474 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436475 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446476 // Response body for first request.
Renjief49758b2019-01-11 23:32:416477 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436478 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336479 ASYNC, ConstructServerDataPacket(
6480 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416481 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446482 // Write error for the third request.
6483 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6484 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6485 mock_quic_data.AddRead(ASYNC, 0); // EOF
6486 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6487
6488 CreateSession();
6489
6490 // Send a request which triggers a push promise from the server.
6491 SendRequestAndExpectQuicResponse("hello!");
6492
6493 // Start a push transaction that will be cancelled after the connection
6494 // is closed, but before the callback is executed.
6495 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196496 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446497 session_.get());
6498 TestCompletionCallback callback2;
6499 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6501 base::RunLoop().RunUntilIdle();
6502
6503 // Cause the connection to close on a write error.
6504 HttpRequestInfo request3;
6505 request3.method = "GET";
6506 request3.url = GURL("https://mail.example.org/");
6507 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106508 request3.traffic_annotation =
6509 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446510 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6511 TestCompletionCallback callback3;
6512 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6513 IsError(ERR_IO_PENDING));
6514
6515 base::RunLoop().RunUntilIdle();
6516
6517 // When |trans2| is destroyed, the underlying stream will be closed.
6518 EXPECT_FALSE(callback2.have_result());
6519 trans2 = nullptr;
6520
6521 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6522}
6523
ckrasicda193a82016-07-09 00:39:366524TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416525 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366526 HostPortPair::FromString("mail.example.org:443"));
6527
6528 MockQuicData mock_quic_data;
6529
Ryan Hamilton8d9ee76e2018-05-29 23:52:526530 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416531 int write_packet_index = 1;
6532 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6533 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366534
Renjief49758b2019-01-11 23:32:416535 quic::QuicString header = ConstructDataHeader(1);
6536 if (version_ != quic::QUIC_VERSION_99) {
6537 mock_quic_data.AddWrite(
6538 SYNCHRONOUS,
6539 ConstructClientRequestHeadersAndDataFramesPacket(
6540 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6541 true, true, DEFAULT_PRIORITY,
6542 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6543 {"1"}));
6544 } else {
6545 mock_quic_data.AddWrite(
6546 SYNCHRONOUS,
6547 ConstructClientRequestHeadersAndDataFramesPacket(
6548 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6549 true, true, DEFAULT_PRIORITY,
6550 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6551 {header, "1"}));
6552 }
ckrasicda193a82016-07-09 00:39:366553
Zhongyi Shi32f2fd02018-04-16 18:23:436554 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336555 ASYNC, ConstructServerResponseHeadersPacket(
6556 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6557 GetResponseHeaders("200 OK")));
6558
Renjief49758b2019-01-11 23:32:416559 quic::QuicString header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336560 mock_quic_data.AddRead(
6561 ASYNC, ConstructServerDataPacket(
6562 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416563 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366564
Renjief49758b2019-01-11 23:32:416565 mock_quic_data.AddWrite(
6566 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366567
6568 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6569 mock_quic_data.AddRead(ASYNC, 0); // EOF
6570 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6571
6572 // The non-alternate protocol job needs to hang in order to guarantee that
6573 // the alternate-protocol job will "win".
6574 AddHangingNonAlternateProtocolSocketData();
6575
6576 CreateSession();
6577 request_.method = "POST";
6578 ChunkedUploadDataStream upload_data(0);
6579 upload_data.AppendData("1", 1, true);
6580
6581 request_.upload_data_stream = &upload_data;
6582
6583 SendRequestAndExpectQuicResponse("hello!");
6584}
6585
allada71b2efb2016-09-09 04:57:486586class QuicURLRequestContext : public URLRequestContext {
6587 public:
6588 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6589 MockClientSocketFactory* socket_factory)
6590 : storage_(this) {
6591 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076592 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046593 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486594 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046595 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596596 storage_.set_proxy_resolution_service(
6597 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076598 storage_.set_ssl_config_service(
6599 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486600 storage_.set_http_auth_handler_factory(
6601 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6602 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076603 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046604 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486605 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046606 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6607 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6608 false));
allada71b2efb2016-09-09 04:57:486609 }
6610
6611 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6612
6613 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6614
6615 private:
6616 MockClientSocketFactory* socket_factory_;
6617 URLRequestContextStorage storage_;
6618};
6619
6620TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416621 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486622 HostPortPair::FromString("mail.example.org:443"));
6623
6624 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526625 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366626 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436627 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136628 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486629 headers["user-agent"] = "";
6630 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336631 mock_quic_data.AddWrite(
6632 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6633 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6634 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486635
Ryan Hamilton8d9ee76e2018-05-29 23:52:526636 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336637 mock_quic_data.AddRead(
6638 ASYNC,
6639 ConstructServerResponseHeadersPacket(
6640 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6641 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486642
Renjief49758b2019-01-11 23:32:416643 quic::QuicString header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366644 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336645 ASYNC, ConstructServerDataPacket(
6646 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6647 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436648 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486649
6650 mock_quic_data.AddRead(ASYNC, 0); // EOF
6651
6652 CreateSession();
6653
6654 TestDelegate delegate;
6655 QuicURLRequestContext quic_url_request_context(std::move(session_),
6656 &socket_factory_);
6657
6658 mock_quic_data.AddSocketDataToFactory(
6659 &quic_url_request_context.socket_factory());
6660 TestNetworkDelegate network_delegate;
6661 quic_url_request_context.set_network_delegate(&network_delegate);
6662
6663 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296664 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6665 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486666 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6667 &ssl_data_);
6668
6669 request->Start();
Wez2a31b222018-06-07 22:07:156670 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486671
6672 EXPECT_LT(0, request->GetTotalSentBytes());
6673 EXPECT_LT(0, request->GetTotalReceivedBytes());
6674 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6675 request->GetTotalSentBytes());
6676 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6677 request->GetTotalReceivedBytes());
6678 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6679 request->raw_header_size());
Wez0e717112018-06-18 23:09:226680
6681 // Pump the message loop to allow all data to be consumed.
6682 base::RunLoop().RunUntilIdle();
6683
allada71b2efb2016-09-09 04:57:486684 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6685 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6686}
6687
6688TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416689 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486690 HostPortPair::FromString("mail.example.org:443"));
6691
6692 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526693 quic::QuicStreamOffset header_stream_offset = 0;
6694 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436695 mock_quic_data.AddWrite(
6696 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6697 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136698 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486699 headers["user-agent"] = "";
6700 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436701 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336702 SYNCHRONOUS,
6703 ConstructClientRequestHeadersPacket(
6704 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6705 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486706
Ryan Hamilton8d9ee76e2018-05-29 23:52:526707 quic::QuicStreamOffset server_header_offset = 0;
6708 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486709
Zhongyi Shi32f2fd02018-04-16 18:23:436710 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336711 ASYNC, ConstructServerPushPromisePacket(
6712 1, GetNthClientInitiatedBidirectionalStreamId(0),
6713 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6714 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6715 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486716
Yixin Wangb470bc882018-02-15 18:43:576717 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266718 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336719 mock_quic_data.AddWrite(SYNCHRONOUS,
6720 ConstructClientPriorityPacket(
6721 client_packet_number++, false,
6722 GetNthServerInitiatedUnidirectionalStreamId(0),
6723 GetNthClientInitiatedBidirectionalStreamId(0),
6724 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576725 }
6726
allada71b2efb2016-09-09 04:57:486727 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436728 mock_quic_data.AddRead(
6729 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336730 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436731 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486732 expected_raw_header_response_size =
6733 server_header_offset - expected_raw_header_response_size;
6734
Yixin Wangb470bc882018-02-15 18:43:576735 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436736 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486737
ckrasicbf2f59c2017-05-04 23:54:366738 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436739 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336740 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6741 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416742 quic::QuicString header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436743 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336744 ASYNC, ConstructServerDataPacket(
6745 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416746 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486747
Yixin Wangb470bc882018-02-15 18:43:576748 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436749 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416750 quic::QuicString header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366751 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336752 ASYNC, ConstructServerDataPacket(
6753 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416754 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486755
Zhongyi Shi32f2fd02018-04-16 18:23:436756 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486757
6758 CreateSession();
6759
6760 TestDelegate delegate;
6761 QuicURLRequestContext quic_url_request_context(std::move(session_),
6762 &socket_factory_);
6763
6764 mock_quic_data.AddSocketDataToFactory(
6765 &quic_url_request_context.socket_factory());
6766 TestNetworkDelegate network_delegate;
6767 quic_url_request_context.set_network_delegate(&network_delegate);
6768
6769 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296770 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6771 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486772 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6773 &ssl_data_);
6774
6775 request->Start();
Wez2a31b222018-06-07 22:07:156776 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486777
6778 EXPECT_LT(0, request->GetTotalSentBytes());
6779 EXPECT_LT(0, request->GetTotalReceivedBytes());
6780 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6781 request->GetTotalSentBytes());
6782 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6783 request->GetTotalReceivedBytes());
6784 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6785 request->raw_header_size());
Wez0e717112018-06-18 23:09:226786
6787 // Pump the message loop to allow all data to be consumed.
6788 base::RunLoop().RunUntilIdle();
6789
allada71b2efb2016-09-09 04:57:486790 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6791 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6792}
6793
Yixin Wang10f477ed2017-11-21 04:20:206794TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6795 session_params_.quic_host_whitelist.insert("mail.example.org");
6796
6797 MockRead http_reads[] = {
6798 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6799 MockRead("hello world"),
6800 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6801 MockRead(ASYNC, OK)};
6802
Ryan Sleevib8d7ea02018-05-07 20:01:016803 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206804 socket_factory_.AddSocketDataProvider(&http_data);
6805 AddCertificate(&ssl_data_);
6806 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6807
6808 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526809 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206810 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436811 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6812 mock_quic_data.AddWrite(
6813 SYNCHRONOUS,
6814 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336815 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436816 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436817 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336818 ASYNC, ConstructServerResponseHeadersPacket(
6819 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6820 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416821 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336822 mock_quic_data.AddRead(
6823 ASYNC, ConstructServerDataPacket(
6824 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416825 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436826 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206827 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6828 mock_quic_data.AddRead(ASYNC, 0); // EOF
6829
6830 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6831
6832 AddHangingNonAlternateProtocolSocketData();
6833 CreateSession();
6834
6835 SendRequestAndExpectHttpResponse("hello world");
6836 SendRequestAndExpectQuicResponse("hello!");
6837}
6838
6839TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6840 session_params_.quic_host_whitelist.insert("mail.example.com");
6841
6842 MockRead http_reads[] = {
6843 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6844 MockRead("hello world"),
6845 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6846 MockRead(ASYNC, OK)};
6847
Ryan Sleevib8d7ea02018-05-07 20:01:016848 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206849 socket_factory_.AddSocketDataProvider(&http_data);
6850 AddCertificate(&ssl_data_);
6851 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6852 socket_factory_.AddSocketDataProvider(&http_data);
6853 AddCertificate(&ssl_data_);
6854 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6855
6856 AddHangingNonAlternateProtocolSocketData();
6857 CreateSession();
6858
6859 SendRequestAndExpectHttpResponse("hello world");
6860 SendRequestAndExpectHttpResponse("hello world");
6861}
6862
bnc359ed2a2016-04-29 20:43:456863class QuicNetworkTransactionWithDestinationTest
6864 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016865 public ::testing::WithParamInterface<PoolingTestParams>,
6866 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456867 protected:
6868 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556869 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056870 client_headers_include_h2_stream_dependency_(
6871 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526872 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456873 destination_type_(GetParam().destination_type),
6874 cert_transparency_verifier_(new MultiLogCTVerifier()),
6875 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596876 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456877 auth_handler_factory_(
6878 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6879 random_generator_(0),
6880 ssl_data_(ASYNC, OK) {}
6881
6882 void SetUp() override {
6883 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556884 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456885
mmenke6ddfbea2017-05-31 21:48:416886 HttpNetworkSession::Params session_params;
6887 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346888 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446889 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056890 session_params.quic_headers_include_h2_stream_dependency =
6891 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416892
6893 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456894
Ryan Hamilton8d9ee76e2018-05-29 23:52:526895 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416896 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456897
6898 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276899 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416900 session_context.quic_crypto_client_stream_factory =
6901 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456902
mmenke6ddfbea2017-05-31 21:48:416903 session_context.quic_random = &random_generator_;
6904 session_context.client_socket_factory = &socket_factory_;
6905 session_context.host_resolver = &host_resolver_;
6906 session_context.cert_verifier = &cert_verifier_;
6907 session_context.transport_security_state = &transport_security_state_;
6908 session_context.cert_transparency_verifier =
6909 cert_transparency_verifier_.get();
6910 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6911 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456912 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416913 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596914 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416915 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6916 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456917
mmenke6ddfbea2017-05-31 21:48:416918 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456919 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456920 }
6921
6922 void TearDown() override {
6923 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6924 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556925 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456926 PlatformTest::TearDown();
6927 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556928 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406929 session_.reset();
bnc359ed2a2016-04-29 20:43:456930 }
6931
zhongyie537a002017-06-27 16:48:216932 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456933 HostPortPair destination;
6934 switch (destination_type_) {
6935 case SAME_AS_FIRST:
6936 destination = HostPortPair(origin1_, 443);
6937 break;
6938 case SAME_AS_SECOND:
6939 destination = HostPortPair(origin2_, 443);
6940 break;
6941 case DIFFERENT:
6942 destination = HostPortPair(kDifferentHostname, 443);
6943 break;
6944 }
bnc3472afd2016-11-17 15:27:216945 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456946 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216947 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456948 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446949 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456950 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526951 std::unique_ptr<quic::QuicEncryptedPacket>
6952 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6953 quic::QuicStreamId stream_id,
6954 bool should_include_version,
6955 quic::QuicStreamOffset* offset,
6956 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486957 return ConstructClientRequestHeadersPacket(
6958 packet_number, stream_id, should_include_version, 0, offset, maker);
6959 }
bnc359ed2a2016-04-29 20:43:456960
Ryan Hamilton8d9ee76e2018-05-29 23:52:526961 std::unique_ptr<quic::QuicEncryptedPacket>
6962 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6963 quic::QuicStreamId stream_id,
6964 bool should_include_version,
6965 quic::QuicStreamId parent_stream_id,
6966 quic::QuicStreamOffset* offset,
6967 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136968 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456969 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136970 spdy::SpdyHeaderBlock headers(
6971 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456972 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6973 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486974 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456975 }
6976
Ryan Hamilton8d9ee76e2018-05-29 23:52:526977 std::unique_ptr<quic::QuicEncryptedPacket>
6978 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6979 quic::QuicStreamId stream_id,
6980 bool should_include_version,
6981 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586982 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456983 packet_number, stream_id, should_include_version, nullptr, maker);
6984 }
6985
Ryan Hamilton8d9ee76e2018-05-29 23:52:526986 std::unique_ptr<quic::QuicEncryptedPacket>
6987 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6988 quic::QuicStreamId stream_id,
6989 quic::QuicStreamOffset* offset,
6990 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136991 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456992 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266993 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456994 }
6995
Ryan Hamilton8d9ee76e2018-05-29 23:52:526996 std::unique_ptr<quic::QuicEncryptedPacket>
6997 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6998 quic::QuicStreamId stream_id,
6999 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587000 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
7001 nullptr, maker);
bnc359ed2a2016-04-29 20:43:457002 }
7003
Ryan Hamilton8d9ee76e2018-05-29 23:52:527004 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
7005 quic::QuicPacketNumber packet_number,
7006 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457007 QuicTestPacketMaker* maker) {
Renjief49758b2019-01-11 23:32:417008 quic::QuicString header = "";
7009 if (version_ == quic::QUIC_VERSION_99) {
7010 quic::HttpEncoder encoder;
7011 std::unique_ptr<char[]> buffer;
7012 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
7013 header = quic::QuicString(buffer.get(), header_length);
7014 }
bnc359ed2a2016-04-29 20:43:457015 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:417016 header + "hello");
bnc359ed2a2016-04-29 20:43:457017 }
7018
Ryan Hamilton8d9ee76e2018-05-29 23:52:527019 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
7020 quic::QuicPacketNumber packet_number,
7021 quic::QuicPacketNumber largest_received,
7022 quic::QuicPacketNumber smallest_received,
7023 quic::QuicPacketNumber least_unacked,
bnc359ed2a2016-04-29 20:43:457024 QuicTestPacketMaker* maker) {
7025 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497026 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457027 }
7028
Ryan Hamilton8d9ee76e2018-05-29 23:52:527029 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
7030 quic::QuicPacketNumber packet_number,
7031 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:377032 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:367033 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:377034 }
7035
bnc359ed2a2016-04-29 20:43:457036 void AddRefusedSocketData() {
7037 std::unique_ptr<StaticSocketDataProvider> refused_data(
7038 new StaticSocketDataProvider());
7039 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7040 refused_data->set_connect_data(refused_connect);
7041 socket_factory_.AddSocketDataProvider(refused_data.get());
7042 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7043 }
7044
7045 void AddHangingSocketData() {
7046 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7047 new StaticSocketDataProvider());
7048 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7049 hanging_data->set_connect_data(hanging_connect);
7050 socket_factory_.AddSocketDataProvider(hanging_data.get());
7051 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7052 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7053 }
7054
7055 bool AllDataConsumed() {
7056 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7057 if (!socket_data_ptr->AllReadDataConsumed() ||
7058 !socket_data_ptr->AllWriteDataConsumed()) {
7059 return false;
7060 }
7061 }
7062 return true;
7063 }
7064
7065 void SendRequestAndExpectQuicResponse(const std::string& host) {
7066 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7067 HttpRequestInfo request;
7068 std::string url("https://");
7069 url.append(host);
7070 request.url = GURL(url);
7071 request.load_flags = 0;
7072 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107073 request.traffic_annotation =
7074 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457075 TestCompletionCallback callback;
7076 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017077 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457078
7079 std::string response_data;
robpercival214763f2016-07-01 23:27:017080 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457081 EXPECT_EQ("hello", response_data);
7082
7083 const HttpResponseInfo* response = trans.GetResponseInfo();
7084 ASSERT_TRUE(response != nullptr);
7085 ASSERT_TRUE(response->headers.get() != nullptr);
7086 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7087 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527088 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:447089 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457090 response->connection_info);
7091 EXPECT_EQ(443, response->socket_address.port());
7092 }
7093
Fan Yang32c5a112018-12-10 20:06:337094 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
7095 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:367096 }
7097
Ryan Hamilton8d9ee76e2018-05-29 23:52:527098 quic::MockClock clock_;
7099 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:057100 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527101 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457102 DestinationType destination_type_;
7103 std::string origin1_;
7104 std::string origin2_;
7105 std::unique_ptr<HttpNetworkSession> session_;
7106 MockClientSocketFactory socket_factory_;
7107 MockHostResolver host_resolver_;
7108 MockCertVerifier cert_verifier_;
7109 TransportSecurityState transport_security_state_;
7110 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237111 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457112 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077113 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597114 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457115 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527116 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:457117 HttpServerPropertiesImpl http_server_properties_;
7118 BoundTestNetLog net_log_;
7119 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7120 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7121 static_socket_data_provider_vector_;
7122 SSLSocketDataProvider ssl_data_;
7123};
7124
Bence Békyce380cb2018-04-26 23:39:557125INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
bnc359ed2a2016-04-29 20:43:457126 QuicNetworkTransactionWithDestinationTest,
7127 ::testing::ValuesIn(GetPoolingTestParams()));
7128
7129// A single QUIC request fails because the certificate does not match the origin
7130// hostname, regardless of whether it matches the alternative service hostname.
7131TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7132 if (destination_type_ == DIFFERENT)
7133 return;
7134
7135 GURL url("https://mail.example.com/");
7136 origin1_ = url.host();
7137
7138 // Not used for requests, but this provides a test case where the certificate
7139 // is valid for the hostname of the alternative service.
7140 origin2_ = "mail.example.org";
7141
zhongyie537a002017-06-27 16:48:217142 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457143
7144 scoped_refptr<X509Certificate> cert(
7145 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247146 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7147 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457148
7149 ProofVerifyDetailsChromium verify_details;
7150 verify_details.cert_verify_result.verified_cert = cert;
7151 verify_details.cert_verify_result.is_issued_by_known_root = true;
7152 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7153
7154 MockQuicData mock_quic_data;
7155 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7156 mock_quic_data.AddRead(ASYNC, 0);
7157
7158 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7159
7160 AddRefusedSocketData();
7161
7162 HttpRequestInfo request;
7163 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107164 request.traffic_annotation =
7165 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457166
7167 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7168 TestCompletionCallback callback;
7169 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017170 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457171
7172 EXPECT_TRUE(AllDataConsumed());
7173}
7174
7175// First request opens QUIC session to alternative service. Second request
7176// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527177// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457178TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7179 origin1_ = "mail.example.org";
7180 origin2_ = "news.example.org";
7181
zhongyie537a002017-06-27 16:48:217182 SetQuicAlternativeService(origin1_);
7183 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457184
7185 scoped_refptr<X509Certificate> cert(
7186 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247187 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7188 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7189 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457190
7191 ProofVerifyDetailsChromium verify_details;
7192 verify_details.cert_verify_result.verified_cert = cert;
7193 verify_details.cert_verify_result.is_issued_by_known_root = true;
7194 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7195
Yixin Wang079ad542018-01-11 04:06:057196 QuicTestPacketMaker client_maker(
Fan Yang32c5a112018-12-10 20:06:337197 version_, quic::EmptyQuicConnectionId(), &clock_, origin1_,
7198 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057199 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:337200 QuicTestPacketMaker server_maker(version_, quic::EmptyQuicConnectionId(),
7201 &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527202 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457203
Ryan Hamilton8d9ee76e2018-05-29 23:52:527204 quic::QuicStreamOffset request_header_offset(0);
7205 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457206
7207 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057208 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437209 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057210 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337211 mock_quic_data.AddWrite(
7212 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7213 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7214 &request_header_offset, &client_maker));
7215 mock_quic_data.AddRead(ASYNC,
7216 ConstructServerResponseHeadersPacket(
7217 1, GetNthClientInitiatedBidirectionalStreamId(0),
7218 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437219 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337220 ASYNC,
7221 ConstructServerDataPacket(
7222 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437223 mock_quic_data.AddWrite(SYNCHRONOUS,
7224 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457225
Yixin Wang079ad542018-01-11 04:06:057226 client_maker.set_hostname(origin2_);
7227 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457228
Zhongyi Shi32f2fd02018-04-16 18:23:437229 mock_quic_data.AddWrite(
7230 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337231 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7232 GetNthClientInitiatedBidirectionalStreamId(0),
7233 &request_header_offset, &client_maker));
7234 mock_quic_data.AddRead(ASYNC,
7235 ConstructServerResponseHeadersPacket(
7236 3, GetNthClientInitiatedBidirectionalStreamId(1),
7237 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437238 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337239 ASYNC,
7240 ConstructServerDataPacket(
7241 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437242 mock_quic_data.AddWrite(SYNCHRONOUS,
7243 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457244 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7245 mock_quic_data.AddRead(ASYNC, 0); // EOF
7246
7247 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7248
7249 AddHangingSocketData();
7250 AddHangingSocketData();
7251
Fan Yangc9e00dc2018-10-09 14:17:567252 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7253 QuicStreamFactoryPeer::SetAlarmFactory(
7254 session_->quic_stream_factory(),
7255 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7256 &clock_));
7257
bnc359ed2a2016-04-29 20:43:457258 SendRequestAndExpectQuicResponse(origin1_);
7259 SendRequestAndExpectQuicResponse(origin2_);
7260
7261 EXPECT_TRUE(AllDataConsumed());
7262}
7263
7264// First request opens QUIC session to alternative service. Second request does
7265// not pool to it, even though destination matches, because certificate is not
7266// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527267// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457268TEST_P(QuicNetworkTransactionWithDestinationTest,
7269 DoNotPoolIfCertificateInvalid) {
7270 origin1_ = "news.example.org";
7271 origin2_ = "mail.example.com";
7272
zhongyie537a002017-06-27 16:48:217273 SetQuicAlternativeService(origin1_);
7274 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457275
7276 scoped_refptr<X509Certificate> cert1(
7277 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247278 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7279 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7280 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457281
7282 scoped_refptr<X509Certificate> cert2(
7283 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247284 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7285 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457286
7287 ProofVerifyDetailsChromium verify_details1;
7288 verify_details1.cert_verify_result.verified_cert = cert1;
7289 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7290 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7291
7292 ProofVerifyDetailsChromium verify_details2;
7293 verify_details2.cert_verify_result.verified_cert = cert2;
7294 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7295 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7296
Yixin Wang079ad542018-01-11 04:06:057297 QuicTestPacketMaker client_maker1(
Fan Yang32c5a112018-12-10 20:06:337298 version_, quic::EmptyQuicConnectionId(), &clock_, origin1_,
7299 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057300 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:337301 QuicTestPacketMaker server_maker1(version_, quic::EmptyQuicConnectionId(),
7302 &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527303 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457304
7305 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527306 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457307 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437308 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7309 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337310 mock_quic_data1.AddWrite(
7311 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7312 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7313 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437314 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337315 ASYNC,
7316 ConstructServerResponseHeadersPacket(
7317 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437318 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337319 ASYNC,
7320 ConstructServerDataPacket(
7321 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437322 mock_quic_data1.AddWrite(
7323 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457324 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7325 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7326
7327 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7328
Yixin Wang079ad542018-01-11 04:06:057329 QuicTestPacketMaker client_maker2(
Fan Yang32c5a112018-12-10 20:06:337330 version_, quic::EmptyQuicConnectionId(), &clock_, origin2_,
7331 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057332 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:337333 QuicTestPacketMaker server_maker2(version_, quic::EmptyQuicConnectionId(),
7334 &clock_, origin2_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527335 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457336
7337 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527338 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457339 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437340 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7341 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337342 mock_quic_data2.AddWrite(
7343 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7344 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7345 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437346 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337347 ASYNC,
7348 ConstructServerResponseHeadersPacket(
7349 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437350 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337351 ASYNC,
7352 ConstructServerDataPacket(
7353 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437354 mock_quic_data2.AddWrite(
7355 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457356 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7357 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7358
7359 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7360
bnc359ed2a2016-04-29 20:43:457361 SendRequestAndExpectQuicResponse(origin1_);
7362 SendRequestAndExpectQuicResponse(origin2_);
7363
7364 EXPECT_TRUE(AllDataConsumed());
7365}
7366
ckrasicdee37572017-04-06 22:42:277367// crbug.com/705109 - this confirms that matching request with a body
7368// triggers a crash (pre-fix).
7369TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417370 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277371 HostPortPair::FromString("mail.example.org:443"));
7372
7373 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527374 quic::QuicStreamOffset header_stream_offset = 0;
7375 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437376 mock_quic_data.AddWrite(
7377 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7378 &header_stream_offset));
7379 mock_quic_data.AddWrite(
7380 SYNCHRONOUS,
7381 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337382 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7383 true, true, GetRequestHeaders("GET", "https", "/"),
7384 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527385 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437386 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337387 ASYNC, ConstructServerPushPromisePacket(
7388 1, GetNthClientInitiatedBidirectionalStreamId(0),
7389 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7390 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7391 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577392 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267393 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337394 mock_quic_data.AddWrite(SYNCHRONOUS,
7395 ConstructClientPriorityPacket(
7396 client_packet_number++, false,
7397 GetNthServerInitiatedUnidirectionalStreamId(0),
7398 GetNthClientInitiatedBidirectionalStreamId(0),
7399 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577400 }
Zhongyi Shi32f2fd02018-04-16 18:23:437401 mock_quic_data.AddRead(
7402 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337403 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437404 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577405 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437406 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7407 mock_quic_data.AddRead(
7408 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337409 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7410 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417411 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437412 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337413 ASYNC, ConstructServerDataPacket(
7414 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417415 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577416 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437417 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417418
7419 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437420 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337421 ASYNC, ConstructServerDataPacket(
7422 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417423 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277424
7425 // Because the matching request has a body, we will see the push
7426 // stream get cancelled, and the matching request go out on the
7427 // wire.
Fan Yang32c5a112018-12-10 20:06:337428 mock_quic_data.AddWrite(SYNCHRONOUS,
7429 ConstructClientAckAndRstPacket(
7430 client_packet_number++,
7431 GetNthServerInitiatedUnidirectionalStreamId(0),
7432 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277433 const char kBody[] = "1";
Renjief49758b2019-01-11 23:32:417434 quic::QuicString header3 = ConstructDataHeader(1);
7435 if (version_ != quic::QUIC_VERSION_99) {
7436 mock_quic_data.AddWrite(
7437 SYNCHRONOUS,
7438 ConstructClientRequestHeadersAndDataFramesPacket(
7439 client_packet_number++,
7440 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7441 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7442 GetNthServerInitiatedUnidirectionalStreamId(0),
7443 &header_stream_offset, nullptr, {kBody}));
7444 } else {
7445 mock_quic_data.AddWrite(
7446 SYNCHRONOUS,
7447 ConstructClientRequestHeadersAndDataFramesPacket(
7448 client_packet_number++,
7449 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7450 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7451 GetNthServerInitiatedUnidirectionalStreamId(0),
7452 &header_stream_offset, nullptr, {header3, kBody}));
7453 }
ckrasicdee37572017-04-06 22:42:277454
7455 // We see the same response as for the earlier pushed and cancelled
7456 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437457 mock_quic_data.AddRead(
7458 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337459 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437460 GetResponseHeaders("200 OK"), &server_header_offset));
7461 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337462 ASYNC, ConstructServerDataPacket(
7463 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417464 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277465
Yixin Wangb470bc882018-02-15 18:43:577466 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437467 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277468 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7469 mock_quic_data.AddRead(ASYNC, 0); // EOF
7470 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7471
7472 // The non-alternate protocol job needs to hang in order to guarantee that
7473 // the alternate-protocol job will "win".
7474 AddHangingNonAlternateProtocolSocketData();
7475
7476 CreateSession();
7477
7478 // PUSH_PROMISE handling in the http layer gets exercised here.
7479 SendRequestAndExpectQuicResponse("hello!");
7480
7481 request_.url = GURL("https://mail.example.org/pushed.jpg");
7482 ChunkedUploadDataStream upload_data(0);
7483 upload_data.AppendData("1", 1, true);
7484 request_.upload_data_stream = &upload_data;
7485 SendRequestAndExpectQuicResponse("and hello!");
7486}
7487
Bence Béky7538a952018-02-01 16:59:527488// Regression test for https://crbug.com/797825: If pushed headers describe a
7489// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7490// not be called (otherwise a DCHECK fails).
7491TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137492 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527493 pushed_request_headers[":authority"] = "";
7494 pushed_request_headers[":method"] = "GET";
7495 pushed_request_headers[":path"] = "/";
7496 pushed_request_headers[":scheme"] = "nosuchscheme";
7497
7498 session_params_.origins_to_force_quic_on.insert(
7499 HostPortPair::FromString("mail.example.org:443"));
7500
7501 MockQuicData mock_quic_data;
7502
Ryan Hamilton8d9ee76e2018-05-29 23:52:527503 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527504 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437505 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7506 mock_quic_data.AddWrite(
7507 SYNCHRONOUS,
7508 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337509 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437510 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527511
Ryan Hamilton8d9ee76e2018-05-29 23:52:527512 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337513 mock_quic_data.AddRead(
7514 ASYNC, ConstructServerPushPromisePacket(
7515 1, GetNthClientInitiatedBidirectionalStreamId(0),
7516 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7517 std::move(pushed_request_headers), &server_header_offset,
7518 &server_maker_));
7519 mock_quic_data.AddWrite(SYNCHRONOUS,
7520 ConstructClientRstPacket(
7521 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7522 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527523
Zhongyi Shi32f2fd02018-04-16 18:23:437524 mock_quic_data.AddRead(
7525 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337526 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437527 GetResponseHeaders("200 OK"), &server_header_offset));
7528 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527529
Zhongyi Shi32f2fd02018-04-16 18:23:437530 mock_quic_data.AddRead(
7531 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337532 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7533 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417534 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437535 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337536 ASYNC, ConstructServerDataPacket(
7537 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417538 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437539 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527540
7541 mock_quic_data.AddRead(ASYNC, 0);
7542 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7543
7544 // The non-alternate protocol job needs to hang in order to guarantee that
7545 // the alternate-protocol job will "win".
7546 AddHangingNonAlternateProtocolSocketData();
7547
7548 CreateSession();
7549
7550 // PUSH_PROMISE handling in the http layer gets exercised here.
7551 SendRequestAndExpectQuicResponse("hello!");
7552
7553 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7554 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7555}
7556
Yixin Wang46a273ec302018-01-23 17:59:567557// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147558TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567559 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147560 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567561 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497562 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567563
7564 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527565 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417566 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567567 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417568 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7569 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337570 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417571 SYNCHRONOUS,
7572 ConstructClientRequestHeadersPacket(
7573 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7574 true, false, ConnectRequestHeaders("mail.example.org:443"),
7575 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337576 mock_quic_data.AddRead(
7577 ASYNC, ConstructServerResponseHeadersPacket(
7578 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7579 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567580
7581 const char get_request[] =
7582 "GET / HTTP/1.1\r\n"
7583 "Host: mail.example.org\r\n"
7584 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417585 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7586 if (version_ != quic::QUIC_VERSION_99) {
7587 mock_quic_data.AddWrite(
7588 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7589 write_packet_index++, false,
7590 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7591 false, 0, quic::QuicStringPiece(get_request)));
7592 } else {
7593 mock_quic_data.AddWrite(
7594 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7595 write_packet_index++, false,
7596 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7597 false, 0, header));
7598 mock_quic_data.AddWrite(
7599 SYNCHRONOUS,
7600 ConstructClientDataPacket(
7601 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7602 false, false, header.length(), quic::QuicStringPiece(get_request)));
7603 }
7604
Yixin Wang46a273ec302018-01-23 17:59:567605 const char get_response[] =
7606 "HTTP/1.1 200 OK\r\n"
7607 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417608 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437609 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337610 ASYNC, ConstructServerDataPacket(
7611 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417612 0, header2 + quic::QuicString(get_response)));
7613 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337614 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417615 SYNCHRONOUS, ConstructServerDataPacket(
7616 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7617 false, strlen(get_response) + header2.length(),
7618 header3 + quic::QuicString("0123456789")));
7619 mock_quic_data.AddWrite(
7620 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567621 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7622
7623 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417624 SYNCHRONOUS,
7625 ConstructClientRstPacket(
7626 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7627 quic::QUIC_STREAM_CANCELLED, strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567628
7629 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7630
7631 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7632
7633 CreateSession();
7634
7635 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097636 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567637 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7638 HeadersHandler headers_handler;
7639 trans.SetBeforeHeadersSentCallback(
7640 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7641 base::Unretained(&headers_handler)));
7642 RunTransaction(&trans);
7643 CheckWasHttpResponse(&trans);
7644 CheckResponsePort(&trans, 70);
7645 CheckResponseData(&trans, "0123456789");
7646 EXPECT_TRUE(headers_handler.was_proxied());
7647 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7648
7649 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7650 // proxy socket to disconnect.
7651 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7652
7653 base::RunLoop().RunUntilIdle();
7654 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7655 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7656}
7657
7658// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147659TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567660 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147661 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567662 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497663 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567664
7665 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527666 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417667 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567668 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417669 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7670 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337671 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417672 SYNCHRONOUS,
7673 ConstructClientRequestHeadersPacket(
7674 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7675 true, false, ConnectRequestHeaders("mail.example.org:443"),
7676 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337677 mock_quic_data.AddRead(
7678 ASYNC, ConstructServerResponseHeadersPacket(
7679 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7680 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567681
7682 SpdyTestUtil spdy_util;
7683
Ryan Hamilton0239aac2018-05-19 00:03:137684 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567685 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417686 quic::QuicString header = ConstructDataHeader(get_frame.size());
7687 if (version_ != quic::QUIC_VERSION_99) {
7688 mock_quic_data.AddWrite(
7689 SYNCHRONOUS,
7690 ConstructClientAckAndDataPacket(
7691 write_packet_index++, false,
7692 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false, 0,
7693 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7694 } else {
7695 mock_quic_data.AddWrite(
7696 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7697 write_packet_index++, false,
7698 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7699 false, 0, header));
7700 mock_quic_data.AddWrite(
7701 SYNCHRONOUS,
7702 ConstructClientDataPacket(
7703 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7704 false, false, header.length(),
7705 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7706 }
Ryan Hamilton0239aac2018-05-19 00:03:137707 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567708 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417709 quic::QuicString header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437710 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337711 ASYNC,
7712 ConstructServerDataPacket(
7713 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Renjief49758b2019-01-11 23:32:417714 header2 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567715
Ryan Hamilton0239aac2018-05-19 00:03:137716 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197717 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Renjief49758b2019-01-11 23:32:417718 quic::QuicString header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437719 mock_quic_data.AddRead(
7720 SYNCHRONOUS,
7721 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337722 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417723 resp_frame.size() + header2.length(),
7724 header3 + quic::QuicString(data_frame.data(), data_frame.size())));
7725 mock_quic_data.AddWrite(
7726 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567727 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7728
7729 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437730 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417731 ConstructClientRstPacket(
7732 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7733 quic::QUIC_STREAM_CANCELLED, get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567734
7735 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7736
7737 SSLSocketDataProvider ssl_data(ASYNC, OK);
7738 ssl_data.next_proto = kProtoHTTP2;
7739 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7740
7741 CreateSession();
7742
7743 request_.url = GURL("https://mail.example.org/");
7744 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7745 HeadersHandler headers_handler;
7746 trans.SetBeforeHeadersSentCallback(
7747 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7748 base::Unretained(&headers_handler)));
7749 RunTransaction(&trans);
7750 CheckWasSpdyResponse(&trans);
7751 CheckResponsePort(&trans, 70);
7752 CheckResponseData(&trans, "0123456789");
7753 EXPECT_TRUE(headers_handler.was_proxied());
7754 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7755
Wez0e717112018-06-18 23:09:227756 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7757 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567758 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7759
7760 base::RunLoop().RunUntilIdle();
7761 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7762 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7763}
7764
7765// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7766// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147767TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567768 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147769 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567770 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497771 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567772
7773 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527774 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417775 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567776 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417777 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7778 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337779 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417780 SYNCHRONOUS,
7781 ConstructClientRequestHeadersPacket(
7782 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7783 true, false, ConnectRequestHeaders("mail.example.org:443"),
7784 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337785 mock_quic_data.AddRead(
7786 ASYNC, ConstructServerResponseHeadersPacket(
7787 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7788 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567789
Ryan Hamilton8d9ee76e2018-05-29 23:52:527790 quic::QuicStreamOffset client_data_offset = 0;
7791 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567792 const char get_request_1[] =
7793 "GET / HTTP/1.1\r\n"
7794 "Host: mail.example.org\r\n"
7795 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417796 quic::QuicString header = ConstructDataHeader(strlen(get_request_1));
7797 if (version_ != quic::QUIC_VERSION_99) {
7798 mock_quic_data.AddWrite(
7799 SYNCHRONOUS,
7800 ConstructClientAckAndDataPacket(
7801 write_packet_index++, false,
7802 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7803 client_data_offset, quic::QuicStringPiece(get_request_1)));
7804 } else {
7805 mock_quic_data.AddWrite(
7806 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7807 write_packet_index++, false,
7808 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7809 false, client_data_offset, header));
7810 mock_quic_data.AddWrite(
7811 SYNCHRONOUS,
7812 ConstructClientDataPacket(write_packet_index++,
7813 GetNthClientInitiatedBidirectionalStreamId(0),
7814 false, false, header.length(),
7815 quic::QuicStringPiece(get_request_1)));
7816 }
7817
7818 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567819
7820 const char get_response_1[] =
7821 "HTTP/1.1 200 OK\r\n"
7822 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417823 quic::QuicString header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437824 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417825 ASYNC,
7826 ConstructServerDataPacket(
7827 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7828 server_data_offset, header2 + quic::QuicString(get_response_1)));
7829 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567830
Renjief49758b2019-01-11 23:32:417831 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337832 mock_quic_data.AddRead(
7833 SYNCHRONOUS,
7834 ConstructServerDataPacket(
7835 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417836 server_data_offset, header3 + quic::QuicString("0123456789")));
7837 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567838
Renjief49758b2019-01-11 23:32:417839 mock_quic_data.AddWrite(
7840 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567841
7842 const char get_request_2[] =
7843 "GET /2 HTTP/1.1\r\n"
7844 "Host: mail.example.org\r\n"
7845 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417846 quic::QuicString header4 = ConstructDataHeader(strlen(get_request_2));
7847 if (version_ == quic::QUIC_VERSION_99) {
7848 mock_quic_data.AddWrite(
7849 SYNCHRONOUS,
7850 ConstructClientDataPacket(write_packet_index++,
7851 GetNthClientInitiatedBidirectionalStreamId(0),
7852 false, false, client_data_offset, header4));
7853 client_data_offset += header4.length();
7854 }
Zhongyi Shi32f2fd02018-04-16 18:23:437855 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527856 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417857 ConstructClientDataPacket(write_packet_index++,
7858 GetNthClientInitiatedBidirectionalStreamId(0),
7859 false, false, client_data_offset,
7860 quic::QuicStringPiece(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:567861 client_data_offset += strlen(get_request_2);
7862
7863 const char get_response_2[] =
7864 "HTTP/1.1 200 OK\r\n"
7865 "Content-Length: 7\r\n\r\n";
Renjief49758b2019-01-11 23:32:417866 quic::QuicString header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437867 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417868 ASYNC,
7869 ConstructServerDataPacket(
7870 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7871 server_data_offset, header5 + quic::QuicString(get_response_2)));
7872 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567873
Renjief49758b2019-01-11 23:32:417874 quic::QuicString header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527875 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337876 SYNCHRONOUS,
7877 ConstructServerDataPacket(
7878 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417879 server_data_offset, header6 + quic::QuicString("0123456")));
7880 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567881
Renjief49758b2019-01-11 23:32:417882 mock_quic_data.AddWrite(
7883 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567884 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7885
Renjief49758b2019-01-11 23:32:417886 mock_quic_data.AddWrite(
7887 SYNCHRONOUS,
7888 ConstructClientRstPacket(
7889 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7890 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567891
7892 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7893
7894 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7895
7896 CreateSession();
7897
7898 request_.url = GURL("https://mail.example.org/");
7899 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7900 HeadersHandler headers_handler_1;
7901 trans_1.SetBeforeHeadersSentCallback(
7902 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7903 base::Unretained(&headers_handler_1)));
7904 RunTransaction(&trans_1);
7905 CheckWasHttpResponse(&trans_1);
7906 CheckResponsePort(&trans_1, 70);
7907 CheckResponseData(&trans_1, "0123456789");
7908 EXPECT_TRUE(headers_handler_1.was_proxied());
7909 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7910
7911 request_.url = GURL("https://mail.example.org/2");
7912 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7913 HeadersHandler headers_handler_2;
7914 trans_2.SetBeforeHeadersSentCallback(
7915 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7916 base::Unretained(&headers_handler_2)));
7917 RunTransaction(&trans_2);
7918 CheckWasHttpResponse(&trans_2);
7919 CheckResponsePort(&trans_2, 70);
7920 CheckResponseData(&trans_2, "0123456");
7921 EXPECT_TRUE(headers_handler_2.was_proxied());
7922 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7923
7924 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7925 // proxy socket to disconnect.
7926 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7927
7928 base::RunLoop().RunUntilIdle();
7929 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7930 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7931}
7932
7933// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7934// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7935// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147936TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567937 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147938 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567939 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497940 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567941
7942 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527943 quic::QuicStreamOffset client_header_stream_offset = 0;
7944 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417945 int write_packet_index = 1;
7946 mock_quic_data.AddWrite(
7947 SYNCHRONOUS, ConstructInitialSettingsPacket(
7948 write_packet_index++, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567949
7950 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337951 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417952 SYNCHRONOUS,
7953 ConstructClientRequestHeadersPacket(
7954 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7955 true, false, ConnectRequestHeaders("mail.example.org:443"),
7956 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437957 mock_quic_data.AddRead(
7958 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337959 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437960 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567961
7962 // GET request, response, and data over QUIC tunnel for first request
7963 const char get_request[] =
7964 "GET / HTTP/1.1\r\n"
7965 "Host: mail.example.org\r\n"
7966 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417967 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7968 if (version_ != quic::QUIC_VERSION_99) {
7969 mock_quic_data.AddWrite(
7970 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7971 write_packet_index++, false,
7972 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7973 false, 0, quic::QuicStringPiece(get_request)));
7974 } else {
7975 mock_quic_data.AddWrite(
7976 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7977 write_packet_index++, false,
7978 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7979 false, 0, header));
7980 mock_quic_data.AddWrite(
7981 SYNCHRONOUS,
7982 ConstructClientDataPacket(
7983 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7984 false, false, header.length(), quic::QuicStringPiece(get_request)));
7985 }
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")));
8001 mock_quic_data.AddWrite(
8002 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568003
8004 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438005 mock_quic_data.AddWrite(
8006 SYNCHRONOUS,
8007 ConstructClientRequestHeadersPacket(
Renjief49758b2019-01-11 23:32:418008 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(1),
8009 false, false, ConnectRequestHeaders("different.example.org:443"),
Fan Yang32c5a112018-12-10 20:06:338010 GetNthClientInitiatedBidirectionalStreamId(0),
8011 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438012 mock_quic_data.AddRead(
8013 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338014 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438015 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568016
8017 // GET request, response, and data over QUIC tunnel for second request
8018 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138019 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568020 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:418021 quic::QuicString header4 = ConstructDataHeader(get_frame.size());
8022 if (version_ != quic::QUIC_VERSION_99) {
8023 mock_quic_data.AddWrite(
8024 SYNCHRONOUS,
8025 ConstructClientAckAndDataPacket(
8026 write_packet_index++, false,
8027 GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1, false, 0,
8028 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
8029 } else {
8030 mock_quic_data.AddWrite(
8031 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8032 write_packet_index++, false,
8033 GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
8034 false, 0, header4));
8035 mock_quic_data.AddWrite(
8036 SYNCHRONOUS,
8037 ConstructClientDataPacket(
8038 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(1),
8039 false, false, header4.length(),
8040 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
8041 }
Yixin Wang46a273ec302018-01-23 17:59:568042
Ryan Hamilton0239aac2018-05-19 00:03:138043 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568044 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:418045 quic::QuicString header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438046 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338047 ASYNC,
8048 ConstructServerDataPacket(
8049 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Renjief49758b2019-01-11 23:32:418050 header5 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568051
Ryan Hamilton0239aac2018-05-19 00:03:138052 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198053 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Renjief49758b2019-01-11 23:32:418054 quic::QuicString header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438055 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418056 ASYNC,
8057 ConstructServerDataPacket(
8058 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8059 resp_frame.size() + header5.length(),
8060 header6 + quic::QuicString(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568061
Renjief49758b2019-01-11 23:32:418062 mock_quic_data.AddWrite(
8063 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568064 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8065
8066 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418067 SYNCHRONOUS,
8068 ConstructClientRstPacket(
8069 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
8070 quic::QUIC_STREAM_CANCELLED, strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568071 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438072 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:418073 ConstructClientRstPacket(
8074 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(1),
8075 quic::QUIC_STREAM_CANCELLED, get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:568076
8077 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8078
8079 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8080
8081 SSLSocketDataProvider ssl_data(ASYNC, OK);
8082 ssl_data.next_proto = kProtoHTTP2;
8083 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8084
8085 CreateSession();
8086
8087 request_.url = GURL("https://mail.example.org/");
8088 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8089 HeadersHandler headers_handler_1;
8090 trans_1.SetBeforeHeadersSentCallback(
8091 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8092 base::Unretained(&headers_handler_1)));
8093 RunTransaction(&trans_1);
8094 CheckWasHttpResponse(&trans_1);
8095 CheckResponsePort(&trans_1, 70);
8096 CheckResponseData(&trans_1, "0123456789");
8097 EXPECT_TRUE(headers_handler_1.was_proxied());
8098 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8099
8100 request_.url = GURL("https://different.example.org/");
8101 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8102 HeadersHandler headers_handler_2;
8103 trans_2.SetBeforeHeadersSentCallback(
8104 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8105 base::Unretained(&headers_handler_2)));
8106 RunTransaction(&trans_2);
8107 CheckWasSpdyResponse(&trans_2);
8108 CheckResponsePort(&trans_2, 70);
8109 CheckResponseData(&trans_2, "0123456");
8110 EXPECT_TRUE(headers_handler_2.was_proxied());
8111 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8112
8113 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8114 // proxy socket to disconnect.
8115 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8116
8117 base::RunLoop().RunUntilIdle();
8118 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8119 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8120}
8121
8122// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148123TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568124 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148125 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568126 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498127 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568128
8129 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528130 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568131 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438132 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528133 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338134 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8135 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8136 false, ConnectRequestHeaders("mail.example.org:443"),
8137 &header_stream_offset));
8138 mock_quic_data.AddRead(
8139 ASYNC, ConstructServerResponseHeadersPacket(
8140 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8141 GetResponseHeaders("500")));
8142 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8143 mock_quic_data.AddWrite(SYNCHRONOUS,
8144 ConstructClientAckAndRstPacket(
8145 3, GetNthClientInitiatedBidirectionalStreamId(0),
8146 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568147
8148 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8149
8150 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8151
8152 CreateSession();
8153
8154 request_.url = GURL("https://mail.example.org/");
8155 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8156 HeadersHandler headers_handler;
8157 trans.SetBeforeHeadersSentCallback(
8158 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8159 base::Unretained(&headers_handler)));
8160 TestCompletionCallback callback;
8161 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8162 EXPECT_EQ(ERR_IO_PENDING, rv);
8163 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8164 EXPECT_EQ(false, headers_handler.was_proxied());
8165
8166 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8167 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8168}
8169
8170// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148171TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568172 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148173 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568174 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498175 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568176
8177 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528178 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568179 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438180 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338181 mock_quic_data.AddWrite(
8182 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8183 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8184 false, ConnectRequestHeaders("mail.example.org:443"),
8185 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568186 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8187
8188 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8189
8190 CreateSession();
8191
8192 request_.url = GURL("https://mail.example.org/");
8193 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8194 HeadersHandler headers_handler;
8195 trans.SetBeforeHeadersSentCallback(
8196 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8197 base::Unretained(&headers_handler)));
8198 TestCompletionCallback callback;
8199 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8200 EXPECT_EQ(ERR_IO_PENDING, rv);
8201 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8202
8203 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8204 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8205}
8206
8207// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8208// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148209TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568210 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148211 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568212 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498213 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568214
8215 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528216 quic::QuicStreamOffset client_header_stream_offset = 0;
8217 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:418218 int write_packet_index = 1;
Fan Yang32c5a112018-12-10 20:06:338219 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418220 SYNCHRONOUS, ConstructInitialSettingsPacket(
8221 write_packet_index++, &client_header_stream_offset));
8222 mock_quic_data.AddWrite(
8223 SYNCHRONOUS,
8224 ConstructClientRequestHeadersPacket(
8225 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
8226 true, false, ConnectRequestHeaders("mail.example.org:443"),
8227 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438228 mock_quic_data.AddRead(
8229 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338230 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438231 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjief49758b2019-01-11 23:32:418232 mock_quic_data.AddWrite(
8233 SYNCHRONOUS,
8234 ConstructClientAckAndRstPacket(
8235 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
8236 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568237
Zhongyi Shi32f2fd02018-04-16 18:23:438238 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418239 SYNCHRONOUS,
8240 ConstructClientRequestHeadersPacket(
8241 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(1),
8242 false, false, ConnectRequestHeaders("mail.example.org:443"),
8243 GetNthClientInitiatedBidirectionalStreamId(0),
8244 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438245 mock_quic_data.AddRead(
8246 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338247 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438248 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568249
8250 const char get_request[] =
8251 "GET / HTTP/1.1\r\n"
8252 "Host: mail.example.org\r\n"
8253 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:418254 quic::QuicString header = ConstructDataHeader(strlen(get_request));
8255 if (version_ != quic::QUIC_VERSION_99) {
8256 mock_quic_data.AddWrite(
8257 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8258 write_packet_index++, false,
8259 GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8260 false, 0, quic::QuicStringPiece(get_request)));
8261 } else {
8262 mock_quic_data.AddWrite(
8263 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8264 write_packet_index++, false,
8265 GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8266 false, 0, header));
8267 mock_quic_data.AddWrite(
8268 SYNCHRONOUS,
8269 ConstructClientDataPacket(
8270 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(1),
8271 false, false, header.length(), quic::QuicStringPiece(get_request)));
8272 }
Yixin Wang46a273ec302018-01-23 17:59:568273 const char get_response[] =
8274 "HTTP/1.1 200 OK\r\n"
8275 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:418276 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438277 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338278 ASYNC, ConstructServerDataPacket(
8279 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Renjief49758b2019-01-11 23:32:418280 0, header2 + quic::QuicString(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528281
Renjief49758b2019-01-11 23:32:418282 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338283 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418284 SYNCHRONOUS, ConstructServerDataPacket(
8285 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8286 false, strlen(get_response) + header2.length(),
8287 header3 + quic::QuicString("0123456789")));
8288 mock_quic_data.AddWrite(
8289 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568290 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8291
8292 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418293 SYNCHRONOUS,
8294 ConstructClientRstPacket(
8295 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(1),
8296 quic::QUIC_STREAM_CANCELLED, strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568297
8298 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8299
8300 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8301 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8302
8303 SSLSocketDataProvider ssl_data(ASYNC, OK);
8304 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8305
8306 CreateSession();
8307
8308 request_.url = GURL("https://mail.example.org/");
8309 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8310 HeadersHandler headers_handler;
8311 trans.SetBeforeHeadersSentCallback(
8312 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8313 base::Unretained(&headers_handler)));
8314 TestCompletionCallback callback;
8315 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8316 EXPECT_EQ(ERR_IO_PENDING, rv);
8317 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8318
8319 rv = trans.RestartIgnoringLastError(callback.callback());
8320 EXPECT_EQ(ERR_IO_PENDING, rv);
8321 EXPECT_EQ(OK, callback.WaitForResult());
8322
8323 CheckWasHttpResponse(&trans);
8324 CheckResponsePort(&trans, 70);
8325 CheckResponseData(&trans, "0123456789");
8326 EXPECT_EQ(true, headers_handler.was_proxied());
8327 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8328
8329 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8330 // proxy socket to disconnect.
8331 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8332
8333 base::RunLoop().RunUntilIdle();
8334 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8335 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8336}
8337
8338// Checks if a request's specified "user-agent" header shows up correctly in the
8339// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148340TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Yixin Wang46a273ec302018-01-23 17:59:568341 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148342 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568343 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498344 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568345
8346 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528347 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568348 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438349 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568350
Ryan Hamilton0239aac2018-05-19 00:03:138351 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568352 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Fan Yang32c5a112018-12-10 20:06:338353 mock_quic_data.AddWrite(
8354 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8355 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8356 false, std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568357 // Return an error, so the transaction stops here (this test isn't interested
8358 // in the rest).
8359 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8360
8361 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8362
8363 CreateSession();
8364
8365 request_.url = GURL("https://mail.example.org/");
8366 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8367 "Chromium Ultra Awesome X Edition");
8368 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8369 HeadersHandler headers_handler;
8370 trans.SetBeforeHeadersSentCallback(
8371 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8372 base::Unretained(&headers_handler)));
8373 TestCompletionCallback callback;
8374 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8375 EXPECT_EQ(ERR_IO_PENDING, rv);
8376 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8377
8378 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8379 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8380}
8381
Yixin Wang00fc44c2018-01-23 21:12:208382// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8383// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148384TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208385 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148386 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208387 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498388 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208389
8390 const RequestPriority request_priority = MEDIUM;
8391
8392 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528393 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208394 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438395 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8396 mock_quic_data.AddWrite(
8397 SYNCHRONOUS,
8398 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338399 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8400 request_priority, ConnectRequestHeaders("mail.example.org:443"), 0,
Zhongyi Shi32f2fd02018-04-16 18:23:438401 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208402 // Return an error, so the transaction stops here (this test isn't interested
8403 // in the rest).
8404 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8405
8406 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8407
8408 CreateSession();
8409
8410 request_.url = GURL("https://mail.example.org/");
8411 HttpNetworkTransaction trans(request_priority, session_.get());
8412 TestCompletionCallback callback;
8413 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8414 EXPECT_EQ(ERR_IO_PENDING, rv);
8415 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8416
8417 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8418 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8419}
8420
Yixin Wang46a273ec302018-01-23 17:59:568421// Test the request-challenge-retry sequence for basic auth, over a QUIC
8422// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148423TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568424 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8425 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138426 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568427 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8428
8429 std::unique_ptr<QuicTestPacketMaker> client_maker;
8430 std::unique_ptr<QuicTestPacketMaker> server_maker;
8431
8432 // On the second pass, the body read of the auth challenge is synchronous, so
8433 // IsConnectedAndIdle returns false. The socket should still be drained and
8434 // reused. See http://crbug.com/544255.
8435 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338436 client_maker.reset(new QuicTestPacketMaker(
8437 version_, quic::EmptyQuicConnectionId(), &clock_,
8438 kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8439 client_headers_include_h2_stream_dependency_));
8440 server_maker.reset(new QuicTestPacketMaker(
8441 version_, quic::EmptyQuicConnectionId(), &clock_,
8442 kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568443
8444 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148445 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568446 proxy_resolution_service_ =
8447 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498448 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568449
8450 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528451 quic::QuicStreamOffset client_header_stream_offset = 0;
8452 quic::QuicStreamOffset server_header_stream_offset = 0;
8453 quic::QuicStreamOffset client_data_offset = 0;
8454 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568455
Zhongyi Shi32f2fd02018-04-16 18:23:438456 mock_quic_data.AddWrite(SYNCHRONOUS,
8457 client_maker->MakeInitialSettingsPacket(
8458 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568459
8460 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438461 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568462 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338463 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8464 default_priority,
Yixin Wang46a273ec302018-01-23 17:59:568465 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8466 &client_header_stream_offset));
8467
Ryan Hamilton0239aac2018-05-19 00:03:138468 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568469 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8470 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8471 headers["content-length"] = "10";
8472 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438473 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338474 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8475 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568476
8477 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438478 mock_quic_data.AddRead(
8479 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338480 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8481 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568482 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438483 mock_quic_data.AddRead(
8484 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338485 2, GetNthClientInitiatedBidirectionalStreamId(0),
8486 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568487 }
8488 server_data_offset += 10;
8489
Zhongyi Shi32f2fd02018-04-16 18:23:438490 mock_quic_data.AddWrite(SYNCHRONOUS,
8491 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568492
8493 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338494 SYNCHRONOUS,
8495 client_maker->MakeRstPacket(
8496 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
8497 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:568498
8499 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8500 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8501 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338502 SYNCHRONOUS, client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8503 5, GetNthClientInitiatedBidirectionalStreamId(1),
8504 false, false, default_priority, std::move(headers),
8505 GetNthClientInitiatedBidirectionalStreamId(0),
8506 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568507
8508 // Response to wrong password
8509 headers =
8510 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8511 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8512 headers["content-length"] = "10";
8513 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438514 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338515 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8516 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568517 mock_quic_data.AddRead(SYNCHRONOUS,
8518 ERR_IO_PENDING); // No more data to read
8519
Fan Yang32c5a112018-12-10 20:06:338520 mock_quic_data.AddWrite(
8521 SYNCHRONOUS,
8522 client_maker->MakeAckAndRstPacket(
8523 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8524 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568525
8526 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8527 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8528
8529 CreateSession();
8530
8531 request_.url = GURL("https://mail.example.org/");
8532 // Ensure that proxy authentication is attempted even
8533 // when the no authentication data flag is set.
8534 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8535 {
8536 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8537 HeadersHandler headers_handler;
8538 trans.SetBeforeHeadersSentCallback(
8539 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8540 base::Unretained(&headers_handler)));
8541 RunTransaction(&trans);
8542
8543 const HttpResponseInfo* response = trans.GetResponseInfo();
8544 ASSERT_TRUE(response != nullptr);
8545 ASSERT_TRUE(response->headers.get() != nullptr);
8546 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8547 response->headers->GetStatusLine());
8548 EXPECT_TRUE(response->headers->IsKeepAlive());
8549 EXPECT_EQ(407, response->headers->response_code());
8550 EXPECT_EQ(10, response->headers->GetContentLength());
8551 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8552 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8553 ASSERT_TRUE(auth_challenge != nullptr);
8554 EXPECT_TRUE(auth_challenge->is_proxy);
8555 EXPECT_EQ("https://proxy.example.org:70",
8556 auth_challenge->challenger.Serialize());
8557 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8558 EXPECT_EQ("basic", auth_challenge->scheme);
8559
8560 TestCompletionCallback callback;
8561 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8562 callback.callback());
8563 EXPECT_EQ(ERR_IO_PENDING, rv);
8564 EXPECT_EQ(OK, callback.WaitForResult());
8565
8566 response = trans.GetResponseInfo();
8567 ASSERT_TRUE(response != nullptr);
8568 ASSERT_TRUE(response->headers.get() != nullptr);
8569 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8570 response->headers->GetStatusLine());
8571 EXPECT_TRUE(response->headers->IsKeepAlive());
8572 EXPECT_EQ(407, response->headers->response_code());
8573 EXPECT_EQ(10, response->headers->GetContentLength());
8574 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8575 auth_challenge = response->auth_challenge.get();
8576 ASSERT_TRUE(auth_challenge != nullptr);
8577 EXPECT_TRUE(auth_challenge->is_proxy);
8578 EXPECT_EQ("https://proxy.example.org:70",
8579 auth_challenge->challenger.Serialize());
8580 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8581 EXPECT_EQ("basic", auth_challenge->scheme);
8582 }
8583 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8584 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8585 // reused because it's not connected).
8586 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8587 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8588 }
8589}
8590
Yixin Wang385652a2018-02-16 02:37:238591TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8592 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8593 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268594 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238595 !client_headers_include_h2_stream_dependency_) {
8596 return;
8597 }
8598
8599 session_params_.origins_to_force_quic_on.insert(
8600 HostPortPair::FromString("mail.example.org:443"));
8601
Fan Yang32c5a112018-12-10 20:06:338602 const quic::QuicStreamId client_stream_0 =
8603 GetNthClientInitiatedBidirectionalStreamId(0);
8604 const quic::QuicStreamId client_stream_1 =
8605 GetNthClientInitiatedBidirectionalStreamId(1);
8606 const quic::QuicStreamId client_stream_2 =
8607 GetNthClientInitiatedBidirectionalStreamId(2);
8608 const quic::QuicStreamId push_stream_0 =
8609 GetNthServerInitiatedUnidirectionalStreamId(0);
8610 const quic::QuicStreamId push_stream_1 =
8611 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238612
8613 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528614 quic::QuicStreamOffset header_stream_offset = 0;
8615 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238616 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438617 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238618
8619 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438620 mock_quic_data.AddWrite(SYNCHRONOUS,
8621 ConstructClientRequestHeadersPacket(
8622 2, client_stream_0, true, true, HIGHEST,
8623 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8624 &header_stream_offset));
8625 mock_quic_data.AddWrite(SYNCHRONOUS,
8626 ConstructClientRequestHeadersPacket(
8627 3, client_stream_1, true, true, MEDIUM,
8628 GetRequestHeaders("GET", "https", "/1.jpg"),
8629 client_stream_0, &header_stream_offset));
8630 mock_quic_data.AddWrite(SYNCHRONOUS,
8631 ConstructClientRequestHeadersPacket(
8632 4, client_stream_2, true, true, MEDIUM,
8633 GetRequestHeaders("GET", "https", "/2.jpg"),
8634 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238635
8636 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438637 mock_quic_data.AddRead(
8638 ASYNC, ConstructServerResponseHeadersPacket(
8639 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8640 &server_header_offset));
8641 mock_quic_data.AddRead(
8642 ASYNC, ConstructServerResponseHeadersPacket(
8643 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8644 &server_header_offset));
8645 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8646 mock_quic_data.AddRead(
8647 ASYNC, ConstructServerResponseHeadersPacket(
8648 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8649 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238650
8651 // Server sends two push promises associated with |client_stream_0|; client
8652 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8653 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438654 mock_quic_data.AddRead(ASYNC,
8655 ConstructServerPushPromisePacket(
8656 4, client_stream_0, push_stream_0, false,
8657 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8658 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238659 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438660 SYNCHRONOUS,
8661 ConstructClientAckAndPriorityFramesPacket(
8662 6, false, 4, 3, 1,
8663 {{push_stream_0, client_stream_2,
8664 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8665 &header_stream_offset));
8666 mock_quic_data.AddRead(ASYNC,
8667 ConstructServerPushPromisePacket(
8668 5, client_stream_0, push_stream_1, false,
8669 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8670 &server_header_offset, &server_maker_));
8671 mock_quic_data.AddWrite(
8672 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238673 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8674 DEFAULT_PRIORITY, &header_stream_offset));
8675
8676 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438677 mock_quic_data.AddRead(
8678 ASYNC, ConstructServerResponseHeadersPacket(
8679 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8680 &server_header_offset));
8681 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8682 mock_quic_data.AddRead(
8683 ASYNC, ConstructServerResponseHeadersPacket(
8684 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8685 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238686
8687 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8688 // priority updates to match the request's priority. Client sends PRIORITY
8689 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438690 mock_quic_data.AddWrite(
8691 SYNCHRONOUS,
8692 ConstructClientAckAndPriorityFramesPacket(
8693 9, false, 7, 7, 1,
8694 {{push_stream_1, client_stream_2,
8695 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8696 {push_stream_0, client_stream_0,
8697 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8698 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238699
8700 // Server sends data for the three requests and the two push promises.
Renjief49758b2019-01-11 23:32:418701 quic::QuicString header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438702 mock_quic_data.AddRead(
8703 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418704 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438705 mock_quic_data.AddRead(
8706 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418707 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438708 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8709 mock_quic_data.AddRead(
8710 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418711 header + "hello 2!"));
8712 quic::QuicString header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438713 mock_quic_data.AddRead(
8714 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418715 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438716 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8717 mock_quic_data.AddRead(
8718 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418719 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238720
Yixin Wang385652a2018-02-16 02:37:238721 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8722 mock_quic_data.AddRead(ASYNC, 0); // EOF
8723 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8724
8725 // The non-alternate protocol job needs to hang in order to guarantee that
8726 // the alternate-protocol job will "win".
8727 AddHangingNonAlternateProtocolSocketData();
8728
8729 CreateSession();
8730
8731 request_.url = GURL("https://mail.example.org/0.jpg");
8732 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8733 TestCompletionCallback callback_0;
8734 EXPECT_EQ(ERR_IO_PENDING,
8735 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8736 base::RunLoop().RunUntilIdle();
8737
8738 request_.url = GURL("https://mail.example.org/1.jpg");
8739 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8740 TestCompletionCallback callback_1;
8741 EXPECT_EQ(ERR_IO_PENDING,
8742 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8743 base::RunLoop().RunUntilIdle();
8744
8745 request_.url = GURL("https://mail.example.org/2.jpg");
8746 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8747 TestCompletionCallback callback_2;
8748 EXPECT_EQ(ERR_IO_PENDING,
8749 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8750 base::RunLoop().RunUntilIdle();
8751
8752 // Client makes request that matches resource pushed in |pushed_stream_0|.
8753 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8754 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8755 TestCompletionCallback callback_3;
8756 EXPECT_EQ(ERR_IO_PENDING,
8757 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8758 base::RunLoop().RunUntilIdle();
8759
8760 EXPECT_TRUE(callback_0.have_result());
8761 EXPECT_EQ(OK, callback_0.WaitForResult());
8762 EXPECT_TRUE(callback_1.have_result());
8763 EXPECT_EQ(OK, callback_1.WaitForResult());
8764 EXPECT_TRUE(callback_2.have_result());
8765 EXPECT_EQ(OK, callback_2.WaitForResult());
8766
8767 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8768 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8769 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8770 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8771
8772 mock_quic_data.Resume();
8773 base::RunLoop().RunUntilIdle();
8774 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8775 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8776}
8777
[email protected]61a527782013-02-21 03:58:008778} // namespace test
8779} // namespace net