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