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