• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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