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 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9
10 #include "net/quic/quic_http_stream.h"
11
12 #include <stdint.h>
13
14 #include <memory>
15 #include <string_view>
16 #include <utility>
17
18 #include "base/containers/span.h"
19 #include "base/functional/bind.h"
20 #include "base/memory/ptr_util.h"
21 #include "base/memory/raw_ptr.h"
22 #include "base/run_loop.h"
23 #include "base/strings/strcat.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "base/task/single_thread_task_runner.h"
26 #include "base/test/metrics/histogram_tester.h"
27 #include "base/test/scoped_feature_list.h"
28 #include "base/time/default_tick_clock.h"
29 #include "base/time/time.h"
30 #include "net/base/chunked_upload_data_stream.h"
31 #include "net/base/connection_endpoint_metadata.h"
32 #include "net/base/elements_upload_data_stream.h"
33 #include "net/base/features.h"
34 #include "net/base/load_flags.h"
35 #include "net/base/load_timing_info.h"
36 #include "net/base/load_timing_info_test_util.h"
37 #include "net/base/net_errors.h"
38 #include "net/base/network_anonymization_key.h"
39 #include "net/base/privacy_mode.h"
40 #include "net/base/proxy_chain.h"
41 #include "net/base/session_usage.h"
42 #include "net/base/test_completion_callback.h"
43 #include "net/base/upload_bytes_element_reader.h"
44 #include "net/dns/public/host_resolver_results.h"
45 #include "net/dns/public/secure_dns_policy.h"
46 #include "net/http/http_response_headers.h"
47 #include "net/http/transport_security_state.h"
48 #include "net/log/net_log.h"
49 #include "net/log/net_log_event_type.h"
50 #include "net/log/test_net_log.h"
51 #include "net/log/test_net_log_util.h"
52 #include "net/quic/address_utils.h"
53 #include "net/quic/crypto/proof_verifier_chromium.h"
54 #include "net/quic/mock_crypto_client_stream_factory.h"
55 #include "net/quic/quic_chromium_alarm_factory.h"
56 #include "net/quic/quic_chromium_connection_helper.h"
57 #include "net/quic/quic_chromium_packet_reader.h"
58 #include "net/quic/quic_chromium_packet_writer.h"
59 #include "net/quic/quic_context.h"
60 #include "net/quic/quic_crypto_client_config_handle.h"
61 #include "net/quic/quic_http_utils.h"
62 #include "net/quic/quic_server_info.h"
63 #include "net/quic/quic_session_alias_key.h"
64 #include "net/quic/quic_session_key.h"
65 #include "net/quic/quic_session_pool.h"
66 #include "net/quic/quic_test_packet_maker.h"
67 #include "net/quic/quic_test_packet_printer.h"
68 #include "net/quic/test_quic_crypto_client_config_handle.h"
69 #include "net/quic/test_task_runner.h"
70 #include "net/socket/socket_performance_watcher.h"
71 #include "net/socket/socket_tag.h"
72 #include "net/socket/socket_test_util.h"
73 #include "net/spdy/spdy_http_utils.h"
74 #include "net/ssl/ssl_config_service_defaults.h"
75 #include "net/test/cert_test_util.h"
76 #include "net/test/gtest_util.h"
77 #include "net/test/test_data_directory.h"
78 #include "net/test/test_with_task_environment.h"
79 #include "net/third_party/quiche/src/quiche/common/http/http_header_block.h"
80 #include "net/third_party/quiche/src/quiche/http2/core/spdy_frame_builder.h"
81 #include "net/third_party/quiche/src/quiche/http2/core/spdy_framer.h"
82 #include "net/third_party/quiche/src/quiche/http2/core/spdy_protocol.h"
83 #include "net/third_party/quiche/src/quiche/quic/core/congestion_control/send_algorithm_interface.h"
84 #include "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h"
85 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
86 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
87 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection.h"
88 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
89 #include "net/third_party/quiche/src/quiche/quic/core/quic_write_blocked_list.h"
90 #include "net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.h"
91 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h"
92 #include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
93 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
94 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_connection_id_generator.h"
95 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
96 #include "net/third_party/quiche/src/quiche/quic/test_tools/qpack/qpack_test_utils.h"
97 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h"
98 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
99 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
100 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
101 #include "testing/gmock/include/gmock/gmock.h"
102 #include "testing/gtest/include/gtest/gtest.h"
103 #include "url/scheme_host_port.h"
104 #include "url/url_constants.h"
105
106 using std::string;
107 using testing::_;
108 using testing::AnyNumber;
109 using testing::Return;
110
111 namespace net::test {
112 namespace {
113
114 const char kUploadData[] = "Really nifty data!";
115 const char kDefaultServerHostName[] = "www.example.org";
116 const uint16_t kDefaultServerPort = 443;
117
118 struct TestParams {
119 quic::ParsedQuicVersion version;
120 };
121
122 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParams & p)123 std::string PrintToString(const TestParams& p) {
124 return ParsedQuicVersionToString(p.version);
125 }
126
GetTestParams()127 std::vector<TestParams> GetTestParams() {
128 std::vector<TestParams> params;
129 quic::ParsedQuicVersionVector all_supported_versions =
130 AllSupportedQuicVersions();
131 for (const auto& version : all_supported_versions) {
132 params.push_back(TestParams{version});
133 }
134 return params;
135 }
136
137 // Returns true if |params| is a dict, has an entry with key "headers", that
138 // entry is a list of strings, which when interpreted as colon-separated
139 // key-value pairs has exactly one entry with |key| and that entry has value
140 // |expected_value|.
CheckHeader(const base::Value::Dict & params,std::string_view key,std::string_view expected_value)141 bool CheckHeader(const base::Value::Dict& params,
142 std::string_view key,
143 std::string_view expected_value) {
144 const base::Value::List* headers = params.FindList("headers");
145 if (!headers) {
146 return false;
147 }
148
149 std::string header_prefix = base::StrCat({key, ": "});
150 std::string expected_header = base::StrCat({header_prefix, expected_value});
151
152 bool header_found = false;
153 for (const auto& header_value : *headers) {
154 const std::string* header = header_value.GetIfString();
155 if (!header) {
156 return false;
157 }
158 if (header->starts_with(header_prefix)) {
159 if (header_found) {
160 return false;
161 }
162 if (*header != expected_header) {
163 return false;
164 }
165 header_found = true;
166 }
167 }
168 return header_found;
169 }
170
171 class TestQuicConnection : public quic::QuicConnection {
172 public:
TestQuicConnection(const quic::ParsedQuicVersionVector & versions,quic::QuicConnectionId connection_id,IPEndPoint address,QuicChromiumConnectionHelper * helper,QuicChromiumAlarmFactory * alarm_factory,quic::QuicPacketWriter * writer,quic::ConnectionIdGeneratorInterface & generator)173 TestQuicConnection(const quic::ParsedQuicVersionVector& versions,
174 quic::QuicConnectionId connection_id,
175 IPEndPoint address,
176 QuicChromiumConnectionHelper* helper,
177 QuicChromiumAlarmFactory* alarm_factory,
178 quic::QuicPacketWriter* writer,
179 quic::ConnectionIdGeneratorInterface& generator)
180 : quic::QuicConnection(connection_id,
181 quic::QuicSocketAddress(),
182 ToQuicSocketAddress(address),
183 helper,
184 alarm_factory,
185 writer,
186 true /* owns_writer */,
187 quic::Perspective::IS_CLIENT,
188 versions,
189 generator) {}
190
SetSendAlgorithm(quic::SendAlgorithmInterface * send_algorithm)191 void SetSendAlgorithm(quic::SendAlgorithmInterface* send_algorithm) {
192 quic::test::QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
193 }
194 };
195
196 // UploadDataStream that always returns errors on data read.
197 class ReadErrorUploadDataStream : public UploadDataStream {
198 public:
199 enum class FailureMode { SYNC, ASYNC };
200
ReadErrorUploadDataStream(FailureMode mode)201 explicit ReadErrorUploadDataStream(FailureMode mode)
202 : UploadDataStream(true, 0), async_(mode) {}
203
204 ReadErrorUploadDataStream(const ReadErrorUploadDataStream&) = delete;
205 ReadErrorUploadDataStream& operator=(const ReadErrorUploadDataStream&) =
206 delete;
207
208 ~ReadErrorUploadDataStream() override = default;
209
210 private:
CompleteRead()211 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
212
213 // UploadDataStream implementation:
InitInternal(const NetLogWithSource & net_log)214 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
215
ReadInternal(IOBuffer * buf,int buf_len)216 int ReadInternal(IOBuffer* buf, int buf_len) override {
217 if (async_ == FailureMode::ASYNC) {
218 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
219 FROM_HERE, base::BindOnce(&ReadErrorUploadDataStream::CompleteRead,
220 weak_factory_.GetWeakPtr()));
221 return ERR_IO_PENDING;
222 }
223 return ERR_FAILED;
224 }
225
ResetInternal()226 void ResetInternal() override {}
227
228 const FailureMode async_;
229
230 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_{this};
231 };
232
233 // A helper class that will delete |stream| when the callback is invoked.
234 class DeleteStreamCallback : public TestCompletionCallbackBase {
235 public:
DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)236 explicit DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
237 : stream_(std::move(stream)) {}
238
callback()239 CompletionOnceCallback callback() {
240 return base::BindOnce(&DeleteStreamCallback::DeleteStream,
241 base::Unretained(this));
242 }
243
244 private:
DeleteStream(int result)245 void DeleteStream(int result) {
246 stream_.reset();
247 SetResult(result);
248 }
249
250 std::unique_ptr<QuicHttpStream> stream_;
251 };
252
253 } // namespace
254
255 class QuicHttpStreamPeer {
256 public:
GetQuicChromiumClientStream(QuicHttpStream * stream)257 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
258 QuicHttpStream* stream) {
259 return stream->stream_.get();
260 }
261 };
262
263 class QuicHttpStreamTest : public ::testing::TestWithParam<TestParams>,
264 public WithTaskEnvironment {
265 public:
CloseStream(QuicHttpStream * stream,int)266 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
267
268 protected:
269 static const bool kFin = true;
270
271 // Holds a packet to be written to the wire, and the IO mode that should
272 // be used by the mock socket when performing the write.
273 struct PacketToWrite {
PacketToWritenet::test::QuicHttpStreamTest::PacketToWrite274 PacketToWrite(IoMode mode, std::unique_ptr<quic::QuicReceivedPacket> packet)
275 : mode(mode), packet(std::move(packet)) {}
PacketToWritenet::test::QuicHttpStreamTest::PacketToWrite276 PacketToWrite(IoMode mode, int rv) : mode(mode), rv(rv) {}
277
278 IoMode mode;
279 int rv;
280 std::unique_ptr<quic::QuicReceivedPacket> packet;
281 };
282
QuicHttpStreamTest()283 QuicHttpStreamTest()
284 : version_(GetParam().version),
285 crypto_config_(
286 quic::test::crypto_test_utils::ProofVerifierForTesting()),
287 read_buffer_(base::MakeRefCounted<IOBufferWithSize>(4096)),
288 stream_id_(GetNthClientInitiatedBidirectionalStreamId(0)),
289 connection_id_(quic::test::TestConnectionId(2)),
290 client_maker_(version_,
291 connection_id_,
292 &clock_,
293 kDefaultServerHostName,
294 quic::Perspective::IS_CLIENT,
295 /*client_priority_uses_incremental=*/true,
296 /*use_priority_header=*/true),
297 server_maker_(version_,
298 connection_id_,
299 &clock_,
300 kDefaultServerHostName,
301 quic::Perspective::IS_SERVER,
302 /*client_priority_uses_incremental=*/false,
303 /*use_priority_header=*/false),
304 printer_(version_) {
305 FLAGS_quic_enable_http3_grease_randomness = false;
306 quic::QuicEnableVersion(version_);
307 IPAddress ip(192, 0, 2, 33);
308 peer_addr_ = IPEndPoint(ip, 443);
309 self_addr_ = IPEndPoint(ip, 8435);
310 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
311 request_.traffic_annotation =
312 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
313 }
314
~QuicHttpStreamTest()315 ~QuicHttpStreamTest() override {
316 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
317 quic::ConnectionCloseBehavior::SILENT_CLOSE);
318 }
319
320 // Adds a packet to the list of expected writes.
AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet)321 void AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet) {
322 writes_.emplace_back(SYNCHRONOUS, std::move(packet));
323 }
324
AddWrite(IoMode mode,int rv)325 void AddWrite(IoMode mode, int rv) { writes_.emplace_back(mode, rv); }
326
327 // Returns the packet to be written at position |pos|.
GetWrite(size_t pos)328 quic::QuicReceivedPacket* GetWrite(size_t pos) {
329 return writes_[pos].packet.get();
330 }
331
AtEof()332 bool AtEof() {
333 return socket_data_->AllReadDataConsumed() &&
334 socket_data_->AllWriteDataConsumed();
335 }
336
ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet)337 void ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet) {
338 connection_->ProcessUdpPacket(ToQuicSocketAddress(self_addr_),
339 ToQuicSocketAddress(peer_addr_), *packet);
340 }
341
342 // Configures the test fixture to use the list of expected writes.
Initialize()343 void Initialize() {
344 mock_writes_ = std::make_unique<MockWrite[]>(writes_.size());
345 for (size_t i = 0; i < writes_.size(); i++) {
346 if (writes_[i].packet == nullptr) {
347 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
348 } else {
349 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
350 writes_[i].packet->length());
351 }
352 }
353
354 socket_data_ = std::make_unique<StaticSocketDataProvider>(
355 base::span<MockRead>(), base::span(mock_writes_.get(), writes_.size()));
356 socket_data_->set_printer(&printer_);
357
358 auto socket = std::make_unique<MockUDPClientSocket>(socket_data_.get(),
359 NetLog::Get());
360 socket->Connect(peer_addr_);
361 runner_ = base::MakeRefCounted<TestTaskRunner>(&clock_);
362 send_algorithm_ = new quic::test::MockSendAlgorithm();
363 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
364 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
365 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
366 .Times(testing::AtLeast(1));
367 EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
368 .Times(AnyNumber());
369 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
370 .WillRepeatedly(Return(quic::kMaxOutgoingPacketSize));
371 EXPECT_CALL(*send_algorithm_, PacingRate(_))
372 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
373 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
374 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
375 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
376 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
377 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
378 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
379 .Times(AnyNumber());
380 helper_ = std::make_unique<QuicChromiumConnectionHelper>(
381 &clock_, &random_generator_);
382 alarm_factory_ =
383 std::make_unique<QuicChromiumAlarmFactory>(runner_.get(), &clock_);
384
385 connection_ = new TestQuicConnection(
386 quic::test::SupportedVersions(version_), connection_id_, peer_addr_,
387 helper_.get(), alarm_factory_.get(),
388 new QuicChromiumPacketWriter(
389 socket.get(),
390 base::SingleThreadTaskRunner::GetCurrentDefault().get()),
391 connection_id_generator_);
392 connection_->set_visitor(&visitor_);
393 connection_->SetSendAlgorithm(send_algorithm_);
394
395 // Load a certificate that is valid for *.example.org
396 scoped_refptr<X509Certificate> test_cert(
397 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
398 EXPECT_TRUE(test_cert.get());
399
400 verify_details_.cert_verify_result.verified_cert = test_cert;
401 verify_details_.cert_verify_result.is_issued_by_known_root = true;
402 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
403
404 base::TimeTicks dns_end = base::TimeTicks::Now();
405 base::TimeTicks dns_start = dns_end - base::Milliseconds(1);
406 session_ = std::make_unique<QuicChromiumClientSession>(
407 connection_, std::move(socket),
408 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
409 &transport_security_state_, &ssl_config_service_,
410 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
411 QuicSessionAliasKey(
412 url::SchemeHostPort(),
413 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
414 PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
415 SessionUsage::kDestination, SocketTag(),
416 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
417 /*require_dns_https_alpn=*/false)),
418 /*require_confirmation=*/false,
419 /*migrate_session_early_v2=*/false,
420 /*migrate_session_on_network_change_v2=*/false,
421 /*default_network=*/handles::kInvalidNetworkHandle,
422 quic::QuicTime::Delta::FromMilliseconds(
423 kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
424 /*migrate_idle_session=*/false, /*allow_port_migration=*/false,
425 kDefaultIdleSessionMigrationPeriod, /*multi_port_probing_interval=*/0,
426 kMaxTimeOnNonDefaultNetwork,
427 kMaxMigrationsToNonDefaultNetworkOnWriteError,
428 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
429 kQuicYieldAfterPacketsRead,
430 quic::QuicTime::Delta::FromMilliseconds(
431 kQuicYieldAfterDurationMilliseconds),
432 /*cert_verify_flags=*/0, quic::test::DefaultQuicConfig(),
433 std::make_unique<TestQuicCryptoClientConfigHandle>(&crypto_config_),
434 "CONNECTION_UNKNOWN", dns_start, dns_end,
435 base::DefaultTickClock::GetInstance(),
436 base::SingleThreadTaskRunner::GetCurrentDefault().get(),
437 /*socket_performance_watcher=*/nullptr, ConnectionEndpointMetadata(),
438 /*report_ecn=*/true, /*enable_origin_frame=*/true,
439 /*allow_server_preferred_address=*/true,
440 MultiplexedSessionCreationInitiator::kUnknown,
441 NetLogWithSource::Make(NetLogSourceType::NONE));
442 session_->Initialize();
443
444 // Blackhole QPACK decoder stream instead of constructing mock writes.
445 session_->qpack_decoder()->set_qpack_stream_sender_delegate(
446 &noop_qpack_stream_sender_delegate_);
447
448 TestCompletionCallback callback;
449 session_->CryptoConnect(callback.callback());
450 stream_ = std::make_unique<QuicHttpStream>(
451 session_->CreateHandle(
452 url::SchemeHostPort(url::kHttpsScheme, "www.example.org", 443)),
453 /*dns_aliases=*/std::set<std::string>());
454 }
455
SetRequest(const string & method,const string & path,RequestPriority priority)456 void SetRequest(const string& method,
457 const string& path,
458 RequestPriority priority) {
459 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
460 }
461
SetResponse(const string & status,const string & body)462 void SetResponse(const string& status, const string& body) {
463 response_headers_ = server_maker_.GetResponseHeaders(status);
464 response_data_ = body;
465 }
466
ConstructClientDataPacket(uint64_t packet_number,bool fin,std::string_view data)467 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
468 uint64_t packet_number,
469 bool fin,
470 std::string_view data) {
471 return client_maker_.Packet(packet_number)
472 .AddStreamFrame(stream_id_, fin, data)
473 .Build();
474 }
475
ConstructServerDataPacket(uint64_t packet_number,bool fin,std::string_view data)476 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
477 uint64_t packet_number,
478 bool fin,
479 std::string_view data) {
480 return server_maker_.Packet(packet_number)
481 .AddStreamFrame(stream_id_, fin, data)
482 .Build();
483 }
484
InnerConstructRequestHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,RequestPriority request_priority,size_t * spdy_headers_frame_length)485 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
486 uint64_t packet_number,
487 quic::QuicStreamId stream_id,
488 bool fin,
489 RequestPriority request_priority,
490 size_t* spdy_headers_frame_length) {
491 spdy::SpdyPriority priority =
492 ConvertRequestPriorityToQuicPriority(request_priority);
493 return client_maker_.MakeRequestHeadersPacket(
494 packet_number, stream_id, fin, priority, std::move(request_headers_),
495 spdy_headers_frame_length);
496 }
497
498 std::unique_ptr<quic::QuicReceivedPacket>
ConstructRequestHeadersAndDataFramesPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,RequestPriority request_priority,size_t * spdy_headers_frame_length,const std::vector<std::string> & data_writes)499 ConstructRequestHeadersAndDataFramesPacket(
500 uint64_t packet_number,
501 quic::QuicStreamId stream_id,
502 bool fin,
503 RequestPriority request_priority,
504 size_t* spdy_headers_frame_length,
505 const std::vector<std::string>& data_writes) {
506 spdy::SpdyPriority priority =
507 ConvertRequestPriorityToQuicPriority(request_priority);
508 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
509 packet_number, stream_id, fin, priority, std::move(request_headers_),
510 spdy_headers_frame_length, data_writes);
511 }
512
ConstructRequestAndRstPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,RequestPriority request_priority,size_t * spdy_headers_frame_length,quic::QuicRstStreamErrorCode error_code)513 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
514 uint64_t packet_number,
515 quic::QuicStreamId stream_id,
516 bool fin,
517 RequestPriority request_priority,
518 size_t* spdy_headers_frame_length,
519 quic::QuicRstStreamErrorCode error_code) {
520 spdy::SpdyPriority priority =
521 ConvertRequestPriorityToQuicPriority(request_priority);
522 return client_maker_.MakeRequestHeadersAndRstPacket(
523 packet_number, stream_id, fin, priority, std::move(request_headers_),
524 spdy_headers_frame_length, error_code);
525 }
526
InnerConstructResponseHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,size_t * spdy_headers_frame_length)527 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
528 uint64_t packet_number,
529 quic::QuicStreamId stream_id,
530 bool fin,
531 size_t* spdy_headers_frame_length) {
532 return server_maker_.MakeResponseHeadersPacket(
533 packet_number, stream_id, fin, std::move(response_headers_),
534 spdy_headers_frame_length);
535 }
536
ConstructResponseHeadersPacket(uint64_t packet_number,bool fin,size_t * spdy_headers_frame_length)537 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
538 uint64_t packet_number,
539 bool fin,
540 size_t* spdy_headers_frame_length) {
541 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
542 spdy_headers_frame_length);
543 }
544
ConstructResponseTrailersPacket(uint64_t packet_number,bool fin,quiche::HttpHeaderBlock trailers,size_t * spdy_headers_frame_length)545 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
546 uint64_t packet_number,
547 bool fin,
548 quiche::HttpHeaderBlock trailers,
549 size_t* spdy_headers_frame_length) {
550 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id_,
551 fin, std::move(trailers),
552 spdy_headers_frame_length);
553 }
554
ConstructClientRstStreamErrorPacket(uint64_t packet_number)555 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
556 uint64_t packet_number) {
557 return client_maker_.Packet(packet_number)
558 .AddStopSendingFrame(stream_id_, quic::QUIC_ERROR_PROCESSING_STREAM)
559 .AddRstStreamFrame(stream_id_, quic::QUIC_ERROR_PROCESSING_STREAM)
560 .Build();
561 }
562
ConstructAckAndRstStreamPacket(uint64_t packet_number)563 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
564 uint64_t packet_number) {
565 return client_maker_.Packet(packet_number)
566 .AddAckFrame(/*first_received=*/1, /*largest_received=*/2,
567 /*smallest_received=*/1)
568 .AddStopSendingFrame(stream_id_, quic::QUIC_STREAM_CANCELLED)
569 .AddRstStreamFrame(stream_id_, quic::QUIC_STREAM_CANCELLED)
570 .Build();
571 }
572
ConstructClientAckPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received)573 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
574 uint64_t packet_number,
575 uint64_t largest_received,
576 uint64_t smallest_received) {
577 return client_maker_.Packet(packet_number)
578 .AddAckFrame(1, largest_received, smallest_received)
579 .Build();
580 }
581
ConstructServerAckPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received,uint64_t least_unacked)582 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
583 uint64_t packet_number,
584 uint64_t largest_received,
585 uint64_t smallest_received,
586 uint64_t least_unacked) {
587 return server_maker_.Packet(packet_number)
588 .AddAckFrame(largest_received, smallest_received, least_unacked)
589 .Build();
590 }
591
ConstructInitialSettingsPacket()592 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
593 return client_maker_.MakeInitialSettingsPacket(1);
594 }
595
ConstructInitialSettingsPacket(int packet_number)596 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
597 int packet_number) {
598 return client_maker_.MakeInitialSettingsPacket(packet_number);
599 }
600
ConstructDataHeader(size_t body_len)601 std::string ConstructDataHeader(size_t body_len) {
602 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
603 body_len, quiche::SimpleBufferAllocator::Get());
604 return std::string(buffer.data(), buffer.size());
605 }
606
ExpectLoadTimingValid(const LoadTimingInfo & load_timing_info,bool session_reused)607 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
608 bool session_reused) {
609 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
610 EXPECT_TRUE(load_timing_info.socket_log_id != 0);
611 if (session_reused) {
612 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
613 } else {
614 ExpectConnectTimingHasTimes(
615 load_timing_info.connect_timing,
616 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
617 }
618 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
619 }
620
GetNthClientInitiatedBidirectionalStreamId(int n)621 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
622 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
623 version_.transport_version, n);
624 }
625
GetNthServerInitiatedUnidirectionalStreamId(int n)626 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
627 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
628 version_.transport_version, n);
629 }
630
631 quic::test::QuicFlagSaver saver_;
632
633 const quic::ParsedQuicVersion version_;
634
635 NetLogWithSource net_log_with_source_{
636 NetLogWithSource::Make(NetLog::Get(), NetLogSourceType::NONE)};
637 RecordingNetLogObserver net_log_observer_;
638 scoped_refptr<TestTaskRunner> runner_;
639 std::unique_ptr<MockWrite[]> mock_writes_;
640 quic::MockClock clock_;
641 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
642 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
643 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
644 std::unique_ptr<UploadDataStream> upload_data_stream_;
645 std::unique_ptr<QuicHttpStream> stream_;
646 TransportSecurityState transport_security_state_;
647 SSLConfigServiceDefaults ssl_config_service_;
648
649 // Must outlive `send_algorithm_` and `connection_`.
650 std::unique_ptr<QuicChromiumClientSession> session_;
651 raw_ptr<quic::test::MockSendAlgorithm> send_algorithm_;
652 raw_ptr<TestQuicConnection> connection_;
653
654 quic::QuicCryptoClientConfig crypto_config_;
655 TestCompletionCallback callback_;
656 HttpRequestInfo request_;
657 HttpRequestHeaders headers_;
658 HttpResponseInfo response_;
659 scoped_refptr<IOBufferWithSize> read_buffer_;
660 quiche::HttpHeaderBlock request_headers_;
661 quiche::HttpHeaderBlock response_headers_;
662 string request_data_;
663 string response_data_;
664
665 const quic::QuicStreamId stream_id_;
666
667 const quic::QuicConnectionId connection_id_;
668 QuicTestPacketMaker client_maker_;
669 QuicTestPacketMaker server_maker_;
670 IPEndPoint self_addr_;
671 IPEndPoint peer_addr_;
672 quic::test::MockRandom random_generator_{0};
673 ProofVerifyDetailsChromium verify_details_;
674 MockCryptoClientStreamFactory crypto_client_stream_factory_;
675 std::unique_ptr<StaticSocketDataProvider> socket_data_;
676 QuicPacketPrinter printer_;
677 std::vector<PacketToWrite> writes_;
678 quic::test::MockConnectionIdGenerator connection_id_generator_;
679 quic::test::NoopQpackStreamSenderDelegate noop_qpack_stream_sender_delegate_;
680 };
681
682 INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
683 QuicHttpStreamTest,
684 ::testing::ValuesIn(GetTestParams()),
685 ::testing::PrintToStringParamName());
686
TEST_P(QuicHttpStreamTest,RenewStreamForAuth)687 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
688 Initialize();
689 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
690 }
691
TEST_P(QuicHttpStreamTest,CanReuseConnection)692 TEST_P(QuicHttpStreamTest, CanReuseConnection) {
693 Initialize();
694 EXPECT_FALSE(stream_->CanReuseConnection());
695 }
696
TEST_P(QuicHttpStreamTest,DisableConnectionMigrationForStream)697 TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
698 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
699 Initialize();
700 stream_->RegisterRequest(&request_);
701 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
702 net_log_with_source_,
703 callback_.callback()));
704 QuicChromiumClientStream::Handle* client_stream =
705 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
706 EXPECT_FALSE(client_stream->can_migrate_to_cellular_network());
707 }
708
TEST_P(QuicHttpStreamTest,GetRequest)709 TEST_P(QuicHttpStreamTest, GetRequest) {
710 SetRequest("GET", "/", DEFAULT_PRIORITY);
711 size_t spdy_request_header_frame_length;
712 int packet_number = 1;
713 AddWrite(ConstructInitialSettingsPacket(packet_number++));
714 AddWrite(InnerConstructRequestHeadersPacket(
715 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
716 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
717
718 Initialize();
719
720 request_.method = "GET";
721 request_.url = GURL("https://www.example.org/");
722
723 // Make sure getting load timing from the stream early does not crash.
724 LoadTimingInfo load_timing_info;
725 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
726 stream_->RegisterRequest(&request_);
727 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
728 net_log_with_source_,
729 callback_.callback()));
730 EXPECT_EQ(OK,
731 stream_->SendRequest(headers_, &response_, callback_.callback()));
732
733 // Ack the request.
734 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
735
736 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
737 IsError(ERR_IO_PENDING));
738
739 SetResponse("404", string());
740 size_t spdy_response_header_frame_length;
741 ProcessPacket(ConstructResponseHeadersPacket(
742 2, kFin, &spdy_response_header_frame_length));
743
744 // Now that the headers have been processed, the callback will return.
745 EXPECT_THAT(callback_.WaitForResult(), IsOk());
746 ASSERT_TRUE(response_.headers.get());
747 EXPECT_EQ(404, response_.headers->response_code());
748 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
749 EXPECT_FALSE(response_.response_time.is_null());
750 EXPECT_FALSE(response_.request_time.is_null());
751
752 // There is no body, so this should return immediately.
753 EXPECT_EQ(0,
754 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
755 callback_.callback()));
756 EXPECT_TRUE(stream_->IsResponseBodyComplete());
757 EXPECT_TRUE(AtEof());
758
759 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
760 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
761
762 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
763 // headers and payload.
764 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
765 stream_->GetTotalSentBytes());
766 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
767 stream_->GetTotalReceivedBytes());
768 }
769
TEST_P(QuicHttpStreamTest,LoadTimingTwoRequests)770 TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
771 SetRequest("GET", "/", DEFAULT_PRIORITY);
772 size_t spdy_request_header_frame_length;
773
774 int packet_number = 1;
775 AddWrite(ConstructInitialSettingsPacket(packet_number++));
776 AddWrite(InnerConstructRequestHeadersPacket(
777 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
778 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
779
780 // SetRequest() again for second request as |request_headers_| was moved.
781 SetRequest("GET", "/", DEFAULT_PRIORITY);
782 AddWrite(InnerConstructRequestHeadersPacket(
783 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), kFin,
784 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
785 AddWrite(
786 ConstructClientAckPacket(packet_number++, 3, 1)); // Ack the responses.
787
788 Initialize();
789
790 request_.method = "GET";
791 request_.url = GURL("https://www.example.org/");
792 // Start first request.
793 stream_->RegisterRequest(&request_);
794 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
795 net_log_with_source_,
796 callback_.callback()));
797 EXPECT_EQ(OK,
798 stream_->SendRequest(headers_, &response_, callback_.callback()));
799
800 // Start a second request.
801 QuicHttpStream stream2(session_->CreateHandle(url::SchemeHostPort(
802 url::kHttpsScheme, "www.example.org", 443)),
803 {} /* dns_aliases */);
804 TestCompletionCallback callback2;
805 stream2.RegisterRequest(&request_);
806 EXPECT_EQ(
807 OK, stream2.InitializeStream(true, DEFAULT_PRIORITY, net_log_with_source_,
808 callback2.callback()));
809 EXPECT_EQ(OK,
810 stream2.SendRequest(headers_, &response_, callback2.callback()));
811
812 // Ack both requests.
813 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
814
815 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
816 IsError(ERR_IO_PENDING));
817 size_t spdy_response_header_frame_length;
818 SetResponse("200", string());
819 ProcessPacket(InnerConstructResponseHeadersPacket(
820 2, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
821 &spdy_response_header_frame_length));
822
823 // Now that the headers have been processed, the callback will return.
824 EXPECT_THAT(callback_.WaitForResult(), IsOk());
825 EXPECT_EQ(200, response_.headers->response_code());
826
827 // There is no body, so this should return immediately.
828 EXPECT_EQ(0,
829 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
830 callback_.callback()));
831 EXPECT_TRUE(stream_->IsResponseBodyComplete());
832
833 LoadTimingInfo load_timing_info;
834 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
835 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
836
837 // SetResponse() again for second request as |response_headers_| was moved.
838 SetResponse("200", string());
839 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
840 IsError(ERR_IO_PENDING));
841
842 ProcessPacket(InnerConstructResponseHeadersPacket(
843 3, GetNthClientInitiatedBidirectionalStreamId(1), kFin,
844 &spdy_response_header_frame_length));
845
846 EXPECT_THAT(callback2.WaitForResult(), IsOk());
847
848 // There is no body, so this should return immediately.
849 EXPECT_EQ(0,
850 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
851 callback2.callback()));
852 EXPECT_TRUE(stream2.IsResponseBodyComplete());
853
854 LoadTimingInfo load_timing_info2;
855 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
856 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
857 }
858
859 // QuicHttpStream does not currently support trailers. It should ignore
860 // trailers upon receiving them.
TEST_P(QuicHttpStreamTest,GetRequestWithTrailers)861 TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
862 SetRequest("GET", "/", DEFAULT_PRIORITY);
863 size_t spdy_request_header_frame_length;
864 int packet_number = 1;
865 AddWrite(ConstructInitialSettingsPacket(packet_number++));
866 AddWrite(InnerConstructRequestHeadersPacket(
867 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
868 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
869 AddWrite(
870 ConstructClientAckPacket(packet_number++, 3, 1)); // Ack the data packet.
871
872 Initialize();
873
874 request_.method = "GET";
875 request_.url = GURL("https://www.example.org/");
876 stream_->RegisterRequest(&request_);
877 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
878 net_log_with_source_,
879 callback_.callback()));
880
881 EXPECT_EQ(OK,
882 stream_->SendRequest(headers_, &response_, callback_.callback()));
883 // Ack the request.
884 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
885
886 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
887 IsError(ERR_IO_PENDING));
888
889 SetResponse("200", string());
890
891 // Send the response headers.
892 size_t spdy_response_header_frame_length;
893 ProcessPacket(ConstructResponseHeadersPacket(
894 2, !kFin, &spdy_response_header_frame_length));
895 // Now that the headers have been processed, the callback will return.
896 EXPECT_THAT(callback_.WaitForResult(), IsOk());
897 ASSERT_TRUE(response_.headers.get());
898 EXPECT_EQ(200, response_.headers->response_code());
899 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
900 EXPECT_FALSE(response_.response_time.is_null());
901 EXPECT_FALSE(response_.request_time.is_null());
902
903 // Send the response body.
904 const char kResponseBody[] = "Hello world!";
905 std::string header = ConstructDataHeader(strlen(kResponseBody));
906 ProcessPacket(ConstructServerDataPacket(3, !kFin, header + kResponseBody));
907 quiche::HttpHeaderBlock trailers;
908 size_t spdy_trailers_frame_length;
909 trailers["foo"] = "bar";
910 ProcessPacket(ConstructResponseTrailersPacket(4, kFin, std::move(trailers),
911 &spdy_trailers_frame_length));
912
913 // Make sure trailers are processed.
914 base::RunLoop().RunUntilIdle();
915
916 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
917 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
918 callback_.callback()));
919 EXPECT_TRUE(stream_->IsResponseBodyComplete());
920
921 EXPECT_EQ(OK,
922 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
923 callback_.callback()));
924
925 EXPECT_TRUE(stream_->IsResponseBodyComplete());
926 EXPECT_TRUE(AtEof());
927
928 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
929 // headers and payload.
930 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
931 stream_->GetTotalSentBytes());
932 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length +
933 strlen(kResponseBody) + header.length() +
934 +spdy_trailers_frame_length),
935 stream_->GetTotalReceivedBytes());
936 // Check that NetLog was filled as expected.
937 auto entries = net_log_observer_.GetEntries();
938 size_t pos = ExpectLogContainsSomewhere(
939 entries, /*min_offset=*/0,
940 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
941 NetLogEventPhase::NONE);
942 pos = ExpectLogContainsSomewhere(
943 entries, /*min_offset=*/pos,
944 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
945 NetLogEventPhase::NONE);
946 ExpectLogContainsSomewhere(
947 entries, /*min_offset=*/pos,
948 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
949 NetLogEventPhase::NONE);
950 }
951
TEST_P(QuicHttpStreamTest,ElideHeadersInNetLog)952 TEST_P(QuicHttpStreamTest, ElideHeadersInNetLog) {
953 Initialize();
954
955 net_log_observer_.SetObserverCaptureMode(NetLogCaptureMode::kDefault);
956
957 // Send first request.
958 SetRequest("GET", "/", DEFAULT_PRIORITY);
959 request_.method = "GET";
960 request_.url = GURL("https://www.example.org/");
961 headers_.SetHeader(HttpRequestHeaders::kCookie, "secret");
962
963 size_t spdy_request_header_frame_length;
964 int outgoing_packet_number = 1;
965 AddWrite(ConstructInitialSettingsPacket(outgoing_packet_number++));
966 AddWrite(InnerConstructRequestHeadersPacket(
967 outgoing_packet_number++, stream_id_, kFin, DEFAULT_PRIORITY,
968 &spdy_request_header_frame_length));
969
970 stream_->RegisterRequest(&request_);
971 EXPECT_THAT(
972 stream_->InitializeStream(true, DEFAULT_PRIORITY, net_log_with_source_,
973 callback_.callback()),
974 IsOk());
975 EXPECT_THAT(stream_->SendRequest(headers_, &response_, callback_.callback()),
976 IsOk());
977 int incoming_packet_number = 1;
978 ProcessPacket(ConstructServerAckPacket(incoming_packet_number++, 1, 1,
979 1)); // Ack the request.
980
981 // Process first response.
982 SetResponse("200", string());
983 response_headers_["set-cookie"] = "secret";
984 size_t spdy_response_header_frame_length;
985 ProcessPacket(ConstructResponseHeadersPacket(
986 incoming_packet_number++, kFin, &spdy_response_header_frame_length));
987 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
988
989 ASSERT_TRUE(response_.headers.get());
990 EXPECT_EQ(200, response_.headers->response_code());
991 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
992 EXPECT_TRUE(response_.headers->HasHeaderValue("set-cookie", "secret"));
993
994 net_log_observer_.SetObserverCaptureMode(
995 NetLogCaptureMode::kIncludeSensitive);
996
997 // Send second request.
998 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(1);
999 request_.url = GURL("https://www.example.org/foo");
1000
1001 AddWrite(InnerConstructRequestHeadersPacket(
1002 outgoing_packet_number++, stream_id, kFin, DEFAULT_PRIORITY,
1003 &spdy_request_header_frame_length));
1004
1005 auto stream = std::make_unique<QuicHttpStream>(
1006 session_->CreateHandle(
1007 url::SchemeHostPort(url::kHttpsScheme, "www.example.org/foo", 443)),
1008 /*dns_aliases=*/std::set<std::string>());
1009 stream->RegisterRequest(&request_);
1010 EXPECT_THAT(
1011 stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_with_source_,
1012 callback_.callback()),
1013 IsOk());
1014 EXPECT_THAT(stream->SendRequest(headers_, &response_, callback_.callback()),
1015 IsOk());
1016 ProcessPacket(ConstructServerAckPacket(incoming_packet_number++, 1, 1,
1017 1)); // Ack the request.
1018
1019 // Process second response.
1020 SetResponse("200", string());
1021 response_headers_["set-cookie"] = "secret";
1022 ProcessPacket(InnerConstructResponseHeadersPacket(
1023 incoming_packet_number++, stream_id, kFin,
1024 &spdy_response_header_frame_length));
1025 EXPECT_THAT(stream->ReadResponseHeaders(callback_.callback()), IsOk());
1026
1027 ASSERT_TRUE(response_.headers.get());
1028 EXPECT_EQ(200, response_.headers->response_code());
1029 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1030 EXPECT_TRUE(response_.headers->HasHeaderValue("set-cookie", "secret"));
1031
1032 EXPECT_TRUE(AtEof());
1033
1034 // Check that sensitive header value were stripped
1035 // for the first transaction (logged with NetLogCaptureMode::kDefault)
1036 // but not for the second (logged with NetLogCaptureMode::kIncludeSensitive).
1037 auto entries =
1038 net_log_observer_.GetEntriesWithType(NetLogEventType::HTTP3_HEADERS_SENT);
1039 ASSERT_EQ(2u, entries.size());
1040 EXPECT_TRUE(
1041 CheckHeader(entries[0].params, "cookie", "[6 bytes were stripped]"));
1042 EXPECT_TRUE(CheckHeader(entries[1].params, "cookie", "secret"));
1043
1044 entries = net_log_observer_.GetEntriesWithType(
1045 NetLogEventType::HTTP3_HEADERS_DECODED);
1046 ASSERT_EQ(2u, entries.size());
1047 EXPECT_TRUE(
1048 CheckHeader(entries[0].params, "set-cookie", "[6 bytes were stripped]"));
1049 EXPECT_TRUE(CheckHeader(entries[1].params, "set-cookie", "secret"));
1050 }
1051
1052 // Regression test for http://crbug.com/288128
TEST_P(QuicHttpStreamTest,GetRequestLargeResponse)1053 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
1054 SetRequest("GET", "/", DEFAULT_PRIORITY);
1055 size_t spdy_request_headers_frame_length;
1056 int packet_number = 1;
1057 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1058 AddWrite(InnerConstructRequestHeadersPacket(
1059 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1060 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1061 Initialize();
1062
1063 request_.method = "GET";
1064 request_.url = GURL("https://www.example.org/");
1065
1066 stream_->RegisterRequest(&request_);
1067 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1068 net_log_with_source_,
1069 callback_.callback()));
1070 EXPECT_EQ(OK,
1071 stream_->SendRequest(headers_, &response_, callback_.callback()));
1072
1073 // Ack the request.
1074 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1075
1076 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1077 IsError(ERR_IO_PENDING));
1078
1079 response_headers_[":status"] = "200";
1080 response_headers_[":version"] = "HTTP/1.1";
1081 response_headers_["content-type"] = "text/plain";
1082 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
1083
1084 size_t spdy_response_headers_frame_length;
1085 ProcessPacket(ConstructResponseHeadersPacket(
1086 2, kFin, &spdy_response_headers_frame_length));
1087
1088 // Now that the headers have been processed, the callback will return.
1089 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1090 ASSERT_TRUE(response_.headers.get());
1091 EXPECT_EQ(200, response_.headers->response_code());
1092 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1093
1094 // There is no body, so this should return immediately.
1095 EXPECT_EQ(0,
1096 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1097 callback_.callback()));
1098 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1099 EXPECT_TRUE(AtEof());
1100
1101 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1102 // headers and payload.
1103 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1104 stream_->GetTotalSentBytes());
1105 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
1106 stream_->GetTotalReceivedBytes());
1107 }
1108
1109 // Regression test for http://crbug.com/409101
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendRequest)1110 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
1111 SetRequest("GET", "/", DEFAULT_PRIORITY);
1112 Initialize();
1113
1114 request_.method = "GET";
1115 request_.url = GURL("https://www.example.org/");
1116
1117 stream_->RegisterRequest(&request_);
1118 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1119 net_log_with_source_,
1120 callback_.callback()));
1121
1122 session_->connection()->CloseConnection(
1123 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
1124
1125 EXPECT_EQ(ERR_CONNECTION_CLOSED,
1126 stream_->SendRequest(headers_, &response_, callback_.callback()));
1127
1128 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1129 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1130 }
1131
1132 // Regression test for http://crbug.com/584441
TEST_P(QuicHttpStreamTest,GetSSLInfoAfterSessionClosed)1133 TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
1134 SetRequest("GET", "/", DEFAULT_PRIORITY);
1135 Initialize();
1136
1137 request_.method = "GET";
1138 request_.url = GURL("https://www.example.org/");
1139
1140 stream_->RegisterRequest(&request_);
1141 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1142 net_log_with_source_,
1143 callback_.callback()));
1144
1145 SSLInfo ssl_info;
1146 EXPECT_FALSE(ssl_info.is_valid());
1147 stream_->GetSSLInfo(&ssl_info);
1148 EXPECT_TRUE(ssl_info.is_valid());
1149
1150 session_->connection()->CloseConnection(
1151 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
1152
1153 SSLInfo ssl_info2;
1154 stream_->GetSSLInfo(&ssl_info2);
1155 EXPECT_TRUE(ssl_info2.is_valid());
1156 }
1157
TEST_P(QuicHttpStreamTest,GetAlternativeService)1158 TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1159 SetRequest("GET", "/", DEFAULT_PRIORITY);
1160 Initialize();
1161
1162 request_.method = "GET";
1163 request_.url = GURL("https://www.example.org/");
1164
1165 stream_->RegisterRequest(&request_);
1166 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1167 net_log_with_source_,
1168 callback_.callback()));
1169
1170 AlternativeService alternative_service;
1171 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1172 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1173 alternative_service);
1174
1175 session_->connection()->CloseConnection(
1176 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
1177
1178 AlternativeService alternative_service2;
1179 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1180 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1181 alternative_service2);
1182 }
1183
TEST_P(QuicHttpStreamTest,LogGranularQuicConnectionError)1184 TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1185 SetRequest("GET", "/", DEFAULT_PRIORITY);
1186 size_t spdy_request_headers_frame_length;
1187 int packet_number = 1;
1188 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1189 AddWrite(InnerConstructRequestHeadersPacket(
1190 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1191 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1192 AddWrite(ConstructAckAndRstStreamPacket(3));
1193 Initialize();
1194
1195 request_.method = "GET";
1196 request_.url = GURL("https://www.example.org/");
1197
1198 stream_->RegisterRequest(&request_);
1199 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1200 net_log_with_source_,
1201 callback_.callback()));
1202 EXPECT_EQ(OK,
1203 stream_->SendRequest(headers_, &response_, callback_.callback()));
1204
1205 // Ack the request.
1206 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1207 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1208 IsError(ERR_IO_PENDING));
1209
1210 quic::QuicConnectionCloseFrame frame;
1211 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
1212 session_->connection()->OnConnectionCloseFrame(frame);
1213
1214 NetErrorDetails details;
1215 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
1216 stream_->PopulateNetErrorDetails(&details);
1217 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
1218 }
1219
TEST_P(QuicHttpStreamTest,LogGranularQuicErrorIfHandshakeNotConfirmed)1220 TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
1221 // By default the test setup defaults handshake to be confirmed. Manually set
1222 // it to be not confirmed.
1223 crypto_client_stream_factory_.set_handshake_mode(
1224 MockCryptoClientStream::ZERO_RTT);
1225
1226 SetRequest("GET", "/", DEFAULT_PRIORITY);
1227 size_t spdy_request_headers_frame_length;
1228 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
1229 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
1230 int packet_number = 1;
1231 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1232 AddWrite(InnerConstructRequestHeadersPacket(
1233 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1234 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1235 Initialize();
1236
1237 request_.method = "GET";
1238 request_.url = GURL("https://www.example.org/");
1239
1240 stream_->RegisterRequest(&request_);
1241 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1242 net_log_with_source_,
1243 callback_.callback()));
1244 EXPECT_EQ(OK,
1245 stream_->SendRequest(headers_, &response_, callback_.callback()));
1246
1247 // Ack the request.
1248 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1249 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1250 IsError(ERR_IO_PENDING));
1251
1252 quic::QuicConnectionCloseFrame frame;
1253 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
1254 session_->connection()->OnConnectionCloseFrame(frame);
1255
1256 NetErrorDetails details;
1257 stream_->PopulateNetErrorDetails(&details);
1258 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
1259 }
1260
1261 // Regression test for http://crbug.com/409871
TEST_P(QuicHttpStreamTest,SessionClosedBeforeReadResponseHeaders)1262 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1263 SetRequest("GET", "/", DEFAULT_PRIORITY);
1264 size_t spdy_request_headers_frame_length;
1265 int packet_number = 1;
1266 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1267 AddWrite(InnerConstructRequestHeadersPacket(
1268 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1269 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1270 Initialize();
1271
1272 request_.method = "GET";
1273 request_.url = GURL("https://www.example.org/");
1274
1275 stream_->RegisterRequest(&request_);
1276 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1277 net_log_with_source_,
1278 callback_.callback()));
1279
1280 EXPECT_EQ(OK,
1281 stream_->SendRequest(headers_, &response_, callback_.callback()));
1282
1283 session_->connection()->CloseConnection(
1284 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
1285
1286 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
1287
1288 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1289 // headers and payload.
1290 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1291 stream_->GetTotalSentBytes());
1292 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1293 }
1294
TEST_P(QuicHttpStreamTest,SendPostRequest)1295 TEST_P(QuicHttpStreamTest, SendPostRequest) {
1296 SetRequest("POST", "/", DEFAULT_PRIORITY);
1297 size_t spdy_request_headers_frame_length;
1298 int packet_number = 1;
1299 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1300
1301 std::string header = ConstructDataHeader(strlen(kUploadData));
1302 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1303 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1304 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1305 {header, kUploadData}));
1306
1307 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1308
1309 Initialize();
1310
1311 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
1312 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
1313 base::byte_span_from_cstring(kUploadData)));
1314 upload_data_stream_ =
1315 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
1316 request_.method = "POST";
1317 request_.url = GURL("https://www.example.org/");
1318 request_.upload_data_stream = upload_data_stream_.get();
1319 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
1320 NetLogWithSource()),
1321 IsOk());
1322
1323 stream_->RegisterRequest(&request_);
1324 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1325 net_log_with_source_,
1326 callback_.callback()));
1327 EXPECT_EQ(OK,
1328 stream_->SendRequest(headers_, &response_, callback_.callback()));
1329
1330 // Ack both packets in the request.
1331 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1332
1333 // Send the response headers (but not the body).
1334 SetResponse("200", string());
1335 size_t spdy_response_headers_frame_length;
1336 ProcessPacket(ConstructResponseHeadersPacket(
1337 2, !kFin, &spdy_response_headers_frame_length));
1338
1339 // The headers have already arrived.
1340 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1341 ASSERT_TRUE(response_.headers.get());
1342 EXPECT_EQ(200, response_.headers->response_code());
1343 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1344
1345 // Send the response body.
1346 const char kResponseBody[] = "Hello world!";
1347 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1348 ProcessPacket(ConstructServerDataPacket(3, kFin, header2 + kResponseBody));
1349 // Since the body has already arrived, this should return immediately.
1350 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1351 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1352 callback_.callback()));
1353 EXPECT_EQ(0,
1354 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1355 callback_.callback()));
1356
1357 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1358 EXPECT_TRUE(AtEof());
1359
1360 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1361 // headers and payload.
1362 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1363 strlen(kUploadData) + header.length()),
1364 stream_->GetTotalSentBytes());
1365 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1366 strlen(kResponseBody) + header2.length()),
1367 stream_->GetTotalReceivedBytes());
1368 }
1369
TEST_P(QuicHttpStreamTest,SendPostRequestAndReceiveSoloFin)1370 TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1371 SetRequest("POST", "/", DEFAULT_PRIORITY);
1372 size_t spdy_request_headers_frame_length;
1373 int packet_number = 1;
1374 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1375 std::string header = ConstructDataHeader(strlen(kUploadData));
1376 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1377 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1378 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1379 {header, kUploadData}));
1380
1381 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1382
1383 Initialize();
1384
1385 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
1386 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
1387 base::byte_span_from_cstring(kUploadData)));
1388 upload_data_stream_ =
1389 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
1390 request_.method = "POST";
1391 request_.url = GURL("https://www.example.org/");
1392 request_.upload_data_stream = upload_data_stream_.get();
1393 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
1394 NetLogWithSource()),
1395 IsOk());
1396
1397 stream_->RegisterRequest(&request_);
1398 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1399 net_log_with_source_,
1400 callback_.callback()));
1401 EXPECT_EQ(OK,
1402 stream_->SendRequest(headers_, &response_, callback_.callback()));
1403
1404 // Ack both packets in the request.
1405 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1406
1407 // Send the response headers (but not the body).
1408 SetResponse("200", string());
1409 size_t spdy_response_headers_frame_length;
1410 ProcessPacket(ConstructResponseHeadersPacket(
1411 2, !kFin, &spdy_response_headers_frame_length));
1412
1413 // The headers have already arrived.
1414 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1415 ASSERT_TRUE(response_.headers.get());
1416 EXPECT_EQ(200, response_.headers->response_code());
1417 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1418
1419 // Send the response body.
1420 const char kResponseBody[] = "Hello world!";
1421 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1422 ProcessPacket(ConstructServerDataPacket(3, !kFin, header2 + kResponseBody));
1423 // Since the body has already arrived, this should return immediately.
1424 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1425 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1426 callback_.callback()));
1427 ProcessPacket(ConstructServerDataPacket(4, kFin, ""));
1428 EXPECT_EQ(0,
1429 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1430 callback_.callback()));
1431
1432 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1433 EXPECT_TRUE(AtEof());
1434
1435 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1436 // headers and payload.
1437 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1438 strlen(kUploadData) + header.length()),
1439 stream_->GetTotalSentBytes());
1440 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1441 strlen(kResponseBody) + header2.length()),
1442 stream_->GetTotalReceivedBytes());
1443 }
1444
TEST_P(QuicHttpStreamTest,SendChunkedPostRequest)1445 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1446 SetRequest("POST", "/", DEFAULT_PRIORITY);
1447 size_t chunk_size = strlen(kUploadData);
1448 size_t spdy_request_headers_frame_length;
1449 int packet_number = 1;
1450 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1451 std::string header = ConstructDataHeader(chunk_size);
1452 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1453 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1454 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1455 {header, kUploadData}));
1456 AddWrite(
1457 ConstructClientDataPacket(packet_number++, kFin, {header + kUploadData}));
1458
1459 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1460 Initialize();
1461
1462 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1463 auto* chunked_upload_stream =
1464 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1465 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1466 false);
1467
1468 request_.method = "POST";
1469 request_.url = GURL("https://www.example.org/");
1470 request_.upload_data_stream = upload_data_stream_.get();
1471 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1472 TestCompletionCallback().callback(), NetLogWithSource()));
1473
1474 stream_->RegisterRequest(&request_);
1475 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1476 net_log_with_source_,
1477 callback_.callback()));
1478 ASSERT_EQ(ERR_IO_PENDING,
1479 stream_->SendRequest(headers_, &response_, callback_.callback()));
1480
1481 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1482 true);
1483 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1484
1485 // Ack both packets in the request.
1486 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1487
1488 // Send the response headers (but not the body).
1489 SetResponse("200", string());
1490 size_t spdy_response_headers_frame_length;
1491 ProcessPacket(ConstructResponseHeadersPacket(
1492 2, !kFin, &spdy_response_headers_frame_length));
1493
1494 // The headers have already arrived.
1495 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1496 ASSERT_TRUE(response_.headers.get());
1497 EXPECT_EQ(200, response_.headers->response_code());
1498 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1499
1500 // Send the response body.
1501 const char kResponseBody[] = "Hello world!";
1502 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1503 ProcessPacket(ConstructServerDataPacket(3, kFin, header2 + kResponseBody));
1504
1505 // Since the body has already arrived, this should return immediately.
1506 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1507 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1508 callback_.callback()));
1509
1510 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1511 EXPECT_TRUE(AtEof());
1512
1513 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1514 // headers and payload.
1515 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1516 strlen(kUploadData) * 2 + header.length() * 2),
1517 stream_->GetTotalSentBytes());
1518 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1519 strlen(kResponseBody) + header2.length()),
1520 stream_->GetTotalReceivedBytes());
1521 }
1522
TEST_P(QuicHttpStreamTest,SendChunkedPostRequestWithFinalEmptyDataPacket)1523 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1524 SetRequest("POST", "/", DEFAULT_PRIORITY);
1525 size_t chunk_size = strlen(kUploadData);
1526 size_t spdy_request_headers_frame_length;
1527 int packet_number = 1;
1528 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1529 std::string header = ConstructDataHeader(chunk_size);
1530
1531 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1532 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1533 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1534 {header, kUploadData}));
1535 AddWrite(ConstructClientDataPacket(packet_number++, kFin, ""));
1536 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1537 Initialize();
1538
1539 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1540 auto* chunked_upload_stream =
1541 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1542 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1543 false);
1544
1545 request_.method = "POST";
1546 request_.url = GURL("https://www.example.org/");
1547 request_.upload_data_stream = upload_data_stream_.get();
1548 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1549 TestCompletionCallback().callback(), NetLogWithSource()));
1550
1551 stream_->RegisterRequest(&request_);
1552 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1553 net_log_with_source_,
1554 callback_.callback()));
1555 ASSERT_EQ(ERR_IO_PENDING,
1556 stream_->SendRequest(headers_, &response_, callback_.callback()));
1557
1558 chunked_upload_stream->AppendData(base::byte_span_from_cstring(""), true);
1559 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1560
1561 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1562
1563 // Send the response headers (but not the body).
1564 SetResponse("200", string());
1565 size_t spdy_response_headers_frame_length;
1566 ProcessPacket(ConstructResponseHeadersPacket(
1567 2, !kFin, &spdy_response_headers_frame_length));
1568
1569 // The headers have already arrived.
1570 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1571 ASSERT_TRUE(response_.headers.get());
1572 EXPECT_EQ(200, response_.headers->response_code());
1573 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1574
1575 // Send the response body.
1576 const char kResponseBody[] = "Hello world!";
1577 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1578 ProcessPacket(ConstructServerDataPacket(3, kFin, header2 + kResponseBody));
1579
1580 // The body has arrived, but it is delivered asynchronously
1581 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1582 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1583 callback_.callback()));
1584 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1585 EXPECT_TRUE(AtEof());
1586
1587 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1588 // headers and payload.
1589 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1590 strlen(kUploadData) + header.length()),
1591 stream_->GetTotalSentBytes());
1592 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1593 strlen(kResponseBody) + header2.length()),
1594 stream_->GetTotalReceivedBytes());
1595 }
1596
TEST_P(QuicHttpStreamTest,SendChunkedPostRequestWithOneEmptyDataPacket)1597 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1598 SetRequest("POST", "/", DEFAULT_PRIORITY);
1599 size_t spdy_request_headers_frame_length;
1600 int packet_number = 1;
1601 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1602 AddWrite(InnerConstructRequestHeadersPacket(
1603 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1604 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1605 AddWrite(ConstructClientDataPacket(packet_number++, kFin, ""));
1606 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1607 Initialize();
1608
1609 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1610 auto* chunked_upload_stream =
1611 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1612
1613 request_.method = "POST";
1614 request_.url = GURL("https://www.example.org/");
1615 request_.upload_data_stream = upload_data_stream_.get();
1616 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1617 TestCompletionCallback().callback(), NetLogWithSource()));
1618
1619 stream_->RegisterRequest(&request_);
1620 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1621 net_log_with_source_,
1622 callback_.callback()));
1623 ASSERT_EQ(ERR_IO_PENDING,
1624 stream_->SendRequest(headers_, &response_, callback_.callback()));
1625
1626 chunked_upload_stream->AppendData(base::byte_span_from_cstring(""), true);
1627 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1628
1629 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1630
1631 // Send the response headers (but not the body).
1632 SetResponse("200", string());
1633 size_t spdy_response_headers_frame_length;
1634 ProcessPacket(ConstructResponseHeadersPacket(
1635 2, !kFin, &spdy_response_headers_frame_length));
1636
1637 // The headers have already arrived.
1638 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1639 ASSERT_TRUE(response_.headers.get());
1640 EXPECT_EQ(200, response_.headers->response_code());
1641 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1642
1643 // Send the response body.
1644 const char kResponseBody[] = "Hello world!";
1645 std::string header = ConstructDataHeader(strlen(kResponseBody));
1646 ProcessPacket(ConstructServerDataPacket(3, kFin, header + kResponseBody));
1647
1648 // The body has arrived, but it is delivered asynchronously
1649 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1650 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1651 callback_.callback()));
1652
1653 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1654 EXPECT_TRUE(AtEof());
1655
1656 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1657 // headers and payload.
1658 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1659 stream_->GetTotalSentBytes());
1660 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1661 strlen(kResponseBody) + header.length()),
1662 stream_->GetTotalReceivedBytes());
1663 }
1664
TEST_P(QuicHttpStreamTest,SendChunkedPostRequestAbortedByResetStream)1665 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestAbortedByResetStream) {
1666 SetRequest("POST", "/", DEFAULT_PRIORITY);
1667 size_t chunk_size = strlen(kUploadData);
1668 size_t spdy_request_headers_frame_length;
1669 int packet_number = 1;
1670
1671 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1672
1673 std::string header = ConstructDataHeader(chunk_size);
1674 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1675 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1676 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1677 {header, kUploadData}));
1678 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1679 AddWrite(client_maker_.Packet(packet_number++)
1680 .AddAckFrame(/*first_received=*/1, /*largest_received=*/4,
1681 /*smallest_received=*/1)
1682 .AddRstStreamFrame(stream_id_, quic::QUIC_STREAM_NO_ERROR)
1683 .Build());
1684
1685 Initialize();
1686
1687 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1688 auto* chunked_upload_stream =
1689 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1690 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1691 false);
1692
1693 request_.method = "POST";
1694 request_.url = GURL("https://www.example.org/");
1695 request_.upload_data_stream = upload_data_stream_.get();
1696 ASSERT_THAT(request_.upload_data_stream->Init(
1697 TestCompletionCallback().callback(), NetLogWithSource()),
1698 IsOk());
1699 stream_->RegisterRequest(&request_);
1700 ASSERT_THAT(
1701 stream_->InitializeStream(false, DEFAULT_PRIORITY, net_log_with_source_,
1702 callback_.callback()),
1703 IsOk());
1704 ASSERT_THAT(stream_->SendRequest(headers_, &response_, callback_.callback()),
1705 IsError(ERR_IO_PENDING));
1706
1707 // Ack both packets in the request.
1708 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1709
1710 // Send the response headers (but not the body).
1711 SetResponse("200", string());
1712 size_t spdy_response_headers_frame_length;
1713 ProcessPacket(ConstructResponseHeadersPacket(
1714 2, !kFin, &spdy_response_headers_frame_length));
1715
1716 // Send the response body.
1717 const char kResponseBody[] = "Hello world!";
1718 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1719 ProcessPacket(ConstructServerDataPacket(3, kFin, header2 + kResponseBody));
1720
1721 // The server uses a STOP_SENDING frame to notify the client that it does not
1722 // need any further data to fully process the request.
1723 ProcessPacket(server_maker_.Packet(4)
1724 .AddStopSendingFrame(stream_id_, quic::QUIC_STREAM_NO_ERROR)
1725 .Build());
1726
1727 // Finish feeding request body to QuicHttpStream. Data will be discarded.
1728 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1729 true);
1730 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1731
1732 // Verify response.
1733 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1734 ASSERT_TRUE(response_.headers.get());
1735 EXPECT_EQ(200, response_.headers->response_code());
1736 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1737 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1738 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1739 callback_.callback()));
1740 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1741 EXPECT_TRUE(AtEof());
1742
1743 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1744 // headers and payload.
1745 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1746 strlen(kUploadData) + header.length()),
1747 stream_->GetTotalSentBytes());
1748 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1749 strlen(kResponseBody) + header2.length()),
1750 stream_->GetTotalReceivedBytes());
1751 }
1752
TEST_P(QuicHttpStreamTest,DestroyedEarly)1753 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1754 SetRequest("GET", "/", DEFAULT_PRIORITY);
1755 size_t spdy_request_headers_frame_length;
1756 int packet_number = 1;
1757 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1758 AddWrite(InnerConstructRequestHeadersPacket(
1759 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1760 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1761 AddWrite(ConstructAckAndRstStreamPacket(packet_number++));
1762 Initialize();
1763
1764 request_.method = "GET";
1765 request_.url = GURL("https://www.example.org/");
1766
1767 stream_->RegisterRequest(&request_);
1768 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1769 net_log_with_source_,
1770 callback_.callback()));
1771 EXPECT_EQ(OK,
1772 stream_->SendRequest(headers_, &response_, callback_.callback()));
1773
1774 // Ack the request.
1775 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1776 EXPECT_THAT(stream_->ReadResponseHeaders(
1777 base::BindOnce(&QuicHttpStreamTest::CloseStream,
1778 base::Unretained(this), stream_.get())),
1779 IsError(ERR_IO_PENDING));
1780
1781 // Send the response with a body.
1782 SetResponse("404", "hello world!");
1783 // In the course of processing this packet, the QuicHttpStream close itself.
1784 size_t response_size = 0;
1785 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
1786
1787 base::RunLoop().RunUntilIdle();
1788
1789 EXPECT_TRUE(AtEof());
1790
1791 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1792 // headers and payload.
1793 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1794 stream_->GetTotalSentBytes());
1795 // The stream was closed after receiving the headers.
1796 EXPECT_EQ(static_cast<int64_t>(response_size),
1797 stream_->GetTotalReceivedBytes());
1798 }
1799
TEST_P(QuicHttpStreamTest,Priority)1800 TEST_P(QuicHttpStreamTest, Priority) {
1801 SetRequest("GET", "/", MEDIUM);
1802 size_t spdy_request_headers_frame_length;
1803 int packet_number = 1;
1804 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1805 AddWrite(InnerConstructRequestHeadersPacket(
1806 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1807 MEDIUM, &spdy_request_headers_frame_length));
1808 Initialize();
1809
1810 request_.method = "GET";
1811 request_.url = GURL("https://www.example.org/");
1812
1813 stream_->RegisterRequest(&request_);
1814 EXPECT_EQ(OK, stream_->InitializeStream(true, MEDIUM, net_log_with_source_,
1815 callback_.callback()));
1816
1817 EXPECT_EQ(OK,
1818 stream_->SendRequest(headers_, &response_, callback_.callback()));
1819
1820 // Ack the request.
1821 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1822 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1823 IsError(ERR_IO_PENDING));
1824
1825 // Send the response with a body.
1826 SetResponse("404", "hello world!");
1827 size_t response_size = 0;
1828 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
1829
1830 EXPECT_EQ(OK, callback_.WaitForResult());
1831
1832 EXPECT_TRUE(AtEof());
1833
1834 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1835 // headers and payload.
1836 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1837 stream_->GetTotalSentBytes());
1838 EXPECT_EQ(static_cast<int64_t>(response_size),
1839 stream_->GetTotalReceivedBytes());
1840 }
1841
TEST_P(QuicHttpStreamTest,SessionClosedDuringDoLoop)1842 TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1843 SetRequest("POST", "/", DEFAULT_PRIORITY);
1844 size_t spdy_request_headers_frame_length;
1845 int packet_number = 1;
1846 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1847 std::string header = ConstructDataHeader(strlen(kUploadData));
1848 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1849 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1850 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1851 {header, kUploadData}));
1852
1853 // Second data write will result in a synchronous failure which will close
1854 // the session.
1855 AddWrite(SYNCHRONOUS, ERR_FAILED);
1856 Initialize();
1857
1858 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1859 auto* chunked_upload_stream =
1860 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1861
1862 request_.method = "POST";
1863 request_.url = GURL("https://www.example.org/");
1864 request_.upload_data_stream = upload_data_stream_.get();
1865 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1866 TestCompletionCallback().callback(), NetLogWithSource()));
1867
1868 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1869 false);
1870 stream_->RegisterRequest(&request_);
1871 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1872 net_log_with_source_,
1873 callback_.callback()));
1874 QuicHttpStream* stream = stream_.get();
1875 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1876 // SendRequest() completes asynchronously after the final chunk is added.
1877 // Error does not surface yet since packet write is triggered by a packet
1878 // flusher that tries to bundle request body writes.
1879 ASSERT_EQ(ERR_IO_PENDING,
1880 stream->SendRequest(headers_, &response_, callback_.callback()));
1881 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1882 true);
1883 int rv = callback_.WaitForResult();
1884 EXPECT_EQ(OK, rv);
1885 // Error will be surfaced once an attempt to read the response occurs.
1886 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1887 stream->ReadResponseHeaders(callback_.callback()));
1888 }
1889
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendHeadersComplete)1890 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1891 SetRequest("POST", "/", DEFAULT_PRIORITY);
1892 AddWrite(ConstructInitialSettingsPacket());
1893 AddWrite(SYNCHRONOUS, ERR_FAILED);
1894 Initialize();
1895
1896 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1897 auto* chunked_upload_stream =
1898 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1899
1900 request_.method = "POST";
1901 request_.url = GURL("https://www.example.org/");
1902 request_.upload_data_stream = upload_data_stream_.get();
1903 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1904 TestCompletionCallback().callback(), NetLogWithSource()));
1905
1906 stream_->RegisterRequest(&request_);
1907 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1908 net_log_with_source_,
1909 callback_.callback()));
1910 ASSERT_EQ(ERR_IO_PENDING,
1911 stream_->SendRequest(headers_, &response_, callback_.callback()));
1912
1913 // Error will be surfaced once |upload_data_stream| triggers the next write.
1914 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1915 true);
1916 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
1917
1918 EXPECT_LE(0, stream_->GetTotalSentBytes());
1919 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1920 }
1921
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendHeadersCompleteReadResponse)1922 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
1923 SetRequest("POST", "/", DEFAULT_PRIORITY);
1924 AddWrite(ConstructInitialSettingsPacket());
1925 AddWrite(SYNCHRONOUS, ERR_FAILED);
1926 Initialize();
1927
1928 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1929 auto* chunked_upload_stream =
1930 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1931
1932 request_.method = "POST";
1933 request_.url = GURL("https://www.example.org/");
1934 request_.upload_data_stream = upload_data_stream_.get();
1935
1936 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1937 true);
1938
1939 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1940 TestCompletionCallback().callback(), NetLogWithSource()));
1941
1942 stream_->RegisterRequest(&request_);
1943 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1944 net_log_with_source_,
1945 callback_.callback()));
1946 ASSERT_EQ(OK,
1947 stream_->SendRequest(headers_, &response_, callback_.callback()));
1948
1949 // Error will be surfaced once an attempt to read the response occurs.
1950 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1951 stream_->ReadResponseHeaders(callback_.callback()));
1952
1953 EXPECT_LE(0, stream_->GetTotalSentBytes());
1954 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1955 }
1956
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendBodyComplete)1957 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1958 SetRequest("POST", "/", DEFAULT_PRIORITY);
1959 size_t spdy_request_headers_frame_length;
1960 int packet_number = 1;
1961 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1962 AddWrite(InnerConstructRequestHeadersPacket(
1963 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1964 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1965 AddWrite(SYNCHRONOUS, ERR_FAILED);
1966 Initialize();
1967
1968 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1969 auto* chunked_upload_stream =
1970 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1971
1972 request_.method = "POST";
1973 request_.url = GURL("https://www.example.org/");
1974 request_.upload_data_stream = upload_data_stream_.get();
1975 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1976 TestCompletionCallback().callback(), NetLogWithSource()));
1977
1978 stream_->RegisterRequest(&request_);
1979 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1980 net_log_with_source_,
1981 callback_.callback()));
1982 ASSERT_EQ(ERR_IO_PENDING,
1983 stream_->SendRequest(headers_, &response_, callback_.callback()));
1984
1985 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
1986 true);
1987 // Error does not surface yet since packet write is triggered by a packet
1988 // flusher that tries to bundle request body writes.
1989 ASSERT_EQ(OK, callback_.WaitForResult());
1990 // Error will be surfaced once an attempt to read the response occurs.
1991 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1992 stream_->ReadResponseHeaders(callback_.callback()));
1993
1994 EXPECT_LE(0, stream_->GetTotalSentBytes());
1995 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1996 }
1997
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendBundledBodyComplete)1998 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
1999 SetRequest("POST", "/", DEFAULT_PRIORITY);
2000 size_t spdy_request_headers_frame_length;
2001 int packet_number = 1;
2002 AddWrite(ConstructInitialSettingsPacket(packet_number++));
2003 std::string header = ConstructDataHeader(strlen(kUploadData));
2004 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
2005 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
2006 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2007 {header, kUploadData}));
2008
2009 AddWrite(SYNCHRONOUS, ERR_FAILED);
2010 Initialize();
2011
2012 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
2013 auto* chunked_upload_stream =
2014 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
2015
2016 request_.method = "POST";
2017 request_.url = GURL("https://www.example.org/");
2018 request_.upload_data_stream = upload_data_stream_.get();
2019
2020 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
2021 false);
2022
2023 ASSERT_EQ(OK, request_.upload_data_stream->Init(
2024 TestCompletionCallback().callback(), NetLogWithSource()));
2025
2026 stream_->RegisterRequest(&request_);
2027 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
2028 net_log_with_source_,
2029 callback_.callback()));
2030 ASSERT_EQ(ERR_IO_PENDING,
2031 stream_->SendRequest(headers_, &response_, callback_.callback()));
2032
2033 chunked_upload_stream->AppendData(base::byte_span_from_cstring(kUploadData),
2034 true);
2035
2036 // Error does not surface yet since packet write is triggered by a packet
2037 // flusher that tries to bundle request body writes.
2038 ASSERT_EQ(OK, callback_.WaitForResult());
2039 // Error will be surfaced once an attempt to read the response occurs.
2040 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
2041 stream_->ReadResponseHeaders(callback_.callback()));
2042
2043 EXPECT_LE(0, stream_->GetTotalSentBytes());
2044 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2045 }
2046
TEST_P(QuicHttpStreamTest,DataReadErrorSynchronous)2047 TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2048 SetRequest("POST", "/", DEFAULT_PRIORITY);
2049 size_t spdy_request_headers_frame_length;
2050 int packet_number = 1;
2051 AddWrite(ConstructInitialSettingsPacket(packet_number++));
2052 AddWrite(ConstructRequestAndRstPacket(
2053 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
2054 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2055 quic::QUIC_ERROR_PROCESSING_STREAM));
2056
2057 Initialize();
2058
2059 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
2060 ReadErrorUploadDataStream::FailureMode::SYNC);
2061 request_.method = "POST";
2062 request_.url = GURL("https://www.example.org/");
2063 request_.upload_data_stream = upload_data_stream_.get();
2064 ASSERT_EQ(OK, request_.upload_data_stream->Init(
2065 TestCompletionCallback().callback(), NetLogWithSource()));
2066
2067 stream_->RegisterRequest(&request_);
2068 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
2069 net_log_with_source_,
2070 callback_.callback()));
2071
2072 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2073 EXPECT_THAT(result, IsError(ERR_FAILED));
2074
2075 EXPECT_TRUE(AtEof());
2076
2077 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2078 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2079 stream_->GetTotalSentBytes());
2080 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2081 }
2082
TEST_P(QuicHttpStreamTest,DataReadErrorAsynchronous)2083 TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2084 SetRequest("POST", "/", DEFAULT_PRIORITY);
2085 size_t spdy_request_headers_frame_length;
2086 int packet_number = 1;
2087 AddWrite(ConstructInitialSettingsPacket(packet_number++));
2088 AddWrite(InnerConstructRequestHeadersPacket(
2089 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
2090 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
2091 AddWrite(ConstructClientRstStreamErrorPacket(packet_number++));
2092
2093 Initialize();
2094
2095 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
2096 ReadErrorUploadDataStream::FailureMode::ASYNC);
2097 request_.method = "POST";
2098 request_.url = GURL("https://www.example.org/");
2099 request_.upload_data_stream = upload_data_stream_.get();
2100 ASSERT_EQ(OK, request_.upload_data_stream->Init(
2101 TestCompletionCallback().callback(), NetLogWithSource()));
2102
2103 stream_->RegisterRequest(&request_);
2104 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
2105 net_log_with_source_,
2106 callback_.callback()));
2107
2108 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2109
2110 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
2111 SetResponse("200", string());
2112
2113 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2114 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
2115
2116 EXPECT_TRUE(AtEof());
2117
2118 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2119 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2120 stream_->GetTotalSentBytes());
2121 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2122 }
2123
TEST_P(QuicHttpStreamTest,GetAcceptChViaAlps)2124 TEST_P(QuicHttpStreamTest, GetAcceptChViaAlps) {
2125 AddWrite(ConstructInitialSettingsPacket());
2126 Initialize();
2127
2128 base::HistogramTester histogram_tester;
2129
2130 session_->OnAcceptChFrameReceivedViaAlps(
2131 {{{"https://www.example.org", "Sec-CH-UA-Platform"}}});
2132
2133 request_.method = "GET";
2134 request_.url = GURL("https://www.example.org/foo");
2135
2136 stream_->RegisterRequest(&request_);
2137 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
2138 net_log_with_source_,
2139 callback_.callback()));
2140 EXPECT_EQ("Sec-CH-UA-Platform", stream_->GetAcceptChViaAlps());
2141 EXPECT_TRUE(AtEof());
2142
2143 histogram_tester.ExpectBucketCount(
2144 "Net.QuicSession.AcceptChFrameReceivedViaAlps", 1, 1);
2145 histogram_tester.ExpectTotalCount(
2146 "Net.QuicSession.AcceptChFrameReceivedViaAlps", 1);
2147 histogram_tester.ExpectBucketCount("Net.QuicSession.AcceptChForOrigin", 1, 1);
2148 histogram_tester.ExpectTotalCount("Net.QuicSession.AcceptChForOrigin", 1);
2149 }
2150
2151 } // namespace net::test
2152