1 // 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
5 #include <algorithm>
6 #include <ostream>
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/compiler_specific.h"
13 #include "base/macros.h"
14 #include "base/run_loop.h"
15 #include "base/stl_util.h"
16 #include "base/strings/strcat.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_piece.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/test/metrics/histogram_tester.h"
21 #include "base/test/scoped_feature_list.h"
22 #include "net/base/chunked_upload_data_stream.h"
23 #include "net/base/completion_once_callback.h"
24 #include "net/base/features.h"
25 #include "net/base/ip_endpoint.h"
26 #include "net/base/mock_network_change_notifier.h"
27 #include "net/base/network_isolation_key.h"
28 #include "net/base/test_completion_callback.h"
29 #include "net/base/test_proxy_delegate.h"
30 #include "net/cert/ct_policy_enforcer.h"
31 #include "net/cert/mock_cert_verifier.h"
32 #include "net/cert/multi_log_ct_verifier.h"
33 #include "net/dns/mock_host_resolver.h"
34 #include "net/http/http_auth_handler_factory.h"
35 #include "net/http/http_network_session.h"
36 #include "net/http/http_network_transaction.h"
37 #include "net/http/http_proxy_connect_job.h"
38 #include "net/http/http_server_properties.h"
39 #include "net/http/http_stream.h"
40 #include "net/http/http_stream_factory.h"
41 #include "net/http/http_transaction_test_util.h"
42 #include "net/http/test_upload_data_stream_not_allow_http1.h"
43 #include "net/http/transport_security_state.h"
44 #include "net/log/net_log_event_type.h"
45 #include "net/log/test_net_log.h"
46 #include "net/log/test_net_log_util.h"
47 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
48 #include "net/proxy_resolution/proxy_config_service_fixed.h"
49 #include "net/proxy_resolution/proxy_resolver.h"
50 #include "net/quic/crypto/proof_verifier_chromium.h"
51 #include "net/quic/mock_crypto_client_stream_factory.h"
52 #include "net/quic/mock_quic_context.h"
53 #include "net/quic/mock_quic_data.h"
54 #include "net/quic/quic_chromium_alarm_factory.h"
55 #include "net/quic/quic_http_stream.h"
56 #include "net/quic/quic_http_utils.h"
57 #include "net/quic/quic_stream_factory_peer.h"
58 #include "net/quic/quic_test_packet_maker.h"
59 #include "net/quic/test_task_runner.h"
60 #include "net/socket/client_socket_factory.h"
61 #include "net/socket/mock_client_socket_pool_manager.h"
62 #include "net/socket/next_proto.h"
63 #include "net/socket/socket_performance_watcher.h"
64 #include "net/socket/socket_performance_watcher_factory.h"
65 #include "net/socket/socket_test_util.h"
66 #include "net/spdy/spdy_test_util_common.h"
67 #include "net/ssl/ssl_config_service_defaults.h"
68 #include "net/test/cert_test_util.h"
69 #include "net/test/gtest_util.h"
70 #include "net/test/test_data_directory.h"
71 #include "net/test/test_with_task_environment.h"
72 #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
73 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
74 #include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
75 #include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
76 #include "net/third_party/quiche/src/quic/core/quic_framer.h"
77 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
78 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
79 #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
80 #include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
81 #include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
82 #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
83 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
84 #include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
85 #include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
86 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
87 #include "net/url_request/static_http_user_agent_settings.h"
88 #include "net/url_request/url_request.h"
89 #include "net/url_request/url_request_job_factory.h"
90 #include "net/url_request/url_request_test_util.h"
91 #include "testing/gmock/include/gmock/gmock.h"
92 #include "testing/gtest/include/gtest/gtest.h"
93 #include "testing/platform_test.h"
94 #include "url/gurl.h"
95 #include "url/origin.h"
96
97 using ::testing::ElementsAre;
98 using ::testing::Key;
99
100 namespace net {
101 namespace test {
102
103 namespace {
104
105 enum DestinationType {
106 // In pooling tests with two requests for different origins to the same
107 // destination, the destination should be
108 SAME_AS_FIRST, // the same as the first origin,
109 SAME_AS_SECOND, // the same as the second origin, or
110 DIFFERENT, // different from both.
111 };
112
113 static const char kQuicAlternativeServiceHeader[] =
114 "Alt-Svc: quic=\":443\"\r\n\r\n";
115 static const char kQuicAlternativeServiceWithProbabilityHeader[] =
116 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
117 static const char kQuicAlternativeServiceDifferentPortHeader[] =
118 "Alt-Svc: quic=\":137\"\r\n\r\n";
119
120 const char kDefaultServerHostName[] = "mail.example.org";
121 const char kDifferentHostname[] = "different.example.com";
122
123 struct TestParams {
124 quic::ParsedQuicVersion version;
125 bool client_headers_include_h2_stream_dependency;
126 };
127
128 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParams & p)129 std::string PrintToString(const TestParams& p) {
130 return base::StrCat(
131 {ParsedQuicVersionToString(p.version), "_",
132 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
133 "Dependency"});
134 }
135
136 // Run QuicNetworkTransactionWithDestinationTest instances with all value
137 // combinations of version and destination_type.
138 struct PoolingTestParams {
139 quic::ParsedQuicVersion version;
140 DestinationType destination_type;
141 bool client_headers_include_h2_stream_dependency;
142 };
143
144 // Used by ::testing::PrintToStringParamName().
PrintToString(const PoolingTestParams & p)145 std::string PrintToString(const PoolingTestParams& p) {
146 const char* destination_string = "";
147 switch (p.destination_type) {
148 case SAME_AS_FIRST:
149 destination_string = "SAME_AS_FIRST";
150 break;
151 case SAME_AS_SECOND:
152 destination_string = "SAME_AS_SECOND";
153 break;
154 case DIFFERENT:
155 destination_string = "DIFFERENT";
156 break;
157 }
158 return base::StrCat(
159 {ParsedQuicVersionToString(p.version), "_", destination_string, "_",
160 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
161 "Dependency"});
162 }
163
GenerateQuicAltSvcHeader(const quic::ParsedQuicVersionVector & versions)164 std::string GenerateQuicAltSvcHeader(
165 const quic::ParsedQuicVersionVector& versions) {
166 std::string altsvc_header = "Alt-Svc: ";
167 std::string version_string;
168 bool first_version = true;
169 for (const auto& version : versions) {
170 if (first_version) {
171 first_version = false;
172 } else {
173 altsvc_header.append(", ");
174 }
175 altsvc_header.append(quic::AlpnForVersion(version));
176 altsvc_header.append("=\":443\"");
177 if (version.SupportsGoogleAltSvcFormat()) {
178 if (!version_string.empty()) {
179 version_string.append(",");
180 }
181 version_string.append(base::NumberToString(version.transport_version));
182 }
183 }
184 if (!version_string.empty()) {
185 altsvc_header.append(", quic=\":443\"; v=\"" + version_string + "\"");
186 }
187 altsvc_header.append("\r\n");
188
189 return altsvc_header;
190 }
191
GetTestParams()192 std::vector<TestParams> GetTestParams() {
193 std::vector<TestParams> params;
194 quic::ParsedQuicVersionVector all_supported_versions =
195 quic::AllSupportedVersions();
196 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
197 params.push_back(TestParams{version, false});
198 params.push_back(TestParams{version, true});
199 }
200 return params;
201 }
202
GetPoolingTestParams()203 std::vector<PoolingTestParams> GetPoolingTestParams() {
204 std::vector<PoolingTestParams> params;
205 quic::ParsedQuicVersionVector all_supported_versions =
206 quic::AllSupportedVersions();
207 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
208 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
209 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
210 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
211 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
212 params.push_back(PoolingTestParams{version, DIFFERENT, false});
213 params.push_back(PoolingTestParams{version, DIFFERENT, true});
214 }
215 return params;
216 }
217
ConstructDataFrameForVersion(base::StringPiece body,quic::ParsedQuicVersion version)218 std::string ConstructDataFrameForVersion(base::StringPiece body,
219 quic::ParsedQuicVersion version) {
220 if (!version.HasIetfQuicFrames()) {
221 return body.as_string();
222 }
223 std::unique_ptr<char[]> buffer;
224 auto header_length =
225 quic::HttpEncoder::SerializeDataFrameHeader(body.size(), &buffer);
226 return base::StrCat({base::StringPiece(buffer.get(), header_length), body});
227 }
228
229 } // namespace
230
231 class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
232 public:
TestSocketPerformanceWatcher(bool * should_notify_updated_rtt,bool * rtt_notification_received)233 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
234 bool* rtt_notification_received)
235 : should_notify_updated_rtt_(should_notify_updated_rtt),
236 rtt_notification_received_(rtt_notification_received) {}
~TestSocketPerformanceWatcher()237 ~TestSocketPerformanceWatcher() override {}
238
ShouldNotifyUpdatedRTT() const239 bool ShouldNotifyUpdatedRTT() const override {
240 return *should_notify_updated_rtt_;
241 }
242
OnUpdatedRTTAvailable(const base::TimeDelta & rtt)243 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
244 *rtt_notification_received_ = true;
245 }
246
OnConnectionChanged()247 void OnConnectionChanged() override {}
248
249 private:
250 bool* should_notify_updated_rtt_;
251 bool* rtt_notification_received_;
252
253 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
254 };
255
256 class TestSocketPerformanceWatcherFactory
257 : public SocketPerformanceWatcherFactory {
258 public:
TestSocketPerformanceWatcherFactory()259 TestSocketPerformanceWatcherFactory()
260 : watcher_count_(0u),
261 should_notify_updated_rtt_(true),
262 rtt_notification_received_(false) {}
~TestSocketPerformanceWatcherFactory()263 ~TestSocketPerformanceWatcherFactory() override {}
264
265 // SocketPerformanceWatcherFactory implementation:
CreateSocketPerformanceWatcher(const Protocol protocol,const AddressList &)266 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
267 const Protocol protocol,
268 const AddressList& /* address_list */) override {
269 if (protocol != PROTOCOL_QUIC) {
270 return nullptr;
271 }
272 ++watcher_count_;
273 return std::unique_ptr<SocketPerformanceWatcher>(
274 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
275 &rtt_notification_received_));
276 }
277
watcher_count() const278 size_t watcher_count() const { return watcher_count_; }
279
rtt_notification_received() const280 bool rtt_notification_received() const { return rtt_notification_received_; }
281
set_should_notify_updated_rtt(bool should_notify_updated_rtt)282 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
283 should_notify_updated_rtt_ = should_notify_updated_rtt;
284 }
285
286 private:
287 size_t watcher_count_;
288 bool should_notify_updated_rtt_;
289 bool rtt_notification_received_;
290
291 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
292 };
293
294 class QuicNetworkTransactionTest
295 : public PlatformTest,
296 public ::testing::WithParamInterface<TestParams>,
297 public WithTaskEnvironment {
298 protected:
QuicNetworkTransactionTest()299 QuicNetworkTransactionTest()
300 : version_(GetParam().version),
301 client_headers_include_h2_stream_dependency_(
302 GetParam().client_headers_include_h2_stream_dependency),
303 supported_versions_(quic::test::SupportedVersions(version_)),
304 client_maker_(new QuicTestPacketMaker(
305 version_,
306 quic::QuicUtils::CreateRandomConnectionId(
307 context_.random_generator()),
308 context_.clock(),
309 kDefaultServerHostName,
310 quic::Perspective::IS_CLIENT,
311 client_headers_include_h2_stream_dependency_)),
312 server_maker_(version_,
313 quic::QuicUtils::CreateRandomConnectionId(
314 context_.random_generator()),
315 context_.clock(),
316 kDefaultServerHostName,
317 quic::Perspective::IS_SERVER,
318 false),
319 quic_task_runner_(new TestTaskRunner(context_.mock_clock())),
320 cert_transparency_verifier_(new MultiLogCTVerifier()),
321 ssl_config_service_(new SSLConfigServiceDefaults),
322 proxy_resolution_service_(
323 ConfiguredProxyResolutionService::CreateDirect()),
324 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
325 http_server_properties_(std::make_unique<HttpServerProperties>()),
326 ssl_data_(ASYNC, OK) {
327 FLAGS_quic_enable_http3_grease_randomness = false;
328 request_.method = "GET";
329 std::string url("https://");
330 url.append(kDefaultServerHostName);
331 request_.url = GURL(url);
332 request_.load_flags = 0;
333 request_.traffic_annotation =
334 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
335 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
336
337 scoped_refptr<X509Certificate> cert(
338 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
339 verify_details_.cert_verify_result.verified_cert = cert;
340 verify_details_.cert_verify_result.is_issued_by_known_root = true;
341 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
342 }
343
SetUp()344 void SetUp() override {
345 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
346 base::RunLoop().RunUntilIdle();
347 }
348
TearDown()349 void TearDown() override {
350 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
351 // Empty the current queue.
352 base::RunLoop().RunUntilIdle();
353 PlatformTest::TearDown();
354 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
355 base::RunLoop().RunUntilIdle();
356 session_.reset();
357 }
358
359 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientConnectionClosePacket(uint64_t num)360 ConstructClientConnectionClosePacket(uint64_t num) {
361 return client_maker_->MakeConnectionClosePacket(
362 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
363 }
364
365 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructServerConnectionClosePacket(uint64_t num)366 ConstructServerConnectionClosePacket(uint64_t num) {
367 return server_maker_.MakeConnectionClosePacket(
368 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
369 }
370
ConstructServerGoAwayPacket(uint64_t num,quic::QuicErrorCode error_code,std::string reason_phrase)371 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
372 uint64_t num,
373 quic::QuicErrorCode error_code,
374 std::string reason_phrase) {
375 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
376 }
377
ConstructClientAckPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received)378 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
379 uint64_t packet_number,
380 uint64_t largest_received,
381 uint64_t smallest_received) {
382 return client_maker_->MakeAckPacket(packet_number, largest_received,
383 smallest_received);
384 }
385
ConstructClientAckAndRstPacket(uint64_t num,quic::QuicStreamId stream_id,quic::QuicRstStreamErrorCode error_code,uint64_t largest_received,uint64_t smallest_received)386 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
387 uint64_t num,
388 quic::QuicStreamId stream_id,
389 quic::QuicRstStreamErrorCode error_code,
390 uint64_t largest_received,
391 uint64_t smallest_received) {
392 return client_maker_->MakeAckAndRstPacket(
393 num, false, stream_id, error_code, largest_received, smallest_received);
394 }
395
ConstructClientRstPacket(uint64_t num,quic::QuicStreamId stream_id,quic::QuicRstStreamErrorCode error_code)396 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
397 uint64_t num,
398 quic::QuicStreamId stream_id,
399 quic::QuicRstStreamErrorCode error_code) {
400 return client_maker_->MakeRstPacket(num, false, stream_id, error_code,
401 /*include_stop_sending_if_v99=*/true);
402 }
403
404 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientAckAndConnectionClosePacket(uint64_t num,uint64_t largest_received,uint64_t smallest_received,quic::QuicErrorCode quic_error,const std::string & quic_error_details,uint64_t frame_type)405 ConstructClientAckAndConnectionClosePacket(
406 uint64_t num,
407 uint64_t largest_received,
408 uint64_t smallest_received,
409 quic::QuicErrorCode quic_error,
410 const std::string& quic_error_details,
411 uint64_t frame_type) {
412 return client_maker_->MakeAckAndConnectionClosePacket(
413 num, false, largest_received, smallest_received, quic_error,
414 quic_error_details, frame_type);
415 }
416
ConstructServerRstPacket(uint64_t num,bool include_version,quic::QuicStreamId stream_id,quic::QuicRstStreamErrorCode error_code)417 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
418 uint64_t num,
419 bool include_version,
420 quic::QuicStreamId stream_id,
421 quic::QuicRstStreamErrorCode error_code) {
422 return server_maker_.MakeRstPacket(num, include_version, stream_id,
423 error_code);
424 }
425
ConstructInitialSettingsPacket(uint64_t packet_number)426 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
427 uint64_t packet_number) {
428 return client_maker_->MakeInitialSettingsPacket(packet_number);
429 }
430
ConstructServerAckPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received)431 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
432 uint64_t packet_number,
433 uint64_t largest_received,
434 uint64_t smallest_received) {
435 return server_maker_.MakeAckPacket(packet_number, largest_received,
436 smallest_received);
437 }
438
ConstructClientPriorityPacket(uint64_t packet_number,bool should_include_version,quic::QuicStreamId id,quic::QuicStreamId parent_stream_id,RequestPriority request_priority)439 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
440 uint64_t packet_number,
441 bool should_include_version,
442 quic::QuicStreamId id,
443 quic::QuicStreamId parent_stream_id,
444 RequestPriority request_priority) {
445 return client_maker_->MakePriorityPacket(
446 packet_number, should_include_version, id, parent_stream_id,
447 ConvertRequestPriorityToQuicPriority(request_priority));
448 }
449
450 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientPriorityFramesPacket(uint64_t packet_number,bool should_include_version,const std::vector<QuicTestPacketMaker::Http2StreamDependency> & priority_frames)451 ConstructClientPriorityFramesPacket(
452 uint64_t packet_number,
453 bool should_include_version,
454 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
455 priority_frames) {
456 return client_maker_->MakeMultiplePriorityFramesPacket(
457 packet_number, should_include_version, priority_frames);
458 }
459
460 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientAckAndPriorityFramesPacket(uint64_t packet_number,bool should_include_version,uint64_t largest_received,uint64_t smallest_received,const std::vector<QuicTestPacketMaker::Http2StreamDependency> & priority_frames)461 ConstructClientAckAndPriorityFramesPacket(
462 uint64_t packet_number,
463 bool should_include_version,
464 uint64_t largest_received,
465 uint64_t smallest_received,
466 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
467 priority_frames) {
468 return client_maker_->MakeAckAndMultiplePriorityFramesPacket(
469 packet_number, should_include_version, largest_received,
470 smallest_received, priority_frames);
471 }
472
ConstructClientAckAndPriorityPacket(uint64_t packet_number,bool should_include_version,uint64_t largest_received,uint64_t smallest_received,quic::QuicStreamId id,quic::QuicStreamId parent_stream_id,RequestPriority request_priority)473 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckAndPriorityPacket(
474 uint64_t packet_number,
475 bool should_include_version,
476 uint64_t largest_received,
477 uint64_t smallest_received,
478 quic::QuicStreamId id,
479 quic::QuicStreamId parent_stream_id,
480 RequestPriority request_priority) {
481 return client_maker_->MakeAckAndPriorityPacket(
482 packet_number, should_include_version, largest_received,
483 smallest_received, id, parent_stream_id,
484 ConvertRequestPriorityToQuicPriority(request_priority));
485 }
486
487 // Uses default QuicTestPacketMaker.
GetRequestHeaders(const std::string & method,const std::string & scheme,const std::string & path)488 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
489 const std::string& scheme,
490 const std::string& path) {
491 return GetRequestHeaders(method, scheme, path, client_maker_.get());
492 }
493
494 // Uses customized QuicTestPacketMaker.
GetRequestHeaders(const std::string & method,const std::string & scheme,const std::string & path,QuicTestPacketMaker * maker)495 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
496 const std::string& scheme,
497 const std::string& path,
498 QuicTestPacketMaker* maker) {
499 return maker->GetRequestHeaders(method, scheme, path);
500 }
501
ConnectRequestHeaders(const std::string & host_port)502 spdy::Http2HeaderBlock ConnectRequestHeaders(const std::string& host_port) {
503 return client_maker_->ConnectRequestHeaders(host_port);
504 }
505
GetResponseHeaders(const std::string & status)506 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status) {
507 return server_maker_.GetResponseHeaders(status);
508 }
509
510 // Appends alt_svc headers in the response headers.
GetResponseHeaders(const std::string & status,const std::string & alt_svc)511 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status,
512 const std::string& alt_svc) {
513 return server_maker_.GetResponseHeaders(status, alt_svc);
514 }
515
ConstructServerDataPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool should_include_version,bool fin,absl::string_view data)516 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
517 uint64_t packet_number,
518 quic::QuicStreamId stream_id,
519 bool should_include_version,
520 bool fin,
521 absl::string_view data) {
522 return server_maker_.MakeDataPacket(packet_number, stream_id,
523 should_include_version, fin, data);
524 }
525
ConstructClientDataPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool should_include_version,bool fin,absl::string_view data)526 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
527 uint64_t packet_number,
528 quic::QuicStreamId stream_id,
529 bool should_include_version,
530 bool fin,
531 absl::string_view data) {
532 return client_maker_->MakeDataPacket(packet_number, stream_id,
533 should_include_version, fin, data);
534 }
535
ConstructClientAckAndDataPacket(uint64_t packet_number,bool include_version,quic::QuicStreamId stream_id,uint64_t largest_received,uint64_t smallest_received,bool fin,absl::string_view data)536 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
537 uint64_t packet_number,
538 bool include_version,
539 quic::QuicStreamId stream_id,
540 uint64_t largest_received,
541 uint64_t smallest_received,
542 bool fin,
543 absl::string_view data) {
544 return client_maker_->MakeAckAndDataPacket(packet_number, include_version,
545 stream_id, largest_received,
546 smallest_received, fin, data);
547 }
548
549 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientRequestHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool should_include_version,bool fin,spdy::Http2HeaderBlock headers)550 ConstructClientRequestHeadersPacket(uint64_t packet_number,
551 quic::QuicStreamId stream_id,
552 bool should_include_version,
553 bool fin,
554 spdy::Http2HeaderBlock headers) {
555 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
556 should_include_version, fin,
557 std::move(headers), 0);
558 }
559
560 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientRequestHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool should_include_version,bool fin,spdy::Http2HeaderBlock headers,quic::QuicStreamId parent_stream_id)561 ConstructClientRequestHeadersPacket(uint64_t packet_number,
562 quic::QuicStreamId stream_id,
563 bool should_include_version,
564 bool fin,
565 spdy::Http2HeaderBlock headers,
566 quic::QuicStreamId parent_stream_id) {
567 return ConstructClientRequestHeadersPacket(
568 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
569 std::move(headers), parent_stream_id);
570 }
571
572 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientRequestHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool should_include_version,bool fin,RequestPriority request_priority,spdy::Http2HeaderBlock headers,quic::QuicStreamId parent_stream_id)573 ConstructClientRequestHeadersPacket(uint64_t packet_number,
574 quic::QuicStreamId stream_id,
575 bool should_include_version,
576 bool fin,
577 RequestPriority request_priority,
578 spdy::Http2HeaderBlock headers,
579 quic::QuicStreamId parent_stream_id) {
580 spdy::SpdyPriority priority =
581 ConvertRequestPriorityToQuicPriority(request_priority);
582 return client_maker_->MakeRequestHeadersPacket(
583 packet_number, stream_id, should_include_version, fin, priority,
584 std::move(headers), parent_stream_id, nullptr);
585 }
586
587 std::unique_ptr<quic::QuicReceivedPacket>
ConstructClientRequestHeadersAndDataFramesPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool should_include_version,bool fin,RequestPriority request_priority,spdy::Http2HeaderBlock headers,quic::QuicStreamId parent_stream_id,size_t * spdy_headers_frame_length,const std::vector<std::string> & data_writes)588 ConstructClientRequestHeadersAndDataFramesPacket(
589 uint64_t packet_number,
590 quic::QuicStreamId stream_id,
591 bool should_include_version,
592 bool fin,
593 RequestPriority request_priority,
594 spdy::Http2HeaderBlock headers,
595 quic::QuicStreamId parent_stream_id,
596 size_t* spdy_headers_frame_length,
597 const std::vector<std::string>& data_writes) {
598 spdy::SpdyPriority priority =
599 ConvertRequestPriorityToQuicPriority(request_priority);
600 return client_maker_->MakeRequestHeadersAndMultipleDataFramesPacket(
601 packet_number, stream_id, should_include_version, fin, priority,
602 std::move(headers), parent_stream_id, spdy_headers_frame_length,
603 data_writes);
604 }
605
ConstructServerPushPromisePacket(uint64_t packet_number,quic::QuicStreamId stream_id,quic::QuicStreamId promised_stream_id,bool should_include_version,spdy::Http2HeaderBlock headers)606 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
607 uint64_t packet_number,
608 quic::QuicStreamId stream_id,
609 quic::QuicStreamId promised_stream_id,
610 bool should_include_version,
611 spdy::Http2HeaderBlock headers) {
612 return server_maker_.MakePushPromisePacket(
613 packet_number, stream_id, promised_stream_id, should_include_version,
614 false, std::move(headers), nullptr);
615 }
616
617 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructServerResponseHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool should_include_version,bool fin,spdy::Http2HeaderBlock headers)618 ConstructServerResponseHeadersPacket(uint64_t packet_number,
619 quic::QuicStreamId stream_id,
620 bool should_include_version,
621 bool fin,
622 spdy::Http2HeaderBlock headers) {
623 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
624 should_include_version, fin,
625 std::move(headers), nullptr);
626 }
627
ConstructDataFrame(base::StringPiece body)628 std::string ConstructDataFrame(base::StringPiece body) {
629 return ConstructDataFrameForVersion(body, version_);
630 }
631
CreateSession(const quic::ParsedQuicVersionVector & supported_versions)632 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
633 session_params_.enable_quic = true;
634 context_.params()->supported_versions = supported_versions;
635 context_.params()->headers_include_h2_stream_dependency =
636 client_headers_include_h2_stream_dependency_;
637
638 session_context_.quic_context = &context_;
639 session_context_.client_socket_factory = &socket_factory_;
640 session_context_.quic_crypto_client_stream_factory =
641 &crypto_client_stream_factory_;
642 session_context_.host_resolver = &host_resolver_;
643 session_context_.cert_verifier = &cert_verifier_;
644 session_context_.transport_security_state = &transport_security_state_;
645 session_context_.cert_transparency_verifier =
646 cert_transparency_verifier_.get();
647 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
648 session_context_.socket_performance_watcher_factory =
649 &test_socket_performance_watcher_factory_;
650 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
651 session_context_.ssl_config_service = ssl_config_service_.get();
652 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
653 session_context_.http_server_properties = http_server_properties_.get();
654 session_context_.net_log = net_log_.bound().net_log();
655
656 session_.reset(new HttpNetworkSession(session_params_, session_context_));
657 session_->quic_stream_factory()
658 ->set_is_quic_known_to_work_on_current_network(true);
659 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
660 spdy_pool_peer.SetEnableSendingInitialData(false);
661 }
662
CreateSession()663 void CreateSession() { return CreateSession(supported_versions_); }
664
CheckWasQuicResponse(HttpNetworkTransaction * trans,const std::string & status_line,const quic::ParsedQuicVersion & version)665 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
666 const std::string& status_line,
667 const quic::ParsedQuicVersion& version) {
668 const HttpResponseInfo* response = trans->GetResponseInfo();
669 ASSERT_TRUE(response != nullptr);
670 ASSERT_TRUE(response->headers.get() != nullptr);
671 EXPECT_EQ(status_line, response->headers->GetStatusLine());
672 EXPECT_TRUE(response->was_fetched_via_spdy);
673 EXPECT_TRUE(response->was_alpn_negotiated);
674 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version),
675 response->connection_info);
676 }
677
CheckWasQuicResponse(HttpNetworkTransaction * trans,const std::string & status_line)678 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
679 const std::string& status_line) {
680 CheckWasQuicResponse(trans, status_line, version_);
681 }
682
CheckWasQuicResponse(HttpNetworkTransaction * trans)683 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
684 CheckWasQuicResponse(trans, "HTTP/1.1 200 OK", version_);
685 }
686
CheckResponsePort(HttpNetworkTransaction * trans,uint16_t port)687 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
688 const HttpResponseInfo* response = trans->GetResponseInfo();
689 ASSERT_TRUE(response != nullptr);
690 EXPECT_EQ(port, response->remote_endpoint.port());
691 }
692
CheckWasHttpResponse(HttpNetworkTransaction * trans)693 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
694 const HttpResponseInfo* response = trans->GetResponseInfo();
695 ASSERT_TRUE(response != nullptr);
696 ASSERT_TRUE(response->headers.get() != nullptr);
697 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
698 EXPECT_FALSE(response->was_fetched_via_spdy);
699 EXPECT_FALSE(response->was_alpn_negotiated);
700 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
701 response->connection_info);
702 }
703
CheckWasSpdyResponse(HttpNetworkTransaction * trans)704 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
705 const HttpResponseInfo* response = trans->GetResponseInfo();
706 ASSERT_TRUE(response != nullptr);
707 ASSERT_TRUE(response->headers.get() != nullptr);
708 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
709 EXPECT_TRUE(response->was_fetched_via_spdy);
710 EXPECT_TRUE(response->was_alpn_negotiated);
711 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
712 response->connection_info);
713 }
714
CheckResponseData(HttpNetworkTransaction * trans,const std::string & expected)715 void CheckResponseData(HttpNetworkTransaction* trans,
716 const std::string& expected) {
717 std::string response_data;
718 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
719 EXPECT_EQ(expected, response_data);
720 }
721
RunTransaction(HttpNetworkTransaction * trans)722 void RunTransaction(HttpNetworkTransaction* trans) {
723 TestCompletionCallback callback;
724 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
726 EXPECT_THAT(callback.WaitForResult(), IsOk());
727 }
728
SendRequestAndExpectHttpResponse(const std::string & expected)729 void SendRequestAndExpectHttpResponse(const std::string& expected) {
730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
731 RunTransaction(&trans);
732 CheckWasHttpResponse(&trans);
733 CheckResponseData(&trans, expected);
734 }
735
SendRequestAndExpectHttpResponseFromProxy(const std::string & expected,bool used_proxy,uint16_t port)736 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
737 bool used_proxy,
738 uint16_t port) {
739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
740 RunTransaction(&trans);
741 CheckWasHttpResponse(&trans);
742 CheckResponsePort(&trans, port);
743 CheckResponseData(&trans, expected);
744 if (used_proxy) {
745 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
746 } else {
747 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
748 }
749 }
SendRequestAndExpectQuicResponse(const std::string & expected,const std::string & status_line)750 void SendRequestAndExpectQuicResponse(const std::string& expected,
751 const std::string& status_line) {
752 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
753 status_line);
754 }
755
SendRequestAndExpectQuicResponse(const std::string & expected)756 void SendRequestAndExpectQuicResponse(const std::string& expected) {
757 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
758 }
759
SendRequestAndExpectQuicResponseFromProxyOnPort(const std::string & expected,uint16_t port)760 void SendRequestAndExpectQuicResponseFromProxyOnPort(
761 const std::string& expected,
762 uint16_t port) {
763 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
764 }
765
AddQuicAlternateProtocolMapping(MockCryptoClientStream::HandshakeMode handshake_mode,const NetworkIsolationKey & network_isolation_key=NetworkIsolationKey ())766 void AddQuicAlternateProtocolMapping(
767 MockCryptoClientStream::HandshakeMode handshake_mode,
768 const NetworkIsolationKey& network_isolation_key =
769 NetworkIsolationKey()) {
770 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
771 url::SchemeHostPort server(request_.url);
772 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
773 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
774 http_server_properties_->SetQuicAlternativeService(
775 server, network_isolation_key, alternative_service, expiration,
776 supported_versions_);
777 }
778
AddQuicRemoteAlternativeServiceMapping(MockCryptoClientStream::HandshakeMode handshake_mode,const HostPortPair & alternative)779 void AddQuicRemoteAlternativeServiceMapping(
780 MockCryptoClientStream::HandshakeMode handshake_mode,
781 const HostPortPair& alternative) {
782 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
783 url::SchemeHostPort server(request_.url);
784 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
785 alternative.port());
786 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
787 http_server_properties_->SetQuicAlternativeService(
788 server, NetworkIsolationKey(), alternative_service, expiration,
789 supported_versions_);
790 }
791
ExpectBrokenAlternateProtocolMapping(const NetworkIsolationKey & network_isolation_key=NetworkIsolationKey ())792 void ExpectBrokenAlternateProtocolMapping(
793 const NetworkIsolationKey& network_isolation_key =
794 NetworkIsolationKey()) {
795 const url::SchemeHostPort server(request_.url);
796 const AlternativeServiceInfoVector alternative_service_info_vector =
797 http_server_properties_->GetAlternativeServiceInfos(
798 server, network_isolation_key);
799 EXPECT_EQ(1u, alternative_service_info_vector.size());
800 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
801 alternative_service_info_vector[0].alternative_service(),
802 network_isolation_key));
803 }
804
ExpectQuicAlternateProtocolMapping(const NetworkIsolationKey & network_isolation_key=NetworkIsolationKey ())805 void ExpectQuicAlternateProtocolMapping(
806 const NetworkIsolationKey& network_isolation_key =
807 NetworkIsolationKey()) {
808 const url::SchemeHostPort server(request_.url);
809 const AlternativeServiceInfoVector alternative_service_info_vector =
810 http_server_properties_->GetAlternativeServiceInfos(
811 server, network_isolation_key);
812 EXPECT_EQ(1u, alternative_service_info_vector.size());
813 EXPECT_EQ(
814 kProtoQUIC,
815 alternative_service_info_vector[0].alternative_service().protocol);
816 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
817 alternative_service_info_vector[0].alternative_service(),
818 network_isolation_key));
819 }
820
AddHangingNonAlternateProtocolSocketData()821 void AddHangingNonAlternateProtocolSocketData() {
822 std::unique_ptr<StaticSocketDataProvider> hanging_data;
823 hanging_data.reset(new StaticSocketDataProvider());
824 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
825 hanging_data->set_connect_data(hanging_connect);
826 hanging_data_.push_back(std::move(hanging_data));
827 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
828 }
829
SetUpTestForRetryConnectionOnAlternateNetwork()830 void SetUpTestForRetryConnectionOnAlternateNetwork() {
831 context_.params()->migrate_sessions_on_network_change_v2 = true;
832 context_.params()->migrate_sessions_early_v2 = true;
833 context_.params()->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
842 // Adds a new socket data provider for an HTTP request, and runs a request,
843 // expecting it to be used.
AddHttpDataAndRunRequest()844 void AddHttpDataAndRunRequest() {
845 MockWrite http_writes[] = {
846 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
847 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
848 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
849
850 MockRead http_reads[] = {
851 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
852 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
853 MockRead(SYNCHRONOUS, 5, "http used"),
854 // Connection closed.
855 MockRead(SYNCHRONOUS, OK, 6)};
856 SequencedSocketData http_data(http_reads, http_writes);
857 socket_factory_.AddSocketDataProvider(&http_data);
858 SSLSocketDataProvider ssl_data(ASYNC, OK);
859 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
860 SendRequestAndExpectHttpResponse("http used");
861 EXPECT_TRUE(http_data.AllWriteDataConsumed());
862 EXPECT_TRUE(http_data.AllReadDataConsumed());
863 }
864
865 // Adds a new socket data provider for a QUIC request, and runs a request,
866 // expecting it to be used. The new QUIC session is not closed.
AddQuicDataAndRunRequest()867 void AddQuicDataAndRunRequest() {
868 QuicTestPacketMaker client_maker(
869 version_,
870 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
871 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
872 client_headers_include_h2_stream_dependency_);
873 QuicTestPacketMaker server_maker(
874 version_,
875 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
876 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
877 false);
878 MockQuicData quic_data(version_);
879 int packet_number = 1;
880 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
881 if (VersionUsesHttp3(version_.transport_version)) {
882 quic_data.AddWrite(
883 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
884 }
885 quic_data.AddWrite(
886 SYNCHRONOUS,
887 client_maker.MakeRequestHeadersPacket(
888 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
889 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
890 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
891 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
892 quic_data.AddRead(
893 ASYNC, server_maker.MakeResponseHeadersPacket(
894 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
895 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
896 quic_data.AddRead(
897 ASYNC, server_maker.MakeDataPacket(
898 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
899 true, ConstructDataFrame("quic used")));
900 // Don't care about the final ack.
901 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
902 // No more data to read.
903 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
904 quic_data.AddSocketDataToFactory(&socket_factory_);
905 SendRequestAndExpectQuicResponse("quic used");
906
907 EXPECT_TRUE(quic_data.AllReadDataConsumed());
908 }
909
GetNthClientInitiatedBidirectionalStreamId(int n) const910 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
911 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
912 version_.transport_version, n);
913 }
914
GetNthServerInitiatedUnidirectionalStreamId(int n) const915 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
916 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
917 version_.transport_version, n);
918 }
919
GetQpackDecoderStreamId() const920 quic::QuicStreamId GetQpackDecoderStreamId() const {
921 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
922 version_.transport_version, 1);
923 }
924
StreamCancellationQpackDecoderInstruction(int n) const925 std::string StreamCancellationQpackDecoderInstruction(int n) const {
926 return StreamCancellationQpackDecoderInstruction(n, true);
927 }
928
StreamCancellationQpackDecoderInstruction(int n,bool create_stream) const929 std::string StreamCancellationQpackDecoderInstruction(
930 int n,
931 bool create_stream) const {
932 const quic::QuicStreamId cancelled_stream_id =
933 GetNthClientInitiatedBidirectionalStreamId(n);
934 EXPECT_LT(cancelled_stream_id, 63u);
935
936 const unsigned char opcode = 0x40;
937 if (create_stream) {
938 return {0x03, opcode | static_cast<unsigned char>(cancelled_stream_id)};
939 } else {
940 return {opcode | static_cast<unsigned char>(cancelled_stream_id)};
941 }
942 }
943
AddCertificate(SSLSocketDataProvider * ssl_data)944 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
945 ssl_data->ssl_info.cert =
946 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
947 ASSERT_TRUE(ssl_data->ssl_info.cert);
948 }
949
SendRequestAndExpectQuicResponseMaybeFromProxy(const std::string & expected,bool used_proxy,uint16_t port,const std::string & status_line,const quic::ParsedQuicVersion & version)950 void SendRequestAndExpectQuicResponseMaybeFromProxy(
951 const std::string& expected,
952 bool used_proxy,
953 uint16_t port,
954 const std::string& status_line,
955 const quic::ParsedQuicVersion& version) {
956 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
957 RunTransaction(&trans);
958 CheckWasQuicResponse(&trans, status_line, version);
959 CheckResponsePort(&trans, port);
960 CheckResponseData(&trans, expected);
961 if (used_proxy) {
962 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
963 } else {
964 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
965 }
966 }
967
968 const quic::ParsedQuicVersion version_;
969 const bool client_headers_include_h2_stream_dependency_;
970 quic::ParsedQuicVersionVector supported_versions_;
971 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
972 MockQuicContext context_;
973 std::unique_ptr<QuicTestPacketMaker> client_maker_;
974 QuicTestPacketMaker server_maker_;
975 scoped_refptr<TestTaskRunner> quic_task_runner_;
976 std::unique_ptr<HttpNetworkSession> session_;
977 MockClientSocketFactory socket_factory_;
978 ProofVerifyDetailsChromium verify_details_;
979 MockCryptoClientStreamFactory crypto_client_stream_factory_;
980 MockHostResolver host_resolver_;
981 MockCertVerifier cert_verifier_;
982 TransportSecurityState transport_security_state_;
983 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
984 DefaultCTPolicyEnforcer ct_policy_enforcer_;
985 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
986 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
987 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
988 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
989 std::unique_ptr<HttpServerProperties> http_server_properties_;
990 HttpNetworkSession::Params session_params_;
991 HttpNetworkSession::Context session_context_;
992 HttpRequestInfo request_;
993 RecordingBoundTestNetLog net_log_;
994 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
995 SSLSocketDataProvider ssl_data_;
996 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
997
998 private:
SendRequestAndExpectQuicResponseMaybeFromProxy(const std::string & expected,bool used_proxy,uint16_t port,const std::string & status_line)999 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1000 const std::string& expected,
1001 bool used_proxy,
1002 uint16_t port,
1003 const std::string& status_line) {
1004 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1005 status_line, version_);
1006 }
1007
SendRequestAndExpectQuicResponseMaybeFromProxy(const std::string & expected,bool used_proxy,uint16_t port)1008 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1009 const std::string& expected,
1010 bool used_proxy,
1011 uint16_t port) {
1012 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1013 "HTTP/1.1 200 OK", version_);
1014 }
1015 };
1016
1017 INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1018 QuicNetworkTransactionTest,
1019 ::testing::ValuesIn(GetTestParams()),
1020 ::testing::PrintToStringParamName());
1021
1022 // TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1023 // kAppendInitiatingFrameOriginToNetworkIsolationKey.
1024
TEST_P(QuicNetworkTransactionTest,WriteErrorHandshakeConfirmed)1025 TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
1026 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1027 base::HistogramTester histograms;
1028 context_.params()->origins_to_force_quic_on.insert(
1029 HostPortPair::FromString("mail.example.org:443"));
1030 crypto_client_stream_factory_.set_handshake_mode(
1031 MockCryptoClientStream::CONFIRM_HANDSHAKE);
1032
1033 MockQuicData mock_quic_data(version_);
1034 if (VersionUsesHttp3(version_.transport_version))
1035 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
1036 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1037 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1038 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1039
1040 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1041
1042 CreateSession();
1043
1044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1045 TestCompletionCallback callback;
1046 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1048 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1049
1050 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1051 -ERR_INTERNET_DISCONNECTED, 1);
1052 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1053 -ERR_INTERNET_DISCONNECTED, 1);
1054 }
1055
TEST_P(QuicNetworkTransactionTest,WriteErrorHandshakeConfirmedAsync)1056 TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
1057 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1058 base::HistogramTester histograms;
1059 context_.params()->origins_to_force_quic_on.insert(
1060 HostPortPair::FromString("mail.example.org:443"));
1061 crypto_client_stream_factory_.set_handshake_mode(
1062 MockCryptoClientStream::CONFIRM_HANDSHAKE);
1063
1064 MockQuicData mock_quic_data(version_);
1065 if (VersionUsesHttp3(version_.transport_version))
1066 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
1067 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1068 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1069 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1070
1071 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1072
1073 CreateSession();
1074
1075 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1076 TestCompletionCallback callback;
1077 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1078 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1079 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1080
1081 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1082 -ERR_INTERNET_DISCONNECTED, 1);
1083 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1084 -ERR_INTERNET_DISCONNECTED, 1);
1085 }
1086
TEST_P(QuicNetworkTransactionTest,SocketWatcherEnabled)1087 TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
1088 context_.params()->origins_to_force_quic_on.insert(
1089 HostPortPair::FromString("mail.example.org:443"));
1090
1091 MockQuicData mock_quic_data(version_);
1092 int packet_num = 1;
1093 if (VersionUsesHttp3(version_.transport_version)) {
1094 mock_quic_data.AddWrite(SYNCHRONOUS,
1095 ConstructInitialSettingsPacket(packet_num++));
1096 }
1097 mock_quic_data.AddWrite(
1098 SYNCHRONOUS,
1099 ConstructClientRequestHeadersPacket(
1100 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1101 true, GetRequestHeaders("GET", "https", "/")));
1102 mock_quic_data.AddRead(
1103 ASYNC, ConstructServerResponseHeadersPacket(
1104 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1105 GetResponseHeaders("200 OK")));
1106 mock_quic_data.AddRead(
1107 ASYNC, ConstructServerDataPacket(
1108 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1109 ConstructDataFrame("hello!")));
1110 mock_quic_data.AddWrite(SYNCHRONOUS,
1111 ConstructClientAckPacket(packet_num++, 2, 1));
1112 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1113
1114 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1115
1116 CreateSession();
1117 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1118
1119 EXPECT_FALSE(
1120 test_socket_performance_watcher_factory_.rtt_notification_received());
1121 SendRequestAndExpectQuicResponse("hello!");
1122 EXPECT_TRUE(
1123 test_socket_performance_watcher_factory_.rtt_notification_received());
1124 }
1125
TEST_P(QuicNetworkTransactionTest,SocketWatcherDisabled)1126 TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
1127 context_.params()->origins_to_force_quic_on.insert(
1128 HostPortPair::FromString("mail.example.org:443"));
1129
1130 MockQuicData mock_quic_data(version_);
1131 int packet_num = 1;
1132 if (VersionUsesHttp3(version_.transport_version)) {
1133 mock_quic_data.AddWrite(SYNCHRONOUS,
1134 ConstructInitialSettingsPacket(packet_num++));
1135 }
1136 mock_quic_data.AddWrite(
1137 SYNCHRONOUS,
1138 ConstructClientRequestHeadersPacket(
1139 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1140 true, GetRequestHeaders("GET", "https", "/")));
1141 mock_quic_data.AddRead(
1142 ASYNC, ConstructServerResponseHeadersPacket(
1143 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1144 GetResponseHeaders("200 OK")));
1145 mock_quic_data.AddRead(
1146 ASYNC, ConstructServerDataPacket(
1147 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1148 ConstructDataFrame("hello!")));
1149 mock_quic_data.AddWrite(SYNCHRONOUS,
1150 ConstructClientAckPacket(packet_num++, 2, 1));
1151 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1152
1153 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1154
1155 CreateSession();
1156 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1157
1158 EXPECT_FALSE(
1159 test_socket_performance_watcher_factory_.rtt_notification_received());
1160 SendRequestAndExpectQuicResponse("hello!");
1161 EXPECT_FALSE(
1162 test_socket_performance_watcher_factory_.rtt_notification_received());
1163 }
1164
TEST_P(QuicNetworkTransactionTest,ForceQuic)1165 TEST_P(QuicNetworkTransactionTest, ForceQuic) {
1166 context_.params()->origins_to_force_quic_on.insert(
1167 HostPortPair::FromString("mail.example.org:443"));
1168
1169 MockQuicData mock_quic_data(version_);
1170 int packet_num = 1;
1171 if (VersionUsesHttp3(version_.transport_version)) {
1172 mock_quic_data.AddWrite(SYNCHRONOUS,
1173 ConstructInitialSettingsPacket(packet_num++));
1174 }
1175 mock_quic_data.AddWrite(
1176 SYNCHRONOUS,
1177 ConstructClientRequestHeadersPacket(
1178 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1179 true, GetRequestHeaders("GET", "https", "/")));
1180 mock_quic_data.AddRead(
1181 ASYNC, ConstructServerResponseHeadersPacket(
1182 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1183 GetResponseHeaders("200 OK")));
1184 mock_quic_data.AddRead(
1185 ASYNC, ConstructServerDataPacket(
1186 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1187 ConstructDataFrame("hello!")));
1188 mock_quic_data.AddWrite(SYNCHRONOUS,
1189 ConstructClientAckPacket(packet_num++, 2, 1));
1190 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1191
1192 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1193
1194 CreateSession();
1195
1196 SendRequestAndExpectQuicResponse("hello!");
1197
1198 // Check that the NetLog was filled reasonably.
1199 auto entries = net_log_.GetEntries();
1200 EXPECT_LT(0u, entries.size());
1201
1202 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
1203 int pos = ExpectLogContainsSomewhere(
1204 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1205 NetLogEventPhase::NONE);
1206 EXPECT_LT(0, pos);
1207
1208 // ... and also a TYPE_QUIC_SESSION_PACKET_SENT.
1209 pos = ExpectLogContainsSomewhere(entries, 0,
1210 NetLogEventType::QUIC_SESSION_PACKET_SENT,
1211 NetLogEventPhase::NONE);
1212 EXPECT_LT(0, pos);
1213
1214 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
1215 pos = ExpectLogContainsSomewhere(
1216 entries, 0,
1217 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1218 NetLogEventPhase::NONE);
1219 EXPECT_LT(0, pos);
1220
1221 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
1222
1223 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1224 pos = ExpectLogContainsSomewhere(
1225 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1226 NetLogEventPhase::NONE);
1227 EXPECT_LT(0, pos);
1228
1229 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
1230 pos = ExpectLogContainsSomewhere(
1231 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1232 NetLogEventPhase::NONE);
1233 EXPECT_LT(0, pos);
1234
1235 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
1236 if (quic::VersionUsesHttp3(version_.transport_version)) {
1237 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1238 static_cast<quic::QuicStreamId>(log_stream_id));
1239 } else {
1240 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1241 static_cast<quic::QuicStreamId>(log_stream_id));
1242 }
1243 }
1244
1245 // Regression test for https://crbug.com/1043531.
TEST_P(QuicNetworkTransactionTest,ResetOnEmptyResponseHeaders)1246 TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
1247 if (!quic::VersionUsesHttp3(version_.transport_version)) {
1248 return;
1249 }
1250
1251 context_.params()->origins_to_force_quic_on.insert(
1252 HostPortPair::FromString("mail.example.org:443"));
1253
1254 MockQuicData mock_quic_data(version_);
1255 int write_packet_num = 1;
1256 mock_quic_data.AddWrite(SYNCHRONOUS,
1257 ConstructInitialSettingsPacket(write_packet_num++));
1258 mock_quic_data.AddWrite(
1259 SYNCHRONOUS,
1260 ConstructClientRequestHeadersPacket(
1261 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1262 true, true, GetRequestHeaders("GET", "https", "/")));
1263
1264 const quic::QuicStreamId request_stream_id =
1265 GetNthClientInitiatedBidirectionalStreamId(0);
1266 spdy::Http2HeaderBlock empty_response_headers;
1267 const std::string response_data = server_maker_.QpackEncodeHeaders(
1268 request_stream_id, std::move(empty_response_headers), nullptr);
1269 uint64_t read_packet_num = 1;
1270 mock_quic_data.AddRead(
1271 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
1272 false, false, response_data));
1273 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1274
1275 mock_quic_data.AddWrite(
1276 ASYNC,
1277 ConstructClientAckAndDataPacket(
1278 write_packet_num++, true, GetQpackDecoderStreamId(), 1, 1, false,
1279 StreamCancellationQpackDecoderInstruction(request_stream_id)));
1280
1281 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1282
1283 CreateSession();
1284
1285 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1286 TestCompletionCallback callback;
1287 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1289 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_INVALID_RESPONSE));
1290 }
1291
TEST_P(QuicNetworkTransactionTest,LargeResponseHeaders)1292 TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
1293 context_.params()->origins_to_force_quic_on.insert(
1294 HostPortPair::FromString("mail.example.org:443"));
1295
1296 MockQuicData mock_quic_data(version_);
1297 int packet_num = 1;
1298 if (VersionUsesHttp3(version_.transport_version)) {
1299 mock_quic_data.AddWrite(SYNCHRONOUS,
1300 ConstructInitialSettingsPacket(packet_num++));
1301 }
1302 mock_quic_data.AddWrite(
1303 SYNCHRONOUS,
1304 ConstructClientRequestHeadersPacket(
1305 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1306 true, GetRequestHeaders("GET", "https", "/")));
1307 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200 OK");
1308 response_headers["key1"] = std::string(30000, 'A');
1309 response_headers["key2"] = std::string(30000, 'A');
1310 response_headers["key3"] = std::string(30000, 'A');
1311 response_headers["key4"] = std::string(30000, 'A');
1312 response_headers["key5"] = std::string(30000, 'A');
1313 response_headers["key6"] = std::string(30000, 'A');
1314 response_headers["key7"] = std::string(30000, 'A');
1315 response_headers["key8"] = std::string(30000, 'A');
1316 quic::QuicStreamId stream_id;
1317 std::string response_data;
1318 if (quic::VersionUsesHttp3(version_.transport_version)) {
1319 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1320 response_data = server_maker_.QpackEncodeHeaders(
1321 stream_id, std::move(response_headers), nullptr);
1322 } else {
1323 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1324 spdy::SpdyHeadersIR headers_frame(
1325 GetNthClientInitiatedBidirectionalStreamId(0),
1326 std::move(response_headers));
1327 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1328 spdy::SpdySerializedFrame spdy_frame =
1329 response_framer.SerializeFrame(headers_frame);
1330 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1331 }
1332
1333 uint64_t packet_number = 1;
1334 size_t chunk_size = 1200;
1335 for (size_t offset = 0; offset < response_data.length();
1336 offset += chunk_size) {
1337 size_t len = std::min(chunk_size, response_data.length() - offset);
1338 mock_quic_data.AddRead(
1339 ASYNC, ConstructServerDataPacket(
1340 packet_number++, stream_id, false, false,
1341 absl::string_view(response_data.data() + offset, len)));
1342 }
1343
1344 mock_quic_data.AddRead(
1345 ASYNC, ConstructServerDataPacket(
1346 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
1347 false, true, ConstructDataFrame("hello!")));
1348 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1349 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
1350 mock_quic_data.AddWrite(
1351 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3));
1352
1353 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1354
1355 CreateSession();
1356
1357 SendRequestAndExpectQuicResponse("hello!");
1358 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1359 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1360 }
1361
TEST_P(QuicNetworkTransactionTest,TooLargeResponseHeaders)1362 TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
1363 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1364 context_.params()->origins_to_force_quic_on.insert(
1365 HostPortPair::FromString("mail.example.org:443"));
1366
1367 MockQuicData mock_quic_data(version_);
1368 int packet_num = 1;
1369 if (VersionUsesHttp3(version_.transport_version)) {
1370 mock_quic_data.AddWrite(SYNCHRONOUS,
1371 ConstructInitialSettingsPacket(packet_num++));
1372 }
1373 mock_quic_data.AddWrite(
1374 SYNCHRONOUS,
1375 ConstructClientRequestHeadersPacket(
1376 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1377 true, GetRequestHeaders("GET", "https", "/")));
1378
1379 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200 OK");
1380 response_headers["key1"] = std::string(30000, 'A');
1381 response_headers["key2"] = std::string(30000, 'A');
1382 response_headers["key3"] = std::string(30000, 'A');
1383 response_headers["key4"] = std::string(30000, 'A');
1384 response_headers["key5"] = std::string(30000, 'A');
1385 response_headers["key6"] = std::string(30000, 'A');
1386 response_headers["key7"] = std::string(30000, 'A');
1387 response_headers["key8"] = std::string(30000, 'A');
1388 response_headers["key9"] = std::string(30000, 'A');
1389
1390 quic::QuicStreamId stream_id;
1391 std::string response_data;
1392 if (quic::VersionUsesHttp3(version_.transport_version)) {
1393 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1394 response_data = server_maker_.QpackEncodeHeaders(
1395 stream_id, std::move(response_headers), nullptr);
1396 } else {
1397 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1398 spdy::SpdyHeadersIR headers_frame(
1399 GetNthClientInitiatedBidirectionalStreamId(0),
1400 std::move(response_headers));
1401 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1402 spdy::SpdySerializedFrame spdy_frame =
1403 response_framer.SerializeFrame(headers_frame);
1404 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1405 }
1406
1407 uint64_t packet_number = 1;
1408 size_t chunk_size = 1200;
1409 for (size_t offset = 0; offset < response_data.length();
1410 offset += chunk_size) {
1411 size_t len = std::min(chunk_size, response_data.length() - offset);
1412 mock_quic_data.AddRead(
1413 ASYNC, ConstructServerDataPacket(
1414 packet_number++, stream_id, false, false,
1415 absl::string_view(response_data.data() + offset, len)));
1416 }
1417
1418 mock_quic_data.AddRead(
1419 ASYNC, ConstructServerDataPacket(
1420 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
1421 false, true, ConstructDataFrame("hello!")));
1422 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1423 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
1424 mock_quic_data.AddWrite(
1425 ASYNC, ConstructClientAckAndRstPacket(
1426 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1427 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3));
1428
1429 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1430
1431 CreateSession();
1432
1433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1434 TestCompletionCallback callback;
1435 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1437 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1438 }
1439
TEST_P(QuicNetworkTransactionTest,ForceQuicForAll)1440 TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
1441 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
1442
1443 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1444
1445 MockQuicData mock_quic_data(version_);
1446 int packet_num = 1;
1447 if (VersionUsesHttp3(version_.transport_version)) {
1448 mock_quic_data.AddWrite(SYNCHRONOUS,
1449 ConstructInitialSettingsPacket(packet_num++));
1450 }
1451 mock_quic_data.AddWrite(
1452 SYNCHRONOUS,
1453 ConstructClientRequestHeadersPacket(
1454 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1455 true, GetRequestHeaders("GET", "https", "/")));
1456 mock_quic_data.AddRead(
1457 ASYNC, ConstructServerResponseHeadersPacket(
1458 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1459 GetResponseHeaders("200 OK")));
1460 mock_quic_data.AddRead(
1461 ASYNC, ConstructServerDataPacket(
1462 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1463 ConstructDataFrame("hello!")));
1464 mock_quic_data.AddWrite(SYNCHRONOUS,
1465 ConstructClientAckPacket(packet_num++, 2, 1));
1466 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1467
1468 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1469
1470 CreateSession();
1471
1472 SendRequestAndExpectQuicResponse("hello!");
1473 EXPECT_TRUE(
1474 test_socket_performance_watcher_factory_.rtt_notification_received());
1475 }
1476
1477 // Regression test for https://crbug.com/695225
1478 TEST_P(QuicNetworkTransactionTest, 408Response) {
1479 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
1480
1481 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1482
1483 MockQuicData mock_quic_data(version_);
1484 int packet_num = 1;
1485 if (VersionUsesHttp3(version_.transport_version)) {
1486 mock_quic_data.AddWrite(SYNCHRONOUS,
1487 ConstructInitialSettingsPacket(packet_num++));
1488 }
1489 mock_quic_data.AddWrite(
1490 SYNCHRONOUS,
1491 ConstructClientRequestHeadersPacket(
1492 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1493 true, GetRequestHeaders("GET", "https", "/")));
1494 mock_quic_data.AddRead(
1495 ASYNC, ConstructServerResponseHeadersPacket(
1496 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1497 GetResponseHeaders("408 Request Timeout")));
1498 mock_quic_data.AddRead(
1499 ASYNC, ConstructServerDataPacket(
1500 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1501 ConstructDataFrame("hello!")));
1502 mock_quic_data.AddWrite(SYNCHRONOUS,
1503 ConstructClientAckPacket(packet_num++, 2, 1));
1504 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1505
1506 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1507
1508 CreateSession();
1509
1510 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408 Request Timeout");
1511 }
1512
TEST_P(QuicNetworkTransactionTest,QuicProxy)1513 TEST_P(QuicNetworkTransactionTest, QuicProxy) {
1514 session_params_.enable_quic = true;
1515 proxy_resolution_service_ =
1516 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1517 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
1518
1519 MockQuicData mock_quic_data(version_);
1520 int packet_num = 1;
1521 if (VersionUsesHttp3(version_.transport_version)) {
1522 mock_quic_data.AddWrite(SYNCHRONOUS,
1523 ConstructInitialSettingsPacket(packet_num++));
1524 }
1525 mock_quic_data.AddWrite(
1526 SYNCHRONOUS,
1527 ConstructClientRequestHeadersPacket(
1528 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1529 true, GetRequestHeaders("GET", "http", "/")));
1530 mock_quic_data.AddRead(
1531 ASYNC, ConstructServerResponseHeadersPacket(
1532 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1533 GetResponseHeaders("200 OK")));
1534 mock_quic_data.AddRead(
1535 ASYNC, ConstructServerDataPacket(
1536 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1537 ConstructDataFrame("hello!")));
1538 mock_quic_data.AddWrite(SYNCHRONOUS,
1539 ConstructClientAckPacket(packet_num++, 2, 1));
1540 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1541 mock_quic_data.AddRead(ASYNC, 0); // EOF
1542
1543 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1544
1545 EXPECT_FALSE(
1546 test_socket_performance_watcher_factory_.rtt_notification_received());
1547 // There is no need to set up an alternate protocol job, because
1548 // no attempt will be made to speak to the proxy over TCP.
1549
1550 request_.url = GURL("http://mail.example.org/");
1551 CreateSession();
1552
1553 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1554 EXPECT_TRUE(
1555 test_socket_performance_watcher_factory_.rtt_notification_received());
1556 }
1557
1558 // Regression test for https://crbug.com/492458. Test that for an HTTP
1559 // connection through a QUIC proxy, the certificate exhibited by the proxy is
1560 // checked against the proxy hostname, not the origin hostname.
TEST_P(QuicNetworkTransactionTest,QuicProxyWithCert)1561 TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
1562 const std::string origin_host = "mail.example.com";
1563 const std::string proxy_host = "www.example.org";
1564
1565 session_params_.enable_quic = true;
1566 proxy_resolution_service_ =
1567 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1568 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
1569
1570 client_maker_->set_hostname(origin_host);
1571 MockQuicData mock_quic_data(version_);
1572 int packet_num = 1;
1573 if (VersionUsesHttp3(version_.transport_version)) {
1574 mock_quic_data.AddWrite(SYNCHRONOUS,
1575 ConstructInitialSettingsPacket(packet_num++));
1576 }
1577 mock_quic_data.AddWrite(
1578 SYNCHRONOUS,
1579 ConstructClientRequestHeadersPacket(
1580 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1581 true, GetRequestHeaders("GET", "http", "/")));
1582 mock_quic_data.AddRead(
1583 ASYNC, ConstructServerResponseHeadersPacket(
1584 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1585 GetResponseHeaders("200 OK")));
1586 mock_quic_data.AddRead(
1587 ASYNC, ConstructServerDataPacket(
1588 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1589 ConstructDataFrame("hello!")));
1590 mock_quic_data.AddWrite(SYNCHRONOUS,
1591 ConstructClientAckPacket(packet_num++, 2, 1));
1592 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1593 mock_quic_data.AddRead(ASYNC, 0);
1594 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1595
1596 scoped_refptr<X509Certificate> cert(
1597 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1598 ASSERT_TRUE(cert.get());
1599 // This certificate is valid for the proxy, but not for the origin.
1600 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1601 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
1602 ProofVerifyDetailsChromium verify_details;
1603 verify_details.cert_verify_result.verified_cert = cert;
1604 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1605 ProofVerifyDetailsChromium verify_details2;
1606 verify_details2.cert_verify_result.verified_cert = cert;
1607 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
1608
1609 request_.url = GURL("http://" + origin_host);
1610 AddHangingNonAlternateProtocolSocketData();
1611 CreateSession();
1612 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1613 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1614 }
1615
TEST_P(QuicNetworkTransactionTest,AlternativeServicesDifferentHost)1616 TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
1617 context_.params()->allow_remote_alt_svc = true;
1618 HostPortPair origin("www.example.org", 443);
1619 HostPortPair alternative("mail.example.org", 443);
1620
1621 base::FilePath certs_dir = GetTestCertsDirectory();
1622 scoped_refptr<X509Certificate> cert(
1623 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1624 ASSERT_TRUE(cert.get());
1625 // TODO(rch): the connection should be "to" the origin, so if the cert is
1626 // valid for the origin but not the alternative, that should work too.
1627 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1628 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
1629 ProofVerifyDetailsChromium verify_details;
1630 verify_details.cert_verify_result.verified_cert = cert;
1631 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1632
1633 client_maker_->set_hostname(origin.host());
1634 MockQuicData mock_quic_data(version_);
1635
1636 int packet_num = 1;
1637 if (VersionUsesHttp3(version_.transport_version)) {
1638 mock_quic_data.AddWrite(SYNCHRONOUS,
1639 ConstructInitialSettingsPacket(packet_num++));
1640 }
1641 mock_quic_data.AddWrite(
1642 SYNCHRONOUS,
1643 ConstructClientRequestHeadersPacket(
1644 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1645 true, GetRequestHeaders("GET", "https", "/")));
1646 mock_quic_data.AddRead(
1647 ASYNC, ConstructServerResponseHeadersPacket(
1648 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1649 GetResponseHeaders("200 OK")));
1650 mock_quic_data.AddRead(
1651 ASYNC, ConstructServerDataPacket(
1652 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1653 ConstructDataFrame("hello!")));
1654 mock_quic_data.AddWrite(SYNCHRONOUS,
1655 ConstructClientAckPacket(packet_num++, 2, 1));
1656 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1657 mock_quic_data.AddRead(ASYNC, 0);
1658 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1659
1660 request_.url = GURL("https://" + origin.host());
1661 AddQuicRemoteAlternativeServiceMapping(
1662 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
1663 AddHangingNonAlternateProtocolSocketData();
1664 CreateSession();
1665
1666 SendRequestAndExpectQuicResponse("hello!");
1667 }
1668
TEST_P(QuicNetworkTransactionTest,DoNotUseQuicForUnsupportedVersion)1669 TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
1670 quic::ParsedQuicVersion unsupported_version =
1671 quic::ParsedQuicVersion::Unsupported();
1672 // Add support for another QUIC version besides |version_|. Also find an
1673 // unsupported version.
1674 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
1675 if (version == version_)
1676 continue;
1677 if (supported_versions_.size() != 2) {
1678 supported_versions_.push_back(version);
1679 continue;
1680 }
1681 unsupported_version = version;
1682 break;
1683 }
1684 ASSERT_EQ(2u, supported_versions_.size());
1685 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
1686
1687 // Set up alternative service to use QUIC with a version that is not
1688 // supported.
1689 url::SchemeHostPort server(request_.url);
1690 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1691 443);
1692 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1693 http_server_properties_->SetQuicAlternativeService(
1694 server, NetworkIsolationKey(), alternative_service, expiration,
1695 {unsupported_version});
1696
1697 AlternativeServiceInfoVector alt_svc_info_vector =
1698 http_server_properties_->GetAlternativeServiceInfos(
1699 server, NetworkIsolationKey());
1700 EXPECT_EQ(1u, alt_svc_info_vector.size());
1701 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1702 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1703 EXPECT_EQ(unsupported_version,
1704 alt_svc_info_vector[0].advertised_versions()[0]);
1705
1706 // First request should still be sent via TCP as the QUIC version advertised
1707 // in the stored AlternativeService is not supported by the client. However,
1708 // the response from the server will advertise new Alt-Svc with supported
1709 // versions.
1710 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
1711 MockRead http_reads[] = {
1712 MockRead("HTTP/1.1 200 OK\r\n"),
1713 MockRead(altsvc_header.c_str()),
1714 MockRead("\r\n"),
1715 MockRead("hello world"),
1716 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1717 MockRead(ASYNC, OK)};
1718
1719 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1720 socket_factory_.AddSocketDataProvider(&http_data);
1721 AddCertificate(&ssl_data_);
1722 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1723
1724 // Second request should be sent via QUIC as a new list of verions supported
1725 // by the client has been advertised by the server.
1726 MockQuicData mock_quic_data(version_);
1727 int packet_num = 1;
1728 if (VersionUsesHttp3(version_.transport_version)) {
1729 mock_quic_data.AddWrite(SYNCHRONOUS,
1730 ConstructInitialSettingsPacket(packet_num++));
1731 }
1732 mock_quic_data.AddWrite(
1733 SYNCHRONOUS,
1734 ConstructClientRequestHeadersPacket(
1735 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1736 true, GetRequestHeaders("GET", "https", "/")));
1737 mock_quic_data.AddRead(
1738 ASYNC, ConstructServerResponseHeadersPacket(
1739 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1740 GetResponseHeaders("200 OK")));
1741 mock_quic_data.AddRead(
1742 ASYNC, ConstructServerDataPacket(
1743 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1744 ConstructDataFrame("hello!")));
1745 mock_quic_data.AddWrite(SYNCHRONOUS,
1746 ConstructClientAckPacket(packet_num++, 2, 1));
1747 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1748 mock_quic_data.AddRead(ASYNC, 0); // EOF
1749
1750 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1751
1752 AddHangingNonAlternateProtocolSocketData();
1753
1754 CreateSession(supported_versions_);
1755
1756 SendRequestAndExpectHttpResponse("hello world");
1757 SendRequestAndExpectQuicResponse("hello!");
1758
1759 // Check alternative service list is updated with new versions.
1760 alt_svc_info_vector =
1761 session_->http_server_properties()->GetAlternativeServiceInfos(
1762 server, NetworkIsolationKey());
1763 // Versions that support the legacy Google-specific Alt-Svc format are sent in
1764 // a single Alt-Svc entry, therefore they are accumulated in a single
1765 // AlternativeServiceInfo, whereas more recent versions all have their own
1766 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
1767 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
1768 for (const auto& alt_svc_info : alt_svc_info_vector) {
1769 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
1770 for (const auto& version : alt_svc_info.advertised_versions()) {
1771 if (std::find(alt_svc_negotiated_versions.begin(),
1772 alt_svc_negotiated_versions.end(),
1773 version) == alt_svc_negotiated_versions.end()) {
1774 alt_svc_negotiated_versions.push_back(version);
1775 }
1776 }
1777 }
1778
1779 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
1780 auto version_compare = [](const quic::ParsedQuicVersion& a,
1781 const quic::ParsedQuicVersion& b) {
1782 return std::tie(a.transport_version, a.handshake_protocol) <
1783 std::tie(b.transport_version, b.handshake_protocol);
1784 };
1785 std::sort(supported_versions_.begin(), supported_versions_.end(),
1786 version_compare);
1787 std::sort(alt_svc_negotiated_versions.begin(),
1788 alt_svc_negotiated_versions.end(), version_compare);
1789 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
1790 alt_svc_negotiated_versions.begin()));
1791 }
1792
1793 // Regression test for https://crbug.com/546991.
1794 // The server might not be able to serve a request on an alternative connection,
1795 // and might send a 421 Misdirected Request response status to indicate this.
1796 // HttpNetworkTransaction should reset the request and retry without using
1797 // alternative services.
TEST_P(QuicNetworkTransactionTest,RetryMisdirectedRequest)1798 TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1799 // Set up alternative service to use QUIC.
1800 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1801 // that overrides |enable_alternative_services|.
1802 url::SchemeHostPort server(request_.url);
1803 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1804 443);
1805 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1806 http_server_properties_->SetQuicAlternativeService(
1807 server, NetworkIsolationKey(), alternative_service, expiration,
1808 supported_versions_);
1809
1810 // First try: The alternative job uses QUIC and reports an HTTP 421
1811 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1812 // paused at Connect(), so it will never exit the socket pool. This ensures
1813 // that the alternate job always wins the race and keeps whether the
1814 // |http_data| exits the socket pool before the main job is aborted
1815 // deterministic. The first main job gets aborted without the socket pool ever
1816 // dispensing the socket, making it available for the second try.
1817 MockQuicData mock_quic_data(version_);
1818 int packet_num = 1;
1819 if (VersionUsesHttp3(version_.transport_version)) {
1820 mock_quic_data.AddWrite(SYNCHRONOUS,
1821 ConstructInitialSettingsPacket(packet_num++));
1822 }
1823 mock_quic_data.AddWrite(
1824 SYNCHRONOUS,
1825 ConstructClientRequestHeadersPacket(
1826 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1827 true, GetRequestHeaders("GET", "https", "/")));
1828 mock_quic_data.AddRead(
1829 ASYNC, ConstructServerResponseHeadersPacket(
1830 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1831 GetResponseHeaders("421")));
1832 mock_quic_data.AddRead(ASYNC, OK);
1833 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1834
1835 // Second try: The main job uses TCP, and there is no alternate job. Once the
1836 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1837 // the main job of the second request. It then succeeds over HTTP/1.1.
1838 // Note that if there was an alternative QUIC Job created for the second try,
1839 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1840 // Therefore this test ensures that no alternative Job is created on retry.
1841 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1842 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1843 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1844 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1845 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1846 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
1847 reads, writes);
1848 socket_factory_.AddSocketDataProvider(&http_data);
1849 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1850
1851 CreateSession();
1852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1853
1854 // Run until |mock_quic_data| has failed and |http_data| has paused.
1855 TestCompletionCallback callback;
1856 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1858 base::RunLoop().RunUntilIdle();
1859
1860 // |mock_quic_data| must have run to completion.
1861 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1862 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1863
1864 // Now that the QUIC data has been consumed, unblock |http_data|.
1865 http_data.socket()->OnConnectComplete(MockConnect());
1866
1867 // The retry logic must hide the 421 status. The transaction succeeds on
1868 // |http_data|.
1869 EXPECT_THAT(callback.WaitForResult(), IsOk());
1870 CheckWasHttpResponse(&trans);
1871 CheckResponsePort(&trans, 443);
1872 CheckResponseData(&trans, "hello!");
1873 }
1874
TEST_P(QuicNetworkTransactionTest,ForceQuicWithErrorConnecting)1875 TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
1876 context_.params()->origins_to_force_quic_on.insert(
1877 HostPortPair::FromString("mail.example.org:443"));
1878
1879 MockQuicData mock_quic_data1(version_);
1880 if (VersionUsesHttp3(version_.transport_version))
1881 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
1882 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1883 client_maker_->Reset();
1884 MockQuicData mock_quic_data2(version_);
1885 if (VersionUsesHttp3(version_.transport_version))
1886 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
1887 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
1888 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1889 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
1890
1891 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1892 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
1893
1894 CreateSession();
1895
1896 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
1897 for (size_t i = 0; i < 2; ++i) {
1898 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1899 TestCompletionCallback callback;
1900 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1902 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
1903 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
1904
1905 NetErrorDetails details;
1906 trans.PopulateNetErrorDetails(&details);
1907 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
1908 }
1909 }
1910
TEST_P(QuicNetworkTransactionTest,DoNotForceQuicForHttps)1911 TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1912 // Attempt to "force" quic on 443, which will not be honored.
1913 context_.params()->origins_to_force_quic_on.insert(
1914 HostPortPair::FromString("www.google.com:443"));
1915
1916 MockRead http_reads[] = {
1917 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1918 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1919 MockRead(ASYNC, OK)};
1920
1921 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
1922 socket_factory_.AddSocketDataProvider(&data);
1923 SSLSocketDataProvider ssl(ASYNC, OK);
1924 socket_factory_.AddSSLSocketDataProvider(&ssl);
1925
1926 CreateSession();
1927
1928 SendRequestAndExpectHttpResponse("hello world");
1929 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
1930 }
1931
TEST_P(QuicNetworkTransactionTest,UseAlternativeServiceForQuic)1932 TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
1933 MockRead http_reads[] = {
1934 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1935 MockRead("hello world"),
1936 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1937 MockRead(ASYNC, OK)};
1938
1939 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1940 socket_factory_.AddSocketDataProvider(&http_data);
1941 AddCertificate(&ssl_data_);
1942 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1943
1944 MockQuicData mock_quic_data(version_);
1945 int packet_num = 1;
1946 if (VersionUsesHttp3(version_.transport_version)) {
1947 mock_quic_data.AddWrite(SYNCHRONOUS,
1948 ConstructInitialSettingsPacket(packet_num++));
1949 }
1950 mock_quic_data.AddWrite(
1951 SYNCHRONOUS,
1952 ConstructClientRequestHeadersPacket(
1953 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1954 true, GetRequestHeaders("GET", "https", "/")));
1955 mock_quic_data.AddRead(
1956 ASYNC, ConstructServerResponseHeadersPacket(
1957 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1958 GetResponseHeaders("200 OK")));
1959 mock_quic_data.AddRead(
1960 ASYNC, ConstructServerDataPacket(
1961 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1962 ConstructDataFrame("hello!")));
1963 mock_quic_data.AddWrite(SYNCHRONOUS,
1964 ConstructClientAckPacket(packet_num++, 2, 1));
1965 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1966 mock_quic_data.AddRead(ASYNC, 0); // EOF
1967
1968 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1969
1970 AddHangingNonAlternateProtocolSocketData();
1971 CreateSession();
1972
1973 SendRequestAndExpectHttpResponse("hello world");
1974 SendRequestAndExpectQuicResponse("hello!");
1975 }
1976
TEST_P(QuicNetworkTransactionTest,UseIetfAlternativeServiceForQuic)1977 TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
1978 std::string alt_svc_header =
1979 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1980 MockRead http_reads[] = {
1981 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1982 MockRead("hello world"),
1983 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1984 MockRead(ASYNC, OK)};
1985
1986 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1987 socket_factory_.AddSocketDataProvider(&http_data);
1988 AddCertificate(&ssl_data_);
1989 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1990
1991 MockQuicData mock_quic_data(version_);
1992 int packet_num = 1;
1993 if (VersionUsesHttp3(version_.transport_version)) {
1994 mock_quic_data.AddWrite(SYNCHRONOUS,
1995 ConstructInitialSettingsPacket(packet_num++));
1996 }
1997 mock_quic_data.AddWrite(
1998 SYNCHRONOUS,
1999 ConstructClientRequestHeadersPacket(
2000 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2001 true, GetRequestHeaders("GET", "https", "/")));
2002 mock_quic_data.AddRead(
2003 ASYNC, ConstructServerResponseHeadersPacket(
2004 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2005 GetResponseHeaders("200 OK")));
2006 mock_quic_data.AddRead(
2007 ASYNC, ConstructServerDataPacket(
2008 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2009 ConstructDataFrame("hello!")));
2010 mock_quic_data.AddWrite(SYNCHRONOUS,
2011 ConstructClientAckPacket(packet_num++, 2, 1));
2012 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2013 mock_quic_data.AddRead(ASYNC, 0); // EOF
2014
2015 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2016
2017 AddHangingNonAlternateProtocolSocketData();
2018 CreateSession();
2019
2020 SendRequestAndExpectHttpResponse("hello world");
2021 SendRequestAndExpectQuicResponse("hello!");
2022 }
2023
2024 // Much like above, but makes sure NetworkIsolationKey is respected.
TEST_P(QuicNetworkTransactionTest,UseAlternativeServiceForQuicWithNetworkIsolationKey)2025 TEST_P(QuicNetworkTransactionTest,
2026 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
2027 base::test::ScopedFeatureList feature_list;
2028 feature_list.InitWithFeatures(
2029 // enabled_features
2030 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2031 features::kPartitionConnectionsByNetworkIsolationKey},
2032 // disabled_features
2033 {});
2034 // Since HttpServerProperties caches the feature value, have to create a new
2035 // one.
2036 http_server_properties_ = std::make_unique<HttpServerProperties>();
2037
2038 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2039 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2040 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2041 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2042
2043 MockRead http_reads[] = {
2044 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2045 MockRead("hello world"),
2046 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2047 MockRead(ASYNC, OK)};
2048
2049 AddCertificate(&ssl_data_);
2050
2051 // Request with empty NetworkIsolationKey.
2052 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2053 socket_factory_.AddSocketDataProvider(&http_data1);
2054 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2055
2056 // First request with kNetworkIsolationKey1.
2057 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2058 socket_factory_.AddSocketDataProvider(&http_data2);
2059 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2060
2061 // Request with kNetworkIsolationKey2.
2062 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2063 socket_factory_.AddSocketDataProvider(&http_data3);
2064 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2065
2066 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2067 // alternative service infrmation has been received in this context before.
2068 MockQuicData mock_quic_data(version_);
2069 int packet_num = 1;
2070 if (VersionUsesHttp3(version_.transport_version)) {
2071 mock_quic_data.AddWrite(SYNCHRONOUS,
2072 ConstructInitialSettingsPacket(packet_num++));
2073 }
2074 mock_quic_data.AddWrite(
2075 SYNCHRONOUS,
2076 ConstructClientRequestHeadersPacket(
2077 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2078 true, GetRequestHeaders("GET", "https", "/")));
2079 mock_quic_data.AddRead(
2080 ASYNC, ConstructServerResponseHeadersPacket(
2081 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2082 GetResponseHeaders("200 OK")));
2083 mock_quic_data.AddRead(
2084 ASYNC, ConstructServerDataPacket(
2085 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2086 ConstructDataFrame("hello!")));
2087 mock_quic_data.AddWrite(SYNCHRONOUS,
2088 ConstructClientAckPacket(packet_num++, 2, 1));
2089 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2090 mock_quic_data.AddRead(ASYNC, 0); // EOF
2091
2092 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2093
2094 AddHangingNonAlternateProtocolSocketData();
2095 CreateSession();
2096
2097 // This is first so that the test fails if alternative service info is
2098 // written with the right NetworkIsolationKey, but always queried with an
2099 // empty one.
2100 request_.network_isolation_key = NetworkIsolationKey();
2101 SendRequestAndExpectHttpResponse("hello world");
2102 request_.network_isolation_key = kNetworkIsolationKey1;
2103 SendRequestAndExpectHttpResponse("hello world");
2104 request_.network_isolation_key = kNetworkIsolationKey2;
2105 SendRequestAndExpectHttpResponse("hello world");
2106
2107 // Only use QUIC when using a NetworkIsolationKey which has been used when
2108 // alternative service information was received.
2109 request_.network_isolation_key = kNetworkIsolationKey1;
2110 SendRequestAndExpectQuicResponse("hello!");
2111 }
2112
TEST_P(QuicNetworkTransactionTest,UseAlternativeServiceWithVersionForQuic1)2113 TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2114 // Both server advertises and client supports two QUIC versions.
2115 // Only |version_| is advertised and supported.
2116 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2117 // PacketMakers are using |version_|.
2118
2119 // Add support for another QUIC version besides |version_| on the client side.
2120 // Also find a different version advertised by the server.
2121 quic::ParsedQuicVersion advertised_version_2 =
2122 quic::ParsedQuicVersion::Unsupported();
2123 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
2124 if (version == version_)
2125 continue;
2126 if (supported_versions_.size() != 2) {
2127 supported_versions_.push_back(version);
2128 continue;
2129 }
2130 advertised_version_2 = version;
2131 break;
2132 }
2133 ASSERT_EQ(2u, supported_versions_.size());
2134 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
2135
2136 std::string QuicAltSvcWithVersionHeader =
2137 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2138 quic::AlpnForVersion(advertised_version_2).c_str(),
2139 quic::AlpnForVersion(version_).c_str());
2140
2141 MockRead http_reads[] = {
2142 MockRead("HTTP/1.1 200 OK\r\n"),
2143 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2144 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2145 MockRead(ASYNC, OK)};
2146
2147 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2148 socket_factory_.AddSocketDataProvider(&http_data);
2149 AddCertificate(&ssl_data_);
2150 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2151
2152 MockQuicData mock_quic_data(version_);
2153 int packet_num = 1;
2154 if (VersionUsesHttp3(version_.transport_version)) {
2155 mock_quic_data.AddWrite(SYNCHRONOUS,
2156 ConstructInitialSettingsPacket(packet_num++));
2157 }
2158 mock_quic_data.AddWrite(
2159 SYNCHRONOUS,
2160 ConstructClientRequestHeadersPacket(
2161 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2162 true, GetRequestHeaders("GET", "https", "/")));
2163 mock_quic_data.AddRead(
2164 ASYNC, ConstructServerResponseHeadersPacket(
2165 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2166 GetResponseHeaders("200 OK")));
2167 mock_quic_data.AddRead(
2168 ASYNC, ConstructServerDataPacket(
2169 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2170 ConstructDataFrame("hello!")));
2171 mock_quic_data.AddWrite(SYNCHRONOUS,
2172 ConstructClientAckPacket(packet_num++, 2, 1));
2173 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2174 mock_quic_data.AddRead(ASYNC, 0); // EOF
2175
2176 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2177
2178 AddHangingNonAlternateProtocolSocketData();
2179 CreateSession(supported_versions_);
2180
2181 SendRequestAndExpectHttpResponse("hello world");
2182 SendRequestAndExpectQuicResponse("hello!");
2183 }
2184
TEST_P(QuicNetworkTransactionTest,PickQuicVersionWhenMultipleVersionsAreSupported)2185 TEST_P(QuicNetworkTransactionTest,
2186 PickQuicVersionWhenMultipleVersionsAreSupported) {
2187 // Client and server both support more than one QUIC_VERSION.
2188 // Client prefers |version_|, and then common_version_2.
2189 // Server prefers common_version_2, and then |version_|.
2190 // We should honor the server's preference.
2191 // The picked version is verified via checking the version used by the
2192 // TestPacketMakers and the response.
2193
2194 // Find an alternative commonly supported version other than |version_|.
2195 quic::ParsedQuicVersion common_version_2 =
2196 quic::ParsedQuicVersion::Unsupported();
2197 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
2198 if (version != version_) {
2199 common_version_2 = version;
2200 break;
2201 }
2202 }
2203 ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
2204
2205 // Setting up client's preference list: {|version_|, |common_version_2|}.
2206 supported_versions_.clear();
2207 supported_versions_.push_back(version_);
2208 supported_versions_.push_back(common_version_2);
2209
2210 // Setting up server's Alt-Svc header in the following preference order:
2211 // |common_version_2|, |version_|.
2212 std::string QuicAltSvcWithVersionHeader;
2213 quic::ParsedQuicVersion picked_version =
2214 quic::ParsedQuicVersion::Unsupported();
2215 QuicAltSvcWithVersionHeader =
2216 "Alt-Svc: " + quic::AlpnForVersion(common_version_2) +
2217 "=\":443\"; ma=3600, " + quic::AlpnForVersion(version_) +
2218 "=\":443\"; ma=3600\r\n\r\n";
2219 picked_version = common_version_2; // Use server's preference.
2220
2221 MockRead http_reads[] = {
2222 MockRead("HTTP/1.1 200 OK\r\n"),
2223 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2224 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2225 MockRead(ASYNC, OK)};
2226
2227 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2228 socket_factory_.AddSocketDataProvider(&http_data);
2229 AddCertificate(&ssl_data_);
2230 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2231
2232 MockQuicData mock_quic_data(picked_version);
2233
2234 // Reset QuicTestPacket makers as the version picked may not be |version_|.
2235 client_maker_.reset(new QuicTestPacketMaker(
2236 picked_version,
2237 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2238 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
2239 client_headers_include_h2_stream_dependency_));
2240 QuicTestPacketMaker server_maker(
2241 picked_version,
2242 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2243 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
2244 false);
2245
2246 int packet_num = 1;
2247 if (VersionUsesHttp3(picked_version.transport_version)) {
2248 mock_quic_data.AddWrite(SYNCHRONOUS,
2249 ConstructInitialSettingsPacket(packet_num++));
2250 }
2251
2252 quic::QuicStreamId client_stream_0 =
2253 quic::test::GetNthClientInitiatedBidirectionalStreamId(
2254 picked_version.transport_version, 0);
2255 mock_quic_data.AddWrite(SYNCHRONOUS,
2256 ConstructClientRequestHeadersPacket(
2257 packet_num++, client_stream_0, true, true,
2258 GetRequestHeaders("GET", "https", "/")));
2259 mock_quic_data.AddRead(
2260 ASYNC, server_maker.MakeResponseHeadersPacket(
2261 1, client_stream_0, false, false,
2262 server_maker.GetResponseHeaders("200 OK"), nullptr));
2263 mock_quic_data.AddRead(
2264 ASYNC, server_maker.MakeDataPacket(
2265 2, client_stream_0, false, true,
2266 ConstructDataFrameForVersion("hello!", picked_version)));
2267 mock_quic_data.AddWrite(SYNCHRONOUS,
2268 ConstructClientAckPacket(packet_num++, 2, 1));
2269 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2270 mock_quic_data.AddRead(ASYNC, 0); // EOF
2271
2272 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2273
2274 AddHangingNonAlternateProtocolSocketData();
2275 CreateSession(supported_versions_);
2276
2277 SendRequestAndExpectHttpResponse("hello world");
2278 SendRequestAndExpectQuicResponseMaybeFromProxy(
2279 "hello!", false, 443, "HTTP/1.1 200 OK", picked_version);
2280 }
2281
TEST_P(QuicNetworkTransactionTest,UseAlternativeServiceWithProbabilityForQuic)2282 TEST_P(QuicNetworkTransactionTest,
2283 UseAlternativeServiceWithProbabilityForQuic) {
2284 MockRead http_reads[] = {
2285 MockRead("HTTP/1.1 200 OK\r\n"),
2286 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2287 MockRead("hello world"),
2288 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2289 MockRead(ASYNC, OK)};
2290
2291 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2292 socket_factory_.AddSocketDataProvider(&http_data);
2293 AddCertificate(&ssl_data_);
2294 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2295
2296 MockQuicData mock_quic_data(version_);
2297 int packet_num = 1;
2298 if (VersionUsesHttp3(version_.transport_version)) {
2299 mock_quic_data.AddWrite(SYNCHRONOUS,
2300 ConstructInitialSettingsPacket(packet_num++));
2301 }
2302 mock_quic_data.AddWrite(
2303 SYNCHRONOUS,
2304 ConstructClientRequestHeadersPacket(
2305 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2306 true, GetRequestHeaders("GET", "https", "/")));
2307 mock_quic_data.AddRead(
2308 ASYNC, ConstructServerResponseHeadersPacket(
2309 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2310 GetResponseHeaders("200 OK")));
2311 mock_quic_data.AddRead(
2312 ASYNC, ConstructServerDataPacket(
2313 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2314 ConstructDataFrame("hello!")));
2315 mock_quic_data.AddWrite(SYNCHRONOUS,
2316 ConstructClientAckPacket(packet_num++, 2, 1));
2317 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2318 mock_quic_data.AddRead(ASYNC, 0); // EOF
2319
2320 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2321
2322 AddHangingNonAlternateProtocolSocketData();
2323 CreateSession();
2324
2325 SendRequestAndExpectHttpResponse("hello world");
2326 SendRequestAndExpectQuicResponse("hello!");
2327 }
2328
TEST_P(QuicNetworkTransactionTest,SetAlternativeServiceWithScheme)2329 TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2330 MockRead http_reads[] = {
2331 MockRead("HTTP/1.1 200 OK\r\n"),
2332 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2333 MockRead("hello world"),
2334 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2335 MockRead(ASYNC, OK)};
2336
2337 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2338 socket_factory_.AddSocketDataProvider(&http_data);
2339 AddCertificate(&ssl_data_);
2340 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2341
2342 CreateSession();
2343 // Send https request, ignore alternative service advertising if response
2344 // header advertises alternative service for mail.example.org.
2345 request_.url = GURL("https://mail.example.org:443");
2346 SendRequestAndExpectHttpResponse("hello world");
2347 HttpServerProperties* http_server_properties =
2348 session_->http_server_properties();
2349 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2350 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2351 // Check alternative service is set for the correct origin.
2352 EXPECT_EQ(
2353 2u, http_server_properties
2354 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2355 .size());
2356 EXPECT_TRUE(
2357 http_server_properties
2358 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2359 .empty());
2360 }
2361
TEST_P(QuicNetworkTransactionTest,DoNotGetAltSvcForDifferentOrigin)2362 TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2363 MockRead http_reads[] = {
2364 MockRead("HTTP/1.1 200 OK\r\n"),
2365 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2366 MockRead("hello world"),
2367 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2368 MockRead(ASYNC, OK)};
2369
2370 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2371 AddCertificate(&ssl_data_);
2372
2373 socket_factory_.AddSocketDataProvider(&http_data);
2374 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2375 socket_factory_.AddSocketDataProvider(&http_data);
2376 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2377
2378 CreateSession();
2379
2380 // Send https request and set alternative services if response header
2381 // advertises alternative service for mail.example.org.
2382 SendRequestAndExpectHttpResponse("hello world");
2383 HttpServerProperties* http_server_properties =
2384 session_->http_server_properties();
2385
2386 const url::SchemeHostPort https_server(request_.url);
2387 // Check alternative service is set.
2388 EXPECT_EQ(
2389 2u, http_server_properties
2390 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2391 .size());
2392
2393 // Send http request to the same origin but with diffrent scheme, should not
2394 // use QUIC.
2395 request_.url = GURL("http://mail.example.org:443");
2396 SendRequestAndExpectHttpResponse("hello world");
2397 }
2398
TEST_P(QuicNetworkTransactionTest,StoreMutuallySupportedVersionsWhenProcessAltSvc)2399 TEST_P(QuicNetworkTransactionTest,
2400 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
2401 // Add support for another QUIC version besides |version_|.
2402 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
2403 if (version != version_) {
2404 supported_versions_.push_back(version);
2405 break;
2406 }
2407 }
2408
2409 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
2410 MockRead http_reads[] = {
2411 MockRead("HTTP/1.1 200 OK\r\n"),
2412 MockRead(altsvc_header.c_str()),
2413 MockRead("\r\n"),
2414 MockRead("hello world"),
2415 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2416 MockRead(ASYNC, OK)};
2417
2418 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2419 socket_factory_.AddSocketDataProvider(&http_data);
2420 AddCertificate(&ssl_data_);
2421 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2422
2423 MockQuicData mock_quic_data(version_);
2424 int packet_num = 1;
2425 if (VersionUsesHttp3(version_.transport_version)) {
2426 mock_quic_data.AddWrite(SYNCHRONOUS,
2427 ConstructInitialSettingsPacket(packet_num++));
2428 }
2429 mock_quic_data.AddWrite(
2430 SYNCHRONOUS,
2431 ConstructClientRequestHeadersPacket(
2432 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2433 true, GetRequestHeaders("GET", "https", "/")));
2434 mock_quic_data.AddRead(
2435 ASYNC, ConstructServerResponseHeadersPacket(
2436 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2437 GetResponseHeaders("200 OK")));
2438 mock_quic_data.AddRead(
2439 ASYNC, ConstructServerDataPacket(
2440 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2441 ConstructDataFrame("hello!")));
2442 mock_quic_data.AddWrite(SYNCHRONOUS,
2443 ConstructClientAckPacket(packet_num++, 2, 1));
2444 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2445 mock_quic_data.AddRead(ASYNC, 0); // EOF
2446
2447 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2448
2449 AddHangingNonAlternateProtocolSocketData();
2450
2451 CreateSession(supported_versions_);
2452
2453 SendRequestAndExpectHttpResponse("hello world");
2454 SendRequestAndExpectQuicResponse("hello!");
2455
2456 // Alt-Svc header contains all possible versions, so alternative services
2457 // should contain all of |supported_versions_|.
2458 const url::SchemeHostPort https_server(request_.url);
2459 const AlternativeServiceInfoVector alt_svc_info_vector =
2460 session_->http_server_properties()->GetAlternativeServiceInfos(
2461 https_server, NetworkIsolationKey());
2462 // Versions that support the legacy Google-specific Alt-Svc format are sent in
2463 // a single Alt-Svc entry, therefore they are accumulated in a single
2464 // AlternativeServiceInfo, whereas more recent versions all have their own
2465 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
2466 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
2467 for (const auto& alt_svc_info : alt_svc_info_vector) {
2468 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
2469 for (const auto& version : alt_svc_info.advertised_versions()) {
2470 if (std::find(alt_svc_negotiated_versions.begin(),
2471 alt_svc_negotiated_versions.end(),
2472 version) == alt_svc_negotiated_versions.end()) {
2473 alt_svc_negotiated_versions.push_back(version);
2474 }
2475 }
2476 }
2477
2478 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
2479 auto version_compare = [](const quic::ParsedQuicVersion& a,
2480 const quic::ParsedQuicVersion& b) {
2481 return std::tie(a.transport_version, a.handshake_protocol) <
2482 std::tie(b.transport_version, b.handshake_protocol);
2483 };
2484 std::sort(supported_versions_.begin(), supported_versions_.end(),
2485 version_compare);
2486 std::sort(alt_svc_negotiated_versions.begin(),
2487 alt_svc_negotiated_versions.end(), version_compare);
2488 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
2489 alt_svc_negotiated_versions.begin()));
2490 }
2491
TEST_P(QuicNetworkTransactionTest,UseAlternativeServiceAllSupportedVersion)2492 TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
2493 std::string altsvc_header = base::StringPrintf(
2494 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
2495 MockRead http_reads[] = {
2496 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2497 MockRead("hello world"),
2498 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2499 MockRead(ASYNC, OK)};
2500
2501 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2502 socket_factory_.AddSocketDataProvider(&http_data);
2503 AddCertificate(&ssl_data_);
2504 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2505
2506 MockQuicData mock_quic_data(version_);
2507 int packet_num = 1;
2508 if (VersionUsesHttp3(version_.transport_version)) {
2509 mock_quic_data.AddWrite(SYNCHRONOUS,
2510 ConstructInitialSettingsPacket(packet_num++));
2511 }
2512 mock_quic_data.AddWrite(
2513 SYNCHRONOUS,
2514 ConstructClientRequestHeadersPacket(
2515 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2516 true, GetRequestHeaders("GET", "https", "/")));
2517 mock_quic_data.AddRead(
2518 ASYNC, ConstructServerResponseHeadersPacket(
2519 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2520 GetResponseHeaders("200 OK")));
2521 mock_quic_data.AddRead(
2522 ASYNC, ConstructServerDataPacket(
2523 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2524 ConstructDataFrame("hello!")));
2525 mock_quic_data.AddWrite(SYNCHRONOUS,
2526 ConstructClientAckPacket(packet_num++, 2, 1));
2527 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2528 mock_quic_data.AddRead(ASYNC, 0); // EOF
2529
2530 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2531
2532 AddHangingNonAlternateProtocolSocketData();
2533 CreateSession();
2534
2535 SendRequestAndExpectHttpResponse("hello world");
2536 SendRequestAndExpectQuicResponse("hello!");
2537 }
2538
TEST_P(QuicNetworkTransactionTest,GoAwayWithConnectionMigrationOnPortsOnly)2539 TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
2540 if (version_.HasIetfQuicFrames()) {
2541 // GoAway is not available under version 99
2542 return;
2543 }
2544 MockQuicData mock_quic_data(version_);
2545 int packet_num = 1;
2546 if (VersionUsesHttp3(version_.transport_version)) {
2547 mock_quic_data.AddWrite(SYNCHRONOUS,
2548 ConstructInitialSettingsPacket(packet_num++));
2549 }
2550 mock_quic_data.AddWrite(
2551 SYNCHRONOUS,
2552 ConstructClientRequestHeadersPacket(
2553 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2554 true, GetRequestHeaders("GET", "https", "/")));
2555 mock_quic_data.AddRead(
2556 ASYNC, ConstructServerResponseHeadersPacket(
2557 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2558 GetResponseHeaders("200 OK")));
2559 // Read a GoAway packet with
2560 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
2561 mock_quic_data.AddRead(SYNCHRONOUS,
2562 ConstructServerGoAwayPacket(
2563 2, quic::QUIC_ERROR_MIGRATING_PORT,
2564 "connection migration with port change only"));
2565 mock_quic_data.AddWrite(SYNCHRONOUS,
2566 ConstructClientAckPacket(packet_num++, 2, 1));
2567 mock_quic_data.AddRead(
2568 SYNCHRONOUS, ConstructServerDataPacket(
2569 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
2570 true, ConstructDataFrame("hello!")));
2571 mock_quic_data.AddWrite(
2572 SYNCHRONOUS,
2573 ConstructClientAckAndRstPacket(
2574 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2575 quic::QUIC_STREAM_CANCELLED, 3, 3));
2576 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2577 mock_quic_data.AddRead(ASYNC, 0); // EOF
2578
2579 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2580
2581 // The non-alternate protocol job needs to hang in order to guarantee that
2582 // the alternate-protocol job will "win".
2583 AddHangingNonAlternateProtocolSocketData();
2584
2585 // In order for a new QUIC session to be established via alternate-protocol
2586 // without racing an HTTP connection, we need the host resolution to happen
2587 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2588 // connection to the the server, in this test we require confirmation
2589 // before encrypting so the HTTP job will still start.
2590 host_resolver_.set_synchronous_mode(true);
2591 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2592 "");
2593
2594 CreateSession();
2595 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2596 false);
2597 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
2598
2599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2600 TestCompletionCallback callback;
2601 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2603
2604 crypto_client_stream_factory_.last_stream()
2605 ->NotifySessionOneRttKeyAvailable();
2606 EXPECT_THAT(callback.WaitForResult(), IsOk());
2607
2608 // Check whether this transaction is correctly marked as received a go-away
2609 // because of migrating port.
2610 NetErrorDetails details;
2611 EXPECT_FALSE(details.quic_port_migration_detected);
2612 trans.PopulateNetErrorDetails(&details);
2613 EXPECT_TRUE(details.quic_port_migration_detected);
2614 }
2615
2616 // This test verifies that a new QUIC connection will be attempted on the
2617 // alternate network if the original QUIC connection fails with idle timeout
2618 // before handshake is confirmed. If TCP succeeds and QUIC fails on the
2619 // alternate network as well, QUIC is marked as broken and the brokenness will
2620 // not expire when default network changes.
2621 // TODO(fayang): Add time driven idle network detection test.
TEST_P(QuicNetworkTransactionTest,DISABLED_QuicFailsOnBothNetworksWhileTCPSucceeds)2622 TEST_P(QuicNetworkTransactionTest,
2623 DISABLED_QuicFailsOnBothNetworksWhileTCPSucceeds) {
2624 if (version_.UsesTls()) {
2625 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2626 return;
2627 }
2628 SetUpTestForRetryConnectionOnAlternateNetwork();
2629
2630 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2631
2632 // The request will initially go out over QUIC.
2633 MockQuicData quic_data(version_);
2634 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2635 int packet_num = 1;
2636 quic_data.AddWrite(SYNCHRONOUS,
2637 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
2638 // Retransmit the handshake messages.
2639 quic_data.AddWrite(SYNCHRONOUS,
2640 client_maker_->MakeDummyCHLOPacket(packet_num++));
2641 quic_data.AddWrite(SYNCHRONOUS,
2642 client_maker_->MakeDummyCHLOPacket(packet_num++));
2643 quic_data.AddWrite(SYNCHRONOUS,
2644 client_maker_->MakeDummyCHLOPacket(packet_num++));
2645 quic_data.AddWrite(SYNCHRONOUS,
2646 client_maker_->MakeDummyCHLOPacket(packet_num++));
2647 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2648 quic_data.AddWrite(SYNCHRONOUS,
2649 client_maker_->MakeConnectionClosePacket(
2650 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2651 "No recent network activity after 4s. Timeout:4s"));
2652 quic_data.AddSocketDataToFactory(&socket_factory_);
2653
2654 // Add successful TCP data so that TCP job will succeed.
2655 MockWrite http_writes[] = {
2656 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2657 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2658 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2659
2660 MockRead http_reads[] = {
2661 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2662 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2663 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2664 SequencedSocketData http_data(http_reads, http_writes);
2665 socket_factory_.AddSocketDataProvider(&http_data);
2666 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2667
2668 // Add data for the second QUIC connection to fail.
2669 MockQuicData quic_data2(version_);
2670 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2671 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2672 quic_data2.AddSocketDataToFactory(&socket_factory_);
2673
2674 // Resolve the host resolution synchronously.
2675 host_resolver_.set_synchronous_mode(true);
2676 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2677 "");
2678
2679 CreateSession();
2680 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2681 false);
2682 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2683 QuicStreamFactoryPeer::SetAlarmFactory(
2684 session_->quic_stream_factory(),
2685 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2686 context_.clock()));
2687 // Add alternate protocol mapping to race QUIC and TCP.
2688 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2689 // peer.
2690 AddQuicAlternateProtocolMapping(
2691 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2692
2693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2694 TestCompletionCallback callback;
2695 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2697
2698 // Pump the message loop to get the request started.
2699 // Request will be served with TCP job.
2700 base::RunLoop().RunUntilIdle();
2701 EXPECT_THAT(callback.WaitForResult(), IsOk());
2702 CheckResponseData(&trans, "TCP succeeds");
2703
2704 // Fast forward to idle timeout the original connection. A new connection will
2705 // be kicked off on the alternate network.
2706 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2707 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2708 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2709
2710 // Run the message loop to execute posted tasks, which will report job status.
2711 base::RunLoop().RunUntilIdle();
2712
2713 // Verify that QUIC is marked as broken.
2714 ExpectBrokenAlternateProtocolMapping();
2715
2716 // Deliver a message to notify the new network becomes default, the brokenness
2717 // will not expire as QUIC is broken on both networks.
2718 scoped_mock_change_notifier_->mock_network_change_notifier()
2719 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2720 ExpectBrokenAlternateProtocolMapping();
2721
2722 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2723 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2724 }
2725
2726 // This test verifies that a new QUIC connection will be attempted on the
2727 // alternate network if the original QUIC connection fails with idle timeout
2728 // before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2729 // alternate network, QUIC is marked as broken. The brokenness will expire when
2730 // the default network changes.
2731 // TODO(fayang): Add time driven idle network detection test.
TEST_P(QuicNetworkTransactionTest,DISABLED_RetryOnAlternateNetworkWhileTCPSucceeds)2732 TEST_P(QuicNetworkTransactionTest,
2733 DISABLED_RetryOnAlternateNetworkWhileTCPSucceeds) {
2734 if (version_.UsesTls()) {
2735 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2736 return;
2737 }
2738
2739 SetUpTestForRetryConnectionOnAlternateNetwork();
2740
2741 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2742
2743 // The request will initially go out over QUIC.
2744 MockQuicData quic_data(version_);
2745 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2746 int packet_num = 1;
2747 quic_data.AddWrite(SYNCHRONOUS,
2748 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
2749 // Retransmit the handshake messages.
2750 quic_data.AddWrite(SYNCHRONOUS,
2751 client_maker_->MakeDummyCHLOPacket(packet_num++));
2752 quic_data.AddWrite(SYNCHRONOUS,
2753 client_maker_->MakeDummyCHLOPacket(packet_num++));
2754 quic_data.AddWrite(SYNCHRONOUS,
2755 client_maker_->MakeDummyCHLOPacket(packet_num++));
2756 quic_data.AddWrite(SYNCHRONOUS,
2757 client_maker_->MakeDummyCHLOPacket(packet_num++));
2758 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2759 quic_data.AddWrite(SYNCHRONOUS,
2760 client_maker_->MakeConnectionClosePacket(
2761 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2762 "No recent network activity after 4s. Timeout:4s"));
2763 quic_data.AddSocketDataToFactory(&socket_factory_);
2764
2765 // Add successful TCP data so that TCP job will succeed.
2766 MockWrite http_writes[] = {
2767 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2768 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2769 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2770
2771 MockRead http_reads[] = {
2772 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2773 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2774 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2775 SequencedSocketData http_data(http_reads, http_writes);
2776 socket_factory_.AddSocketDataProvider(&http_data);
2777 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2778
2779 // Quic connection will be retried on the alternate network after the initial
2780 // one fails on the default network.
2781 MockQuicData quic_data2(version_);
2782 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2783 quic_data2.AddWrite(SYNCHRONOUS,
2784 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
2785
2786 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2787 if (VersionUsesHttp3(version_.transport_version))
2788 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2789 quic_data2.AddSocketDataToFactory(&socket_factory_);
2790
2791 // Resolve the host resolution synchronously.
2792 host_resolver_.set_synchronous_mode(true);
2793 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2794 "");
2795
2796 CreateSession();
2797 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2798 false);
2799 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2800 QuicStreamFactoryPeer::SetAlarmFactory(
2801 session_->quic_stream_factory(),
2802 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2803 context_.clock()));
2804 // Add alternate protocol mapping to race QUIC and TCP.
2805 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2806 // peer.
2807 AddQuicAlternateProtocolMapping(
2808 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2809
2810 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2811 TestCompletionCallback callback;
2812 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2814
2815 // Pump the message loop to get the request started.
2816 // Request will be served with TCP job.
2817 base::RunLoop().RunUntilIdle();
2818 EXPECT_THAT(callback.WaitForResult(), IsOk());
2819 CheckResponseData(&trans, "TCP succeeds");
2820
2821 // Fast forward to idle timeout the original connection. A new connection will
2822 // be kicked off on the alternate network.
2823 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2824 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2825 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2826
2827 // The second connection hasn't finish handshake, verify that QUIC is not
2828 // marked as broken.
2829 ExpectQuicAlternateProtocolMapping();
2830 // Explicitly confirm the handshake on the second connection.
2831 crypto_client_stream_factory_.last_stream()
2832 ->NotifySessionOneRttKeyAvailable();
2833 // Run message loop to execute posted tasks, which will notify JoController
2834 // about the orphaned job status.
2835 base::RunLoop().RunUntilIdle();
2836
2837 // Verify that QUIC is marked as broken.
2838 ExpectBrokenAlternateProtocolMapping();
2839
2840 // Deliver a message to notify the new network becomes default, the previous
2841 // brokenness will be clear as the brokenness is bond with old default
2842 // network.
2843 scoped_mock_change_notifier_->mock_network_change_notifier()
2844 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2845 ExpectQuicAlternateProtocolMapping();
2846
2847 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2848 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2849 }
2850
2851 // Much like above test, but verifies NetworkIsolationKeys are respected.
2852 // TODO(fayang): Add time driven idle network detection test.
TEST_P(QuicNetworkTransactionTest,DISABLED_RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey)2853 TEST_P(
2854 QuicNetworkTransactionTest,
2855 DISABLED_RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
2856 if (version_.UsesTls()) {
2857 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2858 return;
2859 }
2860
2861 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2862 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2863 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2864 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2865
2866 base::test::ScopedFeatureList feature_list;
2867 feature_list.InitWithFeatures(
2868 // enabled_features
2869 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2870 // Need to partition connections by NetworkIsolationKey for
2871 // QuicSessionAliasKey to include NetworkIsolationKeys.
2872 features::kPartitionConnectionsByNetworkIsolationKey},
2873 // disabled_features
2874 {});
2875 // Since HttpServerProperties caches the feature value, have to create a new
2876 // one.
2877 http_server_properties_ = std::make_unique<HttpServerProperties>();
2878
2879 SetUpTestForRetryConnectionOnAlternateNetwork();
2880
2881 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2882
2883 // The request will initially go out over QUIC.
2884 MockQuicData quic_data(version_);
2885 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2886 int packet_num = 1;
2887 quic_data.AddWrite(SYNCHRONOUS,
2888 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
2889 // Retransmit the handshake messages.
2890 quic_data.AddWrite(SYNCHRONOUS,
2891 client_maker_->MakeDummyCHLOPacket(packet_num++));
2892 quic_data.AddWrite(SYNCHRONOUS,
2893 client_maker_->MakeDummyCHLOPacket(packet_num++));
2894 quic_data.AddWrite(SYNCHRONOUS,
2895 client_maker_->MakeDummyCHLOPacket(packet_num++));
2896 quic_data.AddWrite(SYNCHRONOUS,
2897 client_maker_->MakeDummyCHLOPacket(packet_num++));
2898 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2899 quic_data.AddWrite(SYNCHRONOUS,
2900 client_maker_->MakeConnectionClosePacket(
2901 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2902 "No recent network activity after 4s. Timeout:4s"));
2903 quic_data.AddSocketDataToFactory(&socket_factory_);
2904
2905 // Add successful TCP data so that TCP job will succeed.
2906 MockWrite http_writes[] = {
2907 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2908 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2909 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2910
2911 MockRead http_reads[] = {
2912 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2913 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2914 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2915 SequencedSocketData http_data(http_reads, http_writes);
2916 socket_factory_.AddSocketDataProvider(&http_data);
2917 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2918
2919 // Quic connection will be retried on the alternate network after the initial
2920 // one fails on the default network.
2921 MockQuicData quic_data2(version_);
2922 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2923 quic_data2.AddWrite(SYNCHRONOUS,
2924 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
2925
2926 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2927 if (VersionUsesHttp3(version_.transport_version))
2928 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2929 quic_data2.AddSocketDataToFactory(&socket_factory_);
2930
2931 // Resolve the host resolution synchronously.
2932 host_resolver_.set_synchronous_mode(true);
2933 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2934 "");
2935
2936 CreateSession();
2937 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2938 false);
2939 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2940 QuicStreamFactoryPeer::SetAlarmFactory(
2941 session_->quic_stream_factory(),
2942 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2943 context_.clock()));
2944 // Add alternate protocol mapping to race QUIC and TCP.
2945 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2946 // peer.
2947 AddQuicAlternateProtocolMapping(
2948 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2949 AddQuicAlternateProtocolMapping(
2950 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2951
2952 request_.network_isolation_key = kNetworkIsolationKey1;
2953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2954 TestCompletionCallback callback;
2955 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2957
2958 // Pump the message loop to get the request started.
2959 // Request will be served with TCP job.
2960 base::RunLoop().RunUntilIdle();
2961 EXPECT_THAT(callback.WaitForResult(), IsOk());
2962 CheckResponseData(&trans, "TCP succeeds");
2963
2964 // Fast forward to idle timeout the original connection. A new connection will
2965 // be kicked off on the alternate network.
2966 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2967 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2968 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2969
2970 // The second connection hasn't finish handshake, verify that QUIC is not
2971 // marked as broken.
2972 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2973 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2974 // Explicitly confirm the handshake on the second connection.
2975 crypto_client_stream_factory_.last_stream()
2976 ->NotifySessionOneRttKeyAvailable();
2977 // Run message loop to execute posted tasks, which will notify JoController
2978 // about the orphaned job status.
2979 base::RunLoop().RunUntilIdle();
2980
2981 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
2982 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
2983 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2984
2985 // Deliver a message to notify the new network becomes default, the previous
2986 // brokenness will be clear as the brokenness is bond with old default
2987 // network.
2988 scoped_mock_change_notifier_->mock_network_change_notifier()
2989 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2990 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2991 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2992
2993 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2994 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2995 }
2996
2997 // This test verifies that a new QUIC connection will be attempted on the
2998 // alternate network if the original QUIC connection fails with idle timeout
2999 // before handshake is confirmed. If TCP doesn't succeed but QUIC on the
3000 // alternative network succeeds, QUIC is not marked as broken.
3001 // TODO(fayang): Add time driven idle network detection test.
TEST_P(QuicNetworkTransactionTest,DISABLED_RetryOnAlternateNetworkWhileTCPHanging)3002 TEST_P(QuicNetworkTransactionTest,
3003 DISABLED_RetryOnAlternateNetworkWhileTCPHanging) {
3004 if (version_.UsesTls()) {
3005 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3006 return;
3007 }
3008
3009 SetUpTestForRetryConnectionOnAlternateNetwork();
3010
3011 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3012
3013 // The request will initially go out over QUIC.
3014 MockQuicData quic_data(version_);
3015 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3016 int packet_num = 1;
3017 quic_data.AddWrite(SYNCHRONOUS,
3018 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
3019 // Retransmit the handshake messages.
3020 quic_data.AddWrite(SYNCHRONOUS,
3021 client_maker_->MakeDummyCHLOPacket(packet_num++));
3022 quic_data.AddWrite(SYNCHRONOUS,
3023 client_maker_->MakeDummyCHLOPacket(packet_num++));
3024 quic_data.AddWrite(SYNCHRONOUS,
3025 client_maker_->MakeDummyCHLOPacket(packet_num++));
3026 quic_data.AddWrite(SYNCHRONOUS,
3027 client_maker_->MakeDummyCHLOPacket(packet_num++));
3028 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3029 quic_data.AddWrite(SYNCHRONOUS,
3030 client_maker_->MakeConnectionClosePacket(
3031 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3032 "No recent network activity after 4s. Timeout:4s"));
3033 quic_data.AddSocketDataToFactory(&socket_factory_);
3034
3035 // Add hanging TCP data so that TCP job will never succeeded.
3036 AddHangingNonAlternateProtocolSocketData();
3037
3038 // Quic connection will then be retried on the alternate network.
3039 MockQuicData quic_data2(version_);
3040 packet_num = 1;
3041 quic_data2.AddWrite(
3042 SYNCHRONOUS,
3043 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
3044
3045 const std::string body = "hello!";
3046
3047 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3048 if (VersionUsesHttp3(version_.transport_version)) {
3049 quic_data2.AddWrite(SYNCHRONOUS,
3050 ConstructInitialSettingsPacket(packet_num++));
3051 }
3052 quic_data2.AddWrite(
3053 SYNCHRONOUS,
3054 ConstructClientRequestHeadersPacket(
3055 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3056 true, GetRequestHeaders("GET", "https", "/")));
3057 quic_data2.AddRead(
3058 ASYNC, ConstructServerResponseHeadersPacket(
3059 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3060 GetResponseHeaders("200 OK")));
3061 quic_data2.AddRead(
3062 ASYNC, ConstructServerDataPacket(
3063 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
3064 ConstructDataFrame(body)));
3065 quic_data2.AddWrite(SYNCHRONOUS,
3066 ConstructClientAckPacket(packet_num++, 2, 1));
3067 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3068 quic_data2.AddSocketDataToFactory(&socket_factory_);
3069
3070 // Resolve the host resolution synchronously.
3071 host_resolver_.set_synchronous_mode(true);
3072 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3073 "");
3074
3075 CreateSession();
3076 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3077 false);
3078 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
3079 QuicStreamFactoryPeer::SetAlarmFactory(
3080 session_->quic_stream_factory(),
3081 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
3082 context_.clock()));
3083 // Add alternate protocol mapping to race QUIC and TCP.
3084 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3085 // peer.
3086 AddQuicAlternateProtocolMapping(
3087 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3088
3089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3090 TestCompletionCallback callback;
3091 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3093
3094 // Pump the message loop to get the request started.
3095 base::RunLoop().RunUntilIdle();
3096
3097 // Fast forward to idle timeout the original connection. A new connection will
3098 // be kicked off on the alternate network.
3099 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3100 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3101 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3102
3103 // Verify that QUIC is not marked as broken.
3104 ExpectQuicAlternateProtocolMapping();
3105 // Explicitly confirm the handshake on the second connection.
3106 crypto_client_stream_factory_.last_stream()
3107 ->NotifySessionOneRttKeyAvailable();
3108
3109 // Read the response.
3110 EXPECT_THAT(callback.WaitForResult(), IsOk());
3111 CheckResponseData(&trans, body);
3112 // Verify that QUIC is not marked as broken.
3113 ExpectQuicAlternateProtocolMapping();
3114
3115 // Deliver a message to notify the new network becomes default.
3116 scoped_mock_change_notifier_->mock_network_change_notifier()
3117 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3118 ExpectQuicAlternateProtocolMapping();
3119 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3120 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3121 }
3122
3123 // Verify that if a QUIC connection times out, the QuicHttpStream will
3124 // return QUIC_PROTOCOL_ERROR.
TEST_P(QuicNetworkTransactionTest,TimeoutAfterHandshakeConfirmed)3125 TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
3126 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3127 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
3128
3129 // The request will initially go out over QUIC.
3130 MockQuicData quic_data(version_);
3131 spdy::SpdyPriority priority =
3132 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3133
3134 client_maker_->set_save_packet_frames(true);
3135 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3136 int packet_num = 1;
3137 if (VersionUsesHttp3(version_.transport_version)) {
3138 quic_data.AddWrite(SYNCHRONOUS,
3139 ConstructInitialSettingsPacket(packet_num++));
3140 }
3141 quic_data.AddWrite(
3142 SYNCHRONOUS,
3143 client_maker_->MakeRequestHeadersPacket(
3144 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3145 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3146
3147 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3148
3149 if (VersionUsesHttp3(version_.transport_version)) {
3150 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3151 // sending PTO packets.
3152 packet_num++;
3153 // PTO 1
3154 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3155 1, packet_num++, true));
3156 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3157 // sending PTO packets.
3158 packet_num++;
3159 // PTO 2
3160 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3161 2, packet_num++, true));
3162 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3163 // sending PTO packets.
3164 packet_num++;
3165 // PTO 3
3166 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3167 1, packet_num++, true));
3168
3169 quic_data.AddWrite(SYNCHRONOUS,
3170 client_maker_->MakeConnectionClosePacket(
3171 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3172 "No recent network activity after 4s. Timeout:4s"));
3173 } else if (version_.UsesTls()) {
3174 // Settings were sent in the request packet so there is only 1 packet to
3175 // retransmit.
3176 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3177 // sending PTO packets.
3178 packet_num++;
3179 // PTO 1
3180 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3181 1, packet_num++, true));
3182 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3183 // sending PTO packets.
3184 packet_num++;
3185 // PTO 2
3186 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3187 1, packet_num++, true));
3188 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3189 // sending PTO packets.
3190 packet_num++;
3191 // PTO 3
3192 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3193 1, packet_num++, true));
3194
3195 quic_data.AddWrite(SYNCHRONOUS,
3196 client_maker_->MakeConnectionClosePacket(
3197 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3198 "No recent network activity after 4s. Timeout:4s"));
3199 } else {
3200 // Settings were sent in the request packet so there is only 1 packet to
3201 // retransmit.
3202 // TLP 1
3203 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3204 1, packet_num++, true));
3205 // TLP 2
3206 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3207 1, packet_num++, true));
3208 // RTO 1
3209 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3210 1, packet_num++, true));
3211 // RTO 2
3212 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3213 1, packet_num++, true));
3214 // RTO 3
3215 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3216 1, packet_num++, true));
3217
3218 quic_data.AddWrite(SYNCHRONOUS,
3219 client_maker_->MakeConnectionClosePacket(
3220 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3221 "No recent network activity after 4s. Timeout:4s"));
3222 }
3223
3224 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3225 quic_data.AddRead(ASYNC, OK);
3226 quic_data.AddSocketDataToFactory(&socket_factory_);
3227
3228 // In order for a new QUIC session to be established via alternate-protocol
3229 // without racing an HTTP connection, we need the host resolution to happen
3230 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3231 // connection to the the server, in this test we require confirmation
3232 // before encrypting so the HTTP job will still start.
3233 host_resolver_.set_synchronous_mode(true);
3234 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3235 "");
3236
3237 CreateSession();
3238 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
3239 QuicStreamFactoryPeer::SetAlarmFactory(
3240 session_->quic_stream_factory(),
3241 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
3242 context_.clock()));
3243
3244 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
3245
3246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3247 TestCompletionCallback callback;
3248 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3250
3251 // Pump the message loop to get the request started.
3252 base::RunLoop().RunUntilIdle();
3253 // Explicitly confirm the handshake.
3254 crypto_client_stream_factory_.last_stream()
3255 ->NotifySessionOneRttKeyAvailable();
3256
3257 // Run the QUIC session to completion.
3258 quic_task_runner_->RunUntilIdle();
3259
3260 ExpectQuicAlternateProtocolMapping();
3261 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3262 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3263 }
3264
3265 // TODO(fayang): Add time driven TOO_MANY_RTOS test.
3266
3267 // Verify that if a QUIC protocol error occurs after the handshake is confirmed
3268 // the request fails with QUIC_PROTOCOL_ERROR.
TEST_P(QuicNetworkTransactionTest,ProtocolErrorAfterHandshakeConfirmed)3269 TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
3270 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3271 // The request will initially go out over QUIC.
3272 MockQuicData quic_data(version_);
3273 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3274 int packet_num = 1;
3275 if (VersionUsesHttp3(version_.transport_version)) {
3276 quic_data.AddWrite(SYNCHRONOUS,
3277 ConstructInitialSettingsPacket(packet_num++));
3278 }
3279 quic_data.AddWrite(
3280 SYNCHRONOUS,
3281 ConstructClientRequestHeadersPacket(
3282 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3283 true, GetRequestHeaders("GET", "https", "/")));
3284 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3285 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3286 // Peer sending data from an non-existing stream causes this end to raise
3287 // error and close connection.
3288 quic_data.AddRead(
3289 ASYNC, ConstructServerRstPacket(
3290 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3291 quic::QUIC_STREAM_LAST_ERROR));
3292 std::string quic_error_details = "Data for nonexistent stream";
3293 quic_data.AddWrite(
3294 SYNCHRONOUS,
3295 ConstructClientAckAndConnectionClosePacket(
3296 packet_num++, 1, 1,
3297 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3298 : quic::QUIC_INVALID_STREAM_ID,
3299 quic_error_details, quic::IETF_RST_STREAM));
3300 quic_data.AddSocketDataToFactory(&socket_factory_);
3301
3302 // In order for a new QUIC session to be established via alternate-protocol
3303 // without racing an HTTP connection, we need the host resolution to happen
3304 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3305 // connection to the the server, in this test we require confirmation
3306 // before encrypting so the HTTP job will still start.
3307 host_resolver_.set_synchronous_mode(true);
3308 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3309 "");
3310
3311 CreateSession();
3312
3313 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
3314
3315 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3316 TestCompletionCallback callback;
3317 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3319
3320 // Pump the message loop to get the request started.
3321 base::RunLoop().RunUntilIdle();
3322 // Explicitly confirm the handshake.
3323 crypto_client_stream_factory_.last_stream()
3324 ->NotifySessionOneRttKeyAvailable();
3325
3326 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3327 quic_data.Resume();
3328
3329 // Run the QUIC session to completion.
3330 base::RunLoop().RunUntilIdle();
3331 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3332 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3333
3334 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3335 ExpectQuicAlternateProtocolMapping();
3336 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3337 }
3338
3339 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3340 // connection times out, then QUIC will be marked as broken and the request
3341 // retried over TCP.
TEST_P(QuicNetworkTransactionTest,TimeoutAfterHandshakeConfirmedThenBroken2)3342 TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
3343 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
3344
3345 // The request will initially go out over QUIC.
3346 MockQuicData quic_data(version_);
3347 spdy::SpdyPriority priority =
3348 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3349
3350 client_maker_->set_save_packet_frames(true);
3351 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3352 int packet_num = 1;
3353 if (VersionUsesHttp3(version_.transport_version)) {
3354 quic_data.AddWrite(SYNCHRONOUS,
3355 client_maker_->MakeInitialSettingsPacket(packet_num++));
3356 }
3357 quic_data.AddWrite(
3358 SYNCHRONOUS,
3359 client_maker_->MakeRequestHeadersPacket(
3360 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3361 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3362
3363 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3364 if (VersionUsesHttp3(version_.transport_version)) {
3365 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3366 // sending PTO packets.
3367 packet_num++;
3368 // PTO 1
3369 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3370 1, packet_num++, true));
3371
3372 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3373 // sending PTO packets.
3374 packet_num++;
3375 // PTO 2
3376 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3377 2, packet_num++, true));
3378
3379 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3380 // sending PTO packets.
3381 packet_num++;
3382 // PTO 3
3383 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3384 1, packet_num++, true));
3385
3386 quic_data.AddWrite(SYNCHRONOUS,
3387 client_maker_->MakeConnectionClosePacket(
3388 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3389 "No recent network activity after 4s. Timeout:4s"));
3390 } else if (version_.UsesTls()) {
3391 // Settings were sent in the request packet so there is only 1 packet to
3392 // retransmit.
3393 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3394 // sending PTO packets.
3395 packet_num++;
3396 // PTO 1
3397 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3398 1, packet_num++, true));
3399 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3400 // sending PTO packets.
3401 packet_num++;
3402 // PTO 2
3403 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3404 1, packet_num++, true));
3405 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3406 // sending PTO packets.
3407 packet_num++;
3408 // PTO 3
3409 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3410 1, packet_num++, true));
3411
3412 quic_data.AddWrite(SYNCHRONOUS,
3413 client_maker_->MakeConnectionClosePacket(
3414 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3415 "No recent network activity after 4s. Timeout:4s"));
3416 } else {
3417 // TLP 1
3418 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3419 1, packet_num++, true));
3420 // TLP 2
3421 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3422 1, packet_num++, true));
3423 // RTO 1
3424 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3425 1, packet_num++, true));
3426 // RTO 2
3427 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3428 1, packet_num++, true));
3429 // RTO 3
3430 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
3431 1, packet_num++, true));
3432
3433 quic_data.AddWrite(SYNCHRONOUS,
3434 client_maker_->MakeConnectionClosePacket(
3435 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3436 "No recent network activity after 4s. Timeout:4s"));
3437 }
3438
3439 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3440 quic_data.AddRead(ASYNC, OK);
3441 quic_data.AddSocketDataToFactory(&socket_factory_);
3442
3443 // After that fails, it will be resent via TCP.
3444 MockWrite http_writes[] = {
3445 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3446 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3447 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3448
3449 MockRead http_reads[] = {
3450 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3451 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3452 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3453 SequencedSocketData http_data(http_reads, http_writes);
3454 socket_factory_.AddSocketDataProvider(&http_data);
3455 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3456
3457 // In order for a new QUIC session to be established via alternate-protocol
3458 // without racing an HTTP connection, we need the host resolution to happen
3459 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3460 // connection to the the server, in this test we require confirmation
3461 // before encrypting so the HTTP job will still start.
3462 host_resolver_.set_synchronous_mode(true);
3463 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3464 "");
3465
3466 CreateSession();
3467 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
3468 QuicStreamFactoryPeer::SetAlarmFactory(
3469 session_->quic_stream_factory(),
3470 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
3471 context_.clock()));
3472
3473 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
3474
3475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3476 TestCompletionCallback callback;
3477 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3479
3480 // Pump the message loop to get the request started.
3481 base::RunLoop().RunUntilIdle();
3482 // Explicitly confirm the handshake.
3483 crypto_client_stream_factory_.last_stream()
3484 ->NotifySessionOneRttKeyAvailable();
3485
3486 // Run the QUIC session to completion.
3487 quic_task_runner_->RunUntilIdle();
3488 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3489
3490 ExpectQuicAlternateProtocolMapping();
3491
3492 // Let the transaction proceed which will result in QUIC being marked
3493 // as broken and the request falling back to TCP.
3494 EXPECT_THAT(callback.WaitForResult(), IsOk());
3495
3496 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3497 ASSERT_FALSE(http_data.AllReadDataConsumed());
3498
3499 // Read the response body over TCP.
3500 CheckResponseData(&trans, "hello world");
3501 ExpectBrokenAlternateProtocolMapping();
3502 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3503 ASSERT_TRUE(http_data.AllReadDataConsumed());
3504 }
3505
3506 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3507 // protocol error occurs after the handshake is confirmed, the request
3508 // retried over TCP and the QUIC will be marked as broken.
TEST_P(QuicNetworkTransactionTest,ProtocolErrorAfterHandshakeConfirmedThenBroken)3509 TEST_P(QuicNetworkTransactionTest,
3510 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
3511 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
3512
3513 // The request will initially go out over QUIC.
3514 MockQuicData quic_data(version_);
3515 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3516 int packet_num = 1;
3517 if (VersionUsesHttp3(version_.transport_version)) {
3518 quic_data.AddWrite(SYNCHRONOUS,
3519 ConstructInitialSettingsPacket(packet_num++));
3520 }
3521 quic_data.AddWrite(
3522 SYNCHRONOUS,
3523 ConstructClientRequestHeadersPacket(
3524 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3525 true, GetRequestHeaders("GET", "https", "/")));
3526 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3527 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3528
3529 // Peer sending data from an non-existing stream causes this end to raise
3530 // error and close connection.
3531 quic_data.AddRead(
3532 ASYNC, ConstructServerRstPacket(
3533 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3534 quic::QUIC_STREAM_LAST_ERROR));
3535 std::string quic_error_details = "Data for nonexistent stream";
3536 quic_data.AddWrite(
3537 SYNCHRONOUS,
3538 ConstructClientAckAndConnectionClosePacket(
3539 packet_num++, 1, 1,
3540 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3541 : quic::QUIC_INVALID_STREAM_ID,
3542 quic_error_details, quic::IETF_RST_STREAM));
3543 quic_data.AddSocketDataToFactory(&socket_factory_);
3544
3545 // After that fails, it will be resent via TCP.
3546 MockWrite http_writes[] = {
3547 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3548 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3549 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3550
3551 MockRead http_reads[] = {
3552 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3553 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3554 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3555 SequencedSocketData http_data(http_reads, http_writes);
3556 socket_factory_.AddSocketDataProvider(&http_data);
3557 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3558
3559 // In order for a new QUIC session to be established via alternate-protocol
3560 // without racing an HTTP connection, we need the host resolution to happen
3561 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3562 // connection to the the server, in this test we require confirmation
3563 // before encrypting so the HTTP job will still start.
3564 host_resolver_.set_synchronous_mode(true);
3565 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3566 "");
3567
3568 CreateSession();
3569
3570 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
3571
3572 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3573 TestCompletionCallback callback;
3574 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3576
3577 // Pump the message loop to get the request started.
3578 base::RunLoop().RunUntilIdle();
3579 // Explicitly confirm the handshake.
3580 crypto_client_stream_factory_.last_stream()
3581 ->NotifySessionOneRttKeyAvailable();
3582 quic_data.Resume();
3583
3584 // Run the QUIC session to completion.
3585 base::RunLoop().RunUntilIdle();
3586 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3587
3588 ExpectQuicAlternateProtocolMapping();
3589
3590 // Let the transaction proceed which will result in QUIC being marked
3591 // as broken and the request falling back to TCP.
3592 EXPECT_THAT(callback.WaitForResult(), IsOk());
3593
3594 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3595 ASSERT_FALSE(http_data.AllReadDataConsumed());
3596
3597 // Read the response body over TCP.
3598 CheckResponseData(&trans, "hello world");
3599 ExpectBrokenAlternateProtocolMapping();
3600 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3601 ASSERT_TRUE(http_data.AllReadDataConsumed());
3602 }
3603
3604 // Much like above test, but verifies that NetworkIsolationKey is respected.
TEST_P(QuicNetworkTransactionTest,ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey)3605 TEST_P(QuicNetworkTransactionTest,
3606 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
3607 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3608 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3609 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3610 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3611
3612 base::test::ScopedFeatureList feature_list;
3613 feature_list.InitWithFeatures(
3614 // enabled_features
3615 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3616 features::kPartitionConnectionsByNetworkIsolationKey},
3617 // disabled_features
3618 {});
3619 // Since HttpServerProperties caches the feature value, have to create a new
3620 // one.
3621 http_server_properties_ = std::make_unique<HttpServerProperties>();
3622
3623 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
3624
3625 // The request will initially go out over QUIC.
3626 MockQuicData quic_data(version_);
3627 uint64_t packet_number = 1;
3628 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3629 if (VersionUsesHttp3(version_.transport_version)) {
3630 quic_data.AddWrite(SYNCHRONOUS,
3631 ConstructInitialSettingsPacket(packet_number++));
3632 }
3633 quic_data.AddWrite(
3634 SYNCHRONOUS,
3635 ConstructClientRequestHeadersPacket(
3636 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3637 true, GetRequestHeaders("GET", "https", "/")));
3638 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3639 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3640
3641 // Peer sending data from an non-existing stream causes this end to raise
3642 // error and close connection.
3643 quic_data.AddRead(
3644 ASYNC, ConstructServerRstPacket(
3645 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3646 quic::QUIC_STREAM_LAST_ERROR));
3647 std::string quic_error_details = "Data for nonexistent stream";
3648 quic::QuicErrorCode quic_error_code = quic::QUIC_INVALID_STREAM_ID;
3649 if (version_.HasIetfQuicFrames()) {
3650 quic_error_code = quic::QUIC_HTTP_STREAM_WRONG_DIRECTION;
3651 }
3652 quic_data.AddWrite(SYNCHRONOUS,
3653 ConstructClientAckAndConnectionClosePacket(
3654 packet_number++, 1, 1, quic_error_code,
3655 quic_error_details, quic::IETF_RST_STREAM));
3656 quic_data.AddSocketDataToFactory(&socket_factory_);
3657
3658 // After that fails, it will be resent via TCP.
3659 MockWrite http_writes[] = {
3660 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3661 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3662 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3663
3664 MockRead http_reads[] = {
3665 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3666 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3667 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3668 SequencedSocketData http_data(http_reads, http_writes);
3669 socket_factory_.AddSocketDataProvider(&http_data);
3670 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3671
3672 // In order for a new QUIC session to be established via alternate-protocol
3673 // without racing an HTTP connection, we need the host resolution to happen
3674 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3675 // connection to the the server, in this test we require confirmation
3676 // before encrypting so the HTTP job will still start.
3677 host_resolver_.set_synchronous_mode(true);
3678 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3679 "");
3680
3681 CreateSession();
3682
3683 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3684 kNetworkIsolationKey1);
3685 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3686 kNetworkIsolationKey2);
3687
3688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3689 TestCompletionCallback callback;
3690 request_.network_isolation_key = kNetworkIsolationKey1;
3691 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3693
3694 // Pump the message loop to get the request started.
3695 base::RunLoop().RunUntilIdle();
3696 // Explicitly confirm the handshake.
3697 crypto_client_stream_factory_.last_stream()
3698 ->NotifySessionOneRttKeyAvailable();
3699 quic_data.Resume();
3700
3701 // Run the QUIC session to completion.
3702 base::RunLoop().RunUntilIdle();
3703 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3704
3705 // Let the transaction proceed which will result in QUIC being marked
3706 // as broken and the request falling back to TCP.
3707 EXPECT_THAT(callback.WaitForResult(), IsOk());
3708 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3709 ASSERT_FALSE(http_data.AllReadDataConsumed());
3710
3711 // Read the response body over TCP.
3712 CheckResponseData(&trans, "hello world");
3713 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3714 ASSERT_TRUE(http_data.AllReadDataConsumed());
3715
3716 // The alternative service shouldhave been marked as broken under
3717 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3718 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3719 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3720
3721 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3722 AddHttpDataAndRunRequest();
3723 // Requests using other NetworkIsolationKeys can still use QUIC.
3724 request_.network_isolation_key = kNetworkIsolationKey2;
3725 AddQuicDataAndRunRequest();
3726
3727 // The last two requests should not have changed the alternative service
3728 // mappings.
3729 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3730 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3731 }
3732
3733 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3734 // request is reset from, then QUIC will be marked as broken and the request
3735 // retried over TCP.
TEST_P(QuicNetworkTransactionTest,ResetAfterHandshakeConfirmedThenBroken)3736 TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
3737 // The request will initially go out over QUIC.
3738 MockQuicData quic_data(version_);
3739 spdy::SpdyPriority priority =
3740 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3741
3742 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3743 int packet_num = 1;
3744 if (VersionUsesHttp3(version_.transport_version)) {
3745 quic_data.AddWrite(SYNCHRONOUS,
3746 ConstructInitialSettingsPacket(packet_num++));
3747 }
3748 quic_data.AddWrite(
3749 SYNCHRONOUS,
3750 client_maker_->MakeRequestHeadersPacket(
3751 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3752 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3753
3754 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3755 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3756
3757 quic_data.AddRead(ASYNC,
3758 ConstructServerRstPacket(
3759 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3760 quic::QUIC_HEADERS_TOO_LARGE));
3761
3762 if (VersionUsesHttp3(version_.transport_version)) {
3763 quic_data.AddWrite(
3764 SYNCHRONOUS, ConstructClientAckAndDataPacket(
3765 packet_num++, true, GetQpackDecoderStreamId(), 1, 1,
3766 false, StreamCancellationQpackDecoderInstruction(0)));
3767 }
3768
3769 quic_data.AddRead(ASYNC, OK);
3770 quic_data.AddSocketDataToFactory(&socket_factory_);
3771
3772 // After that fails, it will be resent via TCP.
3773 MockWrite http_writes[] = {
3774 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3775 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3776 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3777
3778 MockRead http_reads[] = {
3779 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3780 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3781 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3782 SequencedSocketData http_data(http_reads, http_writes);
3783 socket_factory_.AddSocketDataProvider(&http_data);
3784 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3785
3786 // In order for a new QUIC session to be established via alternate-protocol
3787 // without racing an HTTP connection, we need the host resolution to happen
3788 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3789 // connection to the the server, in this test we require confirmation
3790 // before encrypting so the HTTP job will still start.
3791 host_resolver_.set_synchronous_mode(true);
3792 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3793 "");
3794
3795 CreateSession();
3796
3797 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
3798
3799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3800 TestCompletionCallback callback;
3801 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3803
3804 // Pump the message loop to get the request started.
3805 base::RunLoop().RunUntilIdle();
3806 // Explicitly confirm the handshake.
3807 crypto_client_stream_factory_.last_stream()
3808 ->NotifySessionOneRttKeyAvailable();
3809 quic_data.Resume();
3810
3811 // Run the QUIC session to completion.
3812 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3813
3814 ExpectQuicAlternateProtocolMapping();
3815
3816 // Let the transaction proceed which will result in QUIC being marked
3817 // as broken and the request falling back to TCP.
3818 EXPECT_THAT(callback.WaitForResult(), IsOk());
3819
3820 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3821 ASSERT_FALSE(http_data.AllReadDataConsumed());
3822
3823 // Read the response body over TCP.
3824 CheckResponseData(&trans, "hello world");
3825 ExpectBrokenAlternateProtocolMapping();
3826 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3827 ASSERT_TRUE(http_data.AllReadDataConsumed());
3828 }
3829
3830 // Verify that when an origin has two alt-svc advertisements, one local and one
3831 // remote, that when the local is broken the request will go over QUIC via
3832 // the remote Alt-Svc.
3833 // This is a regression test for crbug/825646.
TEST_P(QuicNetworkTransactionTest,RemoteAltSvcWorkingWhileLocalAltSvcBroken)3834 TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3835 context_.params()->allow_remote_alt_svc = true;
3836
3837 GURL origin1 = request_.url; // mail.example.org
3838 GURL origin2("https://www.example.org/");
3839 ASSERT_NE(origin1.host(), origin2.host());
3840
3841 scoped_refptr<X509Certificate> cert(
3842 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
3843 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3844 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
3845
3846 ProofVerifyDetailsChromium verify_details;
3847 verify_details.cert_verify_result.verified_cert = cert;
3848 verify_details.cert_verify_result.is_issued_by_known_root = true;
3849 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3850
3851 MockQuicData mock_quic_data(version_);
3852 int packet_num = 1;
3853 if (VersionUsesHttp3(version_.transport_version)) {
3854 mock_quic_data.AddWrite(SYNCHRONOUS,
3855 ConstructInitialSettingsPacket(packet_num++));
3856 }
3857 mock_quic_data.AddWrite(
3858 SYNCHRONOUS,
3859 ConstructClientRequestHeadersPacket(
3860 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3861 true, GetRequestHeaders("GET", "https", "/")));
3862 mock_quic_data.AddRead(
3863 ASYNC, ConstructServerResponseHeadersPacket(
3864 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3865 GetResponseHeaders("200 OK")));
3866 mock_quic_data.AddRead(
3867 ASYNC, ConstructServerDataPacket(
3868 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
3869 ConstructDataFrame("hello!")));
3870 mock_quic_data.AddWrite(SYNCHRONOUS,
3871 ConstructClientAckPacket(packet_num++, 2, 1));
3872 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3873 mock_quic_data.AddRead(ASYNC, 0); // EOF
3874
3875 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3876 MockQuicData mock_quic_data2(version_);
3877 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3878 AddHangingNonAlternateProtocolSocketData();
3879
3880 CreateSession();
3881
3882 // Set up alternative service for |origin1|.
3883 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3884 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3885 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3886 AlternativeServiceInfoVector alternative_services;
3887 alternative_services.push_back(
3888 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3889 local_alternative, expiration,
3890 context_.params()->supported_versions));
3891 alternative_services.push_back(
3892 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3893 remote_alternative, expiration,
3894 context_.params()->supported_versions));
3895 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
3896 NetworkIsolationKey(),
3897 alternative_services);
3898
3899 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
3900 NetworkIsolationKey());
3901
3902 SendRequestAndExpectQuicResponse("hello!");
3903 }
3904
3905 // Verify that when multiple alternatives are broken,
3906 // ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
3907 // This is a regression test for crbug/1024613.
TEST_P(QuicNetworkTransactionTest,BrokenAlternativeOnlyRecordedOnce)3908 TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
3909 base::HistogramTester histogram_tester;
3910
3911 MockRead http_reads[] = {
3912 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
3913 MockRead("hello world"),
3914 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3915 MockRead(ASYNC, OK)};
3916
3917 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
3918 socket_factory_.AddSocketDataProvider(&http_data);
3919 AddCertificate(&ssl_data_);
3920 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3921
3922 GURL origin1 = request_.url; // mail.example.org
3923
3924 scoped_refptr<X509Certificate> cert(
3925 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
3926 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
3927
3928 ProofVerifyDetailsChromium verify_details;
3929 verify_details.cert_verify_result.verified_cert = cert;
3930 verify_details.cert_verify_result.is_issued_by_known_root = true;
3931 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3932
3933 CreateSession();
3934
3935 // Set up alternative service for |origin1|.
3936 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3937 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3938 AlternativeServiceInfoVector alternative_services;
3939 alternative_services.push_back(
3940 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3941 local_alternative, expiration,
3942 context_.params()->supported_versions));
3943 alternative_services.push_back(
3944 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3945 local_alternative, expiration,
3946 context_.params()->supported_versions));
3947 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
3948 NetworkIsolationKey(),
3949 alternative_services);
3950
3951 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
3952 NetworkIsolationKey());
3953
3954 SendRequestAndExpectHttpResponse("hello world");
3955
3956 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
3957 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
3958 }
3959
3960 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3961 // request is reset from, then QUIC will be marked as broken and the request
3962 // retried over TCP. Then, subsequent requests will go over a new TCP
3963 // connection instead of going back to the broken QUIC connection.
3964 // This is a regression tests for crbug/731303.
TEST_P(QuicNetworkTransactionTest,ResetPooledAfterHandshakeConfirmedThenBroken)3965 TEST_P(QuicNetworkTransactionTest,
3966 ResetPooledAfterHandshakeConfirmedThenBroken) {
3967 context_.params()->allow_remote_alt_svc = true;
3968
3969 GURL origin1 = request_.url;
3970 GURL origin2("https://www.example.org/");
3971 ASSERT_NE(origin1.host(), origin2.host());
3972
3973 MockQuicData mock_quic_data(version_);
3974
3975 scoped_refptr<X509Certificate> cert(
3976 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
3977 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3978 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
3979
3980 ProofVerifyDetailsChromium verify_details;
3981 verify_details.cert_verify_result.verified_cert = cert;
3982 verify_details.cert_verify_result.is_issued_by_known_root = true;
3983 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3984
3985 int packet_num = 1;
3986 if (VersionUsesHttp3(version_.transport_version)) {
3987 mock_quic_data.AddWrite(SYNCHRONOUS,
3988 ConstructInitialSettingsPacket(packet_num++));
3989 }
3990 // First request.
3991 mock_quic_data.AddWrite(
3992 SYNCHRONOUS,
3993 ConstructClientRequestHeadersPacket(
3994 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3995 true, GetRequestHeaders("GET", "https", "/")));
3996 mock_quic_data.AddRead(
3997 ASYNC, ConstructServerResponseHeadersPacket(
3998 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3999 GetResponseHeaders("200 OK")));
4000 mock_quic_data.AddRead(
4001 ASYNC, ConstructServerDataPacket(
4002 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4003 ConstructDataFrame("hello!")));
4004 mock_quic_data.AddWrite(SYNCHRONOUS,
4005 ConstructClientAckPacket(packet_num++, 2, 1));
4006
4007 // Second request will go over the pooled QUIC connection, but will be
4008 // reset by the server.
4009 QuicTestPacketMaker client_maker2(
4010 version_,
4011 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4012 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
4013 client_headers_include_h2_stream_dependency_);
4014 QuicTestPacketMaker server_maker2(
4015 version_,
4016 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4017 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
4018 mock_quic_data.AddWrite(
4019 SYNCHRONOUS,
4020 ConstructClientRequestHeadersPacket(
4021 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4022 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
4023 GetNthClientInitiatedBidirectionalStreamId(0)));
4024 mock_quic_data.AddRead(
4025 ASYNC, ConstructServerRstPacket(
4026 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4027 quic::QUIC_HEADERS_TOO_LARGE));
4028
4029 if (VersionUsesHttp3(version_.transport_version)) {
4030 mock_quic_data.AddWrite(
4031 SYNCHRONOUS,
4032 ConstructClientAckAndDataPacket(
4033 packet_num++, /*include_version=*/true, GetQpackDecoderStreamId(),
4034 3, 2,
4035 /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
4036 }
4037
4038 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4039 mock_quic_data.AddRead(ASYNC, 0); // EOF
4040
4041 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4042
4043 // After that fails, it will be resent via TCP.
4044 MockWrite http_writes[] = {
4045 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4046 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4047 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4048
4049 MockRead http_reads[] = {
4050 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4051 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4052 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
4053 SequencedSocketData http_data(http_reads, http_writes);
4054 socket_factory_.AddSocketDataProvider(&http_data);
4055 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4056
4057 // Then the next request to the second origin will be sent over TCP.
4058 socket_factory_.AddSocketDataProvider(&http_data);
4059 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4060
4061 CreateSession();
4062 QuicStreamFactoryPeer::SetAlarmFactory(
4063 session_->quic_stream_factory(),
4064 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4065 context_.clock()));
4066
4067 // Set up alternative service for |origin1|.
4068 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4069 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
4070 http_server_properties_->SetQuicAlternativeService(
4071 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4072 expiration, supported_versions_);
4073
4074 // Set up alternative service for |origin2|.
4075 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
4076 http_server_properties_->SetQuicAlternativeService(
4077 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4078 expiration, supported_versions_);
4079
4080 // First request opens connection to |destination1|
4081 // with quic::QuicServerId.host() == origin1.host().
4082 SendRequestAndExpectQuicResponse("hello!");
4083
4084 // Second request pools to existing connection with same destination,
4085 // because certificate matches, even though quic::QuicServerId is different.
4086 // After it is reset, it will fail back to TCP and mark QUIC as broken.
4087 request_.url = origin2;
4088 SendRequestAndExpectHttpResponse("hello world");
4089 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4090 alternative1, NetworkIsolationKey()))
4091 << alternative1.ToString();
4092 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4093 alternative2, NetworkIsolationKey()))
4094 << alternative2.ToString();
4095
4096 // The third request should use a new TCP connection, not the broken
4097 // QUIC connection.
4098 SendRequestAndExpectHttpResponse("hello world");
4099 }
4100
TEST_P(QuicNetworkTransactionTest,DoNotUseAlternativeServiceQuicUnsupportedVersion)4101 TEST_P(QuicNetworkTransactionTest,
4102 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4103 std::string altsvc_header =
4104 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4105 version_.transport_version - 1);
4106 MockRead http_reads[] = {
4107 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4108 MockRead("hello world"),
4109 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4110 MockRead(ASYNC, OK)};
4111
4112 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4113 socket_factory_.AddSocketDataProvider(&http_data);
4114 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4115 socket_factory_.AddSocketDataProvider(&http_data);
4116 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4117
4118 CreateSession();
4119
4120 SendRequestAndExpectHttpResponse("hello world");
4121 SendRequestAndExpectHttpResponse("hello world");
4122 }
4123
4124 // When multiple alternative services are advertised, HttpStreamFactory should
4125 // select the alternative service which uses existing QUIC session if available.
4126 // If no existing QUIC session can be used, use the first alternative service
4127 // from the list.
TEST_P(QuicNetworkTransactionTest,UseExistingAlternativeServiceForQuic)4128 TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
4129 context_.params()->allow_remote_alt_svc = true;
4130 MockRead http_reads[] = {
4131 MockRead("HTTP/1.1 200 OK\r\n"),
4132 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
4133 MockRead("hello world"),
4134 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4135 MockRead(ASYNC, OK)};
4136
4137 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4138 socket_factory_.AddSocketDataProvider(&http_data);
4139 AddCertificate(&ssl_data_);
4140 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4141
4142 // First QUIC request data.
4143 // Open a session to foo.example.org:443 using the first entry of the
4144 // alternative service list.
4145 MockQuicData mock_quic_data(version_);
4146 int packet_num = 1;
4147 if (VersionUsesHttp3(version_.transport_version)) {
4148 mock_quic_data.AddWrite(SYNCHRONOUS,
4149 ConstructInitialSettingsPacket(packet_num++));
4150 }
4151 mock_quic_data.AddWrite(
4152 SYNCHRONOUS,
4153 ConstructClientRequestHeadersPacket(
4154 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4155 true, GetRequestHeaders("GET", "https", "/")));
4156
4157 std::string alt_svc_list =
4158 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4159 "quic=\"bar.example.org:445\"";
4160 mock_quic_data.AddRead(
4161 ASYNC, ConstructServerResponseHeadersPacket(
4162 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4163 GetResponseHeaders("200 OK", alt_svc_list)));
4164 mock_quic_data.AddRead(
4165 ASYNC, ConstructServerDataPacket(
4166 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4167 ConstructDataFrame("hello!")));
4168 mock_quic_data.AddWrite(SYNCHRONOUS,
4169 ConstructClientAckPacket(packet_num++, 2, 1));
4170
4171 // Second QUIC request data.
4172 // Connection pooling, using existing session, no need to include version
4173 // as version negotiation has been completed.
4174 mock_quic_data.AddWrite(
4175 SYNCHRONOUS,
4176 ConstructClientRequestHeadersPacket(
4177 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4178 true, GetRequestHeaders("GET", "https", "/"),
4179 GetNthClientInitiatedBidirectionalStreamId(0)));
4180 mock_quic_data.AddRead(
4181 ASYNC, ConstructServerResponseHeadersPacket(
4182 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
4183 GetResponseHeaders("200 OK")));
4184 mock_quic_data.AddRead(
4185 ASYNC, ConstructServerDataPacket(
4186 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
4187 ConstructDataFrame("hello!")));
4188 mock_quic_data.AddWrite(SYNCHRONOUS,
4189 ConstructClientAckPacket(packet_num++, 4, 3));
4190 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4191 mock_quic_data.AddRead(ASYNC, 0); // EOF
4192
4193 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4194
4195 AddHangingNonAlternateProtocolSocketData();
4196 CreateSession();
4197 QuicStreamFactoryPeer::SetAlarmFactory(
4198 session_->quic_stream_factory(),
4199 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4200 context_.clock()));
4201
4202 SendRequestAndExpectHttpResponse("hello world");
4203
4204 SendRequestAndExpectQuicResponse("hello!");
4205 SendRequestAndExpectQuicResponse("hello!");
4206 }
4207
4208 // Pool to existing session with matching quic::QuicServerId
4209 // even if alternative service destination is different.
TEST_P(QuicNetworkTransactionTest,PoolByOrigin)4210 TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
4211 context_.params()->allow_remote_alt_svc = true;
4212 MockQuicData mock_quic_data(version_);
4213
4214 int packet_num = 1;
4215 if (VersionUsesHttp3(version_.transport_version)) {
4216 mock_quic_data.AddWrite(SYNCHRONOUS,
4217 ConstructInitialSettingsPacket(packet_num++));
4218 }
4219 // First request.
4220 mock_quic_data.AddWrite(
4221 SYNCHRONOUS,
4222 ConstructClientRequestHeadersPacket(
4223 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4224 true, GetRequestHeaders("GET", "https", "/")));
4225 mock_quic_data.AddRead(
4226 ASYNC, ConstructServerResponseHeadersPacket(
4227 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4228 GetResponseHeaders("200 OK")));
4229 mock_quic_data.AddRead(
4230 ASYNC, ConstructServerDataPacket(
4231 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4232 ConstructDataFrame("hello!")));
4233 mock_quic_data.AddWrite(SYNCHRONOUS,
4234 ConstructClientAckPacket(packet_num++, 2, 1));
4235
4236 // Second request.
4237 mock_quic_data.AddWrite(
4238 SYNCHRONOUS,
4239 ConstructClientRequestHeadersPacket(
4240 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4241 true, GetRequestHeaders("GET", "https", "/"),
4242 GetNthClientInitiatedBidirectionalStreamId(0)));
4243 mock_quic_data.AddRead(
4244 ASYNC, ConstructServerResponseHeadersPacket(
4245 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
4246 GetResponseHeaders("200 OK")));
4247 mock_quic_data.AddRead(
4248 ASYNC, ConstructServerDataPacket(
4249 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
4250 ConstructDataFrame("hello!")));
4251 mock_quic_data.AddWrite(SYNCHRONOUS,
4252 ConstructClientAckPacket(packet_num++, 4, 3));
4253 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4254 mock_quic_data.AddRead(ASYNC, 0); // EOF
4255
4256 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4257
4258 AddHangingNonAlternateProtocolSocketData();
4259 AddHangingNonAlternateProtocolSocketData();
4260
4261 CreateSession();
4262 QuicStreamFactoryPeer::SetAlarmFactory(
4263 session_->quic_stream_factory(),
4264 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4265 context_.clock()));
4266
4267 const char destination1[] = "first.example.com";
4268 const char destination2[] = "second.example.com";
4269
4270 // Set up alternative service entry to destination1.
4271 url::SchemeHostPort server(request_.url);
4272 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
4273 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4274 http_server_properties_->SetQuicAlternativeService(
4275 server, NetworkIsolationKey(), alternative_service, expiration,
4276 supported_versions_);
4277 // First request opens connection to |destination1|
4278 // with quic::QuicServerId.host() == kDefaultServerHostName.
4279 SendRequestAndExpectQuicResponse("hello!");
4280
4281 // Set up alternative service entry to a different destination.
4282 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
4283 http_server_properties_->SetQuicAlternativeService(
4284 server, NetworkIsolationKey(), alternative_service, expiration,
4285 supported_versions_);
4286 // Second request pools to existing connection with same quic::QuicServerId,
4287 // even though alternative service destination is different.
4288 SendRequestAndExpectQuicResponse("hello!");
4289 }
4290
4291 // Pool to existing session with matching destination and matching certificate
4292 // even if origin is different, and even if the alternative service with
4293 // matching destination is not the first one on the list.
TEST_P(QuicNetworkTransactionTest,PoolByDestination)4294 TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
4295 context_.params()->allow_remote_alt_svc = true;
4296 GURL origin1 = request_.url;
4297 GURL origin2("https://www.example.org/");
4298 ASSERT_NE(origin1.host(), origin2.host());
4299
4300 MockQuicData mock_quic_data(version_);
4301
4302 int packet_num = 1;
4303 if (VersionUsesHttp3(version_.transport_version)) {
4304 mock_quic_data.AddWrite(SYNCHRONOUS,
4305 ConstructInitialSettingsPacket(packet_num++));
4306 }
4307 // First request.
4308 mock_quic_data.AddWrite(
4309 SYNCHRONOUS,
4310 ConstructClientRequestHeadersPacket(
4311 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4312 true, GetRequestHeaders("GET", "https", "/")));
4313 mock_quic_data.AddRead(
4314 ASYNC, ConstructServerResponseHeadersPacket(
4315 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4316 GetResponseHeaders("200 OK")));
4317 mock_quic_data.AddRead(
4318 ASYNC, ConstructServerDataPacket(
4319 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4320 ConstructDataFrame("hello!")));
4321 mock_quic_data.AddWrite(SYNCHRONOUS,
4322 ConstructClientAckPacket(packet_num++, 2, 1));
4323
4324 // Second request.
4325 QuicTestPacketMaker client_maker2(
4326 version_,
4327 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4328 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
4329 client_headers_include_h2_stream_dependency_);
4330 QuicTestPacketMaker server_maker2(
4331 version_,
4332 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4333 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
4334 mock_quic_data.AddWrite(
4335 SYNCHRONOUS,
4336 ConstructClientRequestHeadersPacket(
4337 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4338 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
4339 GetNthClientInitiatedBidirectionalStreamId(0)));
4340 mock_quic_data.AddRead(
4341 ASYNC, ConstructServerResponseHeadersPacket(
4342 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
4343 GetResponseHeaders("200 OK")));
4344 mock_quic_data.AddRead(
4345 ASYNC, ConstructServerDataPacket(
4346 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
4347 ConstructDataFrame("hello!")));
4348 mock_quic_data.AddWrite(SYNCHRONOUS,
4349 ConstructClientAckPacket(packet_num++, 4, 3));
4350 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4351 mock_quic_data.AddRead(ASYNC, 0); // EOF
4352
4353 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4354
4355 AddHangingNonAlternateProtocolSocketData();
4356 AddHangingNonAlternateProtocolSocketData();
4357
4358 CreateSession();
4359 QuicStreamFactoryPeer::SetAlarmFactory(
4360 session_->quic_stream_factory(),
4361 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4362 context_.clock()));
4363
4364 const char destination1[] = "first.example.com";
4365 const char destination2[] = "second.example.com";
4366
4367 // Set up alternative service for |origin1|.
4368 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
4369 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4370 http_server_properties_->SetQuicAlternativeService(
4371 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4372 expiration, supported_versions_);
4373
4374 // Set up multiple alternative service entries for |origin2|,
4375 // the first one with a different destination as for |origin1|,
4376 // the second one with the same. The second one should be used,
4377 // because the request can be pooled to that one.
4378 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
4379 AlternativeServiceInfoVector alternative_services;
4380 alternative_services.push_back(
4381 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4382 alternative_service2, expiration,
4383 context_.params()->supported_versions));
4384 alternative_services.push_back(
4385 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4386 alternative_service1, expiration,
4387 context_.params()->supported_versions));
4388 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4389 NetworkIsolationKey(),
4390 alternative_services);
4391 // First request opens connection to |destination1|
4392 // with quic::QuicServerId.host() == origin1.host().
4393 SendRequestAndExpectQuicResponse("hello!");
4394
4395 // Second request pools to existing connection with same destination,
4396 // because certificate matches, even though quic::QuicServerId is different.
4397 request_.url = origin2;
4398
4399 SendRequestAndExpectQuicResponse("hello!");
4400 }
4401
4402 // Multiple origins have listed the same alternative services. When there's a
4403 // existing QUIC session opened by a request to other origin,
4404 // if the cert is valid, should select this QUIC session to make the request
4405 // if this is also the first existing QUIC session.
TEST_P(QuicNetworkTransactionTest,UseSharedExistingAlternativeServiceForQuicWithValidCert)4406 TEST_P(QuicNetworkTransactionTest,
4407 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
4408 context_.params()->allow_remote_alt_svc = true;
4409 // Default cert is valid for *.example.org
4410
4411 // HTTP data for request to www.example.org.
4412 MockRead http_reads[] = {
4413 MockRead("HTTP/1.1 200 OK\r\n"),
4414 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
4415 MockRead("hello world from www.example.org"),
4416 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4417 MockRead(ASYNC, OK)};
4418
4419 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4420 socket_factory_.AddSocketDataProvider(&http_data);
4421 AddCertificate(&ssl_data_);
4422 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4423
4424 // HTTP data for request to mail.example.org.
4425 MockRead http_reads2[] = {
4426 MockRead("HTTP/1.1 200 OK\r\n"),
4427 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
4428 MockRead("hello world from mail.example.org"),
4429 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4430 MockRead(ASYNC, OK)};
4431
4432 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
4433 socket_factory_.AddSocketDataProvider(&http_data2);
4434 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4435
4436 QuicTestPacketMaker client_maker(
4437 version_,
4438 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4439 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
4440 client_headers_include_h2_stream_dependency_);
4441 server_maker_.set_hostname("www.example.org");
4442 client_maker_->set_hostname("www.example.org");
4443 MockQuicData mock_quic_data(version_);
4444 int packet_num = 1;
4445 if (VersionUsesHttp3(version_.transport_version)) {
4446 mock_quic_data.AddWrite(SYNCHRONOUS,
4447 ConstructInitialSettingsPacket(packet_num++));
4448 }
4449 // First QUIC request data.
4450 mock_quic_data.AddWrite(
4451 SYNCHRONOUS,
4452 ConstructClientRequestHeadersPacket(
4453 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4454 true, GetRequestHeaders("GET", "https", "/")));
4455
4456 mock_quic_data.AddRead(
4457 ASYNC, ConstructServerResponseHeadersPacket(
4458 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4459 GetResponseHeaders("200 OK")));
4460 mock_quic_data.AddRead(
4461 ASYNC, ConstructServerDataPacket(
4462 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4463 ConstructDataFrame("hello from mail QUIC!")));
4464 mock_quic_data.AddWrite(SYNCHRONOUS,
4465 ConstructClientAckPacket(packet_num++, 2, 1));
4466 // Second QUIC request data.
4467 mock_quic_data.AddWrite(
4468 SYNCHRONOUS,
4469 ConstructClientRequestHeadersPacket(
4470 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4471 true, GetRequestHeaders("GET", "https", "/", &client_maker),
4472 GetNthClientInitiatedBidirectionalStreamId(0)));
4473 mock_quic_data.AddRead(
4474 ASYNC, ConstructServerResponseHeadersPacket(
4475 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
4476 GetResponseHeaders("200 OK")));
4477 mock_quic_data.AddRead(
4478 ASYNC, ConstructServerDataPacket(
4479 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
4480 ConstructDataFrame("hello from mail QUIC!")));
4481 mock_quic_data.AddWrite(SYNCHRONOUS,
4482 ConstructClientAckPacket(packet_num++, 4, 3));
4483 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4484 mock_quic_data.AddRead(ASYNC, 0); // EOF
4485
4486 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4487
4488 AddHangingNonAlternateProtocolSocketData();
4489 CreateSession();
4490 QuicStreamFactoryPeer::SetAlarmFactory(
4491 session_->quic_stream_factory(),
4492 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4493 context_.clock()));
4494
4495 // Send two HTTP requests, responses set up alt-svc lists for the origins.
4496 request_.url = GURL("https://www.example.org/");
4497 SendRequestAndExpectHttpResponse("hello world from www.example.org");
4498 request_.url = GURL("https://mail.example.org/");
4499 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4500
4501 // Open a QUIC session to mail.example.org:443 when making request
4502 // to mail.example.org.
4503 request_.url = GURL("https://www.example.org/");
4504 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
4505
4506 // Uses the existing QUIC session when making request to www.example.org.
4507 request_.url = GURL("https://mail.example.org/");
4508 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
4509 }
4510
TEST_P(QuicNetworkTransactionTest,AlternativeServiceDifferentPort)4511 TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
4512 MockRead http_reads[] = {
4513 MockRead("HTTP/1.1 200 OK\r\n"),
4514 MockRead(kQuicAlternativeServiceDifferentPortHeader),
4515 MockRead("hello world"),
4516 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4517 MockRead(ASYNC, OK)};
4518
4519 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4520 socket_factory_.AddSocketDataProvider(&http_data);
4521 AddCertificate(&ssl_data_);
4522 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4523
4524 AddHangingNonAlternateProtocolSocketData();
4525 CreateSession();
4526
4527 SendRequestAndExpectHttpResponse("hello world");
4528
4529 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
4530 AlternativeServiceInfoVector alternative_service_info_vector =
4531 http_server_properties_->GetAlternativeServiceInfos(
4532 http_server, NetworkIsolationKey());
4533 ASSERT_EQ(1u, alternative_service_info_vector.size());
4534 const AlternativeService alternative_service =
4535 alternative_service_info_vector[0].alternative_service();
4536 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4537 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4538 EXPECT_EQ(137, alternative_service.port);
4539 }
4540
TEST_P(QuicNetworkTransactionTest,ConfirmAlternativeService)4541 TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
4542 MockRead http_reads[] = {
4543 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4544 MockRead("hello world"),
4545 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4546 MockRead(ASYNC, OK)};
4547
4548 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4549 socket_factory_.AddSocketDataProvider(&http_data);
4550 AddCertificate(&ssl_data_);
4551 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4552
4553 MockQuicData mock_quic_data(version_);
4554 int packet_num = 1;
4555 if (VersionUsesHttp3(version_.transport_version)) {
4556 mock_quic_data.AddWrite(SYNCHRONOUS,
4557 ConstructInitialSettingsPacket(packet_num++));
4558 }
4559 mock_quic_data.AddWrite(
4560 SYNCHRONOUS,
4561 ConstructClientRequestHeadersPacket(
4562 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4563 true, GetRequestHeaders("GET", "https", "/")));
4564 mock_quic_data.AddRead(
4565 ASYNC, ConstructServerResponseHeadersPacket(
4566 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4567 GetResponseHeaders("200 OK")));
4568 mock_quic_data.AddRead(
4569 ASYNC, ConstructServerDataPacket(
4570 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4571 ConstructDataFrame("hello!")));
4572 mock_quic_data.AddWrite(SYNCHRONOUS,
4573 ConstructClientAckPacket(packet_num++, 2, 1));
4574 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4575 mock_quic_data.AddRead(ASYNC, 0); // EOF
4576
4577 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4578
4579 AddHangingNonAlternateProtocolSocketData();
4580 CreateSession();
4581
4582 AlternativeService alternative_service(kProtoQUIC,
4583 HostPortPair::FromURL(request_.url));
4584 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4585 alternative_service, NetworkIsolationKey());
4586 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4587 alternative_service, NetworkIsolationKey()));
4588
4589 SendRequestAndExpectHttpResponse("hello world");
4590 SendRequestAndExpectQuicResponse("hello!");
4591
4592 mock_quic_data.Resume();
4593
4594 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4595 alternative_service, NetworkIsolationKey()));
4596 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4597 url::SchemeHostPort("https", request_.url.host(), 443),
4598 NetworkIsolationKey()));
4599 }
4600
TEST_P(QuicNetworkTransactionTest,ConfirmAlternativeServiceWithNetworkIsolationKey)4601 TEST_P(QuicNetworkTransactionTest,
4602 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4603 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4604 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4605 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4606 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4607
4608 base::test::ScopedFeatureList feature_list;
4609 feature_list.InitWithFeatures(
4610 // enabled_features
4611 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4612 features::kPartitionConnectionsByNetworkIsolationKey},
4613 // disabled_features
4614 {});
4615 // Since HttpServerProperties caches the feature value, have to create a new
4616 // one.
4617 http_server_properties_ = std::make_unique<HttpServerProperties>();
4618
4619 MockRead http_reads[] = {
4620 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4621 MockRead("hello world"),
4622 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4623 MockRead(ASYNC, OK)};
4624
4625 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4626 socket_factory_.AddSocketDataProvider(&http_data);
4627 AddCertificate(&ssl_data_);
4628 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4629
4630 MockQuicData mock_quic_data(version_);
4631 int packet_num = 1;
4632 if (VersionUsesHttp3(version_.transport_version)) {
4633 mock_quic_data.AddWrite(SYNCHRONOUS,
4634 ConstructInitialSettingsPacket(packet_num++));
4635 }
4636 mock_quic_data.AddWrite(
4637 SYNCHRONOUS,
4638 ConstructClientRequestHeadersPacket(
4639 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4640 true, GetRequestHeaders("GET", "https", "/")));
4641 mock_quic_data.AddRead(
4642 ASYNC, ConstructServerResponseHeadersPacket(
4643 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4644 GetResponseHeaders("200 OK")));
4645 mock_quic_data.AddRead(
4646 ASYNC, ConstructServerDataPacket(
4647 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4648 ConstructDataFrame("hello!")));
4649 mock_quic_data.AddWrite(SYNCHRONOUS,
4650 ConstructClientAckPacket(packet_num++, 2, 1));
4651 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4652 mock_quic_data.AddRead(ASYNC, 0); // EOF
4653
4654 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4655
4656 CreateSession();
4657
4658 AlternativeService alternative_service(kProtoQUIC,
4659 HostPortPair::FromURL(request_.url));
4660 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4661 alternative_service, kNetworkIsolationKey1);
4662 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4663 alternative_service, kNetworkIsolationKey2);
4664 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4665 alternative_service, kNetworkIsolationKey1));
4666 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4667 alternative_service, kNetworkIsolationKey2));
4668
4669 request_.network_isolation_key = kNetworkIsolationKey1;
4670 SendRequestAndExpectHttpResponse("hello world");
4671 SendRequestAndExpectQuicResponse("hello!");
4672
4673 mock_quic_data.Resume();
4674
4675 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4676 alternative_service, kNetworkIsolationKey1));
4677 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4678 url::SchemeHostPort("https", request_.url.host(), 443),
4679 kNetworkIsolationKey1));
4680 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4681 alternative_service, kNetworkIsolationKey2));
4682 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4683 url::SchemeHostPort("https", request_.url.host(), 443),
4684 kNetworkIsolationKey2));
4685 }
4686
TEST_P(QuicNetworkTransactionTest,UseAlternativeServiceForQuicForHttps)4687 TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
4688 MockRead http_reads[] = {
4689 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4690 MockRead("hello world"),
4691 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4692 MockRead(ASYNC, OK)};
4693
4694 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4695 socket_factory_.AddSocketDataProvider(&http_data);
4696 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4697
4698 MockQuicData mock_quic_data(version_);
4699 int packet_num = 1;
4700 if (VersionUsesHttp3(version_.transport_version)) {
4701 mock_quic_data.AddWrite(SYNCHRONOUS,
4702 ConstructInitialSettingsPacket(packet_num++));
4703 }
4704 mock_quic_data.AddWrite(
4705 SYNCHRONOUS,
4706 ConstructClientRequestHeadersPacket(
4707 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4708 true, GetRequestHeaders("GET", "https", "/")));
4709 mock_quic_data.AddRead(
4710 ASYNC, ConstructServerResponseHeadersPacket(
4711 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4712 GetResponseHeaders("200 OK")));
4713 mock_quic_data.AddRead(
4714 ASYNC, ConstructServerDataPacket(
4715 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4716 ConstructDataFrame("hello!")));
4717 mock_quic_data.AddWrite(SYNCHRONOUS,
4718 ConstructClientAckPacket(packet_num++, 2, 1));
4719 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4720
4721 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4722
4723 AddHangingNonAlternateProtocolSocketData();
4724 CreateSession();
4725
4726 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4727 SendRequestAndExpectHttpResponse("hello world");
4728 }
4729
TEST_P(QuicNetworkTransactionTest,HungAlternativeService)4730 TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
4731 crypto_client_stream_factory_.set_handshake_mode(
4732 MockCryptoClientStream::COLD_START);
4733
4734 MockWrite http_writes[] = {
4735 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4736 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
4737 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4738
4739 MockRead http_reads[] = {
4740 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4741 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4742 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
4743
4744 SequencedSocketData http_data(http_reads, http_writes);
4745 socket_factory_.AddSocketDataProvider(&http_data);
4746 AddCertificate(&ssl_data_);
4747 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4748
4749 // The QUIC transaction will not be allowed to complete.
4750 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
4751 MockRead quic_reads[] = {
4752 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
4753 };
4754 SequencedSocketData quic_data(quic_reads, quic_writes);
4755 socket_factory_.AddSocketDataProvider(&quic_data);
4756
4757 // The HTTP transaction will complete.
4758 SequencedSocketData http_data2(http_reads, http_writes);
4759 socket_factory_.AddSocketDataProvider(&http_data2);
4760 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4761
4762 CreateSession();
4763
4764 // Run the first request.
4765 SendRequestAndExpectHttpResponse("hello world");
4766 ASSERT_TRUE(http_data.AllReadDataConsumed());
4767 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4768
4769 // Now run the second request in which the QUIC socket hangs,
4770 // and verify the the transaction continues over HTTP.
4771 SendRequestAndExpectHttpResponse("hello world");
4772 base::RunLoop().RunUntilIdle();
4773
4774 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4775 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
4776 ASSERT_TRUE(quic_data.AllReadDataConsumed());
4777 }
4778
TEST_P(QuicNetworkTransactionTest,ZeroRTTWithHttpRace)4779 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
4780 MockQuicData mock_quic_data(version_);
4781 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
4782 int packet_num = 1;
4783 if (VersionUsesHttp3(version_.transport_version)) {
4784 mock_quic_data.AddWrite(SYNCHRONOUS,
4785 ConstructInitialSettingsPacket(packet_num++));
4786 }
4787 mock_quic_data.AddWrite(
4788 SYNCHRONOUS,
4789 ConstructClientRequestHeadersPacket(
4790 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4791 true, GetRequestHeaders("GET", "https", "/")));
4792 mock_quic_data.AddRead(
4793 ASYNC, ConstructServerResponseHeadersPacket(
4794 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4795 GetResponseHeaders("200 OK")));
4796 mock_quic_data.AddRead(
4797 ASYNC, ConstructServerDataPacket(
4798 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4799 ConstructDataFrame("hello!")));
4800 if (version_.UsesTls()) {
4801 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4802 }
4803 mock_quic_data.AddWrite(SYNCHRONOUS,
4804 ConstructClientAckPacket(packet_num++, 2, 1));
4805 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4806 mock_quic_data.AddRead(ASYNC, 0); // EOF
4807
4808 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4809
4810 // The non-alternate protocol job needs to hang in order to guarantee that
4811 // the alternate-protocol job will "win".
4812 AddHangingNonAlternateProtocolSocketData();
4813
4814 CreateSession();
4815 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
4816 SendRequestAndExpectQuicResponse("hello!");
4817
4818 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4819 url::SchemeHostPort("https", request_.url.host(), 443),
4820 NetworkIsolationKey()));
4821 }
4822
TEST_P(QuicNetworkTransactionTest,ZeroRTTWithNoHttpRace)4823 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
4824 MockQuicData mock_quic_data(version_);
4825 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
4826 int packet_number = 1;
4827 if (VersionUsesHttp3(version_.transport_version)) {
4828 mock_quic_data.AddWrite(
4829 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
4830 }
4831 mock_quic_data.AddWrite(
4832 SYNCHRONOUS,
4833 ConstructClientRequestHeadersPacket(
4834 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4835 true, GetRequestHeaders("GET", "https", "/")));
4836 mock_quic_data.AddRead(
4837 ASYNC, ConstructServerResponseHeadersPacket(
4838 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4839 GetResponseHeaders("200 OK")));
4840 mock_quic_data.AddRead(
4841 ASYNC, ConstructServerDataPacket(
4842 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4843 ConstructDataFrame("hello!")));
4844 if (version_.UsesTls()) {
4845 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4846 }
4847 mock_quic_data.AddWrite(SYNCHRONOUS,
4848 ConstructClientAckPacket(packet_number++, 2, 1));
4849 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4850 mock_quic_data.AddRead(ASYNC, 0); // EOF
4851 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4852
4853 // In order for a new QUIC session to be established via alternate-protocol
4854 // without racing an HTTP connection, we need the host resolution to happen
4855 // synchronously.
4856 host_resolver_.set_synchronous_mode(true);
4857 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4858 "");
4859
4860 AddHangingNonAlternateProtocolSocketData();
4861 CreateSession();
4862 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
4863 SendRequestAndExpectQuicResponse("hello!");
4864 }
4865
TEST_P(QuicNetworkTransactionTest,ZeroRTTWithProxy)4866 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
4867 proxy_resolution_service_ =
4868 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
4869 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4870
4871 // Since we are using a proxy, the QUIC job will not succeed.
4872 MockWrite http_writes[] = {
4873 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4874 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
4875 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
4876
4877 MockRead http_reads[] = {
4878 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4879 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4880 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
4881
4882 StaticSocketDataProvider http_data(http_reads, http_writes);
4883 socket_factory_.AddSocketDataProvider(&http_data);
4884
4885 // In order for a new QUIC session to be established via alternate-protocol
4886 // without racing an HTTP connection, we need the host resolution to happen
4887 // synchronously.
4888 host_resolver_.set_synchronous_mode(true);
4889 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4890 "");
4891
4892 request_.url = GURL("http://mail.example.org/");
4893 CreateSession();
4894 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
4895 SendRequestAndExpectHttpResponse("hello world");
4896 }
4897
TEST_P(QuicNetworkTransactionTest,ZeroRTTWithConfirmationRequired)4898 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
4899 MockQuicData mock_quic_data(version_);
4900 int packet_num = 1;
4901 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
4902 if (VersionUsesHttp3(version_.transport_version)) {
4903 mock_quic_data.AddWrite(SYNCHRONOUS,
4904 ConstructInitialSettingsPacket(packet_num++));
4905 }
4906 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4907 mock_quic_data.AddWrite(
4908 SYNCHRONOUS,
4909 ConstructClientRequestHeadersPacket(
4910 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4911 true, GetRequestHeaders("GET", "https", "/")));
4912 mock_quic_data.AddRead(
4913 ASYNC, ConstructServerResponseHeadersPacket(
4914 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4915 GetResponseHeaders("200 OK")));
4916 mock_quic_data.AddRead(
4917 ASYNC, ConstructServerDataPacket(
4918 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4919 ConstructDataFrame("hello!")));
4920 mock_quic_data.AddWrite(SYNCHRONOUS,
4921 ConstructClientAckPacket(packet_num++, 2, 1));
4922 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
4923 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4924
4925 // The non-alternate protocol job needs to hang in order to guarantee that
4926 // the alternate-protocol job will "win".
4927 AddHangingNonAlternateProtocolSocketData();
4928
4929 // In order for a new QUIC session to be established via alternate-protocol
4930 // without racing an HTTP connection, we need the host resolution to happen
4931 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4932 // connection to the the server, in this test we require confirmation
4933 // before encrypting so the HTTP job will still start.
4934 host_resolver_.set_synchronous_mode(true);
4935 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4936 "");
4937
4938 CreateSession();
4939 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4940 false);
4941 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
4942
4943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4944 TestCompletionCallback callback;
4945 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
4946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4947
4948 crypto_client_stream_factory_.last_stream()
4949 ->NotifySessionOneRttKeyAvailable();
4950 EXPECT_THAT(callback.WaitForResult(), IsOk());
4951
4952 CheckWasQuicResponse(&trans);
4953 CheckResponseData(&trans, "hello!");
4954 }
4955
TEST_P(QuicNetworkTransactionTest,ZeroRTTWithTooEarlyResponse)4956 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
4957 uint64_t packet_number = 1;
4958 MockQuicData mock_quic_data(version_);
4959 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
4960 if (VersionUsesHttp3(version_.transport_version)) {
4961 mock_quic_data.AddWrite(
4962 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
4963 }
4964 mock_quic_data.AddWrite(
4965 SYNCHRONOUS,
4966 ConstructClientRequestHeadersPacket(
4967 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4968 true, GetRequestHeaders("GET", "https", "/")));
4969 mock_quic_data.AddRead(
4970 ASYNC, ConstructServerResponseHeadersPacket(
4971 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4972 GetResponseHeaders("425 TOO_EARLY")));
4973 if (VersionUsesHttp3(version_.transport_version)) {
4974 mock_quic_data.AddWrite(
4975 SYNCHRONOUS,
4976 ConstructClientAckAndDataPacket(
4977 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
4978 StreamCancellationQpackDecoderInstruction(0)));
4979 mock_quic_data.AddWrite(SYNCHRONOUS,
4980 client_maker_->MakeRstPacket(
4981 packet_number++, false,
4982 GetNthClientInitiatedBidirectionalStreamId(0),
4983 quic::QUIC_STREAM_CANCELLED));
4984 } else {
4985 mock_quic_data.AddWrite(
4986 SYNCHRONOUS,
4987 ConstructClientAckAndRstPacket(
4988 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
4989 quic::QUIC_STREAM_CANCELLED, 1, 1));
4990 }
4991
4992 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4993
4994 mock_quic_data.AddWrite(
4995 SYNCHRONOUS,
4996 ConstructClientRequestHeadersPacket(
4997 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4998 true, GetRequestHeaders("GET", "https", "/"),
4999 GetNthClientInitiatedBidirectionalStreamId(0)));
5000 mock_quic_data.AddRead(
5001 ASYNC, ConstructServerResponseHeadersPacket(
5002 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5003 GetResponseHeaders("200 OK")));
5004 mock_quic_data.AddRead(
5005 ASYNC, ConstructServerDataPacket(
5006 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
5007 ConstructDataFrame("hello!")));
5008 mock_quic_data.AddWrite(SYNCHRONOUS,
5009 ConstructClientAckPacket(packet_number++, 3, 1));
5010 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5011 mock_quic_data.AddRead(ASYNC, 0); // EOF
5012
5013 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5014
5015 // In order for a new QUIC session to be established via alternate-protocol
5016 // without racing an HTTP connection, we need the host resolution to happen
5017 // synchronously.
5018 host_resolver_.set_synchronous_mode(true);
5019 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5020 "");
5021
5022 AddHangingNonAlternateProtocolSocketData();
5023 CreateSession();
5024 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
5025 QuicStreamFactoryPeer::SetAlarmFactory(
5026 session_->quic_stream_factory(),
5027 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5028 context_.clock()));
5029
5030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5031 TestCompletionCallback callback;
5032 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5034
5035 // Confirm the handshake after the 425 Too Early.
5036 base::RunLoop().RunUntilIdle();
5037
5038 // The handshake hasn't been confirmed yet, so the retry should not have
5039 // succeeded.
5040 EXPECT_FALSE(callback.have_result());
5041
5042 crypto_client_stream_factory_.last_stream()
5043 ->NotifySessionOneRttKeyAvailable();
5044
5045 EXPECT_THAT(callback.WaitForResult(), IsOk());
5046 CheckWasQuicResponse(&trans);
5047 CheckResponseData(&trans, "hello!");
5048 }
5049
TEST_P(QuicNetworkTransactionTest,ZeroRTTWithMultipleTooEarlyResponse)5050 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5051 uint64_t packet_number = 1;
5052 MockQuicData mock_quic_data(version_);
5053 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
5054 if (VersionUsesHttp3(version_.transport_version)) {
5055 mock_quic_data.AddWrite(
5056 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
5057 }
5058 mock_quic_data.AddWrite(
5059 SYNCHRONOUS,
5060 ConstructClientRequestHeadersPacket(
5061 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5062 true, GetRequestHeaders("GET", "https", "/")));
5063 mock_quic_data.AddRead(
5064 ASYNC, ConstructServerResponseHeadersPacket(
5065 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5066 GetResponseHeaders("425 TOO_EARLY")));
5067 if (VersionUsesHttp3(version_.transport_version)) {
5068 mock_quic_data.AddWrite(
5069 SYNCHRONOUS,
5070 ConstructClientAckAndDataPacket(
5071 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
5072 StreamCancellationQpackDecoderInstruction(0)));
5073 mock_quic_data.AddWrite(SYNCHRONOUS,
5074 client_maker_->MakeRstPacket(
5075 packet_number++, false,
5076 GetNthClientInitiatedBidirectionalStreamId(0),
5077 quic::QUIC_STREAM_CANCELLED));
5078 } else {
5079 mock_quic_data.AddWrite(
5080 SYNCHRONOUS,
5081 ConstructClientAckAndRstPacket(
5082 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5083 quic::QUIC_STREAM_CANCELLED, 1, 1));
5084 }
5085
5086 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5087
5088 mock_quic_data.AddWrite(
5089 SYNCHRONOUS,
5090 ConstructClientRequestHeadersPacket(
5091 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5092 true, GetRequestHeaders("GET", "https", "/"),
5093 GetNthClientInitiatedBidirectionalStreamId(0)));
5094 mock_quic_data.AddRead(
5095 ASYNC, ConstructServerResponseHeadersPacket(
5096 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5097 GetResponseHeaders("425 TOO_EARLY")));
5098 if (VersionUsesHttp3(version_.transport_version)) {
5099 mock_quic_data.AddWrite(
5100 SYNCHRONOUS,
5101 ConstructClientAckAndDataPacket(
5102 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, false,
5103 StreamCancellationQpackDecoderInstruction(1, false)));
5104 mock_quic_data.AddWrite(SYNCHRONOUS,
5105 client_maker_->MakeRstPacket(
5106 packet_number++, false,
5107 GetNthClientInitiatedBidirectionalStreamId(1),
5108 quic::QUIC_STREAM_CANCELLED));
5109 } else {
5110 mock_quic_data.AddWrite(
5111 SYNCHRONOUS,
5112 ConstructClientAckAndRstPacket(
5113 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5114 quic::QUIC_STREAM_CANCELLED, 2, 1));
5115 }
5116 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5117 mock_quic_data.AddRead(ASYNC, 0); // EOF
5118
5119 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5120
5121 // In order for a new QUIC session to be established via alternate-protocol
5122 // without racing an HTTP connection, we need the host resolution to happen
5123 // synchronously.
5124 host_resolver_.set_synchronous_mode(true);
5125 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5126 "");
5127
5128 AddHangingNonAlternateProtocolSocketData();
5129 CreateSession();
5130 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
5131 QuicStreamFactoryPeer::SetAlarmFactory(
5132 session_->quic_stream_factory(),
5133 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5134 context_.clock()));
5135
5136 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5137 TestCompletionCallback callback;
5138 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5140
5141 // Confirm the handshake after the 425 Too Early.
5142 base::RunLoop().RunUntilIdle();
5143
5144 // The handshake hasn't been confirmed yet, so the retry should not have
5145 // succeeded.
5146 EXPECT_FALSE(callback.have_result());
5147
5148 crypto_client_stream_factory_.last_stream()
5149 ->NotifySessionOneRttKeyAvailable();
5150
5151 EXPECT_THAT(callback.WaitForResult(), IsOk());
5152 const HttpResponseInfo* response = trans.GetResponseInfo();
5153 ASSERT_TRUE(response != nullptr);
5154 ASSERT_TRUE(response->headers.get() != nullptr);
5155 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5156 EXPECT_TRUE(response->was_fetched_via_spdy);
5157 EXPECT_TRUE(response->was_alpn_negotiated);
5158 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5159 response->connection_info);
5160 }
5161
TEST_P(QuicNetworkTransactionTest,LogGranularQuicErrorCodeOnQuicProtocolErrorLocal)5162 TEST_P(QuicNetworkTransactionTest,
5163 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
5164 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5165 MockQuicData mock_quic_data(version_);
5166 int packet_num = 1;
5167 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
5168 if (VersionUsesHttp3(version_.transport_version)) {
5169 mock_quic_data.AddWrite(SYNCHRONOUS,
5170 ConstructInitialSettingsPacket(packet_num++));
5171 }
5172 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5173 mock_quic_data.AddWrite(
5174 SYNCHRONOUS,
5175 ConstructClientRequestHeadersPacket(
5176 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5177 true, GetRequestHeaders("GET", "https", "/")));
5178 // Read a close connection packet with
5179 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
5180 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
5181 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5182
5183 // The non-alternate protocol job needs to hang in order to guarantee that
5184 // the alternate-protocol job will "win".
5185 AddHangingNonAlternateProtocolSocketData();
5186
5187 // In order for a new QUIC session to be established via alternate-protocol
5188 // without racing an HTTP connection, we need the host resolution to happen
5189 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5190 // connection to the the server, in this test we require confirmation
5191 // before encrypting so the HTTP job will still start.
5192 host_resolver_.set_synchronous_mode(true);
5193 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5194 "");
5195
5196 CreateSession();
5197 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5198 false);
5199 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
5200
5201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5202 TestCompletionCallback callback;
5203 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5204 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5205
5206 crypto_client_stream_factory_.last_stream()
5207 ->NotifySessionOneRttKeyAvailable();
5208 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5209
5210 NetErrorDetails details;
5211 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
5212
5213 trans.PopulateNetErrorDetails(&details);
5214 // Verify the error code logged is what sent by the peer.
5215 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5216 details.quic_connection_error);
5217 }
5218
TEST_P(QuicNetworkTransactionTest,LogGranularQuicErrorCodeOnQuicProtocolErrorRemote)5219 TEST_P(QuicNetworkTransactionTest,
5220 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
5221 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5222 MockQuicData mock_quic_data(version_);
5223 int packet_num = 1;
5224 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
5225 if (VersionUsesHttp3(version_.transport_version)) {
5226 mock_quic_data.AddWrite(SYNCHRONOUS,
5227 ConstructInitialSettingsPacket(packet_num++));
5228 }
5229 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5230 mock_quic_data.AddWrite(
5231 SYNCHRONOUS,
5232 ConstructClientRequestHeadersPacket(
5233 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5234 true, GetRequestHeaders("GET", "https", "/")));
5235 // Peer sending data from an non-existing stream causes this end to raise
5236 // error and close connection.
5237 mock_quic_data.AddRead(
5238 ASYNC, ConstructServerRstPacket(
5239 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5240 quic::QUIC_STREAM_LAST_ERROR));
5241 std::string quic_error_details = "Data for nonexistent stream";
5242 mock_quic_data.AddWrite(
5243 SYNCHRONOUS,
5244 ConstructClientAckAndConnectionClosePacket(
5245 packet_num++, 1, 1,
5246 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5247 : quic::QUIC_INVALID_STREAM_ID,
5248 quic_error_details, quic::IETF_RST_STREAM));
5249 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5250
5251 // The non-alternate protocol job needs to hang in order to guarantee that
5252 // the alternate-protocol job will "win".
5253 AddHangingNonAlternateProtocolSocketData();
5254
5255 // In order for a new QUIC session to be established via alternate-protocol
5256 // without racing an HTTP connection, we need the host resolution to happen
5257 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5258 // connection to the the server, in this test we require confirmation
5259 // before encrypting so the HTTP job will still start.
5260 host_resolver_.set_synchronous_mode(true);
5261 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5262 "");
5263
5264 CreateSession();
5265 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5266 false);
5267 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
5268
5269 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5270 TestCompletionCallback callback;
5271 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5272 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5273
5274 crypto_client_stream_factory_.last_stream()
5275 ->NotifySessionOneRttKeyAvailable();
5276 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5277 NetErrorDetails details;
5278 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
5279
5280 trans.PopulateNetErrorDetails(&details);
5281 EXPECT_EQ(version_.HasIetfQuicFrames()
5282 ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5283 : quic::QUIC_INVALID_STREAM_ID,
5284 details.quic_connection_error);
5285 }
5286
TEST_P(QuicNetworkTransactionTest,RstStreamErrorHandling)5287 TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
5288 MockQuicData mock_quic_data(version_);
5289 int packet_num = 1;
5290 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
5291 if (VersionUsesHttp3(version_.transport_version)) {
5292 mock_quic_data.AddWrite(SYNCHRONOUS,
5293 ConstructInitialSettingsPacket(packet_num++));
5294 }
5295 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5296 mock_quic_data.AddWrite(
5297 SYNCHRONOUS,
5298 ConstructClientRequestHeadersPacket(
5299 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5300 true, GetRequestHeaders("GET", "https", "/")));
5301 // Read the response headers, then a RST_STREAM frame.
5302 mock_quic_data.AddRead(
5303 ASYNC, ConstructServerResponseHeadersPacket(
5304 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5305 GetResponseHeaders("200 OK")));
5306 mock_quic_data.AddRead(
5307 ASYNC, ConstructServerRstPacket(
5308 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5309 quic::QUIC_STREAM_CANCELLED));
5310
5311 if (VersionUsesHttp3(version_.transport_version)) {
5312 mock_quic_data.AddWrite(
5313 SYNCHRONOUS, ConstructClientAckAndDataPacket(
5314 packet_num++, false, GetQpackDecoderStreamId(), 2, 1,
5315 false, StreamCancellationQpackDecoderInstruction(0)));
5316 } else {
5317 mock_quic_data.AddWrite(SYNCHRONOUS,
5318 ConstructClientAckPacket(packet_num++, 2, 1));
5319 }
5320 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5321 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5322
5323 // The non-alternate protocol job needs to hang in order to guarantee that
5324 // the alternate-protocol job will "win".
5325 AddHangingNonAlternateProtocolSocketData();
5326
5327 // In order for a new QUIC session to be established via alternate-protocol
5328 // without racing an HTTP connection, we need the host resolution to happen
5329 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5330 // connection to the the server, in this test we require confirmation
5331 // before encrypting so the HTTP job will still start.
5332 host_resolver_.set_synchronous_mode(true);
5333 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5334 "");
5335
5336 CreateSession();
5337 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5338 false);
5339 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
5340
5341 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5342 TestCompletionCallback callback;
5343 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5344 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5345
5346 crypto_client_stream_factory_.last_stream()
5347 ->NotifySessionOneRttKeyAvailable();
5348 // Read the headers.
5349 EXPECT_THAT(callback.WaitForResult(), IsOk());
5350
5351 const HttpResponseInfo* response = trans.GetResponseInfo();
5352 ASSERT_TRUE(response != nullptr);
5353 ASSERT_TRUE(response->headers.get() != nullptr);
5354 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5355 EXPECT_TRUE(response->was_fetched_via_spdy);
5356 EXPECT_TRUE(response->was_alpn_negotiated);
5357 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5358 response->connection_info);
5359
5360 std::string response_data;
5361 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
5362 }
5363
TEST_P(QuicNetworkTransactionTest,RstStreamBeforeHeaders)5364 TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
5365 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5366 MockQuicData mock_quic_data(version_);
5367 int packet_num = 1;
5368 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
5369 if (VersionUsesHttp3(version_.transport_version)) {
5370 mock_quic_data.AddWrite(SYNCHRONOUS,
5371 ConstructInitialSettingsPacket(packet_num++));
5372 }
5373 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5374 mock_quic_data.AddWrite(
5375 SYNCHRONOUS,
5376 ConstructClientRequestHeadersPacket(
5377 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5378 true, GetRequestHeaders("GET", "https", "/")));
5379 mock_quic_data.AddRead(
5380 ASYNC, ConstructServerRstPacket(
5381 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5382 quic::QUIC_STREAM_CANCELLED));
5383
5384 if (VersionUsesHttp3(version_.transport_version)) {
5385 mock_quic_data.AddWrite(
5386 SYNCHRONOUS, ConstructClientAckAndDataPacket(
5387 packet_num++, false, GetQpackDecoderStreamId(), 1, 1,
5388 false, StreamCancellationQpackDecoderInstruction(0)));
5389 }
5390
5391 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5392 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5393
5394 // The non-alternate protocol job needs to hang in order to guarantee that
5395 // the alternate-protocol job will "win".
5396 AddHangingNonAlternateProtocolSocketData();
5397
5398 // In order for a new QUIC session to be established via alternate-protocol
5399 // without racing an HTTP connection, we need the host resolution to happen
5400 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5401 // connection to the the server, in this test we require confirmation
5402 // before encrypting so the HTTP job will still start.
5403 host_resolver_.set_synchronous_mode(true);
5404 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5405 "");
5406
5407 CreateSession();
5408 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5409 false);
5410 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
5411
5412 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5413 TestCompletionCallback callback;
5414 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5416
5417 crypto_client_stream_factory_.last_stream()
5418 ->NotifySessionOneRttKeyAvailable();
5419 // Read the headers.
5420 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5421 }
5422
TEST_P(QuicNetworkTransactionTest,BrokenAlternateProtocol)5423 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
5424 // Alternate-protocol job
5425 std::unique_ptr<quic::QuicEncryptedPacket> close(
5426 ConstructServerConnectionClosePacket(1));
5427 MockRead quic_reads[] = {
5428 MockRead(ASYNC, close->data(), close->length()),
5429 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5430 MockRead(ASYNC, OK), // EOF
5431 };
5432 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5433 socket_factory_.AddSocketDataProvider(&quic_data);
5434
5435 // Main job which will succeed even though the alternate job fails.
5436 MockRead http_reads[] = {
5437 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5438 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5439 MockRead(ASYNC, OK)};
5440
5441 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5442 socket_factory_.AddSocketDataProvider(&http_data);
5443 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5444
5445 CreateSession();
5446 AddQuicAlternateProtocolMapping(
5447 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5448 SendRequestAndExpectHttpResponse("hello from http");
5449 ExpectBrokenAlternateProtocolMapping();
5450 }
5451
TEST_P(QuicNetworkTransactionTest,BrokenAlternateProtocolWithNetworkIsolationKey)5452 TEST_P(QuicNetworkTransactionTest,
5453 BrokenAlternateProtocolWithNetworkIsolationKey) {
5454 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5455 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5456 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5457 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5458
5459 base::test::ScopedFeatureList feature_list;
5460 feature_list.InitWithFeatures(
5461 // enabled_features
5462 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5463 features::kPartitionConnectionsByNetworkIsolationKey},
5464 // disabled_features
5465 {});
5466 // Since HttpServerProperties caches the feature value, have to create a new
5467 // one.
5468 http_server_properties_ = std::make_unique<HttpServerProperties>();
5469
5470 // Alternate-protocol job
5471 std::unique_ptr<quic::QuicEncryptedPacket> close(
5472 ConstructServerConnectionClosePacket(1));
5473 MockRead quic_reads[] = {
5474 MockRead(ASYNC, close->data(), close->length()),
5475 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5476 MockRead(ASYNC, OK), // EOF
5477 };
5478 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5479 socket_factory_.AddSocketDataProvider(&quic_data);
5480
5481 // Main job which will succeed even though the alternate job fails.
5482 MockRead http_reads[] = {
5483 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5484 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5485 MockRead(ASYNC, OK)};
5486
5487 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5488 socket_factory_.AddSocketDataProvider(&http_data);
5489 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5490
5491 CreateSession();
5492 AddQuicAlternateProtocolMapping(
5493 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5494 AddQuicAlternateProtocolMapping(
5495 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5496 request_.network_isolation_key = kNetworkIsolationKey1;
5497 SendRequestAndExpectHttpResponse("hello from http");
5498
5499 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5500 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5501 }
5502
TEST_P(QuicNetworkTransactionTest,BrokenAlternateProtocolReadError)5503 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
5504 // Alternate-protocol job
5505 MockRead quic_reads[] = {
5506 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5507 };
5508 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5509 socket_factory_.AddSocketDataProvider(&quic_data);
5510
5511 // Main job which will succeed even though the alternate job fails.
5512 MockRead http_reads[] = {
5513 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5514 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5515 MockRead(ASYNC, OK)};
5516
5517 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5518 socket_factory_.AddSocketDataProvider(&http_data);
5519 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5520
5521 CreateSession();
5522
5523 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
5524 SendRequestAndExpectHttpResponse("hello from http");
5525 ExpectBrokenAlternateProtocolMapping();
5526 }
5527
TEST_P(QuicNetworkTransactionTest,NoBrokenAlternateProtocolIfTcpFails)5528 TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
5529 // Alternate-protocol job will fail when the session attempts to read.
5530 MockRead quic_reads[] = {
5531 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5532 };
5533 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5534 socket_factory_.AddSocketDataProvider(&quic_data);
5535
5536 // Main job will also fail.
5537 MockRead http_reads[] = {
5538 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5539 };
5540
5541 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5542 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5543 socket_factory_.AddSocketDataProvider(&http_data);
5544 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5545
5546 AddHangingNonAlternateProtocolSocketData();
5547 CreateSession();
5548
5549 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
5550 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5551 TestCompletionCallback callback;
5552 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5553 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5554 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
5555 ExpectQuicAlternateProtocolMapping();
5556 }
5557
TEST_P(QuicNetworkTransactionTest,DelayTCPOnStartWithQuicSupportOnSameIP)5558 TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5559 // Tests that TCP job is delayed and QUIC job does not require confirmation
5560 // if QUIC was recently supported on the same IP on start.
5561
5562 // Set QUIC support on the last IP address, which is same with the local IP
5563 // address. Require confirmation mode will be turned off immediately when
5564 // local IP address is sorted out after we configure the UDP socket.
5565 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5566 IPAddress(192, 0, 2, 33));
5567
5568 MockQuicData mock_quic_data(version_);
5569 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
5570 int packet_number = 1;
5571 if (VersionUsesHttp3(version_.transport_version)) {
5572 mock_quic_data.AddWrite(SYNCHRONOUS,
5573 ConstructInitialSettingsPacket(packet_number++));
5574 }
5575 mock_quic_data.AddWrite(
5576 SYNCHRONOUS,
5577 ConstructClientRequestHeadersPacket(
5578 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5579 true, GetRequestHeaders("GET", "https", "/")));
5580 mock_quic_data.AddRead(
5581 ASYNC, ConstructServerResponseHeadersPacket(
5582 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5583 GetResponseHeaders("200 OK")));
5584 mock_quic_data.AddRead(
5585 ASYNC, ConstructServerDataPacket(
5586 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5587 ConstructDataFrame("hello!")));
5588 if (version_.UsesTls()) {
5589 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5590 }
5591 mock_quic_data.AddWrite(SYNCHRONOUS,
5592 ConstructClientAckPacket(packet_number++, 2, 1));
5593 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5594 mock_quic_data.AddRead(ASYNC, 0); // EOF
5595
5596 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5597 // No HTTP data is mocked as TCP job never starts in this case.
5598
5599 CreateSession();
5600 // QuicStreamFactory by default requires confirmation on construction.
5601 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5602 false);
5603
5604 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
5605
5606 // Stall host resolution so that QUIC job will not succeed synchronously.
5607 // Socket will not be configured immediately and QUIC support is not sorted
5608 // out, TCP job will still be delayed as server properties indicates QUIC
5609 // support on last IP address.
5610 host_resolver_.set_synchronous_mode(false);
5611
5612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5613 TestCompletionCallback callback;
5614 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5615 IsError(ERR_IO_PENDING));
5616 // Complete host resolution in next message loop so that QUIC job could
5617 // proceed.
5618 base::RunLoop().RunUntilIdle();
5619 EXPECT_THAT(callback.WaitForResult(), IsOk());
5620
5621 CheckWasQuicResponse(&trans);
5622 CheckResponseData(&trans, "hello!");
5623 }
5624
TEST_P(QuicNetworkTransactionTest,DelayTCPOnStartWithQuicSupportOnDifferentIP)5625 TEST_P(QuicNetworkTransactionTest,
5626 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5627 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5628 // was recently supported on a different IP address on start.
5629
5630 // Set QUIC support on the last IP address, which is different with the local
5631 // IP address. Require confirmation mode will remain when local IP address is
5632 // sorted out after we configure the UDP socket.
5633 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5634 IPAddress(1, 2, 3, 4));
5635
5636 MockQuicData mock_quic_data(version_);
5637 int packet_num = 1;
5638 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
5639 if (VersionUsesHttp3(version_.transport_version)) {
5640 mock_quic_data.AddWrite(SYNCHRONOUS,
5641 ConstructInitialSettingsPacket(packet_num++));
5642 }
5643 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5644 mock_quic_data.AddWrite(
5645 SYNCHRONOUS,
5646 ConstructClientRequestHeadersPacket(
5647 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5648 true, GetRequestHeaders("GET", "https", "/")));
5649 mock_quic_data.AddRead(
5650 ASYNC, ConstructServerResponseHeadersPacket(
5651 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5652 GetResponseHeaders("200 OK")));
5653 mock_quic_data.AddRead(
5654 ASYNC, ConstructServerDataPacket(
5655 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5656 ConstructDataFrame("hello!")));
5657 mock_quic_data.AddWrite(SYNCHRONOUS,
5658 ConstructClientAckPacket(packet_num++, 2, 1));
5659 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5660 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5661 // No HTTP data is mocked as TCP job will be delayed and never starts.
5662
5663 CreateSession();
5664 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5665 false);
5666 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
5667
5668 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5669 // Socket will not be configured immediately and QUIC support is not sorted
5670 // out, TCP job will still be delayed as server properties indicates QUIC
5671 // support on last IP address.
5672 host_resolver_.set_synchronous_mode(false);
5673
5674 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5675 TestCompletionCallback callback;
5676 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5677 IsError(ERR_IO_PENDING));
5678
5679 // Complete host resolution in next message loop so that QUIC job could
5680 // proceed.
5681 base::RunLoop().RunUntilIdle();
5682 // Explicitly confirm the handshake so that QUIC job could succeed.
5683 crypto_client_stream_factory_.last_stream()
5684 ->NotifySessionOneRttKeyAvailable();
5685 EXPECT_THAT(callback.WaitForResult(), IsOk());
5686
5687 CheckWasQuicResponse(&trans);
5688 CheckResponseData(&trans, "hello!");
5689 }
5690
TEST_P(QuicNetworkTransactionTest,NetErrorDetailsSetBeforeHandshake)5691 TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5692 // Test that NetErrorDetails is correctly populated, even if the
5693 // handshake has not yet been confirmed and no stream has been created.
5694
5695 // QUIC job will pause. When resumed, it will fail.
5696 MockQuicData mock_quic_data(version_);
5697 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5698 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5699 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5700
5701 // Main job will also fail.
5702 MockRead http_reads[] = {
5703 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5704 };
5705
5706 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5707 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5708 socket_factory_.AddSocketDataProvider(&http_data);
5709 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5710
5711 AddHangingNonAlternateProtocolSocketData();
5712 CreateSession();
5713 // Require handshake confirmation to ensure that no QUIC streams are
5714 // created, and to ensure that the TCP job does not wait for the QUIC
5715 // job to fail before it starts.
5716 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5717 false);
5718
5719 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
5720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5721 TestCompletionCallback callback;
5722 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5724 // Allow the TCP job to fail.
5725 base::RunLoop().RunUntilIdle();
5726 // Now let the QUIC job fail.
5727 mock_quic_data.Resume();
5728 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5729 ExpectQuicAlternateProtocolMapping();
5730 NetErrorDetails details;
5731 trans.PopulateNetErrorDetails(&details);
5732 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
5733 }
5734
TEST_P(QuicNetworkTransactionTest,FailedZeroRttBrokenAlternateProtocol)5735 TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
5736 // Alternate-protocol job
5737 MockRead quic_reads[] = {
5738 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5739 };
5740 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5741 socket_factory_.AddSocketDataProvider(&quic_data);
5742
5743 // Second Alternate-protocol job which will race with the TCP job.
5744 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5745 socket_factory_.AddSocketDataProvider(&quic_data2);
5746
5747 // Final job that will proceed when the QUIC job fails.
5748 MockRead http_reads[] = {
5749 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5750 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5751 MockRead(ASYNC, OK)};
5752
5753 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5754 socket_factory_.AddSocketDataProvider(&http_data);
5755 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5756
5757 CreateSession();
5758
5759 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
5760
5761 SendRequestAndExpectHttpResponse("hello from http");
5762
5763 ExpectBrokenAlternateProtocolMapping();
5764
5765 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5766 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
5767 }
5768
TEST_P(QuicNetworkTransactionTest,FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey)5769 TEST_P(QuicNetworkTransactionTest,
5770 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5771 base::test::ScopedFeatureList feature_list;
5772 feature_list.InitWithFeatures(
5773 // enabled_features
5774 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5775 features::kPartitionConnectionsByNetworkIsolationKey},
5776 // disabled_features
5777 {});
5778 // Since HttpServerProperties caches the feature value, have to create a new
5779 // one.
5780 http_server_properties_ = std::make_unique<HttpServerProperties>();
5781
5782 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5783 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5784 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5785 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5786
5787 // Alternate-protocol job
5788 MockRead quic_reads[] = {
5789 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5790 };
5791 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5792 socket_factory_.AddSocketDataProvider(&quic_data);
5793
5794 // Second Alternate-protocol job which will race with the TCP job.
5795 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5796 socket_factory_.AddSocketDataProvider(&quic_data2);
5797
5798 // Final job that will proceed when the QUIC job fails.
5799 MockRead http_reads[] = {
5800 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5801 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5802 MockRead(ASYNC, OK)};
5803
5804 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5805 socket_factory_.AddSocketDataProvider(&http_data);
5806 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5807
5808 CreateSession();
5809
5810 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
5811 kNetworkIsolationKey1);
5812 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
5813 kNetworkIsolationKey2);
5814
5815 request_.network_isolation_key = kNetworkIsolationKey1;
5816 SendRequestAndExpectHttpResponse("hello from http");
5817 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5818 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
5819
5820 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5821 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5822
5823 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
5824 AddHttpDataAndRunRequest();
5825 // Requests using other NetworkIsolationKeys can still use QUIC.
5826 request_.network_isolation_key = kNetworkIsolationKey2;
5827 AddQuicDataAndRunRequest();
5828
5829 // The last two requests should not have changed the alternative service
5830 // mappings.
5831 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5832 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5833 }
5834
TEST_P(QuicNetworkTransactionTest,BrokenAlternateProtocolOnConnectFailure)5835 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
5836 // Alternate-protocol job will fail before creating a QUIC session.
5837 StaticSocketDataProvider quic_data;
5838 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
5839 socket_factory_.AddSocketDataProvider(&quic_data);
5840
5841 // Main job which will succeed even though the alternate job fails.
5842 MockRead http_reads[] = {
5843 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5844 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5845 MockRead(ASYNC, OK)};
5846
5847 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5848 socket_factory_.AddSocketDataProvider(&http_data);
5849 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5850
5851 CreateSession();
5852 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
5853 SendRequestAndExpectHttpResponse("hello from http");
5854
5855 ExpectBrokenAlternateProtocolMapping();
5856 }
5857
TEST_P(QuicNetworkTransactionTest,ConnectionCloseDuringConnect)5858 TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
5859 MockQuicData mock_quic_data(version_);
5860 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
5861 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
5862 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5863
5864 // When the QUIC connection fails, we will try the request again over HTTP.
5865 MockRead http_reads[] = {
5866 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5867 MockRead("hello world"),
5868 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5869 MockRead(ASYNC, OK)};
5870
5871 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5872 socket_factory_.AddSocketDataProvider(&http_data);
5873 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5874
5875 // In order for a new QUIC session to be established via alternate-protocol
5876 // without racing an HTTP connection, we need the host resolution to happen
5877 // synchronously.
5878 host_resolver_.set_synchronous_mode(true);
5879 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5880 "");
5881
5882 CreateSession();
5883 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5884 AddQuicAlternateProtocolMapping(
5885 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5886 SendRequestAndExpectHttpResponse("hello world");
5887 }
5888
TEST_P(QuicNetworkTransactionTest,ConnectionCloseDuringConnectProxy)5889 TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5890 MockQuicData mock_quic_data(version_);
5891 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
5892 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
5893 mock_quic_data.AddWrite(
5894 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5895 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5896 true, GetRequestHeaders("GET", "https", "/")));
5897 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1));
5898 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5899
5900 // When the QUIC connection fails, we will try the request again over HTTP.
5901 MockRead http_reads[] = {
5902 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5903 MockRead("hello world"),
5904 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5905 MockRead(ASYNC, OK)};
5906
5907 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5908 socket_factory_.AddSocketDataProvider(&http_data);
5909 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5910
5911 TestProxyDelegate test_proxy_delegate;
5912 const HostPortPair host_port_pair("myproxy.org", 443);
5913
5914 proxy_resolution_service_ =
5915 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5916 "QUIC myproxy.org:443; HTTPS myproxy.org:443",
5917 TRAFFIC_ANNOTATION_FOR_TESTS);
5918 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
5919 request_.url = GURL("http://mail.example.org/");
5920
5921 // In order for a new QUIC session to be established via alternate-protocol
5922 // without racing an HTTP connection, we need the host resolution to happen
5923 // synchronously.
5924 host_resolver_.set_synchronous_mode(true);
5925 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
5926
5927 CreateSession();
5928 crypto_client_stream_factory_.set_handshake_mode(
5929 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5930 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
5931 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
5932 ElementsAre(Key("quic://myproxy.org:443")));
5933 }
5934
TEST_P(QuicNetworkTransactionTest,SecureResourceOverSecureQuic)5935 TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
5936 client_maker_->set_hostname("www.example.org");
5937 EXPECT_FALSE(
5938 test_socket_performance_watcher_factory_.rtt_notification_received());
5939 MockQuicData mock_quic_data(version_);
5940 int packet_num = 1;
5941 if (VersionUsesHttp3(version_.transport_version)) {
5942 mock_quic_data.AddWrite(SYNCHRONOUS,
5943 ConstructInitialSettingsPacket(packet_num++));
5944 }
5945 mock_quic_data.AddWrite(
5946 SYNCHRONOUS,
5947 ConstructClientRequestHeadersPacket(
5948 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5949 true, GetRequestHeaders("GET", "https", "/")));
5950 mock_quic_data.AddRead(
5951 ASYNC, ConstructServerResponseHeadersPacket(
5952 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5953 GetResponseHeaders("200 OK")));
5954 mock_quic_data.AddRead(
5955 ASYNC, ConstructServerDataPacket(
5956 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5957 ConstructDataFrame("hello!")));
5958 mock_quic_data.AddWrite(SYNCHRONOUS,
5959 ConstructClientAckPacket(packet_num++, 2, 1));
5960 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5961 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5962
5963 request_.url = GURL("https://www.example.org:443");
5964 AddHangingNonAlternateProtocolSocketData();
5965 CreateSession();
5966 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
5967 SendRequestAndExpectQuicResponse("hello!");
5968 EXPECT_TRUE(
5969 test_socket_performance_watcher_factory_.rtt_notification_received());
5970 }
5971
TEST_P(QuicNetworkTransactionTest,QuicUpload)5972 TEST_P(QuicNetworkTransactionTest, QuicUpload) {
5973 context_.params()->origins_to_force_quic_on.insert(
5974 HostPortPair::FromString("mail.example.org:443"));
5975
5976 MockQuicData mock_quic_data(version_);
5977 if (!VersionUsesHttp3(version_.transport_version))
5978 mock_quic_data.AddRead(SYNCHRONOUS, OK);
5979 else
5980 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5981 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5982 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5983
5984 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5985 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
5986 MockWrite writes[] = {};
5987 SequencedSocketData socket_data(reads, writes);
5988 socket_factory_.AddSocketDataProvider(&socket_data);*/
5989
5990 // The non-alternate protocol job needs to hang in order to guarantee that
5991 // the alternate-protocol job will "win".
5992 AddHangingNonAlternateProtocolSocketData();
5993
5994 CreateSession();
5995 request_.method = "POST";
5996 ChunkedUploadDataStream upload_data(0);
5997 upload_data.AppendData("1", 1, true);
5998
5999 request_.upload_data_stream = &upload_data;
6000
6001 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6002 TestCompletionCallback callback;
6003 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6005 EXPECT_NE(OK, callback.WaitForResult());
6006 }
6007
TEST_P(QuicNetworkTransactionTest,QuicUploadWriteError)6008 TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
6009 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6010 ScopedMockNetworkChangeNotifier network_change_notifier;
6011 MockNetworkChangeNotifier* mock_ncn =
6012 network_change_notifier.mock_network_change_notifier();
6013 mock_ncn->ForceNetworkHandlesSupported();
6014 mock_ncn->SetConnectedNetworksList(
6015 {kDefaultNetworkForTests, kNewNetworkForTests});
6016
6017 context_.params()->origins_to_force_quic_on.insert(
6018 HostPortPair::FromString("mail.example.org:443"));
6019 context_.params()->migrate_sessions_on_network_change_v2 = true;
6020
6021 MockQuicData socket_data(version_);
6022 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6023 int packet_num = 1;
6024 if (VersionUsesHttp3(version_.transport_version)) {
6025 socket_data.AddWrite(SYNCHRONOUS,
6026 ConstructInitialSettingsPacket(packet_num++));
6027 }
6028 socket_data.AddWrite(
6029 SYNCHRONOUS,
6030 ConstructClientRequestHeadersPacket(
6031 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6032 false, GetRequestHeaders("POST", "https", "/")));
6033 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6034 socket_data.AddSocketDataToFactory(&socket_factory_);
6035
6036 MockQuicData socket_data2(version_);
6037 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6038 socket_data2.AddSocketDataToFactory(&socket_factory_);
6039
6040 // The non-alternate protocol job needs to hang in order to guarantee that
6041 // the alternate-protocol job will "win".
6042 AddHangingNonAlternateProtocolSocketData();
6043
6044 CreateSession();
6045 request_.method = "POST";
6046 ChunkedUploadDataStream upload_data(0);
6047
6048 request_.upload_data_stream = &upload_data;
6049
6050 std::unique_ptr<HttpNetworkTransaction> trans(
6051 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
6052 TestCompletionCallback callback;
6053 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
6054 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6055
6056 base::RunLoop().RunUntilIdle();
6057 upload_data.AppendData("1", 1, true);
6058 base::RunLoop().RunUntilIdle();
6059
6060 EXPECT_NE(OK, callback.WaitForResult());
6061 trans.reset();
6062 session_.reset();
6063 }
6064
TEST_P(QuicNetworkTransactionTest,RetryAfterAsyncNoBufferSpace)6065 TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6066 context_.params()->origins_to_force_quic_on.insert(
6067 HostPortPair::FromString("mail.example.org:443"));
6068
6069 MockQuicData socket_data(version_);
6070 int packet_num = 1;
6071 if (VersionUsesHttp3(version_.transport_version)) {
6072 socket_data.AddWrite(SYNCHRONOUS,
6073 ConstructInitialSettingsPacket(packet_num++));
6074 }
6075 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6076 socket_data.AddWrite(
6077 SYNCHRONOUS,
6078 ConstructClientRequestHeadersPacket(
6079 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6080 true, GetRequestHeaders("GET", "https", "/")));
6081 socket_data.AddRead(
6082 ASYNC, ConstructServerResponseHeadersPacket(
6083 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6084 GetResponseHeaders("200 OK")));
6085 socket_data.AddRead(
6086 ASYNC, ConstructServerDataPacket(
6087 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6088 ConstructDataFrame("hello!")));
6089 socket_data.AddWrite(SYNCHRONOUS,
6090 ConstructClientAckPacket(packet_num++, 2, 1));
6091 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6092 socket_data.AddWrite(SYNCHRONOUS,
6093 client_maker_->MakeAckAndConnectionClosePacket(
6094 packet_num++, false, 2, 1,
6095 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
6096
6097 socket_data.AddSocketDataToFactory(&socket_factory_);
6098
6099 CreateSession();
6100
6101 SendRequestAndExpectQuicResponse("hello!");
6102 session_.reset();
6103 }
6104
TEST_P(QuicNetworkTransactionTest,RetryAfterSynchronousNoBufferSpace)6105 TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6106 context_.params()->origins_to_force_quic_on.insert(
6107 HostPortPair::FromString("mail.example.org:443"));
6108
6109 MockQuicData socket_data(version_);
6110 int packet_num = 1;
6111 if (VersionUsesHttp3(version_.transport_version)) {
6112 socket_data.AddWrite(SYNCHRONOUS,
6113 ConstructInitialSettingsPacket(packet_num++));
6114 }
6115 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
6116 socket_data.AddWrite(
6117 SYNCHRONOUS,
6118 ConstructClientRequestHeadersPacket(
6119 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6120 true, GetRequestHeaders("GET", "https", "/")));
6121 socket_data.AddRead(
6122 ASYNC, ConstructServerResponseHeadersPacket(
6123 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6124 GetResponseHeaders("200 OK")));
6125 socket_data.AddRead(
6126 ASYNC, ConstructServerDataPacket(
6127 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6128 ConstructDataFrame("hello!")));
6129 socket_data.AddWrite(SYNCHRONOUS,
6130 ConstructClientAckPacket(packet_num++, 2, 1));
6131 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6132 socket_data.AddWrite(SYNCHRONOUS,
6133 client_maker_->MakeAckAndConnectionClosePacket(
6134 packet_num++, false, 2, 1,
6135 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
6136
6137 socket_data.AddSocketDataToFactory(&socket_factory_);
6138
6139 CreateSession();
6140
6141 SendRequestAndExpectQuicResponse("hello!");
6142 session_.reset();
6143 }
6144
TEST_P(QuicNetworkTransactionTest,MaxRetriesAfterAsyncNoBufferSpace)6145 TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
6146 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6147 context_.params()->origins_to_force_quic_on.insert(
6148 HostPortPair::FromString("mail.example.org:443"));
6149
6150 MockQuicData socket_data(version_);
6151 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6152 if (VersionUsesHttp3(version_.transport_version))
6153 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
6154 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
6155 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6156 }
6157 socket_data.AddSocketDataToFactory(&socket_factory_);
6158
6159 CreateSession();
6160 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6161 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6162 quic_task_runner_.get());
6163
6164 quic::QuicTime start = context_.clock()->Now();
6165 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6166 TestCompletionCallback callback;
6167 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6168 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6169 while (!callback.have_result()) {
6170 base::RunLoop().RunUntilIdle();
6171 quic_task_runner_->RunUntilIdle();
6172 }
6173 ASSERT_TRUE(callback.have_result());
6174 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6175 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6176 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6177 // Backoff should take between 4 - 5 seconds.
6178 EXPECT_TRUE(context_.clock()->Now() - start >
6179 quic::QuicTime::Delta::FromSeconds(4));
6180 EXPECT_TRUE(context_.clock()->Now() - start <
6181 quic::QuicTime::Delta::FromSeconds(5));
6182 }
6183
TEST_P(QuicNetworkTransactionTest,MaxRetriesAfterSynchronousNoBufferSpace)6184 TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
6185 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6186 context_.params()->origins_to_force_quic_on.insert(
6187 HostPortPair::FromString("mail.example.org:443"));
6188
6189 MockQuicData socket_data(version_);
6190 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6191 if (VersionUsesHttp3(version_.transport_version))
6192 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
6193 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
6194 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6195 }
6196 socket_data.AddSocketDataToFactory(&socket_factory_);
6197
6198 CreateSession();
6199 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6200 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6201 quic_task_runner_.get());
6202
6203 quic::QuicTime start = context_.clock()->Now();
6204 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6205 TestCompletionCallback callback;
6206 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6207 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6208 while (!callback.have_result()) {
6209 base::RunLoop().RunUntilIdle();
6210 quic_task_runner_->RunUntilIdle();
6211 }
6212 ASSERT_TRUE(callback.have_result());
6213 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6214 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6215 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6216 // Backoff should take between 4 - 5 seconds.
6217 EXPECT_TRUE(context_.clock()->Now() - start >
6218 quic::QuicTime::Delta::FromSeconds(4));
6219 EXPECT_TRUE(context_.clock()->Now() - start <
6220 quic::QuicTime::Delta::FromSeconds(5));
6221 }
6222
TEST_P(QuicNetworkTransactionTest,NoMigrationForMsgTooBig)6223 TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
6224 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6225 context_.params()->origins_to_force_quic_on.insert(
6226 HostPortPair::FromString("mail.example.org:443"));
6227 const std::string error_details = base::StrCat(
6228 {"Write failed with error: ", base::NumberToString(ERR_MSG_TOO_BIG), " (",
6229 strerror(ERR_MSG_TOO_BIG), ")"});
6230
6231 MockQuicData socket_data(version_);
6232 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6233 int packet_num = 1;
6234 if (VersionUsesHttp3(version_.transport_version)) {
6235 socket_data.AddWrite(SYNCHRONOUS,
6236 ConstructInitialSettingsPacket(packet_num++));
6237 }
6238 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6239 // Connection close packet will be sent for MSG_TOO_BIG.
6240 socket_data.AddWrite(
6241 SYNCHRONOUS,
6242 client_maker_->MakeConnectionClosePacket(
6243 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
6244 socket_data.AddSocketDataToFactory(&socket_factory_);
6245
6246 CreateSession();
6247
6248 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6249 TestCompletionCallback callback;
6250 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6251 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6252 base::RunLoop().RunUntilIdle();
6253 ASSERT_TRUE(callback.have_result());
6254 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6255 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6256 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6257 }
6258
6259 // Adds coverage to catch regression such as https://crbug.com/622043
TEST_P(QuicNetworkTransactionTest,QuicServerPush)6260 TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
6261 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
6262 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
6263 context_.params()->origins_to_force_quic_on.insert(
6264 HostPortPair::FromString("mail.example.org:443"));
6265
6266 MockQuicData mock_quic_data(version_);
6267 uint64_t client_packet_number = 1;
6268 if (VersionUsesHttp3(version_.transport_version)) {
6269 mock_quic_data.AddWrite(
6270 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6271 }
6272 mock_quic_data.AddWrite(
6273 SYNCHRONOUS,
6274 ConstructClientRequestHeadersPacket(
6275 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6276 true, true, GetRequestHeaders("GET", "https", "/")));
6277 mock_quic_data.AddRead(
6278 ASYNC, ConstructServerPushPromisePacket(
6279 1, GetNthClientInitiatedBidirectionalStreamId(0),
6280 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6281 GetRequestHeaders("GET", "https", "/pushed.jpg")));
6282 const bool should_send_priority_packet =
6283 client_headers_include_h2_stream_dependency_ &&
6284 !VersionUsesHttp3(version_.transport_version);
6285 if (should_send_priority_packet) {
6286 mock_quic_data.AddWrite(
6287 SYNCHRONOUS,
6288 ConstructClientAckAndPriorityPacket(
6289 client_packet_number++, false,
6290 /*largest_received=*/1, /*smallest_received=*/1,
6291 GetNthServerInitiatedUnidirectionalStreamId(0),
6292 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
6293 }
6294 mock_quic_data.AddRead(
6295 ASYNC, ConstructServerResponseHeadersPacket(
6296 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6297 GetResponseHeaders("200 OK")));
6298 if (!should_send_priority_packet) {
6299 mock_quic_data.AddWrite(
6300 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
6301 }
6302 mock_quic_data.AddRead(
6303 ASYNC, ConstructServerResponseHeadersPacket(
6304 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6305 false, GetResponseHeaders("200 OK")));
6306 if (should_send_priority_packet) {
6307 mock_quic_data.AddWrite(
6308 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
6309 }
6310 mock_quic_data.AddRead(
6311 ASYNC, ConstructServerDataPacket(
6312 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6313 ConstructDataFrame("hello!")));
6314 if (!should_send_priority_packet) {
6315 mock_quic_data.AddWrite(
6316 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
6317 }
6318 mock_quic_data.AddRead(
6319 ASYNC, ConstructServerDataPacket(
6320 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
6321 ConstructDataFrame("and hello!")));
6322 if (should_send_priority_packet) {
6323 mock_quic_data.AddWrite(
6324 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
6325 }
6326 if (!VersionUsesHttp3(version_.transport_version)) {
6327 mock_quic_data.AddWrite(SYNCHRONOUS,
6328 ConstructClientAckAndRstPacket(
6329 client_packet_number++,
6330 GetNthServerInitiatedUnidirectionalStreamId(0),
6331 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6332 } else {
6333 mock_quic_data.AddWrite(
6334 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
6335 client_packet_number++, true, 5, 5, 3,
6336 GetNthServerInitiatedUnidirectionalStreamId(0)));
6337 }
6338 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6339 mock_quic_data.AddRead(ASYNC, 0); // EOF
6340 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6341
6342 // The non-alternate protocol job needs to hang in order to guarantee that
6343 // the alternate-protocol job will "win".
6344 AddHangingNonAlternateProtocolSocketData();
6345
6346 CreateSession();
6347
6348 // PUSH_PROMISE handling in the http layer gets exercised here.
6349 SendRequestAndExpectQuicResponse("hello!");
6350
6351 request_.url = GURL("https://mail.example.org/pushed.jpg");
6352 SendRequestAndExpectQuicResponse("and hello!");
6353
6354 // Check that the NetLog was filled reasonably.
6355 auto entries = net_log_.GetEntries();
6356 EXPECT_LT(0u, entries.size());
6357
6358 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6359 int pos = ExpectLogContainsSomewhere(
6360 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6361 NetLogEventPhase::NONE);
6362 EXPECT_LT(0, pos);
6363 }
6364
6365 // Checks that if the same resource is pushed using two different
6366 // NetworkIsolationKeys, both pushed resources are tracked independently, and
6367 // NetworkIsolationKeys are respected.
TEST_P(QuicNetworkTransactionTest,QuicServerPushRespectsNetworkIsolationKey)6368 TEST_P(QuicNetworkTransactionTest, QuicServerPushRespectsNetworkIsolationKey) {
6369 base::test::ScopedFeatureList feature_list;
6370 feature_list.InitAndEnableFeature(
6371 features::kPartitionConnectionsByNetworkIsolationKey);
6372 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
6373 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
6374 context_.params()->origins_to_force_quic_on.insert(
6375 HostPortPair::FromString("mail.example.org:443"));
6376
6377 MockQuicData mock_quic_data1(version_);
6378 uint64_t client_packet_number1 = 1;
6379 if (VersionUsesHttp3(version_.transport_version)) {
6380 mock_quic_data1.AddWrite(
6381 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number1++));
6382 }
6383 mock_quic_data1.AddWrite(
6384 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6385 client_packet_number1++,
6386 GetNthClientInitiatedBidirectionalStreamId(0), true,
6387 true, GetRequestHeaders("GET", "https", "/")));
6388 mock_quic_data1.AddRead(
6389 ASYNC, ConstructServerPushPromisePacket(
6390 1, GetNthClientInitiatedBidirectionalStreamId(0),
6391 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6392 GetRequestHeaders("GET", "https", "/pushed.jpg")));
6393 const bool should_send_priority_packet =
6394 client_headers_include_h2_stream_dependency_ &&
6395 !VersionUsesHttp3(version_.transport_version);
6396 if (should_send_priority_packet) {
6397 mock_quic_data1.AddWrite(
6398 SYNCHRONOUS,
6399 ConstructClientAckAndPriorityPacket(
6400 client_packet_number1++, false,
6401 /*largest_received=*/1, /*smallest_received=*/1,
6402 GetNthServerInitiatedUnidirectionalStreamId(0),
6403 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
6404 }
6405 mock_quic_data1.AddRead(
6406 ASYNC, ConstructServerResponseHeadersPacket(
6407 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6408 GetResponseHeaders("200 OK")));
6409 if (!should_send_priority_packet) {
6410 mock_quic_data1.AddWrite(
6411 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 2, 1));
6412 }
6413 mock_quic_data1.AddRead(
6414 ASYNC, ConstructServerResponseHeadersPacket(
6415 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6416 false, GetResponseHeaders("200 OK")));
6417 if (should_send_priority_packet) {
6418 mock_quic_data1.AddWrite(
6419 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 3, 1));
6420 }
6421 mock_quic_data1.AddRead(
6422 ASYNC, ConstructServerDataPacket(
6423 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6424 ConstructDataFrame("hello1")));
6425 if (!should_send_priority_packet) {
6426 mock_quic_data1.AddWrite(
6427 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 4, 3));
6428 }
6429 mock_quic_data1.AddRead(
6430 ASYNC, ConstructServerDataPacket(
6431 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
6432 ConstructDataFrame("and hello1")));
6433 if (should_send_priority_packet) {
6434 mock_quic_data1.AddWrite(
6435 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 5, 3));
6436 }
6437 if (!VersionUsesHttp3(version_.transport_version)) {
6438 mock_quic_data1.AddWrite(SYNCHRONOUS,
6439 ConstructClientAckAndRstPacket(
6440 client_packet_number1++,
6441 GetNthServerInitiatedUnidirectionalStreamId(0),
6442 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6443 } else {
6444 mock_quic_data1.AddWrite(
6445 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
6446 client_packet_number1++, true, 5, 5, 3,
6447 GetNthServerInitiatedUnidirectionalStreamId(0)));
6448 }
6449 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6450 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6451 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6452
6453 QuicTestPacketMaker client_maker2(
6454 version_,
6455 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6456 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
6457 client_headers_include_h2_stream_dependency_);
6458 client_maker2.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6459 QuicTestPacketMaker server_maker2(
6460 version_,
6461 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6462 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
6463 false);
6464 MockQuicData mock_quic_data2(version_);
6465 uint64_t client_packet_number2 = 1;
6466 if (VersionUsesHttp3(version_.transport_version)) {
6467 mock_quic_data2.AddWrite(
6468 SYNCHRONOUS,
6469 client_maker2.MakeInitialSettingsPacket(client_packet_number2++));
6470 }
6471 mock_quic_data2.AddWrite(
6472 SYNCHRONOUS,
6473 client_maker2.MakeRequestHeadersPacket(
6474 client_packet_number2++,
6475 GetNthClientInitiatedBidirectionalStreamId(0), true, true,
6476 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
6477 GetRequestHeaders("GET", "https", "/"), 0, nullptr));
6478 mock_quic_data2.AddRead(
6479 ASYNC, server_maker2.MakePushPromisePacket(
6480 1, GetNthClientInitiatedBidirectionalStreamId(0),
6481 GetNthServerInitiatedUnidirectionalStreamId(0), false, false,
6482 GetRequestHeaders("GET", "https", "/pushed.jpg"), nullptr));
6483 if (should_send_priority_packet) {
6484 mock_quic_data2.AddWrite(
6485 SYNCHRONOUS,
6486 client_maker2.MakeAckAndPriorityPacket(
6487 client_packet_number2++, false,
6488 /*largest_received=*/1, /*smallest_received=*/1,
6489 GetNthServerInitiatedUnidirectionalStreamId(0),
6490 GetNthClientInitiatedBidirectionalStreamId(0),
6491 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)));
6492 }
6493 mock_quic_data2.AddRead(
6494 ASYNC, server_maker2.MakeResponseHeadersPacket(
6495 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6496 GetResponseHeaders("200 OK"), nullptr));
6497 if (!should_send_priority_packet) {
6498 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6499 client_packet_number2++, 2, 1));
6500 }
6501 mock_quic_data2.AddRead(
6502 ASYNC, server_maker2.MakeResponseHeadersPacket(
6503 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6504 false, GetResponseHeaders("200 OK"), nullptr));
6505 if (should_send_priority_packet) {
6506 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6507 client_packet_number2++, 3, 1));
6508 }
6509 mock_quic_data2.AddRead(
6510 ASYNC, server_maker2.MakeDataPacket(
6511 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6512 ConstructDataFrame("hello2")));
6513 if (!should_send_priority_packet) {
6514 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6515 client_packet_number2++, 4, 3));
6516 }
6517 mock_quic_data2.AddRead(
6518 ASYNC, server_maker2.MakeDataPacket(
6519 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
6520 ConstructDataFrame("and hello2")));
6521 if (should_send_priority_packet) {
6522 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6523 client_packet_number2++, 5, 3));
6524 }
6525 if (!VersionUsesHttp3(version_.transport_version)) {
6526 mock_quic_data2.AddWrite(SYNCHRONOUS,
6527 client_maker2.MakeAckAndRstPacket(
6528 client_packet_number2++, false,
6529 GetNthServerInitiatedUnidirectionalStreamId(0),
6530 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6531 } else {
6532 mock_quic_data2.AddWrite(
6533 SYNCHRONOUS, client_maker2.MakeAckAndPriorityUpdatePacket(
6534 client_packet_number2++, true, 5, 5, 3,
6535 GetNthServerInitiatedUnidirectionalStreamId(0)));
6536 }
6537 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6538 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6539 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6540
6541 scoped_refptr<X509Certificate> cert(
6542 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
6543 verify_details_.cert_verify_result.verified_cert = cert;
6544 verify_details_.cert_verify_result.is_issued_by_known_root = true;
6545 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
6546
6547 // The non-alternate protocol jobs need to hang in order to guarantee that
6548 // the alternate-protocol job will "win". Use "AddTcpSocketDataProvider()", as
6549 // the connection requests may or may not actually make it to the socket
6550 // factory, there may or may not be a TCP connection made in between the two
6551 // QUIC connection attempts.
6552 StaticSocketDataProvider hanging_data1;
6553 hanging_data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6554 socket_factory_.AddTcpSocketDataProvider(&hanging_data1);
6555 StaticSocketDataProvider hanging_data2;
6556 hanging_data2.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6557 socket_factory_.AddTcpSocketDataProvider(&hanging_data2);
6558
6559 CreateSession();
6560
6561 NetworkIsolationKey network_isolation_key1 =
6562 NetworkIsolationKey::CreateTransient();
6563 NetworkIsolationKey network_isolation_key2 =
6564 NetworkIsolationKey::CreateTransient();
6565
6566 // Creates the first QUIC session, and triggers the first push.
6567 request_.network_isolation_key = network_isolation_key1;
6568 SendRequestAndExpectQuicResponse("hello1");
6569
6570 // Use a different NIK, which creates another QUIC session, triggering a
6571 // second push,
6572 request_.network_isolation_key = network_isolation_key2;
6573 SendRequestAndExpectQuicResponse("hello2");
6574
6575 // Use the second NIK again, should receive the push body from the second
6576 // session.
6577 request_.url = GURL("https://mail.example.org/pushed.jpg");
6578 SendRequestAndExpectQuicResponse("and hello2");
6579
6580 // Use the first NIK again, should receive the push body from the first
6581 // session.
6582 request_.network_isolation_key = network_isolation_key1;
6583 SendRequestAndExpectQuicResponse("and hello1");
6584 }
6585
6586 // Regression test for http://crbug.com/719461 in which a promised stream
6587 // is closed before the pushed headers arrive, but after the connection
6588 // is closed and before the callbacks are executed.
TEST_P(QuicNetworkTransactionTest,CancelServerPushAfterConnectionClose)6589 TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
6590 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
6591 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
6592 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6593 context_.params()->origins_to_force_quic_on.insert(
6594 HostPortPair::FromString("mail.example.org:443"));
6595
6596 MockQuicData mock_quic_data(version_);
6597 uint64_t client_packet_number = 1;
6598 // Initial SETTINGS frame.
6599 if (VersionUsesHttp3(version_.transport_version)) {
6600 mock_quic_data.AddWrite(
6601 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6602 }
6603 // First request: GET https://mail.example.org/
6604 mock_quic_data.AddWrite(
6605 SYNCHRONOUS,
6606 ConstructClientRequestHeadersPacket(
6607 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6608 true, true, GetRequestHeaders("GET", "https", "/")));
6609 // Server promise for: https://mail.example.org/pushed.jpg
6610 mock_quic_data.AddRead(
6611 ASYNC, ConstructServerPushPromisePacket(
6612 1, GetNthClientInitiatedBidirectionalStreamId(0),
6613 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6614 GetRequestHeaders("GET", "https", "/pushed.jpg")));
6615 const bool should_send_priority_packet =
6616 client_headers_include_h2_stream_dependency_ &&
6617 !VersionUsesHttp3(version_.transport_version);
6618 if (should_send_priority_packet) {
6619 mock_quic_data.AddWrite(
6620 SYNCHRONOUS,
6621 ConstructClientAckAndPriorityPacket(
6622 client_packet_number++, false,
6623 /*largest_received=*/1, /*smallest_received=*/1,
6624 GetNthServerInitiatedUnidirectionalStreamId(0),
6625 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
6626 }
6627 // Response headers for first request.
6628 mock_quic_data.AddRead(
6629 ASYNC, ConstructServerResponseHeadersPacket(
6630 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6631 GetResponseHeaders("200 OK")));
6632 if (!should_send_priority_packet) {
6633 // Client ACKs the response headers.
6634 mock_quic_data.AddWrite(
6635 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
6636 }
6637 // Response body for first request.
6638 mock_quic_data.AddRead(
6639 ASYNC, ConstructServerDataPacket(
6640 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6641 ConstructDataFrame("hello!")));
6642 if (should_send_priority_packet) {
6643 // Client ACKs the response headers.
6644 mock_quic_data.AddWrite(
6645 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
6646 }
6647 // Write error for the third request.
6648 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6649 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6650 mock_quic_data.AddRead(ASYNC, 0); // EOF
6651 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6652
6653 CreateSession();
6654
6655 // Send a request which triggers a push promise from the server.
6656 SendRequestAndExpectQuicResponse("hello!");
6657
6658 // Start a push transaction that will be cancelled after the connection
6659 // is closed, but before the callback is executed.
6660 request_.url = GURL("https://mail.example.org/pushed.jpg");
6661 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
6662 session_.get());
6663 TestCompletionCallback callback2;
6664 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6666 base::RunLoop().RunUntilIdle();
6667
6668 // Cause the connection to close on a write error.
6669 HttpRequestInfo request3;
6670 request3.method = "GET";
6671 request3.url = GURL("https://mail.example.org/");
6672 request3.load_flags = 0;
6673 request3.traffic_annotation =
6674 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6675 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6676 TestCompletionCallback callback3;
6677 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6678 IsError(ERR_IO_PENDING));
6679
6680 base::RunLoop().RunUntilIdle();
6681
6682 // When |trans2| is destroyed, the underlying stream will be closed.
6683 EXPECT_FALSE(callback2.have_result());
6684 trans2 = nullptr;
6685
6686 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6687 }
6688
TEST_P(QuicNetworkTransactionTest,QuicForceHolBlocking)6689 TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
6690 context_.params()->origins_to_force_quic_on.insert(
6691 HostPortPair::FromString("mail.example.org:443"));
6692
6693 MockQuicData mock_quic_data(version_);
6694
6695 int write_packet_index = 1;
6696 if (VersionUsesHttp3(version_.transport_version)) {
6697 mock_quic_data.AddWrite(
6698 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6699 }
6700
6701 mock_quic_data.AddWrite(
6702 SYNCHRONOUS,
6703 ConstructClientRequestHeadersAndDataFramesPacket(
6704 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6705 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
6706 0, nullptr, {ConstructDataFrame("1")}));
6707
6708 mock_quic_data.AddRead(
6709 ASYNC, ConstructServerResponseHeadersPacket(
6710 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6711 GetResponseHeaders("200 OK")));
6712
6713 mock_quic_data.AddRead(
6714 ASYNC, ConstructServerDataPacket(
6715 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6716 ConstructDataFrame("hello!")));
6717
6718 mock_quic_data.AddWrite(SYNCHRONOUS,
6719 ConstructClientAckPacket(write_packet_index++, 2, 1));
6720
6721 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6722 mock_quic_data.AddRead(ASYNC, 0); // EOF
6723 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6724
6725 // The non-alternate protocol job needs to hang in order to guarantee that
6726 // the alternate-protocol job will "win".
6727 AddHangingNonAlternateProtocolSocketData();
6728
6729 CreateSession();
6730 request_.method = "POST";
6731 ChunkedUploadDataStream upload_data(0);
6732 upload_data.AppendData("1", 1, true);
6733
6734 request_.upload_data_stream = &upload_data;
6735
6736 SendRequestAndExpectQuicResponse("hello!");
6737 }
6738
6739 class QuicURLRequestContext : public URLRequestContext {
6740 public:
QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,MockClientSocketFactory * socket_factory)6741 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6742 MockClientSocketFactory* socket_factory)
6743 : storage_(this) {
6744 socket_factory_ = socket_factory;
6745 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
6746 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
6747 storage_.set_transport_security_state(
6748 std::make_unique<TransportSecurityState>());
6749 storage_.set_proxy_resolution_service(
6750 ConfiguredProxyResolutionService::CreateDirect());
6751 storage_.set_ssl_config_service(
6752 std::make_unique<SSLConfigServiceDefaults>());
6753 storage_.set_http_auth_handler_factory(
6754 HttpAuthHandlerFactory::CreateDefault());
6755 storage_.set_http_server_properties(
6756 std::make_unique<HttpServerProperties>());
6757 storage_.set_job_factory(std::make_unique<URLRequestJobFactory>());
6758 storage_.set_http_network_session(std::move(session));
6759 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6760 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6761 false));
6762 }
6763
~QuicURLRequestContext()6764 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6765
socket_factory()6766 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6767
6768 private:
6769 MockClientSocketFactory* socket_factory_;
6770 URLRequestContextStorage storage_;
6771 };
6772
TEST_P(QuicNetworkTransactionTest,RawHeaderSizeSuccessfullRequest)6773 TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
6774 context_.params()->origins_to_force_quic_on.insert(
6775 HostPortPair::FromString("mail.example.org:443"));
6776
6777 MockQuicData mock_quic_data(version_);
6778 int packet_num = 1;
6779 if (VersionUsesHttp3(version_.transport_version)) {
6780 mock_quic_data.AddWrite(SYNCHRONOUS,
6781 ConstructInitialSettingsPacket(packet_num++));
6782 }
6783 spdy::Http2HeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
6784 headers["user-agent"] = "";
6785 headers["accept-encoding"] = "gzip, deflate";
6786 mock_quic_data.AddWrite(
6787 SYNCHRONOUS,
6788 ConstructClientRequestHeadersPacket(
6789 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6790 true, std::move(headers)));
6791
6792 mock_quic_data.AddRead(
6793 ASYNC, ConstructServerResponseHeadersPacket(
6794 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6795 GetResponseHeaders("200 OK")));
6796 quic::QuicStreamOffset expected_raw_header_response_size =
6797 server_maker_.stream_offset(
6798 quic::VersionUsesHttp3(version_.transport_version)
6799 ? GetNthClientInitiatedBidirectionalStreamId(0)
6800 : quic::QuicUtils::GetHeadersStreamId(
6801 version_.transport_version));
6802
6803 mock_quic_data.AddRead(
6804 ASYNC, ConstructServerDataPacket(
6805 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6806 "Main Resource Data"));
6807 mock_quic_data.AddWrite(SYNCHRONOUS,
6808 ConstructClientAckPacket(packet_num++, 2, 1));
6809
6810 mock_quic_data.AddRead(ASYNC, 0); // EOF
6811
6812 CreateSession();
6813
6814 TestDelegate delegate;
6815 QuicURLRequestContext quic_url_request_context(std::move(session_),
6816 &socket_factory_);
6817
6818 mock_quic_data.AddSocketDataToFactory(
6819 &quic_url_request_context.socket_factory());
6820 TestNetworkDelegate network_delegate;
6821 quic_url_request_context.set_network_delegate(&network_delegate);
6822
6823 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
6824 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6825 TRAFFIC_ANNOTATION_FOR_TESTS));
6826 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6827 &ssl_data_);
6828
6829 request->Start();
6830 delegate.RunUntilComplete();
6831
6832 EXPECT_LT(0, request->GetTotalSentBytes());
6833 EXPECT_LT(0, request->GetTotalReceivedBytes());
6834 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6835 request->raw_header_size());
6836
6837 // Pump the message loop to allow all data to be consumed.
6838 base::RunLoop().RunUntilIdle();
6839
6840 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6841 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6842 }
6843
TEST_P(QuicNetworkTransactionTest,RawHeaderSizeSuccessfullPushHeadersFirst)6844 TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
6845 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
6846 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
6847 context_.params()->origins_to_force_quic_on.insert(
6848 HostPortPair::FromString("mail.example.org:443"));
6849
6850 MockQuicData mock_quic_data(version_);
6851 uint64_t client_packet_number = 1;
6852 if (VersionUsesHttp3(version_.transport_version)) {
6853 mock_quic_data.AddWrite(
6854 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6855 }
6856 spdy::Http2HeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
6857 headers["user-agent"] = "";
6858 headers["accept-encoding"] = "gzip, deflate";
6859 mock_quic_data.AddWrite(
6860 SYNCHRONOUS,
6861 ConstructClientRequestHeadersPacket(
6862 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6863 true, true, std::move(headers)));
6864
6865 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
6866 GetNthClientInitiatedBidirectionalStreamId(0));
6867 mock_quic_data.AddRead(
6868 ASYNC, ConstructServerPushPromisePacket(
6869 1, GetNthClientInitiatedBidirectionalStreamId(0),
6870 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6871 GetRequestHeaders("GET", "https", "/pushed.jpg")));
6872 quic::QuicStreamOffset push_promise_offset = 0;
6873 if (VersionUsesHttp3(version_.transport_version)) {
6874 push_promise_offset = server_maker_.stream_offset(
6875 GetNthClientInitiatedBidirectionalStreamId(0)) -
6876 initial;
6877 }
6878
6879 const bool should_send_priority_packet =
6880 client_headers_include_h2_stream_dependency_ &&
6881 !VersionUsesHttp3(version_.transport_version);
6882 if (should_send_priority_packet) {
6883 mock_quic_data.AddWrite(
6884 SYNCHRONOUS,
6885 ConstructClientAckAndPriorityPacket(
6886 client_packet_number++, false,
6887 /*largest_received=*/1, /*smallest_received=*/1,
6888 GetNthServerInitiatedUnidirectionalStreamId(0),
6889 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
6890 }
6891
6892 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
6893 quic::VersionUsesHttp3(version_.transport_version)
6894 ? GetNthClientInitiatedBidirectionalStreamId(0)
6895 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
6896 mock_quic_data.AddRead(
6897 ASYNC, ConstructServerResponseHeadersPacket(
6898 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6899 GetResponseHeaders("200 OK")));
6900 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
6901 quic::VersionUsesHttp3(version_.transport_version)
6902 ? GetNthClientInitiatedBidirectionalStreamId(0)
6903 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
6904 quic::QuicStreamOffset expected_raw_header_response_size =
6905 final_offset - initial_offset;
6906
6907 if (!should_send_priority_packet) {
6908 mock_quic_data.AddWrite(
6909 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
6910 }
6911
6912 mock_quic_data.AddRead(
6913 ASYNC, ConstructServerResponseHeadersPacket(
6914 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6915 false, GetResponseHeaders("200 OK")));
6916 if (should_send_priority_packet) {
6917 mock_quic_data.AddWrite(
6918 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
6919 }
6920 mock_quic_data.AddRead(
6921 ASYNC, ConstructServerDataPacket(
6922 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
6923 ConstructDataFrame("Pushed Resource Data")));
6924
6925 if (!should_send_priority_packet) {
6926 mock_quic_data.AddWrite(
6927 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
6928 }
6929 mock_quic_data.AddRead(
6930 ASYNC, ConstructServerDataPacket(
6931 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6932 ConstructDataFrame("Main Resource Data")));
6933 if (should_send_priority_packet) {
6934 mock_quic_data.AddWrite(
6935 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
6936 }
6937
6938 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
6939
6940 CreateSession();
6941
6942 TestDelegate delegate;
6943 QuicURLRequestContext quic_url_request_context(std::move(session_),
6944 &socket_factory_);
6945
6946 mock_quic_data.AddSocketDataToFactory(
6947 &quic_url_request_context.socket_factory());
6948 TestNetworkDelegate network_delegate;
6949 quic_url_request_context.set_network_delegate(&network_delegate);
6950
6951 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
6952 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6953 TRAFFIC_ANNOTATION_FOR_TESTS));
6954 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6955 &ssl_data_);
6956
6957 request->Start();
6958 delegate.RunUntilComplete();
6959
6960 EXPECT_LT(0, request->GetTotalSentBytes());
6961 EXPECT_LT(0, request->GetTotalReceivedBytes());
6962 EXPECT_EQ(
6963 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
6964 request->raw_header_size());
6965
6966 // Pump the message loop to allow all data to be consumed.
6967 base::RunLoop().RunUntilIdle();
6968
6969 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6970 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6971 }
6972
TEST_P(QuicNetworkTransactionTest,HostInAllowlist)6973 TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
6974 session_params_.quic_host_allowlist.insert("mail.example.org");
6975
6976 MockRead http_reads[] = {
6977 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6978 MockRead("hello world"),
6979 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6980 MockRead(ASYNC, OK)};
6981
6982 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6983 socket_factory_.AddSocketDataProvider(&http_data);
6984 AddCertificate(&ssl_data_);
6985 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6986
6987 MockQuicData mock_quic_data(version_);
6988 int packet_num = 1;
6989 if (VersionUsesHttp3(version_.transport_version)) {
6990 mock_quic_data.AddWrite(SYNCHRONOUS,
6991 ConstructInitialSettingsPacket(packet_num++));
6992 }
6993 mock_quic_data.AddWrite(
6994 SYNCHRONOUS,
6995 ConstructClientRequestHeadersPacket(
6996 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6997 true, GetRequestHeaders("GET", "https", "/")));
6998 mock_quic_data.AddRead(
6999 ASYNC, ConstructServerResponseHeadersPacket(
7000 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7001 GetResponseHeaders("200 OK")));
7002 mock_quic_data.AddRead(
7003 ASYNC, ConstructServerDataPacket(
7004 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7005 ConstructDataFrame("hello!")));
7006 mock_quic_data.AddWrite(SYNCHRONOUS,
7007 ConstructClientAckPacket(packet_num++, 2, 1));
7008 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7009 mock_quic_data.AddRead(ASYNC, 0); // EOF
7010
7011 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7012
7013 AddHangingNonAlternateProtocolSocketData();
7014 CreateSession();
7015
7016 SendRequestAndExpectHttpResponse("hello world");
7017 SendRequestAndExpectQuicResponse("hello!");
7018 }
7019
TEST_P(QuicNetworkTransactionTest,HostNotInAllowlist)7020 TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7021 session_params_.quic_host_allowlist.insert("mail.example.com");
7022
7023 MockRead http_reads[] = {
7024 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7025 MockRead("hello world"),
7026 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7027 MockRead(ASYNC, OK)};
7028
7029 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
7030 socket_factory_.AddSocketDataProvider(&http_data);
7031 AddCertificate(&ssl_data_);
7032 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7033 socket_factory_.AddSocketDataProvider(&http_data);
7034 AddCertificate(&ssl_data_);
7035 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7036
7037 AddHangingNonAlternateProtocolSocketData();
7038 CreateSession();
7039
7040 SendRequestAndExpectHttpResponse("hello world");
7041 SendRequestAndExpectHttpResponse("hello world");
7042 }
7043
7044 class QuicNetworkTransactionWithDestinationTest
7045 : public PlatformTest,
7046 public ::testing::WithParamInterface<PoolingTestParams>,
7047 public WithTaskEnvironment {
7048 protected:
QuicNetworkTransactionWithDestinationTest()7049 QuicNetworkTransactionWithDestinationTest()
7050 : version_(GetParam().version),
7051 client_headers_include_h2_stream_dependency_(
7052 GetParam().client_headers_include_h2_stream_dependency),
7053 supported_versions_(quic::test::SupportedVersions(version_)),
7054 destination_type_(GetParam().destination_type),
7055 cert_transparency_verifier_(new MultiLogCTVerifier()),
7056 ssl_config_service_(new SSLConfigServiceDefaults),
7057 proxy_resolution_service_(
7058 ConfiguredProxyResolutionService::CreateDirect()),
7059 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
7060 ssl_data_(ASYNC, OK) {
7061 FLAGS_quic_enable_http3_grease_randomness = false;
7062 }
7063
SetUp()7064 void SetUp() override {
7065 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7066 base::RunLoop().RunUntilIdle();
7067
7068 HttpNetworkSession::Params session_params;
7069 session_params.enable_quic = true;
7070 context_.params()->allow_remote_alt_svc = true;
7071 context_.params()->supported_versions = supported_versions_;
7072 context_.params()->headers_include_h2_stream_dependency =
7073 client_headers_include_h2_stream_dependency_;
7074
7075 HttpNetworkSession::Context session_context;
7076
7077 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
7078
7079 crypto_client_stream_factory_.set_handshake_mode(
7080 MockCryptoClientStream::CONFIRM_HANDSHAKE);
7081 session_context.quic_crypto_client_stream_factory =
7082 &crypto_client_stream_factory_;
7083
7084 session_context.quic_context = &context_;
7085 session_context.client_socket_factory = &socket_factory_;
7086 session_context.host_resolver = &host_resolver_;
7087 session_context.cert_verifier = &cert_verifier_;
7088 session_context.transport_security_state = &transport_security_state_;
7089 session_context.cert_transparency_verifier =
7090 cert_transparency_verifier_.get();
7091 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7092 session_context.socket_performance_watcher_factory =
7093 &test_socket_performance_watcher_factory_;
7094 session_context.ssl_config_service = ssl_config_service_.get();
7095 session_context.proxy_resolution_service = proxy_resolution_service_.get();
7096 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7097 session_context.http_server_properties = &http_server_properties_;
7098
7099 session_.reset(new HttpNetworkSession(session_params, session_context));
7100 session_->quic_stream_factory()
7101 ->set_is_quic_known_to_work_on_current_network(false);
7102 }
7103
TearDown()7104 void TearDown() override {
7105 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7106 // Empty the current queue.
7107 base::RunLoop().RunUntilIdle();
7108 PlatformTest::TearDown();
7109 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7110 base::RunLoop().RunUntilIdle();
7111 session_.reset();
7112 }
7113
SetQuicAlternativeService(const std::string & origin)7114 void SetQuicAlternativeService(const std::string& origin) {
7115 HostPortPair destination;
7116 switch (destination_type_) {
7117 case SAME_AS_FIRST:
7118 destination = HostPortPair(origin1_, 443);
7119 break;
7120 case SAME_AS_SECOND:
7121 destination = HostPortPair(origin2_, 443);
7122 break;
7123 case DIFFERENT:
7124 destination = HostPortPair(kDifferentHostname, 443);
7125 break;
7126 }
7127 AlternativeService alternative_service(kProtoQUIC, destination);
7128 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
7129 http_server_properties_.SetQuicAlternativeService(
7130 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7131 alternative_service, expiration, supported_versions_);
7132 }
7133
7134 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientRequestHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool should_include_version,quic::QuicStreamId parent_stream_id,QuicTestPacketMaker * maker)7135 ConstructClientRequestHeadersPacket(uint64_t packet_number,
7136 quic::QuicStreamId stream_id,
7137 bool should_include_version,
7138 quic::QuicStreamId parent_stream_id,
7139 QuicTestPacketMaker* maker) {
7140 spdy::SpdyPriority priority =
7141 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
7142 spdy::Http2HeaderBlock headers(
7143 maker->GetRequestHeaders("GET", "https", "/"));
7144 return maker->MakeRequestHeadersPacket(
7145 packet_number, stream_id, should_include_version, true, priority,
7146 std::move(headers), parent_stream_id, nullptr);
7147 }
7148
7149 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientRequestHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool should_include_version,QuicTestPacketMaker * maker)7150 ConstructClientRequestHeadersPacket(uint64_t packet_number,
7151 quic::QuicStreamId stream_id,
7152 bool should_include_version,
7153 QuicTestPacketMaker* maker) {
7154 return ConstructClientRequestHeadersPacket(
7155 packet_number, stream_id, should_include_version, 0, maker);
7156 }
7157
7158 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructServerResponseHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,QuicTestPacketMaker * maker)7159 ConstructServerResponseHeadersPacket(uint64_t packet_number,
7160 quic::QuicStreamId stream_id,
7161 QuicTestPacketMaker* maker) {
7162 spdy::Http2HeaderBlock headers(maker->GetResponseHeaders("200 OK"));
7163 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7164 false, std::move(headers), nullptr);
7165 }
7166
ConstructServerDataPacket(uint64_t packet_number,quic::QuicStreamId stream_id,QuicTestPacketMaker * maker)7167 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
7168 uint64_t packet_number,
7169 quic::QuicStreamId stream_id,
7170 QuicTestPacketMaker* maker) {
7171 return maker->MakeDataPacket(
7172 packet_number, stream_id, false, true,
7173 ConstructDataFrameForVersion("hello", version_));
7174 }
7175
ConstructClientAckPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received,QuicTestPacketMaker * maker)7176 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
7177 uint64_t packet_number,
7178 uint64_t largest_received,
7179 uint64_t smallest_received,
7180 QuicTestPacketMaker* maker) {
7181 return maker->MakeAckPacket(packet_number, largest_received,
7182 smallest_received);
7183 }
7184
ConstructInitialSettingsPacket(uint64_t packet_number,QuicTestPacketMaker * maker)7185 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
7186 uint64_t packet_number,
7187 QuicTestPacketMaker* maker) {
7188 return maker->MakeInitialSettingsPacket(packet_number);
7189 }
7190
AddRefusedSocketData()7191 void AddRefusedSocketData() {
7192 std::unique_ptr<StaticSocketDataProvider> refused_data(
7193 new StaticSocketDataProvider());
7194 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7195 refused_data->set_connect_data(refused_connect);
7196 socket_factory_.AddSocketDataProvider(refused_data.get());
7197 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7198 }
7199
AddHangingSocketData()7200 void AddHangingSocketData() {
7201 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7202 new StaticSocketDataProvider());
7203 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7204 hanging_data->set_connect_data(hanging_connect);
7205 socket_factory_.AddSocketDataProvider(hanging_data.get());
7206 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7207 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7208 }
7209
AllDataConsumed()7210 bool AllDataConsumed() {
7211 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7212 if (!socket_data_ptr->AllReadDataConsumed() ||
7213 !socket_data_ptr->AllWriteDataConsumed()) {
7214 return false;
7215 }
7216 }
7217 return true;
7218 }
7219
SendRequestAndExpectQuicResponse(const std::string & host)7220 void SendRequestAndExpectQuicResponse(const std::string& host) {
7221 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7222 HttpRequestInfo request;
7223 std::string url("https://");
7224 url.append(host);
7225 request.url = GURL(url);
7226 request.load_flags = 0;
7227 request.method = "GET";
7228 request.traffic_annotation =
7229 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7230 TestCompletionCallback callback;
7231 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
7232 EXPECT_THAT(callback.GetResult(rv), IsOk());
7233
7234 std::string response_data;
7235 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
7236 EXPECT_EQ("hello", response_data);
7237
7238 const HttpResponseInfo* response = trans.GetResponseInfo();
7239 ASSERT_TRUE(response != nullptr);
7240 ASSERT_TRUE(response->headers.get() != nullptr);
7241 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7242 EXPECT_TRUE(response->was_fetched_via_spdy);
7243 EXPECT_TRUE(response->was_alpn_negotiated);
7244 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
7245 response->connection_info);
7246 EXPECT_EQ(443, response->remote_endpoint.port());
7247 }
7248
GetNthClientInitiatedBidirectionalStreamId(int n)7249 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
7250 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7251 version_.transport_version, n);
7252 }
7253
7254 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
7255 const quic::ParsedQuicVersion version_;
7256 const bool client_headers_include_h2_stream_dependency_;
7257 quic::ParsedQuicVersionVector supported_versions_;
7258 DestinationType destination_type_;
7259 std::string origin1_;
7260 std::string origin2_;
7261 MockQuicContext context_;
7262 std::unique_ptr<HttpNetworkSession> session_;
7263 MockClientSocketFactory socket_factory_;
7264 MockHostResolver host_resolver_;
7265 MockCertVerifier cert_verifier_;
7266 TransportSecurityState transport_security_state_;
7267 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
7268 DefaultCTPolicyEnforcer ct_policy_enforcer_;
7269 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
7270 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
7271 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
7272 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
7273 HttpServerProperties http_server_properties_;
7274 RecordingBoundTestNetLog net_log_;
7275 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7276 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7277 static_socket_data_provider_vector_;
7278 SSLSocketDataProvider ssl_data_;
7279 };
7280
7281 INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7282 QuicNetworkTransactionWithDestinationTest,
7283 ::testing::ValuesIn(GetPoolingTestParams()),
7284 ::testing::PrintToStringParamName());
7285
7286 // A single QUIC request fails because the certificate does not match the origin
7287 // hostname, regardless of whether it matches the alternative service hostname.
TEST_P(QuicNetworkTransactionWithDestinationTest,InvalidCertificate)7288 TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7289 if (destination_type_ == DIFFERENT)
7290 return;
7291
7292 GURL url("https://mail.example.com/");
7293 origin1_ = url.host();
7294
7295 // Not used for requests, but this provides a test case where the certificate
7296 // is valid for the hostname of the alternative service.
7297 origin2_ = "mail.example.org";
7298
7299 SetQuicAlternativeService(origin1_);
7300
7301 scoped_refptr<X509Certificate> cert(
7302 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
7303 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7304 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7305
7306 ProofVerifyDetailsChromium verify_details;
7307 verify_details.cert_verify_result.verified_cert = cert;
7308 verify_details.cert_verify_result.is_issued_by_known_root = true;
7309 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7310
7311 MockQuicData mock_quic_data(version_);
7312 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7313 mock_quic_data.AddRead(ASYNC, 0);
7314
7315 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7316
7317 AddRefusedSocketData();
7318
7319 HttpRequestInfo request;
7320 request.url = url;
7321 request.traffic_annotation =
7322 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7323
7324 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7325 TestCompletionCallback callback;
7326 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
7327 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
7328
7329 EXPECT_TRUE(AllDataConsumed());
7330 }
7331
7332 // First request opens QUIC session to alternative service. Second request
7333 // pools to it, because destination matches and certificate is valid, even
7334 // though quic::QuicServerId is different.
TEST_P(QuicNetworkTransactionWithDestinationTest,PoolIfCertificateValid)7335 TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7336 origin1_ = "mail.example.org";
7337 origin2_ = "news.example.org";
7338
7339 SetQuicAlternativeService(origin1_);
7340 SetQuicAlternativeService(origin2_);
7341
7342 scoped_refptr<X509Certificate> cert(
7343 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
7344 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7345 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7346 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
7347
7348 ProofVerifyDetailsChromium verify_details;
7349 verify_details.cert_verify_result.verified_cert = cert;
7350 verify_details.cert_verify_result.is_issued_by_known_root = true;
7351 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7352
7353 QuicTestPacketMaker client_maker(
7354 version_,
7355 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7356 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
7357 client_headers_include_h2_stream_dependency_);
7358 QuicTestPacketMaker server_maker(
7359 version_,
7360 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7361 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
7362
7363 MockQuicData mock_quic_data(version_);
7364 int packet_num = 1;
7365 if (VersionUsesHttp3(version_.transport_version)) {
7366 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7367 packet_num++, &client_maker));
7368 }
7369 mock_quic_data.AddWrite(
7370 SYNCHRONOUS,
7371 ConstructClientRequestHeadersPacket(
7372 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7373 &client_maker));
7374 mock_quic_data.AddRead(
7375 ASYNC,
7376 ConstructServerResponseHeadersPacket(
7377 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
7378 mock_quic_data.AddRead(
7379 ASYNC,
7380 ConstructServerDataPacket(
7381 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
7382 mock_quic_data.AddWrite(
7383 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, &client_maker));
7384
7385 client_maker.set_hostname(origin2_);
7386 server_maker.set_hostname(origin2_);
7387
7388 mock_quic_data.AddWrite(
7389 SYNCHRONOUS,
7390 ConstructClientRequestHeadersPacket(
7391 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
7392 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7393 mock_quic_data.AddRead(
7394 ASYNC,
7395 ConstructServerResponseHeadersPacket(
7396 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
7397 mock_quic_data.AddRead(
7398 ASYNC,
7399 ConstructServerDataPacket(
7400 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
7401 mock_quic_data.AddWrite(
7402 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3, &client_maker));
7403 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7404 mock_quic_data.AddRead(ASYNC, 0); // EOF
7405
7406 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7407
7408 AddHangingSocketData();
7409 AddHangingSocketData();
7410
7411 scoped_refptr<TestTaskRunner> quic_task_runner(
7412 new TestTaskRunner(context_.mock_clock()));
7413 QuicStreamFactoryPeer::SetAlarmFactory(
7414 session_->quic_stream_factory(),
7415 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
7416 context_.clock()));
7417
7418 SendRequestAndExpectQuicResponse(origin1_);
7419 SendRequestAndExpectQuicResponse(origin2_);
7420
7421 EXPECT_TRUE(AllDataConsumed());
7422 }
7423
7424 // First request opens QUIC session to alternative service. Second request does
7425 // not pool to it, even though destination matches, because certificate is not
7426 // valid. Instead, a new QUIC session is opened to the same destination with a
7427 // different quic::QuicServerId.
TEST_P(QuicNetworkTransactionWithDestinationTest,DoNotPoolIfCertificateInvalid)7428 TEST_P(QuicNetworkTransactionWithDestinationTest,
7429 DoNotPoolIfCertificateInvalid) {
7430 origin1_ = "news.example.org";
7431 origin2_ = "mail.example.com";
7432
7433 SetQuicAlternativeService(origin1_);
7434 SetQuicAlternativeService(origin2_);
7435
7436 scoped_refptr<X509Certificate> cert1(
7437 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
7438 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7439 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7440 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
7441
7442 scoped_refptr<X509Certificate> cert2(
7443 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
7444 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7445 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
7446
7447 ProofVerifyDetailsChromium verify_details1;
7448 verify_details1.cert_verify_result.verified_cert = cert1;
7449 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7450 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7451
7452 ProofVerifyDetailsChromium verify_details2;
7453 verify_details2.cert_verify_result.verified_cert = cert2;
7454 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7455 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7456
7457 QuicTestPacketMaker client_maker1(
7458 version_,
7459 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7460 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
7461 client_headers_include_h2_stream_dependency_);
7462 QuicTestPacketMaker server_maker1(
7463 version_,
7464 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7465 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
7466
7467 MockQuicData mock_quic_data1(version_);
7468 int packet_num = 1;
7469 if (VersionUsesHttp3(version_.transport_version)) {
7470 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7471 packet_num++, &client_maker1));
7472 }
7473 mock_quic_data1.AddWrite(
7474 SYNCHRONOUS,
7475 ConstructClientRequestHeadersPacket(
7476 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7477 &client_maker1));
7478 mock_quic_data1.AddRead(
7479 ASYNC,
7480 ConstructServerResponseHeadersPacket(
7481 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
7482 mock_quic_data1.AddRead(
7483 ASYNC,
7484 ConstructServerDataPacket(
7485 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
7486 mock_quic_data1.AddWrite(
7487 SYNCHRONOUS,
7488 ConstructClientAckPacket(packet_num++, 2, 1, &client_maker1));
7489 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7490 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7491
7492 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7493
7494 QuicTestPacketMaker client_maker2(
7495 version_,
7496 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7497 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
7498 client_headers_include_h2_stream_dependency_);
7499 QuicTestPacketMaker server_maker2(
7500 version_,
7501 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7502 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
7503
7504 MockQuicData mock_quic_data2(version_);
7505 int packet_num2 = 1;
7506 if (VersionUsesHttp3(version_.transport_version)) {
7507 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7508 packet_num2++, &client_maker2));
7509 }
7510 mock_quic_data2.AddWrite(
7511 SYNCHRONOUS,
7512 ConstructClientRequestHeadersPacket(
7513 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7514 &client_maker2));
7515 mock_quic_data2.AddRead(
7516 ASYNC,
7517 ConstructServerResponseHeadersPacket(
7518 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
7519 mock_quic_data2.AddRead(
7520 ASYNC,
7521 ConstructServerDataPacket(
7522 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
7523 mock_quic_data2.AddWrite(
7524 SYNCHRONOUS,
7525 ConstructClientAckPacket(packet_num2++, 2, 1, &client_maker2));
7526 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7527 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7528
7529 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7530
7531 SendRequestAndExpectQuicResponse(origin1_);
7532 SendRequestAndExpectQuicResponse(origin2_);
7533
7534 EXPECT_TRUE(AllDataConsumed());
7535 }
7536
7537 // crbug.com/705109 - this confirms that matching request with a body
7538 // triggers a crash (pre-fix).
TEST_P(QuicNetworkTransactionTest,QuicServerPushMatchesRequestWithBody)7539 TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
7540 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
7541 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
7542 context_.params()->origins_to_force_quic_on.insert(
7543 HostPortPair::FromString("mail.example.org:443"));
7544
7545 MockQuicData mock_quic_data(version_);
7546 uint64_t client_packet_number = 1;
7547 if (VersionUsesHttp3(version_.transport_version)) {
7548 mock_quic_data.AddWrite(
7549 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7550 }
7551 mock_quic_data.AddWrite(
7552 SYNCHRONOUS,
7553 ConstructClientRequestHeadersPacket(
7554 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7555 true, true, GetRequestHeaders("GET", "https", "/")));
7556 mock_quic_data.AddRead(
7557 ASYNC, ConstructServerPushPromisePacket(
7558 1, GetNthClientInitiatedBidirectionalStreamId(0),
7559 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7560 GetRequestHeaders("GET", "https", "/pushed.jpg")));
7561
7562 const bool should_send_priority_packet =
7563 client_headers_include_h2_stream_dependency_ &&
7564 !VersionUsesHttp3(version_.transport_version);
7565 if (should_send_priority_packet) {
7566 mock_quic_data.AddWrite(
7567 SYNCHRONOUS,
7568 ConstructClientAckAndPriorityPacket(
7569 client_packet_number++, false,
7570 /*largest_received=*/1, /*smallest_received=*/1,
7571 GetNthServerInitiatedUnidirectionalStreamId(0),
7572 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
7573 }
7574 mock_quic_data.AddRead(
7575 ASYNC, ConstructServerResponseHeadersPacket(
7576 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7577 GetResponseHeaders("200 OK")));
7578 if (!should_send_priority_packet) {
7579 mock_quic_data.AddWrite(
7580 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
7581 }
7582 mock_quic_data.AddRead(
7583 ASYNC, ConstructServerResponseHeadersPacket(
7584 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7585 false, GetResponseHeaders("200 OK")));
7586 if (should_send_priority_packet) {
7587 mock_quic_data.AddWrite(
7588 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
7589 }
7590 mock_quic_data.AddRead(
7591 ASYNC, ConstructServerDataPacket(
7592 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7593 ConstructDataFrame("hello!")));
7594 if (!should_send_priority_packet) {
7595 mock_quic_data.AddWrite(
7596 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
7597 }
7598
7599 mock_quic_data.AddRead(
7600 ASYNC, ConstructServerDataPacket(
7601 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
7602 ConstructDataFrame("and hello!")));
7603 if (should_send_priority_packet) {
7604 mock_quic_data.AddWrite(
7605 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
7606 }
7607
7608 // Because the matching request has a body, we will see the push
7609 // stream get cancelled, and the matching request go out on the
7610 // wire.
7611 if (should_send_priority_packet) {
7612 mock_quic_data.AddWrite(
7613 SYNCHRONOUS,
7614 ConstructClientRstPacket(client_packet_number++,
7615 GetNthServerInitiatedUnidirectionalStreamId(0),
7616 quic::QUIC_STREAM_CANCELLED));
7617 } else {
7618 mock_quic_data.AddWrite(SYNCHRONOUS,
7619 ConstructClientAckAndRstPacket(
7620 client_packet_number++,
7621 GetNthServerInitiatedUnidirectionalStreamId(0),
7622 quic::QUIC_STREAM_CANCELLED, 5, 5));
7623 }
7624 mock_quic_data.AddWrite(
7625 SYNCHRONOUS,
7626 ConstructClientRequestHeadersAndDataFramesPacket(
7627 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
7628 false, true, DEFAULT_PRIORITY,
7629 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7630 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7631 {ConstructDataFrame("1")}));
7632
7633 // We see the same response as for the earlier pushed and cancelled
7634 // stream.
7635 mock_quic_data.AddRead(
7636 ASYNC, ConstructServerResponseHeadersPacket(
7637 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7638 GetResponseHeaders("200 OK")));
7639 mock_quic_data.AddRead(
7640 ASYNC, ConstructServerDataPacket(
7641 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7642 ConstructDataFrame("and hello!")));
7643
7644 mock_quic_data.AddWrite(
7645 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6));
7646 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7647 mock_quic_data.AddRead(ASYNC, 0); // EOF
7648 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7649
7650 // The non-alternate protocol job needs to hang in order to guarantee that
7651 // the alternate-protocol job will "win".
7652 AddHangingNonAlternateProtocolSocketData();
7653
7654 CreateSession();
7655
7656 // PUSH_PROMISE handling in the http layer gets exercised here.
7657 SendRequestAndExpectQuicResponse("hello!");
7658
7659 request_.url = GURL("https://mail.example.org/pushed.jpg");
7660 ChunkedUploadDataStream upload_data(0);
7661 upload_data.AppendData("1", 1, true);
7662 request_.upload_data_stream = &upload_data;
7663 SendRequestAndExpectQuicResponse("and hello!");
7664 }
7665
7666 // Regression test for https://crbug.com/797825: If pushed headers describe a
7667 // valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7668 // not be called (otherwise a DCHECK fails).
TEST_P(QuicNetworkTransactionTest,QuicServerPushWithEmptyHostname)7669 TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
7670 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
7671 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
7672
7673 spdy::Http2HeaderBlock pushed_request_headers;
7674 pushed_request_headers[":authority"] = "";
7675 pushed_request_headers[":method"] = "GET";
7676 pushed_request_headers[":path"] = "/";
7677 pushed_request_headers[":scheme"] = "nosuchscheme";
7678
7679 context_.params()->origins_to_force_quic_on.insert(
7680 HostPortPair::FromString("mail.example.org:443"));
7681
7682 MockQuicData mock_quic_data(version_);
7683
7684 int packet_num = 1;
7685 if (VersionUsesHttp3(version_.transport_version)) {
7686 mock_quic_data.AddWrite(SYNCHRONOUS,
7687 ConstructInitialSettingsPacket(packet_num++));
7688 }
7689 mock_quic_data.AddWrite(
7690 SYNCHRONOUS,
7691 ConstructClientRequestHeadersPacket(
7692 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7693 true, GetRequestHeaders("GET", "https", "/")));
7694
7695 mock_quic_data.AddRead(
7696 ASYNC, ConstructServerPushPromisePacket(
7697 1, GetNthClientInitiatedBidirectionalStreamId(0),
7698 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7699 std::move(pushed_request_headers)));
7700 mock_quic_data.AddWrite(
7701 SYNCHRONOUS,
7702 ConstructClientAckAndRstPacket(
7703 packet_num++, GetNthServerInitiatedUnidirectionalStreamId(0),
7704 quic::QUIC_INVALID_PROMISE_URL, 1, 1));
7705
7706 mock_quic_data.AddRead(
7707 ASYNC, ConstructServerResponseHeadersPacket(
7708 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7709 GetResponseHeaders("200 OK")));
7710
7711 mock_quic_data.AddRead(
7712 ASYNC, ConstructServerResponseHeadersPacket(
7713 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7714 false, GetResponseHeaders("200 OK")));
7715 mock_quic_data.AddWrite(SYNCHRONOUS,
7716 ConstructClientAckPacket(packet_num++, 3, 1));
7717 mock_quic_data.AddRead(
7718 ASYNC, ConstructServerDataPacket(
7719 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7720 ConstructDataFrame("hello!")));
7721
7722 mock_quic_data.AddRead(ASYNC, 0);
7723 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7724
7725 // The non-alternate protocol job needs to hang in order to guarantee that
7726 // the alternate-protocol job will "win".
7727 AddHangingNonAlternateProtocolSocketData();
7728
7729 CreateSession();
7730
7731 // PUSH_PROMISE handling in the http layer gets exercised here.
7732 SendRequestAndExpectQuicResponse("hello!");
7733
7734 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7735 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7736 }
7737
7738 // Performs an HTTPS/1.1 request over QUIC proxy tunnel.
TEST_P(QuicNetworkTransactionTest,QuicProxyConnectHttpsServer)7739 TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
7740 session_params_.enable_quic = true;
7741 session_params_.enable_quic_proxies_for_https_urls = true;
7742 proxy_resolution_service_ =
7743 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7744 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7745
7746 MockQuicData mock_quic_data(version_);
7747 int packet_num = 1;
7748 if (VersionUsesHttp3(version_.transport_version)) {
7749 mock_quic_data.AddWrite(SYNCHRONOUS,
7750 ConstructInitialSettingsPacket(packet_num++));
7751 }
7752 mock_quic_data.AddWrite(
7753 SYNCHRONOUS,
7754 ConstructClientRequestHeadersPacket(
7755 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7756 false,
7757 VersionUsesHttp3(version_.transport_version)
7758 ? DEFAULT_PRIORITY
7759 : HttpProxyConnectJob::kH2QuicTunnelPriority,
7760 ConnectRequestHeaders("mail.example.org:443"), 0));
7761 mock_quic_data.AddRead(
7762 ASYNC, ConstructServerResponseHeadersPacket(
7763 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7764 GetResponseHeaders("200 OK")));
7765
7766 const char get_request[] =
7767 "GET / HTTP/1.1\r\n"
7768 "Host: mail.example.org\r\n"
7769 "Connection: keep-alive\r\n\r\n";
7770 mock_quic_data.AddWrite(
7771 SYNCHRONOUS,
7772 ConstructClientAckAndDataPacket(
7773 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7774 1, false, ConstructDataFrame(get_request)));
7775
7776 const char get_response[] =
7777 "HTTP/1.1 200 OK\r\n"
7778 "Content-Length: 10\r\n\r\n";
7779 mock_quic_data.AddRead(
7780 ASYNC, ConstructServerDataPacket(
7781 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7782 ConstructDataFrame(get_response)));
7783 mock_quic_data.AddRead(
7784 SYNCHRONOUS, ConstructServerDataPacket(
7785 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7786 false, ConstructDataFrame("0123456789")));
7787 mock_quic_data.AddWrite(SYNCHRONOUS,
7788 ConstructClientAckPacket(packet_num++, 3, 2));
7789 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7790
7791 if (VersionUsesHttp3(version_.transport_version)) {
7792 mock_quic_data.AddWrite(
7793 SYNCHRONOUS, ConstructClientDataPacket(
7794 packet_num++, GetQpackDecoderStreamId(), true, false,
7795 StreamCancellationQpackDecoderInstruction(0)));
7796 }
7797
7798 mock_quic_data.AddWrite(
7799 SYNCHRONOUS,
7800 ConstructClientRstPacket(packet_num++,
7801 GetNthClientInitiatedBidirectionalStreamId(0),
7802 quic::QUIC_STREAM_CANCELLED));
7803
7804 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7805
7806 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7807
7808 CreateSession();
7809
7810 request_.url = GURL("https://mail.example.org/");
7811 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
7812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7813 RunTransaction(&trans);
7814 CheckWasHttpResponse(&trans);
7815 CheckResponsePort(&trans, 70);
7816 CheckResponseData(&trans, "0123456789");
7817 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7818
7819 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7820 // proxy socket to disconnect.
7821 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7822
7823 base::RunLoop().RunUntilIdle();
7824 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7825 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7826 }
7827
7828 // Performs an HTTP/2 request over QUIC proxy tunnel.
TEST_P(QuicNetworkTransactionTest,QuicProxyConnectSpdyServer)7829 TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
7830 session_params_.enable_quic = true;
7831 session_params_.enable_quic_proxies_for_https_urls = true;
7832 proxy_resolution_service_ =
7833 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7834 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7835
7836 MockQuicData mock_quic_data(version_);
7837 int packet_num = 1;
7838 if (VersionUsesHttp3(version_.transport_version)) {
7839 mock_quic_data.AddWrite(SYNCHRONOUS,
7840 ConstructInitialSettingsPacket(packet_num++));
7841 }
7842 mock_quic_data.AddWrite(
7843 SYNCHRONOUS,
7844 ConstructClientRequestHeadersPacket(
7845 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7846 false,
7847 VersionUsesHttp3(version_.transport_version)
7848 ? DEFAULT_PRIORITY
7849 : HttpProxyConnectJob::kH2QuicTunnelPriority,
7850 ConnectRequestHeaders("mail.example.org:443"), 0));
7851 mock_quic_data.AddRead(
7852 ASYNC, ConstructServerResponseHeadersPacket(
7853 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7854 GetResponseHeaders("200 OK")));
7855
7856 SpdyTestUtil spdy_util;
7857
7858 spdy::SpdySerializedFrame get_frame =
7859 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
7860 mock_quic_data.AddWrite(
7861 SYNCHRONOUS,
7862 ConstructClientAckAndDataPacket(
7863 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7864 1, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
7865 spdy::SpdySerializedFrame resp_frame =
7866 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
7867 mock_quic_data.AddRead(
7868 ASYNC, ConstructServerDataPacket(
7869 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7870 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
7871
7872 spdy::SpdySerializedFrame data_frame =
7873 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
7874 mock_quic_data.AddRead(
7875 SYNCHRONOUS,
7876 ConstructServerDataPacket(
7877 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7878 ConstructDataFrame({data_frame.data(), data_frame.size()})));
7879 mock_quic_data.AddWrite(SYNCHRONOUS,
7880 ConstructClientAckPacket(packet_num++, 3, 2));
7881 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7882
7883 if (VersionUsesHttp3(version_.transport_version)) {
7884 mock_quic_data.AddWrite(
7885 SYNCHRONOUS, ConstructClientDataPacket(
7886 packet_num++, GetQpackDecoderStreamId(), true, false,
7887 StreamCancellationQpackDecoderInstruction(0)));
7888 }
7889
7890 mock_quic_data.AddWrite(
7891 SYNCHRONOUS,
7892 ConstructClientRstPacket(packet_num++,
7893 GetNthClientInitiatedBidirectionalStreamId(0),
7894 quic::QUIC_STREAM_CANCELLED));
7895
7896 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7897
7898 SSLSocketDataProvider ssl_data(ASYNC, OK);
7899 ssl_data.next_proto = kProtoHTTP2;
7900 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7901
7902 CreateSession();
7903
7904 request_.url = GURL("https://mail.example.org/");
7905 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7906 RunTransaction(&trans);
7907 CheckWasSpdyResponse(&trans);
7908 CheckResponsePort(&trans, 70);
7909 CheckResponseData(&trans, "0123456789");
7910 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7911
7912 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7913 // underlying QUIC proxy socket to disconnect.
7914 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7915
7916 base::RunLoop().RunUntilIdle();
7917 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7918 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7919 }
7920
7921 // Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7922 // check that the proxy socket is reused for the second request.
TEST_P(QuicNetworkTransactionTest,QuicProxyConnectReuseTransportSocket)7923 TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
7924 session_params_.enable_quic = true;
7925 session_params_.enable_quic_proxies_for_https_urls = true;
7926 proxy_resolution_service_ =
7927 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7928 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7929
7930 MockQuicData mock_quic_data(version_);
7931 int write_packet_index = 1;
7932 if (VersionUsesHttp3(version_.transport_version)) {
7933 mock_quic_data.AddWrite(
7934 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7935 }
7936 mock_quic_data.AddWrite(
7937 SYNCHRONOUS,
7938 ConstructClientRequestHeadersPacket(
7939 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7940 true, false,
7941 VersionUsesHttp3(version_.transport_version)
7942 ? DEFAULT_PRIORITY
7943 : HttpProxyConnectJob::kH2QuicTunnelPriority,
7944 ConnectRequestHeaders("mail.example.org:443"), 0));
7945 mock_quic_data.AddRead(
7946 ASYNC, ConstructServerResponseHeadersPacket(
7947 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7948 GetResponseHeaders("200 OK")));
7949
7950 const char get_request_1[] =
7951 "GET / HTTP/1.1\r\n"
7952 "Host: mail.example.org\r\n"
7953 "Connection: keep-alive\r\n\r\n";
7954 mock_quic_data.AddWrite(
7955 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7956 write_packet_index++, false,
7957 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
7958 false, ConstructDataFrame(get_request_1)));
7959
7960 const char get_response_1[] =
7961 "HTTP/1.1 200 OK\r\n"
7962 "Content-Length: 10\r\n\r\n";
7963 mock_quic_data.AddRead(
7964 ASYNC, ConstructServerDataPacket(
7965 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7966 ConstructDataFrame(get_response_1)));
7967
7968 mock_quic_data.AddRead(
7969 SYNCHRONOUS, ConstructServerDataPacket(
7970 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7971 false, ConstructDataFrame("0123456789")));
7972
7973 mock_quic_data.AddWrite(SYNCHRONOUS,
7974 ConstructClientAckPacket(write_packet_index++, 3, 2));
7975
7976 const char get_request_2[] =
7977 "GET /2 HTTP/1.1\r\n"
7978 "Host: mail.example.org\r\n"
7979 "Connection: keep-alive\r\n\r\n";
7980 mock_quic_data.AddWrite(
7981 SYNCHRONOUS,
7982 ConstructClientDataPacket(
7983 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7984 false, false, ConstructDataFrame(get_request_2)));
7985
7986 const char get_response_2[] =
7987 "HTTP/1.1 200 OK\r\n"
7988 "Content-Length: 7\r\n\r\n";
7989 mock_quic_data.AddRead(
7990 ASYNC, ConstructServerDataPacket(
7991 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7992 ConstructDataFrame(get_response_2)));
7993
7994 mock_quic_data.AddRead(
7995 SYNCHRONOUS, ConstructServerDataPacket(
7996 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
7997 false, ConstructDataFrame("0123456")));
7998
7999 mock_quic_data.AddWrite(SYNCHRONOUS,
8000 ConstructClientAckPacket(write_packet_index++, 5, 4));
8001 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8002
8003 if (VersionUsesHttp3(version_.transport_version)) {
8004 mock_quic_data.AddWrite(
8005 SYNCHRONOUS, ConstructClientDataPacket(
8006 write_packet_index++, GetQpackDecoderStreamId(), true,
8007 false, StreamCancellationQpackDecoderInstruction(0)));
8008 }
8009
8010 mock_quic_data.AddWrite(
8011 SYNCHRONOUS,
8012 ConstructClientRstPacket(write_packet_index++,
8013 GetNthClientInitiatedBidirectionalStreamId(0),
8014 quic::QUIC_STREAM_CANCELLED));
8015
8016 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8017
8018 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8019
8020 CreateSession();
8021
8022 request_.url = GURL("https://mail.example.org/");
8023 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8024 RunTransaction(&trans_1);
8025 CheckWasHttpResponse(&trans_1);
8026 CheckResponsePort(&trans_1, 70);
8027 CheckResponseData(&trans_1, "0123456789");
8028 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8029
8030 request_.url = GURL("https://mail.example.org/2");
8031 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8032 RunTransaction(&trans_2);
8033 CheckWasHttpResponse(&trans_2);
8034 CheckResponsePort(&trans_2, 70);
8035 CheckResponseData(&trans_2, "0123456");
8036 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8037
8038 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8039 // proxy socket to disconnect.
8040 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8041
8042 base::RunLoop().RunUntilIdle();
8043 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8044 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8045 }
8046
8047 // Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8048 // host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8049 // server is reused for the second request.
TEST_P(QuicNetworkTransactionTest,QuicProxyConnectReuseQuicSession)8050 TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
8051 session_params_.enable_quic = true;
8052 session_params_.enable_quic_proxies_for_https_urls = true;
8053 proxy_resolution_service_ =
8054 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8055 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8056
8057 MockQuicData mock_quic_data(version_);
8058 int packet_num = 1;
8059 if (VersionUsesHttp3(version_.transport_version)) {
8060 mock_quic_data.AddWrite(SYNCHRONOUS,
8061 ConstructInitialSettingsPacket(packet_num++));
8062 }
8063
8064 // CONNECT request and response for first request
8065 mock_quic_data.AddWrite(
8066 SYNCHRONOUS,
8067 ConstructClientRequestHeadersPacket(
8068 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8069 false,
8070 VersionUsesHttp3(version_.transport_version)
8071 ? DEFAULT_PRIORITY
8072 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8073 ConnectRequestHeaders("mail.example.org:443"), 0));
8074 mock_quic_data.AddRead(
8075 ASYNC, ConstructServerResponseHeadersPacket(
8076 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8077 GetResponseHeaders("200 OK")));
8078
8079 // GET request, response, and data over QUIC tunnel for first request
8080 const char get_request[] =
8081 "GET / HTTP/1.1\r\n"
8082 "Host: mail.example.org\r\n"
8083 "Connection: keep-alive\r\n\r\n";
8084 mock_quic_data.AddWrite(
8085 SYNCHRONOUS,
8086 ConstructClientAckAndDataPacket(
8087 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
8088 1, false, ConstructDataFrame(get_request)));
8089
8090 const char get_response[] =
8091 "HTTP/1.1 200 OK\r\n"
8092 "Content-Length: 10\r\n\r\n";
8093 mock_quic_data.AddRead(
8094 ASYNC, ConstructServerDataPacket(
8095 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8096 ConstructDataFrame(get_response)));
8097 mock_quic_data.AddRead(
8098 SYNCHRONOUS, ConstructServerDataPacket(
8099 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8100 false, ConstructDataFrame("0123456789")));
8101 mock_quic_data.AddWrite(SYNCHRONOUS,
8102 ConstructClientAckPacket(packet_num++, 3, 2));
8103
8104 // CONNECT request and response for second request
8105 mock_quic_data.AddWrite(
8106 SYNCHRONOUS,
8107 ConstructClientRequestHeadersPacket(
8108 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8109 false,
8110 VersionUsesHttp3(version_.transport_version)
8111 ? DEFAULT_PRIORITY
8112 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8113 ConnectRequestHeaders("different.example.org:443"),
8114 GetNthClientInitiatedBidirectionalStreamId(0)));
8115 mock_quic_data.AddRead(
8116 ASYNC, ConstructServerResponseHeadersPacket(
8117 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8118 GetResponseHeaders("200 OK")));
8119
8120 // GET request, response, and data over QUIC tunnel for second request
8121 SpdyTestUtil spdy_util;
8122 spdy::SpdySerializedFrame get_frame =
8123 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
8124 mock_quic_data.AddWrite(
8125 SYNCHRONOUS,
8126 ConstructClientAckAndDataPacket(
8127 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 4,
8128 4, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
8129
8130 spdy::SpdySerializedFrame resp_frame =
8131 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
8132 mock_quic_data.AddRead(
8133 ASYNC, ConstructServerDataPacket(
8134 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8135 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
8136
8137 spdy::SpdySerializedFrame data_frame =
8138 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
8139 mock_quic_data.AddRead(
8140 ASYNC, ConstructServerDataPacket(
8141 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8142 ConstructDataFrame({data_frame.data(), data_frame.size()})));
8143
8144 mock_quic_data.AddWrite(SYNCHRONOUS,
8145 ConstructClientAckPacket(packet_num++, 6, 5));
8146 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8147
8148 if (VersionUsesHttp3(version_.transport_version)) {
8149 mock_quic_data.AddWrite(
8150 SYNCHRONOUS, ConstructClientDataPacket(
8151 packet_num++, GetQpackDecoderStreamId(), true, false,
8152 StreamCancellationQpackDecoderInstruction(0)));
8153 }
8154
8155 mock_quic_data.AddWrite(
8156 SYNCHRONOUS,
8157 ConstructClientRstPacket(packet_num++,
8158 GetNthClientInitiatedBidirectionalStreamId(0),
8159 quic::QUIC_STREAM_CANCELLED));
8160
8161 if (VersionUsesHttp3(version_.transport_version)) {
8162 mock_quic_data.AddWrite(
8163 SYNCHRONOUS, ConstructClientDataPacket(
8164 packet_num++, GetQpackDecoderStreamId(), true, false,
8165 StreamCancellationQpackDecoderInstruction(1, false)));
8166 }
8167
8168 mock_quic_data.AddWrite(
8169 SYNCHRONOUS,
8170 ConstructClientRstPacket(packet_num++,
8171 GetNthClientInitiatedBidirectionalStreamId(1),
8172 quic::QUIC_STREAM_CANCELLED));
8173
8174 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8175
8176 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8177
8178 SSLSocketDataProvider ssl_data(ASYNC, OK);
8179 ssl_data.next_proto = kProtoHTTP2;
8180 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8181
8182 CreateSession();
8183
8184 request_.url = GURL("https://mail.example.org/");
8185 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8186 RunTransaction(&trans_1);
8187 CheckWasHttpResponse(&trans_1);
8188 CheckResponsePort(&trans_1, 70);
8189 CheckResponseData(&trans_1, "0123456789");
8190 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8191
8192 request_.url = GURL("https://different.example.org/");
8193 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8194 RunTransaction(&trans_2);
8195 CheckWasSpdyResponse(&trans_2);
8196 CheckResponsePort(&trans_2, 70);
8197 CheckResponseData(&trans_2, "0123456");
8198 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8199
8200 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8201 // proxy socket to disconnect.
8202 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8203
8204 base::RunLoop().RunUntilIdle();
8205 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8206 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8207 }
8208
8209 // Sends a CONNECT request to a QUIC proxy and receive a 500 response.
TEST_P(QuicNetworkTransactionTest,QuicProxyConnectFailure)8210 TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
8211 session_params_.enable_quic = true;
8212 session_params_.enable_quic_proxies_for_https_urls = true;
8213 proxy_resolution_service_ =
8214 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8215 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8216
8217 MockQuicData mock_quic_data(version_);
8218 int packet_num = 1;
8219 if (VersionUsesHttp3(version_.transport_version)) {
8220 mock_quic_data.AddWrite(SYNCHRONOUS,
8221 ConstructInitialSettingsPacket(packet_num++));
8222 }
8223 mock_quic_data.AddWrite(
8224 SYNCHRONOUS,
8225 ConstructClientRequestHeadersPacket(
8226 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8227 false,
8228 VersionUsesHttp3(version_.transport_version)
8229 ? DEFAULT_PRIORITY
8230 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8231 ConnectRequestHeaders("mail.example.org:443"), 0));
8232 mock_quic_data.AddRead(
8233 ASYNC, ConstructServerResponseHeadersPacket(
8234 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8235 GetResponseHeaders("500")));
8236 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8237 mock_quic_data.AddWrite(
8238 SYNCHRONOUS,
8239 ConstructClientAckAndRstPacket(
8240 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8241 quic::QUIC_STREAM_CANCELLED, 1, 1));
8242
8243 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8244
8245 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8246
8247 CreateSession();
8248
8249 request_.url = GURL("https://mail.example.org/");
8250 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8251 TestCompletionCallback callback;
8252 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8253 EXPECT_EQ(ERR_IO_PENDING, rv);
8254 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8255
8256 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8257 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8258 }
8259
8260 // Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
TEST_P(QuicNetworkTransactionTest,QuicProxyQuicConnectionError)8261 TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
8262 session_params_.enable_quic = true;
8263 session_params_.enable_quic_proxies_for_https_urls = true;
8264 proxy_resolution_service_ =
8265 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8266 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8267
8268 MockQuicData mock_quic_data(version_);
8269 int packet_num = 1;
8270 if (VersionUsesHttp3(version_.transport_version)) {
8271 mock_quic_data.AddWrite(SYNCHRONOUS,
8272 ConstructInitialSettingsPacket(packet_num++));
8273 }
8274 mock_quic_data.AddWrite(
8275 SYNCHRONOUS,
8276 ConstructClientRequestHeadersPacket(
8277 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8278 false,
8279 VersionUsesHttp3(version_.transport_version)
8280 ? DEFAULT_PRIORITY
8281 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8282 ConnectRequestHeaders("mail.example.org:443"), 0));
8283 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8284
8285 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8286
8287 CreateSession();
8288
8289 request_.url = GURL("https://mail.example.org/");
8290 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8291 TestCompletionCallback callback;
8292 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8293 EXPECT_EQ(ERR_IO_PENDING, rv);
8294 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8295
8296 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8297 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8298 }
8299
8300 // Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8301 // host. Retries request and succeeds.
TEST_P(QuicNetworkTransactionTest,QuicProxyConnectBadCertificate)8302 TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
8303 session_params_.enable_quic = true;
8304 session_params_.enable_quic_proxies_for_https_urls = true;
8305 proxy_resolution_service_ =
8306 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8307 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8308
8309 MockQuicData mock_quic_data(version_);
8310 int packet_num = 1;
8311 if (VersionUsesHttp3(version_.transport_version)) {
8312 mock_quic_data.AddWrite(SYNCHRONOUS,
8313 ConstructInitialSettingsPacket(packet_num++));
8314 }
8315 mock_quic_data.AddWrite(
8316 SYNCHRONOUS,
8317 ConstructClientRequestHeadersPacket(
8318 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8319 false,
8320 VersionUsesHttp3(version_.transport_version)
8321 ? DEFAULT_PRIORITY
8322 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8323 ConnectRequestHeaders("mail.example.org:443"), 0));
8324 mock_quic_data.AddRead(
8325 ASYNC, ConstructServerResponseHeadersPacket(
8326 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8327 GetResponseHeaders("200 OK")));
8328 if (VersionUsesHttp3(version_.transport_version)) {
8329 mock_quic_data.AddWrite(
8330 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8331 packet_num++, false, GetQpackDecoderStreamId(), 1, 1,
8332 false, StreamCancellationQpackDecoderInstruction(0)));
8333 mock_quic_data.AddWrite(
8334 SYNCHRONOUS,
8335 ConstructClientRstPacket(packet_num++,
8336 GetNthClientInitiatedBidirectionalStreamId(0),
8337 quic::QUIC_STREAM_CANCELLED));
8338 } else {
8339 mock_quic_data.AddWrite(
8340 SYNCHRONOUS,
8341 ConstructClientAckAndRstPacket(
8342 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8343 quic::QUIC_STREAM_CANCELLED, 1, 1));
8344 }
8345
8346 mock_quic_data.AddWrite(
8347 SYNCHRONOUS,
8348 ConstructClientRequestHeadersPacket(
8349 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8350 false,
8351 VersionUsesHttp3(version_.transport_version)
8352 ? DEFAULT_PRIORITY
8353 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8354 ConnectRequestHeaders("mail.example.org:443"),
8355 GetNthClientInitiatedBidirectionalStreamId(0)));
8356 mock_quic_data.AddRead(
8357 ASYNC, ConstructServerResponseHeadersPacket(
8358 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8359 GetResponseHeaders("200 OK")));
8360
8361 const char get_request[] =
8362 "GET / HTTP/1.1\r\n"
8363 "Host: mail.example.org\r\n"
8364 "Connection: keep-alive\r\n\r\n";
8365 mock_quic_data.AddWrite(
8366 SYNCHRONOUS,
8367 ConstructClientAckAndDataPacket(
8368 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 2,
8369 2, false, ConstructDataFrame(get_request)));
8370 const char get_response[] =
8371 "HTTP/1.1 200 OK\r\n"
8372 "Content-Length: 10\r\n\r\n";
8373 mock_quic_data.AddRead(
8374 ASYNC, ConstructServerDataPacket(
8375 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8376 ConstructDataFrame(get_response)));
8377
8378 mock_quic_data.AddRead(
8379 SYNCHRONOUS, ConstructServerDataPacket(
8380 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8381 false, ConstructDataFrame("0123456789")));
8382 mock_quic_data.AddWrite(SYNCHRONOUS,
8383 ConstructClientAckPacket(packet_num++, 4, 3));
8384 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8385
8386 if (VersionUsesHttp3(version_.transport_version)) {
8387 mock_quic_data.AddWrite(
8388 SYNCHRONOUS, ConstructClientDataPacket(
8389 packet_num++, GetQpackDecoderStreamId(), true, false,
8390 StreamCancellationQpackDecoderInstruction(1, false)));
8391 }
8392 mock_quic_data.AddWrite(
8393 SYNCHRONOUS,
8394 ConstructClientRstPacket(packet_num++,
8395 GetNthClientInitiatedBidirectionalStreamId(1),
8396 quic::QUIC_STREAM_CANCELLED));
8397
8398 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8399
8400 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8401 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8402
8403 SSLSocketDataProvider ssl_data(ASYNC, OK);
8404 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8405
8406 CreateSession();
8407
8408 request_.url = GURL("https://mail.example.org/");
8409 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8410 TestCompletionCallback callback;
8411 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8412 EXPECT_EQ(ERR_IO_PENDING, rv);
8413 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8414
8415 rv = trans.RestartIgnoringLastError(callback.callback());
8416 EXPECT_EQ(ERR_IO_PENDING, rv);
8417 EXPECT_EQ(OK, callback.WaitForResult());
8418
8419 CheckWasHttpResponse(&trans);
8420 CheckResponsePort(&trans, 70);
8421 CheckResponseData(&trans, "0123456789");
8422 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8423
8424 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8425 // proxy socket to disconnect.
8426 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8427
8428 base::RunLoop().RunUntilIdle();
8429 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8430 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8431 }
8432
8433 // Checks if a request's specified "user-agent" header shows up correctly in the
8434 // CONNECT request to a QUIC proxy.
TEST_P(QuicNetworkTransactionTest,QuicProxyUserAgent)8435 TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
8436 const char kConfiguredUserAgent[] = "Configured User-Agent";
8437 const char kRequestUserAgent[] = "Request User-Agent";
8438 session_params_.enable_quic = true;
8439 session_params_.enable_quic_proxies_for_https_urls = true;
8440 proxy_resolution_service_ =
8441 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8442 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8443
8444 MockQuicData mock_quic_data(version_);
8445 int packet_num = 1;
8446 if (VersionUsesHttp3(version_.transport_version)) {
8447 mock_quic_data.AddWrite(SYNCHRONOUS,
8448 ConstructInitialSettingsPacket(packet_num++));
8449 }
8450
8451 spdy::Http2HeaderBlock headers =
8452 ConnectRequestHeaders("mail.example.org:443");
8453 headers["user-agent"] = kConfiguredUserAgent;
8454 mock_quic_data.AddWrite(
8455 SYNCHRONOUS,
8456 ConstructClientRequestHeadersPacket(
8457 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8458 false,
8459 VersionUsesHttp3(version_.transport_version)
8460 ? DEFAULT_PRIORITY
8461 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8462 std::move(headers), 0));
8463 // Return an error, so the transaction stops here (this test isn't interested
8464 // in the rest).
8465 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8466
8467 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8468
8469 StaticHttpUserAgentSettings http_user_agent_settings(
8470 std::string() /* accept_language */, kConfiguredUserAgent);
8471 session_context_.http_user_agent_settings = &http_user_agent_settings;
8472 CreateSession();
8473
8474 request_.url = GURL("https://mail.example.org/");
8475 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8476 kRequestUserAgent);
8477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8478 TestCompletionCallback callback;
8479 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8480 EXPECT_EQ(ERR_IO_PENDING, rv);
8481 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8482
8483 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8484 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8485 }
8486
8487 // Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8488 // HTTP/2 stream dependency and weights given the request priority.
TEST_P(QuicNetworkTransactionTest,QuicProxyRequestPriority)8489 TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
8490 session_params_.enable_quic = true;
8491 session_params_.enable_quic_proxies_for_https_urls = true;
8492 proxy_resolution_service_ =
8493 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8494 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8495
8496 const RequestPriority request_priority = MEDIUM;
8497
8498 MockQuicData mock_quic_data(version_);
8499 int packet_num = 1;
8500 if (VersionUsesHttp3(version_.transport_version)) {
8501 mock_quic_data.AddWrite(SYNCHRONOUS,
8502 ConstructInitialSettingsPacket(packet_num++));
8503 }
8504 mock_quic_data.AddWrite(
8505 SYNCHRONOUS,
8506 ConstructClientRequestHeadersPacket(
8507 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8508 false,
8509 VersionUsesHttp3(version_.transport_version)
8510 ? DEFAULT_PRIORITY
8511 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8512 ConnectRequestHeaders("mail.example.org:443"), 0));
8513 // Return an error, so the transaction stops here (this test isn't interested
8514 // in the rest).
8515 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8516
8517 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8518
8519 CreateSession();
8520
8521 request_.url = GURL("https://mail.example.org/");
8522 HttpNetworkTransaction trans(request_priority, session_.get());
8523 TestCompletionCallback callback;
8524 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8525 EXPECT_EQ(ERR_IO_PENDING, rv);
8526 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8527
8528 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8529 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8530 }
8531
8532 // Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8533 // HTTP/2 stream dependency and weights given the request priority.
TEST_P(QuicNetworkTransactionTest,QuicProxyMultipleRequestsError)8534 TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8535 session_params_.enable_quic = true;
8536 session_params_.enable_quic_proxies_for_https_urls = true;
8537 proxy_resolution_service_ =
8538 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8539 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8540
8541 const RequestPriority kRequestPriority = MEDIUM;
8542 const RequestPriority kRequestPriority2 = LOWEST;
8543
8544 MockQuicData mock_quic_data(version_);
8545 if (VersionUsesHttp3(version_.transport_version)) {
8546 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8547 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8548 } else {
8549 mock_quic_data.AddWrite(
8550 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8551 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8552 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8553 ConnectRequestHeaders("mail.example.org:443"), 0));
8554 }
8555 // This should never be reached.
8556 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8557 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8558
8559 // Second connection attempt just fails - result doesn't really matter.
8560 MockQuicData mock_quic_data2(version_);
8561 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8562 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8563
8564 int original_max_sockets_per_group =
8565 ClientSocketPoolManager::max_sockets_per_group(
8566 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8567 ClientSocketPoolManager::set_max_sockets_per_group(
8568 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8569 int original_max_sockets_per_pool =
8570 ClientSocketPoolManager::max_sockets_per_pool(
8571 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8572 ClientSocketPoolManager::set_max_sockets_per_pool(
8573 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8574 CreateSession();
8575
8576 request_.url = GURL("https://mail.example.org/");
8577 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8578 TestCompletionCallback callback;
8579 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8580 EXPECT_EQ(ERR_IO_PENDING, rv);
8581
8582 HttpRequestInfo request2;
8583 request2.url = GURL("https://mail.example.org/some/other/path/");
8584 request2.traffic_annotation =
8585 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8586
8587 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8588 TestCompletionCallback callback2;
8589 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8590 EXPECT_EQ(ERR_IO_PENDING, rv2);
8591
8592 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8593 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8594
8595 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8596
8597 ClientSocketPoolManager::set_max_sockets_per_pool(
8598 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8599 original_max_sockets_per_pool);
8600 ClientSocketPoolManager::set_max_sockets_per_group(
8601 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8602 original_max_sockets_per_group);
8603 }
8604
8605 // Test the request-challenge-retry sequence for basic auth, over a QUIC
8606 // connection when setting up a QUIC proxy tunnel.
TEST_P(QuicNetworkTransactionTest,QuicProxyAuth)8607 TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
8608 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8609 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
8610
8611 // On the second pass, the body read of the auth challenge is synchronous, so
8612 // IsConnectedAndIdle returns false. The socket should still be drained and
8613 // reused. See http://crbug.com/544255.
8614 for (int i = 0; i < 2; ++i) {
8615 QuicTestPacketMaker client_maker(
8616 version_,
8617 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8618 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8619 client_headers_include_h2_stream_dependency_);
8620 QuicTestPacketMaker server_maker(
8621 version_,
8622 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8623 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
8624 false);
8625
8626 session_params_.enable_quic = true;
8627 session_params_.enable_quic_proxies_for_https_urls = true;
8628 proxy_resolution_service_ =
8629 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8630 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8631
8632 MockQuicData mock_quic_data(version_);
8633
8634 int packet_num = 1;
8635 if (VersionUsesHttp3(version_.transport_version)) {
8636 mock_quic_data.AddWrite(
8637 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
8638 }
8639
8640 mock_quic_data.AddWrite(
8641 SYNCHRONOUS,
8642 client_maker.MakeRequestHeadersPacket(
8643 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8644 false,
8645 VersionUsesHttp3(version_.transport_version)
8646 ? quic::QuicStream::kDefaultUrgency
8647 : ConvertRequestPriorityToQuicPriority(
8648 HttpProxyConnectJob::kH2QuicTunnelPriority),
8649 client_maker.ConnectRequestHeaders("mail.example.org:443"), 0,
8650 nullptr));
8651
8652 spdy::Http2HeaderBlock headers =
8653 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
8654 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8655 headers["content-length"] = "10";
8656 mock_quic_data.AddRead(
8657 ASYNC, server_maker.MakeResponseHeadersPacket(
8658 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8659 false, std::move(headers), nullptr));
8660
8661 if (i == 0) {
8662 mock_quic_data.AddRead(
8663 ASYNC, server_maker.MakeDataPacket(
8664 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8665 false, "0123456789"));
8666 } else {
8667 mock_quic_data.AddRead(
8668 SYNCHRONOUS, server_maker.MakeDataPacket(
8669 2, GetNthClientInitiatedBidirectionalStreamId(0),
8670 false, false, "0123456789"));
8671 }
8672
8673 mock_quic_data.AddWrite(SYNCHRONOUS,
8674 client_maker.MakeAckPacket(packet_num++, 2, 1));
8675
8676 if (VersionUsesHttp3(version_.transport_version)) {
8677 mock_quic_data.AddWrite(
8678 SYNCHRONOUS,
8679 client_maker.MakeDataPacket(
8680 packet_num++, GetQpackDecoderStreamId(),
8681 /* should_include_version = */ true,
8682 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
8683 }
8684
8685 mock_quic_data.AddWrite(
8686 SYNCHRONOUS,
8687 client_maker.MakeRstPacket(
8688 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8689 quic::QUIC_STREAM_CANCELLED,
8690 /*include_stop_sending_if_v99=*/true));
8691
8692 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
8693 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8694 mock_quic_data.AddWrite(
8695 SYNCHRONOUS,
8696 client_maker.MakeRequestHeadersPacket(
8697 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8698 false,
8699 VersionUsesHttp3(version_.transport_version)
8700 ? quic::QuicStream::kDefaultUrgency
8701 : ConvertRequestPriorityToQuicPriority(
8702 HttpProxyConnectJob::kH2QuicTunnelPriority),
8703 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
8704 nullptr));
8705
8706 // Response to wrong password
8707 headers =
8708 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
8709 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8710 headers["content-length"] = "10";
8711 mock_quic_data.AddRead(
8712 ASYNC, server_maker.MakeResponseHeadersPacket(
8713 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8714 false, std::move(headers), nullptr));
8715 mock_quic_data.AddRead(SYNCHRONOUS,
8716 ERR_IO_PENDING); // No more data to read
8717
8718 if (VersionUsesHttp3(version_.transport_version)) {
8719 mock_quic_data.AddWrite(
8720 SYNCHRONOUS,
8721 client_maker.MakeAckAndDataPacket(
8722 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, false,
8723 StreamCancellationQpackDecoderInstruction(1, false)));
8724 mock_quic_data.AddWrite(SYNCHRONOUS,
8725 client_maker.MakeRstPacket(
8726 packet_num++, false,
8727 GetNthClientInitiatedBidirectionalStreamId(1),
8728 quic::QUIC_STREAM_CANCELLED));
8729 } else {
8730 mock_quic_data.AddWrite(SYNCHRONOUS,
8731 client_maker.MakeAckAndRstPacket(
8732 packet_num++, false,
8733 GetNthClientInitiatedBidirectionalStreamId(1),
8734 quic::QUIC_STREAM_CANCELLED, 3, 3));
8735 }
8736
8737 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8738 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8739
8740 CreateSession();
8741
8742 request_.url = GURL("https://mail.example.org/");
8743 // Ensure that proxy authentication is attempted even
8744 // when privacy mode is enabled.
8745 request_.privacy_mode = PRIVACY_MODE_ENABLED;
8746 {
8747 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8748 RunTransaction(&trans);
8749
8750 const HttpResponseInfo* response = trans.GetResponseInfo();
8751 ASSERT_TRUE(response != nullptr);
8752 ASSERT_TRUE(response->headers.get() != nullptr);
8753 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8754 response->headers->GetStatusLine());
8755 EXPECT_TRUE(response->headers->IsKeepAlive());
8756 EXPECT_EQ(407, response->headers->response_code());
8757 EXPECT_EQ(10, response->headers->GetContentLength());
8758 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8759 base::Optional<AuthChallengeInfo> auth_challenge =
8760 response->auth_challenge;
8761 ASSERT_TRUE(auth_challenge.has_value());
8762 EXPECT_TRUE(auth_challenge->is_proxy);
8763 EXPECT_EQ("https://proxy.example.org:70",
8764 auth_challenge->challenger.Serialize());
8765 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8766 EXPECT_EQ("basic", auth_challenge->scheme);
8767
8768 TestCompletionCallback callback;
8769 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8770 callback.callback());
8771 EXPECT_EQ(ERR_IO_PENDING, rv);
8772 EXPECT_EQ(OK, callback.WaitForResult());
8773
8774 response = trans.GetResponseInfo();
8775 ASSERT_TRUE(response != nullptr);
8776 ASSERT_TRUE(response->headers.get() != nullptr);
8777 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8778 response->headers->GetStatusLine());
8779 EXPECT_TRUE(response->headers->IsKeepAlive());
8780 EXPECT_EQ(407, response->headers->response_code());
8781 EXPECT_EQ(10, response->headers->GetContentLength());
8782 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8783 auth_challenge = response->auth_challenge;
8784 ASSERT_TRUE(auth_challenge.has_value());
8785 EXPECT_TRUE(auth_challenge->is_proxy);
8786 EXPECT_EQ("https://proxy.example.org:70",
8787 auth_challenge->challenger.Serialize());
8788 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8789 EXPECT_EQ("basic", auth_challenge->scheme);
8790 }
8791 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8792 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8793 // reused because it's not connected).
8794 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8795 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8796 }
8797 }
8798
TEST_P(QuicNetworkTransactionTest,QuicServerPushUpdatesPriority)8799 TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8800 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
8801 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
8802
8803 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8804 // in HEADERS frames for requests and PRIORITY frames).
8805 if (!client_headers_include_h2_stream_dependency_) {
8806 return;
8807 }
8808
8809 if (quic::VersionUsesHttp3(version_.transport_version)) {
8810 // HTTP/3 currently doesn't support PRIORITY.
8811 return;
8812 }
8813
8814 context_.params()->origins_to_force_quic_on.insert(
8815 HostPortPair::FromString("mail.example.org:443"));
8816
8817 const quic::QuicStreamId client_stream_0 =
8818 GetNthClientInitiatedBidirectionalStreamId(0);
8819 const quic::QuicStreamId client_stream_1 =
8820 GetNthClientInitiatedBidirectionalStreamId(1);
8821 const quic::QuicStreamId client_stream_2 =
8822 GetNthClientInitiatedBidirectionalStreamId(2);
8823 const quic::QuicStreamId push_stream_0 =
8824 GetNthServerInitiatedUnidirectionalStreamId(0);
8825 const quic::QuicStreamId push_stream_1 =
8826 GetNthServerInitiatedUnidirectionalStreamId(1);
8827
8828 MockQuicData mock_quic_data(version_);
8829 int packet_num = 1;
8830 if (VersionUsesHttp3(version_.transport_version)) {
8831 mock_quic_data.AddWrite(SYNCHRONOUS,
8832 ConstructInitialSettingsPacket(packet_num++));
8833 }
8834
8835 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
8836 mock_quic_data.AddWrite(
8837 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8838 packet_num++, client_stream_0, true, true, HIGHEST,
8839 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
8840 mock_quic_data.AddWrite(
8841 SYNCHRONOUS,
8842 ConstructClientRequestHeadersPacket(
8843 packet_num++, client_stream_1, true, true, MEDIUM,
8844 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8845 mock_quic_data.AddWrite(
8846 SYNCHRONOUS,
8847 ConstructClientRequestHeadersPacket(
8848 packet_num++, client_stream_2, true, true, MEDIUM,
8849 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
8850
8851 // Server replies "OK" for the three requests.
8852 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8853 1, client_stream_0, false, false,
8854 GetResponseHeaders("200 OK")));
8855 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8856 2, client_stream_1, false, false,
8857 GetResponseHeaders("200 OK")));
8858 mock_quic_data.AddWrite(SYNCHRONOUS,
8859 ConstructClientAckPacket(packet_num++, 2, 1));
8860 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8861 3, client_stream_2, false, false,
8862 GetResponseHeaders("200 OK")));
8863
8864 // Server sends two push promises associated with |client_stream_0|; client
8865 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8866 // dependency info for each push promise stream.
8867 mock_quic_data.AddRead(
8868 ASYNC, ConstructServerPushPromisePacket(
8869 4, client_stream_0, push_stream_0, false,
8870 GetRequestHeaders("GET", "https", "/pushed_0.jpg")));
8871 mock_quic_data.AddWrite(
8872 SYNCHRONOUS,
8873 ConstructClientAckAndPriorityFramesPacket(
8874 packet_num++, false, 4, 3,
8875 {{push_stream_0, client_stream_2,
8876 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8877 mock_quic_data.AddRead(
8878 ASYNC, ConstructServerPushPromisePacket(
8879 5, client_stream_0, push_stream_1, false,
8880 GetRequestHeaders("GET", "https", "/pushed_1.jpg")));
8881 mock_quic_data.AddWrite(SYNCHRONOUS,
8882 ConstructClientAckAndPriorityPacket(
8883 packet_num++, false,
8884 /*largest_received=*/5, /*smallest_received=*/4,
8885 push_stream_1, push_stream_0, DEFAULT_PRIORITY));
8886
8887 // Server sends the response headers for the two push promises.
8888 mock_quic_data.AddRead(
8889 ASYNC, ConstructServerResponseHeadersPacket(
8890 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
8891 mock_quic_data.AddRead(
8892 ASYNC, ConstructServerResponseHeadersPacket(
8893 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
8894 mock_quic_data.AddWrite(SYNCHRONOUS,
8895 ConstructClientAckPacket(packet_num++, 7, 5));
8896
8897 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8898 // priority updates to match the request's priority. Client sends PRIORITY
8899 // frames to inform server of new HTTP/2 stream dependencies.
8900 mock_quic_data.AddWrite(
8901 SYNCHRONOUS,
8902 ConstructClientPriorityFramesPacket(
8903 packet_num++, false,
8904 {{push_stream_1, client_stream_2,
8905 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8906 {push_stream_0, client_stream_0,
8907 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
8908
8909 // Server sends data for the three requests and the two push promises.
8910 mock_quic_data.AddRead(
8911 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
8912 ConstructDataFrame("hello 0!")));
8913 mock_quic_data.AddRead(
8914 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
8915 ConstructDataFrame("hello 1!")));
8916 mock_quic_data.AddWrite(SYNCHRONOUS,
8917 ConstructClientAckPacket(packet_num++, 9, 8));
8918 mock_quic_data.AddRead(
8919 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
8920 ConstructDataFrame("hello 2!")));
8921 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
8922 11, push_stream_0, false, true,
8923 ConstructDataFrame("and hello 0!")));
8924 mock_quic_data.AddWrite(SYNCHRONOUS,
8925 ConstructClientAckPacket(packet_num++, 11, 10));
8926 mock_quic_data.AddRead(
8927 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
8928 ConstructDataFrame("and hello 1!")));
8929
8930 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8931 mock_quic_data.AddRead(ASYNC, 0); // EOF
8932 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8933
8934 // The non-alternate protocol job needs to hang in order to guarantee that
8935 // the alternate-protocol job will "win".
8936 AddHangingNonAlternateProtocolSocketData();
8937
8938 CreateSession();
8939
8940 request_.url = GURL("https://mail.example.org/0.jpg");
8941 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8942 TestCompletionCallback callback_0;
8943 EXPECT_EQ(ERR_IO_PENDING,
8944 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8945 base::RunLoop().RunUntilIdle();
8946
8947 request_.url = GURL("https://mail.example.org/1.jpg");
8948 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8949 TestCompletionCallback callback_1;
8950 EXPECT_EQ(ERR_IO_PENDING,
8951 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8952 base::RunLoop().RunUntilIdle();
8953
8954 request_.url = GURL("https://mail.example.org/2.jpg");
8955 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8956 TestCompletionCallback callback_2;
8957 EXPECT_EQ(ERR_IO_PENDING,
8958 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8959 base::RunLoop().RunUntilIdle();
8960
8961 // Client makes request that matches resource pushed in |pushed_stream_0|.
8962 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8963 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8964 TestCompletionCallback callback_3;
8965 EXPECT_EQ(ERR_IO_PENDING,
8966 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8967 base::RunLoop().RunUntilIdle();
8968
8969 EXPECT_TRUE(callback_0.have_result());
8970 EXPECT_EQ(OK, callback_0.WaitForResult());
8971 EXPECT_TRUE(callback_1.have_result());
8972 EXPECT_EQ(OK, callback_1.WaitForResult());
8973 EXPECT_TRUE(callback_2.have_result());
8974 EXPECT_EQ(OK, callback_2.WaitForResult());
8975
8976 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8977 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8978 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8979 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8980
8981 mock_quic_data.Resume();
8982 base::RunLoop().RunUntilIdle();
8983 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8984 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8985 }
8986
8987 // Test that NetworkIsolationKey is respected by QUIC connections, when
8988 // kPartitionConnectionsByNetworkIsolationKey is enabled.
TEST_P(QuicNetworkTransactionTest,NetworkIsolation)8989 TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
8990 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
8991 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
8992 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
8993 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
8994
8995 context_.params()->origins_to_force_quic_on.insert(
8996 HostPortPair::FromString("mail.example.org:443"));
8997
8998 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
8999 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9000 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9001 // the same way as the HTTP over H2 proxy case.
9002 for (bool use_proxy : {false, true}) {
9003 SCOPED_TRACE(use_proxy);
9004
9005 if (use_proxy) {
9006 proxy_resolution_service_ =
9007 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9008 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9009 } else {
9010 proxy_resolution_service_ =
9011 ConfiguredProxyResolutionService::CreateDirect();
9012 }
9013
9014 GURL url1;
9015 GURL url2;
9016 GURL url3;
9017 if (use_proxy) {
9018 url1 = GURL("http://mail.example.org/1");
9019 url2 = GURL("http://mail.example.org/2");
9020 url3 = GURL("http://mail.example.org/3");
9021 } else {
9022 url1 = GURL("https://mail.example.org/1");
9023 url2 = GURL("https://mail.example.org/2");
9024 url3 = GURL("https://mail.example.org/3");
9025 }
9026
9027 for (bool partition_connections : {false, true}) {
9028 SCOPED_TRACE(partition_connections);
9029
9030 base::test::ScopedFeatureList feature_list;
9031 if (partition_connections) {
9032 feature_list.InitAndEnableFeature(
9033 features::kPartitionConnectionsByNetworkIsolationKey);
9034 } else {
9035 feature_list.InitAndDisableFeature(
9036 features::kPartitionConnectionsByNetworkIsolationKey);
9037 }
9038
9039 // Reads and writes for the unpartitioned case, where only one socket is
9040 // used.
9041
9042 context_.params()->origins_to_force_quic_on.insert(
9043 HostPortPair::FromString("mail.example.org:443"));
9044
9045 MockQuicData unpartitioned_mock_quic_data(version_);
9046 QuicTestPacketMaker client_maker1(
9047 version_,
9048 quic::QuicUtils::CreateRandomConnectionId(
9049 context_.random_generator()),
9050 context_.clock(), kDefaultServerHostName,
9051 quic::Perspective::IS_CLIENT,
9052 client_headers_include_h2_stream_dependency_);
9053 QuicTestPacketMaker server_maker1(
9054 version_,
9055 quic::QuicUtils::CreateRandomConnectionId(
9056 context_.random_generator()),
9057 context_.clock(), kDefaultServerHostName,
9058 quic::Perspective::IS_SERVER, false);
9059
9060 int packet_num = 1;
9061 if (VersionUsesHttp3(version_.transport_version)) {
9062 unpartitioned_mock_quic_data.AddWrite(
9063 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9064 }
9065
9066 unpartitioned_mock_quic_data.AddWrite(
9067 SYNCHRONOUS,
9068 client_maker1.MakeRequestHeadersPacket(
9069 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9070 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
9071 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
9072 unpartitioned_mock_quic_data.AddRead(
9073 ASYNC, server_maker1.MakeResponseHeadersPacket(
9074 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9075 false, GetResponseHeaders("200 OK"), nullptr));
9076 unpartitioned_mock_quic_data.AddRead(
9077 ASYNC, server_maker1.MakeDataPacket(
9078 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9079 true, ConstructDataFrame("1")));
9080 unpartitioned_mock_quic_data.AddWrite(
9081 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
9082
9083 unpartitioned_mock_quic_data.AddWrite(
9084 SYNCHRONOUS,
9085 client_maker1.MakeRequestHeadersPacket(
9086 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9087 false, true,
9088 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
9089 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
9090 unpartitioned_mock_quic_data.AddRead(
9091 ASYNC, server_maker1.MakeResponseHeadersPacket(
9092 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9093 false, GetResponseHeaders("200 OK"), nullptr));
9094 unpartitioned_mock_quic_data.AddRead(
9095 ASYNC, server_maker1.MakeDataPacket(
9096 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
9097 true, ConstructDataFrame("2")));
9098 unpartitioned_mock_quic_data.AddWrite(
9099 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
9100
9101 unpartitioned_mock_quic_data.AddWrite(
9102 SYNCHRONOUS,
9103 client_maker1.MakeRequestHeadersPacket(
9104 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9105 false, true,
9106 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
9107 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
9108 unpartitioned_mock_quic_data.AddRead(
9109 ASYNC, server_maker1.MakeResponseHeadersPacket(
9110 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9111 false, GetResponseHeaders("200 OK"), nullptr));
9112 unpartitioned_mock_quic_data.AddRead(
9113 ASYNC, server_maker1.MakeDataPacket(
9114 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
9115 true, ConstructDataFrame("3")));
9116 unpartitioned_mock_quic_data.AddWrite(
9117 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
9118
9119 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9120
9121 // Reads and writes for the partitioned case, where two sockets are used.
9122
9123 MockQuicData partitioned_mock_quic_data1(version_);
9124 QuicTestPacketMaker client_maker2(
9125 version_,
9126 quic::QuicUtils::CreateRandomConnectionId(
9127 context_.random_generator()),
9128 context_.clock(), kDefaultServerHostName,
9129 quic::Perspective::IS_CLIENT,
9130 client_headers_include_h2_stream_dependency_);
9131 QuicTestPacketMaker server_maker2(
9132 version_,
9133 quic::QuicUtils::CreateRandomConnectionId(
9134 context_.random_generator()),
9135 context_.clock(), kDefaultServerHostName,
9136 quic::Perspective::IS_SERVER, false);
9137
9138 int packet_num2 = 1;
9139 if (VersionUsesHttp3(version_.transport_version)) {
9140 partitioned_mock_quic_data1.AddWrite(
9141 SYNCHRONOUS,
9142 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9143 }
9144
9145 partitioned_mock_quic_data1.AddWrite(
9146 SYNCHRONOUS,
9147 client_maker2.MakeRequestHeadersPacket(
9148 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9149 true, true,
9150 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
9151 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
9152 partitioned_mock_quic_data1.AddRead(
9153 ASYNC, server_maker2.MakeResponseHeadersPacket(
9154 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9155 false, GetResponseHeaders("200 OK"), nullptr));
9156 partitioned_mock_quic_data1.AddRead(
9157 ASYNC, server_maker2.MakeDataPacket(
9158 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9159 true, ConstructDataFrame("1")));
9160 partitioned_mock_quic_data1.AddWrite(
9161 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
9162
9163 partitioned_mock_quic_data1.AddWrite(
9164 SYNCHRONOUS,
9165 client_maker2.MakeRequestHeadersPacket(
9166 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9167 false, true,
9168 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
9169 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
9170 partitioned_mock_quic_data1.AddRead(
9171 ASYNC, server_maker2.MakeResponseHeadersPacket(
9172 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9173 false, GetResponseHeaders("200 OK"), nullptr));
9174 partitioned_mock_quic_data1.AddRead(
9175 ASYNC, server_maker2.MakeDataPacket(
9176 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
9177 true, ConstructDataFrame("3")));
9178 partitioned_mock_quic_data1.AddWrite(
9179 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
9180
9181 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9182
9183 MockQuicData partitioned_mock_quic_data2(version_);
9184 QuicTestPacketMaker client_maker3(
9185 version_,
9186 quic::QuicUtils::CreateRandomConnectionId(
9187 context_.random_generator()),
9188 context_.clock(), kDefaultServerHostName,
9189 quic::Perspective::IS_CLIENT,
9190 client_headers_include_h2_stream_dependency_);
9191 QuicTestPacketMaker server_maker3(
9192 version_,
9193 quic::QuicUtils::CreateRandomConnectionId(
9194 context_.random_generator()),
9195 context_.clock(), kDefaultServerHostName,
9196 quic::Perspective::IS_SERVER, false);
9197
9198 int packet_num3 = 1;
9199 if (VersionUsesHttp3(version_.transport_version)) {
9200 partitioned_mock_quic_data2.AddWrite(
9201 SYNCHRONOUS,
9202 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9203 }
9204
9205 partitioned_mock_quic_data2.AddWrite(
9206 SYNCHRONOUS,
9207 client_maker3.MakeRequestHeadersPacket(
9208 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9209 true, true,
9210 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
9211 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
9212 partitioned_mock_quic_data2.AddRead(
9213 ASYNC, server_maker3.MakeResponseHeadersPacket(
9214 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9215 false, GetResponseHeaders("200 OK"), nullptr));
9216 partitioned_mock_quic_data2.AddRead(
9217 ASYNC, server_maker3.MakeDataPacket(
9218 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9219 true, ConstructDataFrame("2")));
9220 partitioned_mock_quic_data2.AddWrite(
9221 SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
9222
9223 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9224
9225 if (partition_connections) {
9226 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9227 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9228 } else {
9229 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9230 }
9231
9232 CreateSession();
9233
9234 TestCompletionCallback callback;
9235 HttpRequestInfo request1;
9236 request1.method = "GET";
9237 request1.url = GURL(url1);
9238 request1.traffic_annotation =
9239 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9240 request1.network_isolation_key = network_isolation_key1;
9241 HttpNetworkTransaction trans1(LOWEST, session_.get());
9242 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9243 EXPECT_THAT(callback.GetResult(rv), IsOk());
9244 std::string response_data1;
9245 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9246 EXPECT_EQ("1", response_data1);
9247
9248 HttpRequestInfo request2;
9249 request2.method = "GET";
9250 request2.url = GURL(url2);
9251 request2.traffic_annotation =
9252 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9253 request2.network_isolation_key = network_isolation_key2;
9254 HttpNetworkTransaction trans2(LOWEST, session_.get());
9255 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9256 EXPECT_THAT(callback.GetResult(rv), IsOk());
9257 std::string response_data2;
9258 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9259 EXPECT_EQ("2", response_data2);
9260
9261 HttpRequestInfo request3;
9262 request3.method = "GET";
9263 request3.url = GURL(url3);
9264 request3.traffic_annotation =
9265 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9266 request3.network_isolation_key = network_isolation_key1;
9267 HttpNetworkTransaction trans3(LOWEST, session_.get());
9268 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9269 EXPECT_THAT(callback.GetResult(rv), IsOk());
9270 std::string response_data3;
9271 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9272 EXPECT_EQ("3", response_data3);
9273
9274 if (partition_connections) {
9275 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9276 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9277 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9278 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9279 } else {
9280 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9281 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9282 }
9283 }
9284 }
9285 }
9286
9287 // Test that two requests to the same origin over QUIC tunnels use different
9288 // QUIC sessions if their NetworkIsolationKeys don't match, and
9289 // kPartitionConnectionsByNetworkIsolationKey is enabled.
TEST_P(QuicNetworkTransactionTest,NetworkIsolationTunnel)9290 TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9291 base::test::ScopedFeatureList feature_list;
9292 feature_list.InitAndEnableFeature(
9293 features::kPartitionConnectionsByNetworkIsolationKey);
9294
9295 session_params_.enable_quic = true;
9296 session_params_.enable_quic_proxies_for_https_urls = true;
9297 proxy_resolution_service_ =
9298 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9299 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9300
9301 const char kGetRequest[] =
9302 "GET / HTTP/1.1\r\n"
9303 "Host: mail.example.org\r\n"
9304 "Connection: keep-alive\r\n\r\n";
9305 const char kGetResponse[] =
9306 "HTTP/1.1 200 OK\r\n"
9307 "Content-Length: 10\r\n\r\n";
9308
9309 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9310 std::make_unique<MockQuicData>(version_),
9311 std::make_unique<MockQuicData>(version_)};
9312
9313 for (int index : {0, 1}) {
9314 QuicTestPacketMaker client_maker(
9315 version_,
9316 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9317 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9318 client_headers_include_h2_stream_dependency_);
9319 QuicTestPacketMaker server_maker(
9320 version_,
9321 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9322 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9323 false);
9324
9325 int packet_num = 1;
9326 if (VersionUsesHttp3(version_.transport_version)) {
9327 mock_quic_data[index]->AddWrite(
9328 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9329 }
9330
9331 mock_quic_data[index]->AddWrite(
9332 SYNCHRONOUS,
9333 client_maker.MakeRequestHeadersPacket(
9334 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9335 false,
9336 VersionUsesHttp3(version_.transport_version)
9337 ? quic::QuicStream::kDefaultUrgency
9338 : ConvertRequestPriorityToQuicPriority(
9339 HttpProxyConnectJob::kH2QuicTunnelPriority),
9340 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
9341 mock_quic_data[index]->AddRead(
9342 ASYNC, server_maker.MakeResponseHeadersPacket(
9343 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9344 false, GetResponseHeaders("200 OK"), nullptr));
9345
9346 mock_quic_data[index]->AddWrite(
9347 SYNCHRONOUS,
9348 client_maker.MakeAckAndDataPacket(
9349 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
9350 1, 1, false, ConstructDataFrame(kGetRequest)));
9351
9352 mock_quic_data[index]->AddRead(
9353 ASYNC, server_maker.MakeDataPacket(
9354 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9355 false, ConstructDataFrame(kGetResponse)));
9356 mock_quic_data[index]->AddRead(
9357 SYNCHRONOUS, server_maker.MakeDataPacket(
9358 3, GetNthClientInitiatedBidirectionalStreamId(0),
9359 false, false, ConstructDataFrame("0123456789")));
9360 mock_quic_data[index]->AddWrite(
9361 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2));
9362 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9363 ERR_IO_PENDING); // No more data to read
9364
9365 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
9366 }
9367
9368 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9369 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9370 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9371
9372 CreateSession();
9373
9374 request_.url = GURL("https://mail.example.org/");
9375 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9377 RunTransaction(&trans);
9378 CheckResponseData(&trans, "0123456789");
9379
9380 HttpRequestInfo request2;
9381 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9382 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
9383 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9384 RunTransaction(&trans2);
9385 CheckResponseData(&trans2, "0123456789");
9386
9387 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9388 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9389 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9390 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
9391 }
9392
TEST_P(QuicNetworkTransactionTest,AllowHTTP1FalseProhibitsH1)9393 TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
9394 MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
9395 MockRead(ASYNC, OK)};
9396 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9397 socket_factory_.AddSocketDataProvider(&http_data);
9398 AddCertificate(&ssl_data_);
9399 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9400
9401 CreateSession();
9402
9403 request_.method = "POST";
9404 UploadDataStreamNotAllowHTTP1 upload_data("");
9405 request_.upload_data_stream = &upload_data;
9406
9407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9408 TestCompletionCallback callback;
9409 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9411 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
9412 }
9413
9414 // Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
9415 // QUIC.
TEST_P(QuicNetworkTransactionTest,AllowHTTP1MockTest)9416 TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
9417 context_.params()->origins_to_force_quic_on.insert(
9418 HostPortPair::FromString("mail.example.org:443"));
9419
9420 MockQuicData mock_quic_data(version_);
9421 int write_packet_index = 1;
9422 if (VersionUsesHttp3(version_.transport_version)) {
9423 mock_quic_data.AddWrite(
9424 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9425 }
9426 const std::string upload_content = "foo";
9427 mock_quic_data.AddWrite(
9428 SYNCHRONOUS,
9429 ConstructClientRequestHeadersAndDataFramesPacket(
9430 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9431 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9432 0, nullptr, {ConstructDataFrame(upload_content)}));
9433 mock_quic_data.AddRead(
9434 ASYNC, ConstructServerResponseHeadersPacket(
9435 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9436 GetResponseHeaders("200 OK")));
9437
9438 mock_quic_data.AddRead(
9439 ASYNC, ConstructServerDataPacket(
9440 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
9441 ConstructDataFrame("hello!")));
9442
9443 mock_quic_data.AddWrite(SYNCHRONOUS,
9444 ConstructClientAckPacket(write_packet_index++, 2, 1));
9445
9446 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9447 mock_quic_data.AddRead(ASYNC, 0); // EOF
9448 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9449
9450 // The non-alternate protocol job needs to hang in order to guarantee that
9451 // the alternate-protocol job will "win".
9452 AddHangingNonAlternateProtocolSocketData();
9453
9454 CreateSession();
9455 request_.method = "POST";
9456 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9457 request_.upload_data_stream = &upload_data;
9458
9459 SendRequestAndExpectQuicResponse("hello!");
9460 }
9461
TEST_P(QuicNetworkTransactionTest,AllowHTTP1UploadPauseAndResume)9462 TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadPauseAndResume) {
9463 context_.params()->origins_to_force_quic_on.insert(
9464 HostPortPair::FromString("mail.example.org:443"));
9465
9466 MockQuicData mock_quic_data(version_);
9467 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9468 int write_packet_index = 1;
9469 mock_quic_data.AddWrite(
9470 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9471 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9472 if (VersionUsesHttp3(version_.transport_version)) {
9473 mock_quic_data.AddWrite(
9474 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9475 }
9476 const std::string upload_content = "foo";
9477 mock_quic_data.AddWrite(
9478 SYNCHRONOUS,
9479 ConstructClientRequestHeadersAndDataFramesPacket(
9480 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9481 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9482 0, nullptr, {ConstructDataFrame(upload_content)}));
9483 mock_quic_data.AddRead(
9484 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9485 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9486 false, GetResponseHeaders("200 OK")));
9487 mock_quic_data.AddRead(
9488 SYNCHRONOUS, ConstructServerDataPacket(
9489 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9490 true, ConstructDataFrame("hello!")));
9491
9492 mock_quic_data.AddWrite(SYNCHRONOUS,
9493 ConstructClientAckPacket(write_packet_index++, 2, 1));
9494 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9495 mock_quic_data.AddRead(ASYNC, 0); // EOF
9496 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9497 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9498
9499 CreateSession();
9500
9501 AddQuicAlternateProtocolMapping(
9502 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9503
9504 // Set up request.
9505 request_.method = "POST";
9506 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9507 request_.upload_data_stream = &upload_data;
9508
9509 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9510 TestCompletionCallback callback;
9511 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9513 base::RunLoop().RunUntilIdle();
9514 // Resume QUIC job
9515 crypto_client_stream_factory_.last_stream()
9516 ->NotifySessionOneRttKeyAvailable();
9517 socket_data->Resume();
9518
9519 base::RunLoop().RunUntilIdle();
9520 CheckResponseData(&trans, "hello!");
9521 }
9522
TEST_P(QuicNetworkTransactionTest,AllowHTTP1UploadFailH1AndResumeQuic)9523 TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadFailH1AndResumeQuic) {
9524 // This test confirms failed main job should not bother quic job.
9525 MockRead http_reads[] = {
9526 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
9527 MockRead("1.1 Body"),
9528 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9529 MockRead(ASYNC, OK)};
9530 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9531 socket_factory_.AddSocketDataProvider(&http_data);
9532 AddCertificate(&ssl_data_);
9533 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9534
9535 MockQuicData mock_quic_data(version_);
9536 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9537 int write_packet_index = 1;
9538 mock_quic_data.AddWrite(
9539 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9540 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9541 if (VersionUsesHttp3(version_.transport_version)) {
9542 mock_quic_data.AddWrite(
9543 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9544 }
9545 const std::string upload_content = "foo";
9546 mock_quic_data.AddWrite(
9547 SYNCHRONOUS,
9548 ConstructClientRequestHeadersAndDataFramesPacket(
9549 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9550 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9551 0, nullptr, {ConstructDataFrame(upload_content)}));
9552 mock_quic_data.AddRead(
9553 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9554 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9555 false, GetResponseHeaders("200 OK")));
9556 mock_quic_data.AddRead(
9557 SYNCHRONOUS, ConstructServerDataPacket(
9558 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9559 true, ConstructDataFrame("hello!")));
9560 mock_quic_data.AddWrite(SYNCHRONOUS,
9561 ConstructClientAckPacket(write_packet_index++, 2, 1));
9562 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9563 mock_quic_data.AddRead(ASYNC, 0); // EOF
9564 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9565 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9566
9567 // This packet won't be read because AllowHTTP1:false doesn't allow H/1
9568 // connection.
9569 MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
9570 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
9571 socket_factory_.AddSocketDataProvider(&http_data2);
9572 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9573
9574 CreateSession();
9575
9576 // Send the first request via TCP and set up alternative service (QUIC) for
9577 // the origin.
9578 SendRequestAndExpectHttpResponse("1.1 Body");
9579
9580 // Settings to resume main H/1 job quickly while pausing quic job.
9581 AddQuicAlternateProtocolMapping(
9582 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9583 ServerNetworkStats stats1;
9584 stats1.srtt = base::TimeDelta::FromMicroseconds(10);
9585 http_server_properties_->SetServerNetworkStats(
9586 url::SchemeHostPort(request_.url), NetworkIsolationKey(), stats1);
9587
9588 // Set up request.
9589 request_.method = "POST";
9590 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9591 request_.upload_data_stream = &upload_data;
9592
9593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9594 TestCompletionCallback callback;
9595 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9596 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9597 // Confirm TCP job was resumed.
9598 // We can not check its failure because HttpStreamFactory::JobController.
9599 // main_job_net_error is not exposed.
9600 while (socket_factory_.mock_data().next_index() < 3u)
9601 base::RunLoop().RunUntilIdle();
9602 // Resume QUIC job.
9603 crypto_client_stream_factory_.last_stream()
9604 ->NotifySessionOneRttKeyAvailable();
9605 socket_data->Resume();
9606 base::RunLoop().RunUntilIdle();
9607 CheckResponseData(&trans, "hello!");
9608 }
9609
TEST_P(QuicNetworkTransactionTest,IncorrectHttp3GoAway)9610 TEST_P(QuicNetworkTransactionTest, IncorrectHttp3GoAway) {
9611 if (!version_.HasIetfQuicFrames()) {
9612 return;
9613 }
9614
9615 context_.params()->retry_without_alt_svc_on_quic_errors = false;
9616
9617 MockQuicData mock_quic_data(version_);
9618 int write_packet_number = 1;
9619 mock_quic_data.AddWrite(
9620 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number++));
9621 mock_quic_data.AddWrite(
9622 SYNCHRONOUS,
9623 ConstructClientRequestHeadersPacket(
9624 write_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
9625 true, true, GetRequestHeaders("GET", "https", "/")));
9626
9627 int read_packet_number = 1;
9628 mock_quic_data.AddRead(
9629 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number++));
9630 // The GOAWAY frame sent by the server MUST have a stream ID corresponding to
9631 // a client-initiated bidirectional stream. Any other kind of stream ID
9632 // should cause the client to close the connection.
9633 quic::GoAwayFrame goaway{3};
9634 std::unique_ptr<char[]> goaway_buffer;
9635 auto goaway_length =
9636 quic::HttpEncoder::SerializeGoAwayFrame(goaway, &goaway_buffer);
9637 const quic::QuicStreamId control_stream_id =
9638 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9639 version_.transport_version, quic::Perspective::IS_SERVER);
9640 mock_quic_data.AddRead(
9641 ASYNC, ConstructServerDataPacket(
9642 read_packet_number++, control_stream_id, false, false,
9643 absl::string_view(goaway_buffer.get(), goaway_length)));
9644 mock_quic_data.AddWrite(
9645 SYNCHRONOUS,
9646 ConstructClientAckAndConnectionClosePacket(
9647 write_packet_number++, 2, 4, quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
9648 "GOAWAY with invalid stream ID", 0));
9649 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9650
9651 // In order for a new QUIC session to be established via alternate-protocol
9652 // without racing an HTTP connection, we need the host resolution to happen
9653 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
9654 // connection to the the server, in this test we require confirmation
9655 // before encrypting so the HTTP job will still start.
9656 host_resolver_.set_synchronous_mode(true);
9657 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
9658 "");
9659
9660 CreateSession();
9661 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9662
9663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9664 TestCompletionCallback callback;
9665 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9667
9668 crypto_client_stream_factory_.last_stream()
9669 ->NotifySessionOneRttKeyAvailable();
9670 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
9671
9672 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9673 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9674
9675 NetErrorDetails details;
9676 trans.PopulateNetErrorDetails(&details);
9677 EXPECT_THAT(details.quic_connection_error,
9678 quic::test::IsError(quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID));
9679 }
9680
TEST_P(QuicNetworkTransactionTest,RetryOnHttp3GoAway)9681 TEST_P(QuicNetworkTransactionTest, RetryOnHttp3GoAway) {
9682 if (!version_.HasIetfQuicFrames()) {
9683 return;
9684 }
9685
9686 MockQuicData mock_quic_data1(version_);
9687 int write_packet_number1 = 1;
9688 mock_quic_data1.AddWrite(
9689 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number1++));
9690 const quic::QuicStreamId stream_id1 =
9691 GetNthClientInitiatedBidirectionalStreamId(0);
9692 mock_quic_data1.AddWrite(SYNCHRONOUS,
9693 ConstructClientRequestHeadersPacket(
9694 write_packet_number1++, stream_id1, true, true,
9695 GetRequestHeaders("GET", "https", "/")));
9696 const quic::QuicStreamId stream_id2 =
9697 GetNthClientInitiatedBidirectionalStreamId(1);
9698 mock_quic_data1.AddWrite(SYNCHRONOUS,
9699 ConstructClientRequestHeadersPacket(
9700 write_packet_number1++, stream_id2, true, true,
9701 GetRequestHeaders("GET", "https", "/foo")));
9702
9703 int read_packet_number1 = 1;
9704 mock_quic_data1.AddRead(
9705 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number1++));
9706
9707 // GOAWAY with stream_id2 informs the client that stream_id2 (and streams with
9708 // larger IDs) have not been processed and can safely be retried.
9709 quic::GoAwayFrame goaway{stream_id2};
9710 std::unique_ptr<char[]> goaway_buffer;
9711 auto goaway_length =
9712 quic::HttpEncoder::SerializeGoAwayFrame(goaway, &goaway_buffer);
9713 const quic::QuicStreamId control_stream_id =
9714 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9715 version_.transport_version, quic::Perspective::IS_SERVER);
9716 mock_quic_data1.AddRead(
9717 ASYNC, ConstructServerDataPacket(
9718 read_packet_number1++, control_stream_id, false, false,
9719 absl::string_view(goaway_buffer.get(), goaway_length)));
9720 mock_quic_data1.AddWrite(
9721 ASYNC, ConstructClientAckPacket(write_packet_number1++, 2, 1));
9722
9723 // Response to first request is accepted after GOAWAY.
9724 mock_quic_data1.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9725 read_packet_number1++, stream_id1, false,
9726 false, GetResponseHeaders("200 OK")));
9727 mock_quic_data1.AddRead(
9728 ASYNC, ConstructServerDataPacket(
9729 read_packet_number1++, stream_id1, false, true,
9730 ConstructDataFrame("response on the first connection")));
9731 mock_quic_data1.AddWrite(
9732 ASYNC, ConstructClientAckPacket(write_packet_number1++, 4, 1));
9733 mock_quic_data1.AddRead(ASYNC, 0); // EOF
9734 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9735
9736 // Second request is retried on a new connection.
9737 MockQuicData mock_quic_data2(version_);
9738 QuicTestPacketMaker client_maker2(
9739 version_,
9740 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9741 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9742 client_headers_include_h2_stream_dependency_);
9743 int write_packet_number2 = 1;
9744 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(
9745 write_packet_number2++));
9746 spdy::SpdyPriority priority =
9747 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
9748 mock_quic_data2.AddWrite(
9749 SYNCHRONOUS, client_maker2.MakeRequestHeadersPacket(
9750 write_packet_number2++, stream_id1, true, true, priority,
9751 GetRequestHeaders("GET", "https", "/foo"), 0, nullptr));
9752
9753 QuicTestPacketMaker server_maker2(
9754 version_,
9755 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9756 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9757 false);
9758 int read_packet_number2 = 1;
9759 mock_quic_data2.AddRead(ASYNC,
9760 server_maker2.MakeResponseHeadersPacket(
9761 read_packet_number2++, stream_id1, false, false,
9762 GetResponseHeaders("200 OK"), nullptr));
9763 mock_quic_data2.AddRead(
9764 ASYNC, server_maker2.MakeDataPacket(
9765 read_packet_number2++, stream_id1, false, true,
9766 ConstructDataFrame("response on the second connection")));
9767 mock_quic_data2.AddWrite(
9768 ASYNC, client_maker2.MakeAckPacket(write_packet_number2++, 2, 1));
9769 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9770 mock_quic_data2.AddRead(ASYNC, 0); // EOF
9771 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9772
9773 AddHangingNonAlternateProtocolSocketData();
9774 CreateSession();
9775 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9776
9777 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
9778 TestCompletionCallback callback1;
9779 int rv = trans1.Start(&request_, callback1.callback(), net_log_.bound());
9780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9781 base::RunLoop().RunUntilIdle();
9782
9783 HttpRequestInfo request2;
9784 request2.method = "GET";
9785 std::string url("https://");
9786 url.append(kDefaultServerHostName);
9787 url.append("/foo");
9788 request2.url = GURL(url);
9789 request2.load_flags = 0;
9790 request2.traffic_annotation =
9791 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9792 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9793 TestCompletionCallback callback2;
9794 rv = trans2.Start(&request2, callback2.callback(), net_log_.bound());
9795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9796
9797 EXPECT_THAT(callback1.WaitForResult(), IsOk());
9798 CheckResponseData(&trans1, "response on the first connection");
9799
9800 EXPECT_THAT(callback2.WaitForResult(), IsOk());
9801 CheckResponseData(&trans2, "response on the second connection");
9802
9803 mock_quic_data2.Resume();
9804 EXPECT_TRUE(mock_quic_data1.AllWriteDataConsumed());
9805 EXPECT_TRUE(mock_quic_data1.AllReadDataConsumed());
9806 EXPECT_TRUE(mock_quic_data2.AllWriteDataConsumed());
9807 EXPECT_TRUE(mock_quic_data2.AllReadDataConsumed());
9808 }
9809
9810 // TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
9811
9812 } // namespace test
9813 } // namespace net
9814