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