xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/http/quic_spdy_stream.h"
6 
7 #include <cstring>
8 #include <memory>
9 #include <string>
10 #include <utility>
11 
12 #include "absl/base/macros.h"
13 #include "absl/memory/memory.h"
14 #include "absl/strings/escaping.h"
15 #include "absl/strings/str_cat.h"
16 #include "absl/strings/string_view.h"
17 #include "quiche/quic/core/crypto/null_encrypter.h"
18 #include "quiche/quic/core/http/http_constants.h"
19 #include "quiche/quic/core/http/http_encoder.h"
20 #include "quiche/quic/core/http/http_frames.h"
21 #include "quiche/quic/core/http/quic_spdy_session.h"
22 #include "quiche/quic/core/http/spdy_utils.h"
23 #include "quiche/quic/core/http/web_transport_http3.h"
24 #include "quiche/quic/core/quic_connection.h"
25 #include "quiche/quic/core/quic_stream_sequencer_buffer.h"
26 #include "quiche/quic/core/quic_utils.h"
27 #include "quiche/quic/core/quic_versions.h"
28 #include "quiche/quic/core/quic_write_blocked_list.h"
29 #include "quiche/quic/platform/api/quic_expect_bug.h"
30 #include "quiche/quic/platform/api/quic_flags.h"
31 #include "quiche/quic/platform/api/quic_test.h"
32 #include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
33 #include "quiche/quic/test_tools/quic_config_peer.h"
34 #include "quiche/quic/test_tools/quic_connection_peer.h"
35 #include "quiche/quic/test_tools/quic_flow_controller_peer.h"
36 #include "quiche/quic/test_tools/quic_session_peer.h"
37 #include "quiche/quic/test_tools/quic_spdy_session_peer.h"
38 #include "quiche/quic/test_tools/quic_spdy_stream_peer.h"
39 #include "quiche/quic/test_tools/quic_stream_peer.h"
40 #include "quiche/quic/test_tools/quic_test_utils.h"
41 #include "quiche/common/capsule.h"
42 #include "quiche/common/quiche_ip_address.h"
43 #include "quiche/common/quiche_mem_slice_storage.h"
44 #include "quiche/common/simple_buffer_allocator.h"
45 
46 using quiche::Capsule;
47 using quiche::IpAddressRange;
48 using spdy::Http2HeaderBlock;
49 using spdy::kV3HighestPriority;
50 using spdy::kV3LowestPriority;
51 using testing::_;
52 using testing::AnyNumber;
53 using testing::AtLeast;
54 using testing::DoAll;
55 using testing::ElementsAre;
56 using testing::HasSubstr;
57 using testing::Invoke;
58 using testing::InvokeWithoutArgs;
59 using testing::MatchesRegex;
60 using testing::Pair;
61 using testing::Return;
62 using testing::SaveArg;
63 using testing::StrictMock;
64 
65 namespace quic {
66 namespace test {
67 namespace {
68 
69 constexpr bool kShouldProcessData = true;
70 constexpr absl::string_view kDataFramePayload = "some data";
71 
72 class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
73  public:
TestCryptoStream(QuicSession * session)74   explicit TestCryptoStream(QuicSession* session)
75       : QuicCryptoStream(session),
76         QuicCryptoHandshaker(this, session),
77         encryption_established_(false),
78         one_rtt_keys_available_(false),
79         params_(new QuicCryptoNegotiatedParameters) {
80     // Simulate a negotiated cipher_suite with a fake value.
81     params_->cipher_suite = 1;
82   }
83 
OnHandshakeMessage(const CryptoHandshakeMessage &)84   void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
85     encryption_established_ = true;
86     one_rtt_keys_available_ = true;
87     QuicErrorCode error;
88     std::string error_details;
89     session()->config()->SetInitialStreamFlowControlWindowToSend(
90         kInitialStreamFlowControlWindowForTest);
91     session()->config()->SetInitialSessionFlowControlWindowToSend(
92         kInitialSessionFlowControlWindowForTest);
93     if (session()->version().UsesTls()) {
94       if (session()->perspective() == Perspective::IS_CLIENT) {
95         session()->config()->SetOriginalConnectionIdToSend(
96             session()->connection()->connection_id());
97         session()->config()->SetInitialSourceConnectionIdToSend(
98             session()->connection()->connection_id());
99       } else {
100         session()->config()->SetInitialSourceConnectionIdToSend(
101             session()->connection()->client_connection_id());
102       }
103       TransportParameters transport_parameters;
104       EXPECT_TRUE(
105           session()->config()->FillTransportParameters(&transport_parameters));
106       error = session()->config()->ProcessTransportParameters(
107           transport_parameters, /* is_resumption = */ false, &error_details);
108     } else {
109       CryptoHandshakeMessage msg;
110       session()->config()->ToHandshakeMessage(&msg, transport_version());
111       error =
112           session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
113     }
114     EXPECT_THAT(error, IsQuicNoError());
115     session()->OnNewEncryptionKeyAvailable(
116         ENCRYPTION_FORWARD_SECURE,
117         std::make_unique<NullEncrypter>(session()->perspective()));
118     session()->OnConfigNegotiated();
119     if (session()->version().UsesTls()) {
120       session()->OnTlsHandshakeComplete();
121     } else {
122       session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
123     }
124     if (session()->version().UsesTls()) {
125       // HANDSHAKE_DONE frame.
126       EXPECT_CALL(*this, HasPendingRetransmission());
127     }
128     session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
129   }
130 
131   // QuicCryptoStream implementation
EarlyDataReason() const132   ssl_early_data_reason_t EarlyDataReason() const override {
133     return ssl_early_data_unknown;
134   }
encryption_established() const135   bool encryption_established() const override {
136     return encryption_established_;
137   }
one_rtt_keys_available() const138   bool one_rtt_keys_available() const override {
139     return one_rtt_keys_available_;
140   }
GetHandshakeState() const141   HandshakeState GetHandshakeState() const override {
142     return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
143   }
SetServerApplicationStateForResumption(std::unique_ptr<ApplicationState>)144   void SetServerApplicationStateForResumption(
145       std::unique_ptr<ApplicationState> /*application_state*/) override {}
AdvanceKeysAndCreateCurrentOneRttDecrypter()146   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
147       override {
148     return nullptr;
149   }
CreateCurrentOneRttEncrypter()150   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
151     return nullptr;
152   }
crypto_negotiated_params() const153   const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
154       const override {
155     return *params_;
156   }
crypto_message_parser()157   CryptoMessageParser* crypto_message_parser() override {
158     return QuicCryptoHandshaker::crypto_message_parser();
159   }
OnPacketDecrypted(EncryptionLevel)160   void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
OnOneRttPacketAcknowledged()161   void OnOneRttPacketAcknowledged() override {}
OnHandshakePacketSent()162   void OnHandshakePacketSent() override {}
OnConnectionClosed(QuicErrorCode,ConnectionCloseSource)163   void OnConnectionClosed(QuicErrorCode /*error*/,
164                           ConnectionCloseSource /*source*/) override {}
OnHandshakeDoneReceived()165   void OnHandshakeDoneReceived() override {}
OnNewTokenReceived(absl::string_view)166   void OnNewTokenReceived(absl::string_view /*token*/) override {}
GetAddressToken(const CachedNetworkParameters *) const167   std::string GetAddressToken(
168       const CachedNetworkParameters* /*cached_network_parameters*/)
169       const override {
170     return "";
171   }
ValidateAddressToken(absl::string_view) const172   bool ValidateAddressToken(absl::string_view /*token*/) const override {
173     return true;
174   }
PreviousCachedNetworkParams() const175   const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
176     return nullptr;
177   }
SetPreviousCachedNetworkParams(CachedNetworkParameters)178   void SetPreviousCachedNetworkParams(
179       CachedNetworkParameters /*cached_network_params*/) override {}
180 
181   MOCK_METHOD(void, OnCanWrite, (), (override));
182 
HasPendingCryptoRetransmission() const183   bool HasPendingCryptoRetransmission() const override { return false; }
184 
185   MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
186 
ExportKeyingMaterial(absl::string_view,absl::string_view,size_t,std::string *)187   bool ExportKeyingMaterial(absl::string_view /*label*/,
188                             absl::string_view /*context*/,
189                             size_t /*result_len*/,
190                             std::string* /*result*/) override {
191     return false;
192   }
193 
GetSsl() const194   SSL* GetSsl() const override { return nullptr; }
195 
IsCryptoFrameExpectedForEncryptionLevel(EncryptionLevel level) const196   bool IsCryptoFrameExpectedForEncryptionLevel(
197       EncryptionLevel level) const override {
198     return level != ENCRYPTION_ZERO_RTT;
199   }
200 
GetEncryptionLevelToSendCryptoDataOfSpace(PacketNumberSpace space) const201   EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
202       PacketNumberSpace space) const override {
203     switch (space) {
204       case INITIAL_DATA:
205         return ENCRYPTION_INITIAL;
206       case HANDSHAKE_DATA:
207         return ENCRYPTION_HANDSHAKE;
208       case APPLICATION_DATA:
209         return ENCRYPTION_FORWARD_SECURE;
210       default:
211         QUICHE_DCHECK(false);
212         return NUM_ENCRYPTION_LEVELS;
213     }
214   }
215 
216  private:
217   using QuicCryptoStream::session;
218 
219   bool encryption_established_;
220   bool one_rtt_keys_available_;
221   quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
222 };
223 
224 class TestStream : public QuicSpdyStream {
225  public:
TestStream(QuicStreamId id,QuicSpdySession * session,bool should_process_data)226   TestStream(QuicStreamId id, QuicSpdySession* session,
227              bool should_process_data)
228       : QuicSpdyStream(id, session, BIDIRECTIONAL),
229         should_process_data_(should_process_data),
230         headers_payload_length_(0) {}
231   ~TestStream() override = default;
232 
233   using QuicSpdyStream::set_ack_listener;
234   using QuicSpdyStream::ValidateReceivedHeaders;
235   using QuicStream::CloseWriteSide;
236   using QuicStream::sequencer;
237   using QuicStream::WriteOrBufferData;
238 
OnBodyAvailable()239   void OnBodyAvailable() override {
240     if (!should_process_data_) {
241       return;
242     }
243     char buffer[2048];
244     struct iovec vec;
245     vec.iov_base = buffer;
246     vec.iov_len = ABSL_ARRAYSIZE(buffer);
247     size_t bytes_read = Readv(&vec, 1);
248     data_ += std::string(buffer, bytes_read);
249   }
250 
251   MOCK_METHOD(void, WriteHeadersMock, (bool fin), ());
252 
WriteHeadersImpl(spdy::Http2HeaderBlock header_block,bool fin,quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>)253   size_t WriteHeadersImpl(
254       spdy::Http2HeaderBlock header_block, bool fin,
255       quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
256       /*ack_listener*/) override {
257     saved_headers_ = std::move(header_block);
258     WriteHeadersMock(fin);
259     if (VersionUsesHttp3(transport_version())) {
260       // In this case, call QuicSpdyStream::WriteHeadersImpl() that does the
261       // actual work of closing the stream.
262       return QuicSpdyStream::WriteHeadersImpl(saved_headers_.Clone(), fin,
263                                               nullptr);
264     }
265     return 0;
266   }
267 
data() const268   const std::string& data() const { return data_; }
saved_headers() const269   const spdy::Http2HeaderBlock& saved_headers() const { return saved_headers_; }
270 
OnStreamHeaderList(bool fin,size_t frame_len,const QuicHeaderList & header_list)271   void OnStreamHeaderList(bool fin, size_t frame_len,
272                           const QuicHeaderList& header_list) override {
273     headers_payload_length_ = frame_len;
274     QuicSpdyStream::OnStreamHeaderList(fin, frame_len, header_list);
275   }
276 
headers_payload_length() const277   size_t headers_payload_length() const { return headers_payload_length_; }
278 
279  private:
280   bool should_process_data_;
281   spdy::Http2HeaderBlock saved_headers_;
282   std::string data_;
283   size_t headers_payload_length_;
284 };
285 
286 class TestSession : public MockQuicSpdySession {
287  public:
TestSession(QuicConnection * connection)288   explicit TestSession(QuicConnection* connection)
289       : MockQuicSpdySession(connection, /*create_mock_crypto_stream=*/false),
290         crypto_stream_(this) {}
291 
GetMutableCryptoStream()292   TestCryptoStream* GetMutableCryptoStream() override {
293     return &crypto_stream_;
294   }
295 
GetCryptoStream() const296   const TestCryptoStream* GetCryptoStream() const override {
297     return &crypto_stream_;
298   }
299 
LocallySupportedWebTransportVersions() const300   WebTransportHttp3VersionSet LocallySupportedWebTransportVersions()
301       const override {
302     return locally_supported_webtransport_versions_;
303   }
EnableWebTransport(WebTransportHttp3VersionSet versions=kDefaultSupportedWebTransportVersions)304   void EnableWebTransport(WebTransportHttp3VersionSet versions =
305                               kDefaultSupportedWebTransportVersions) {
306     locally_supported_webtransport_versions_ = versions;
307   }
308 
LocalHttpDatagramSupport()309   HttpDatagramSupport LocalHttpDatagramSupport() override {
310     return local_http_datagram_support_;
311   }
set_local_http_datagram_support(HttpDatagramSupport value)312   void set_local_http_datagram_support(HttpDatagramSupport value) {
313     local_http_datagram_support_ = value;
314   }
315 
316  private:
317   WebTransportHttp3VersionSet locally_supported_webtransport_versions_;
318   HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
319   StrictMock<TestCryptoStream> crypto_stream_;
320 };
321 
322 class TestMockUpdateStreamSession : public MockQuicSpdySession {
323  public:
TestMockUpdateStreamSession(QuicConnection * connection)324   explicit TestMockUpdateStreamSession(QuicConnection* connection)
325       : MockQuicSpdySession(connection) {}
326 
UpdateStreamPriority(QuicStreamId id,const QuicStreamPriority & new_priority)327   void UpdateStreamPriority(QuicStreamId id,
328                             const QuicStreamPriority& new_priority) override {
329     EXPECT_EQ(id, expected_stream_->id());
330     EXPECT_EQ(expected_priority_, new_priority.http());
331     EXPECT_EQ(QuicStreamPriority(expected_priority_),
332               expected_stream_->priority());
333   }
334 
SetExpectedStream(QuicSpdyStream * stream)335   void SetExpectedStream(QuicSpdyStream* stream) { expected_stream_ = stream; }
SetExpectedPriority(const HttpStreamPriority & priority)336   void SetExpectedPriority(const HttpStreamPriority& priority) {
337     expected_priority_ = priority;
338   }
339 
340  private:
341   QuicSpdyStream* expected_stream_;
342   HttpStreamPriority expected_priority_;
343 };
344 
345 class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
346  protected:
QuicSpdyStreamTest()347   QuicSpdyStreamTest() {
348     headers_[":host"] = "www.google.com";
349     headers_[":path"] = "/index.hml";
350     headers_[":scheme"] = "https";
351     headers_["cookie"] =
352         "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
353         "__utmc=160408618; "
354         "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
355         "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
356         "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
357         "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
358         "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
359         "1zFMi5vzcns38-8_Sns; "
360         "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
361         "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
362         "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
363         "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
364         "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
365         "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
366         "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
367         "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
368         "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
369         "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
370         "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
371         "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
372         "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
373         "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
374         "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
375   }
376 
377   ~QuicSpdyStreamTest() override = default;
378 
379   // Return QPACK-encoded header block without using the dynamic table.
EncodeQpackHeaders(std::vector<std::pair<absl::string_view,absl::string_view>> headers)380   std::string EncodeQpackHeaders(
381       std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
382     Http2HeaderBlock header_block;
383     for (const auto& header_field : headers) {
384       header_block.AppendValueOrAddHeader(header_field.first,
385                                           header_field.second);
386     }
387 
388     return EncodeQpackHeaders(header_block);
389   }
390 
391   // Return QPACK-encoded header block without using the dynamic table.
EncodeQpackHeaders(const Http2HeaderBlock & header)392   std::string EncodeQpackHeaders(const Http2HeaderBlock& header) {
393     NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
394     auto qpack_encoder = std::make_unique<QpackEncoder>(
395         session_.get(), HuffmanEncoding::kEnabled);
396     qpack_encoder->set_qpack_stream_sender_delegate(
397         &encoder_stream_sender_delegate);
398     // QpackEncoder does not use the dynamic table by default,
399     // therefore the value of |stream_id| does not matter.
400     return qpack_encoder->EncodeHeaderList(/* stream_id = */ 0, header,
401                                            nullptr);
402   }
403 
Initialize(bool stream_should_process_data)404   void Initialize(bool stream_should_process_data) {
405     InitializeWithPerspective(stream_should_process_data,
406                               Perspective::IS_SERVER);
407   }
408 
InitializeWithPerspective(bool stream_should_process_data,Perspective perspective)409   void InitializeWithPerspective(bool stream_should_process_data,
410                                  Perspective perspective) {
411     connection_ = new StrictMock<MockQuicConnection>(
412         &helper_, &alarm_factory_, perspective, SupportedVersions(GetParam()));
413     session_ = std::make_unique<StrictMock<TestSession>>(connection_);
414     EXPECT_CALL(*session_, OnCongestionWindowChange(_)).Times(AnyNumber());
415     session_->Initialize();
416     if (connection_->version().SupportsAntiAmplificationLimit()) {
417       QuicConnectionPeer::SetAddressValidated(connection_);
418     }
419     connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
420     ON_CALL(*session_, WritevData(_, _, _, _, _, _))
421         .WillByDefault(
422             Invoke(session_.get(), &MockQuicSpdySession::ConsumeData));
423 
424     stream_ =
425         new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(0),
426                                    session_.get(), stream_should_process_data);
427     session_->ActivateStream(absl::WrapUnique(stream_));
428     stream2_ =
429         new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalId(1),
430                                    session_.get(), stream_should_process_data);
431     session_->ActivateStream(absl::WrapUnique(stream2_));
432     QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
433         session_->config(), kMinimumFlowControlSendWindow);
434     QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
435         session_->config(), kMinimumFlowControlSendWindow);
436     QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
437         session_->config(), kMinimumFlowControlSendWindow);
438     QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
439         session_->config(), kMinimumFlowControlSendWindow);
440     QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 10);
441     session_->OnConfigNegotiated();
442     if (UsesHttp3()) {
443       // The control stream will write the stream type, a greased frame, and
444       // SETTINGS frame.
445       int num_control_stream_writes = 3;
446       auto send_control_stream =
447           QuicSpdySessionPeer::GetSendControlStream(session_.get());
448       EXPECT_CALL(*session_,
449                   WritevData(send_control_stream->id(), _, _, _, _, _))
450           .Times(num_control_stream_writes);
451     }
452     TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
453     EXPECT_CALL(*crypto_stream, HasPendingRetransmission()).Times(AnyNumber());
454 
455     if (connection_->version().UsesTls() &&
456         session_->perspective() == Perspective::IS_SERVER) {
457       // HANDSHAKE_DONE frame.
458       EXPECT_CALL(*connection_, SendControlFrame(_))
459           .WillOnce(Invoke(&ClearControlFrame));
460     }
461     CryptoHandshakeMessage message;
462     session_->GetMutableCryptoStream()->OnHandshakeMessage(message);
463   }
464 
ProcessHeaders(bool fin,const Http2HeaderBlock & headers)465   QuicHeaderList ProcessHeaders(bool fin, const Http2HeaderBlock& headers) {
466     QuicHeaderList h = AsHeaderList(headers);
467     stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h);
468     return h;
469   }
470 
GetNthClientInitiatedBidirectionalId(int n)471   QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
472     return GetNthClientInitiatedBidirectionalStreamId(
473         connection_->transport_version(), n);
474   }
475 
UsesHttp3() const476   bool UsesHttp3() const {
477     return VersionUsesHttp3(GetParam().transport_version);
478   }
479 
480   // Construct HEADERS frame with QPACK-encoded |headers| without using the
481   // dynamic table.
HeadersFrame(std::vector<std::pair<absl::string_view,absl::string_view>> headers)482   std::string HeadersFrame(
483       std::vector<std::pair<absl::string_view, absl::string_view>> headers) {
484     return HeadersFrame(EncodeQpackHeaders(headers));
485   }
486 
487   // Construct HEADERS frame with QPACK-encoded |headers| without using the
488   // dynamic table.
HeadersFrame(const Http2HeaderBlock & headers)489   std::string HeadersFrame(const Http2HeaderBlock& headers) {
490     return HeadersFrame(EncodeQpackHeaders(headers));
491   }
492 
493   // Construct HEADERS frame with given payload.
HeadersFrame(absl::string_view payload)494   std::string HeadersFrame(absl::string_view payload) {
495     std::string headers_frame_header =
496         HttpEncoder::SerializeHeadersFrameHeader(payload.length());
497     return absl::StrCat(headers_frame_header, payload);
498   }
499 
DataFrame(absl::string_view payload)500   std::string DataFrame(absl::string_view payload) {
501     quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
502         payload.length(), quiche::SimpleBufferAllocator::Get());
503     return absl::StrCat(header.AsStringView(), payload);
504   }
505 
UnknownFrame(uint64_t frame_type,absl::string_view payload)506   std::string UnknownFrame(uint64_t frame_type, absl::string_view payload) {
507     std::string frame;
508     const size_t length = QuicDataWriter::GetVarInt62Len(frame_type) +
509                           QuicDataWriter::GetVarInt62Len(payload.size()) +
510                           payload.size();
511     frame.resize(length);
512 
513     QuicDataWriter writer(length, const_cast<char*>(frame.data()));
514     writer.WriteVarInt62(frame_type);
515     writer.WriteStringPieceVarInt62(payload);
516     // Even though integers can be encoded with different lengths,
517     // QuicDataWriter is expected to produce an encoding in Write*() of length
518     // promised in GetVarInt62Len().
519     QUICHE_DCHECK_EQ(length, writer.length());
520 
521     return frame;
522   }
523 
524   MockQuicConnectionHelper helper_;
525   MockAlarmFactory alarm_factory_;
526   MockQuicConnection* connection_;
527   std::unique_ptr<TestSession> session_;
528 
529   // Owned by the |session_|.
530   TestStream* stream_;
531   TestStream* stream2_;
532 
533   Http2HeaderBlock headers_;
534 };
535 
536 INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamTest,
537                          ::testing::ValuesIn(AllSupportedVersions()),
538                          ::testing::PrintToStringParamName());
539 
TEST_P(QuicSpdyStreamTest,ProcessHeaderList)540 TEST_P(QuicSpdyStreamTest, ProcessHeaderList) {
541   Initialize(kShouldProcessData);
542 
543   stream_->OnStreamHeadersPriority(
544       spdy::SpdyStreamPrecedence(kV3HighestPriority));
545   ProcessHeaders(false, headers_);
546   EXPECT_EQ("", stream_->data());
547   EXPECT_FALSE(stream_->header_list().empty());
548   EXPECT_FALSE(stream_->IsDoneReading());
549 }
550 
TEST_P(QuicSpdyStreamTest,ProcessTooLargeHeaderList)551 TEST_P(QuicSpdyStreamTest, ProcessTooLargeHeaderList) {
552   Initialize(kShouldProcessData);
553 
554   if (!UsesHttp3()) {
555     QuicHeaderList headers;
556     stream_->OnStreamHeadersPriority(
557         spdy::SpdyStreamPrecedence(kV3HighestPriority));
558 
559     EXPECT_CALL(
560         *session_,
561         MaybeSendRstStreamFrame(
562             stream_->id(),
563             QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
564     stream_->OnStreamHeaderList(false, 1 << 20, headers);
565 
566     EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
567 
568     return;
569   }
570 
571   // Header list size includes 32 bytes for overhead per header field.
572   session_->set_max_inbound_header_list_size(40);
573   std::string headers =
574       HeadersFrame({std::make_pair("foo", "too long headers")});
575 
576   QuicStreamFrame frame(stream_->id(), false, 0, headers);
577 
578   EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
579                              stream_->id(), QuicResetStreamError::FromInternal(
580                                                 QUIC_HEADERS_TOO_LARGE)));
581   EXPECT_CALL(
582       *session_,
583       MaybeSendRstStreamFrame(
584           stream_->id(),
585           QuicResetStreamError::FromInternal(QUIC_HEADERS_TOO_LARGE), 0));
586 
587   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
588     auto qpack_decoder_stream =
589         QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
590     // Stream type and stream cancellation.
591     EXPECT_CALL(*session_,
592                 WritevData(qpack_decoder_stream->id(), _, _, NO_FIN, _, _))
593         .Times(2);
594   }
595 
596   stream_->OnStreamFrame(frame);
597   EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
598 }
599 
TEST_P(QuicSpdyStreamTest,QpackProcessLargeHeaderListDiscountOverhead)600 TEST_P(QuicSpdyStreamTest, QpackProcessLargeHeaderListDiscountOverhead) {
601   if (!UsesHttp3()) {
602     return;
603   }
604   // Setting this flag to false causes no per-entry overhead to be included
605   // in the header size.
606   SetQuicFlag(quic_header_size_limit_includes_overhead, false);
607   Initialize(kShouldProcessData);
608   session_->set_max_inbound_header_list_size(40);
609   std::string headers =
610       HeadersFrame({std::make_pair("foo", "too long headers")});
611 
612   QuicStreamFrame frame(stream_->id(), false, 0, headers);
613   stream_->OnStreamFrame(frame);
614   EXPECT_THAT(stream_->stream_error(), IsStreamError(QUIC_STREAM_NO_ERROR));
615 }
616 
TEST_P(QuicSpdyStreamTest,ProcessHeaderListWithFin)617 TEST_P(QuicSpdyStreamTest, ProcessHeaderListWithFin) {
618   Initialize(kShouldProcessData);
619 
620   size_t total_bytes = 0;
621   QuicHeaderList headers;
622   for (auto p : headers_) {
623     headers.OnHeader(p.first, p.second);
624     total_bytes += p.first.size() + p.second.size();
625   }
626   stream_->OnStreamHeadersPriority(
627       spdy::SpdyStreamPrecedence(kV3HighestPriority));
628   stream_->OnStreamHeaderList(true, total_bytes, headers);
629   EXPECT_EQ("", stream_->data());
630   EXPECT_FALSE(stream_->header_list().empty());
631   EXPECT_FALSE(stream_->IsDoneReading());
632   EXPECT_TRUE(stream_->HasReceivedFinalOffset());
633 }
634 
635 // A valid status code should be 3-digit integer. The first digit should be in
636 // the range of [1, 5]. All the others are invalid.
TEST_P(QuicSpdyStreamTest,ParseHeaderStatusCode)637 TEST_P(QuicSpdyStreamTest, ParseHeaderStatusCode) {
638   Initialize(kShouldProcessData);
639   int status_code = 0;
640 
641   // Valid status codes.
642   headers_[":status"] = "404";
643   EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
644   EXPECT_EQ(404, status_code);
645 
646   headers_[":status"] = "100";
647   EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
648   EXPECT_EQ(100, status_code);
649 
650   headers_[":status"] = "599";
651   EXPECT_TRUE(stream_->ParseHeaderStatusCode(headers_, &status_code));
652   EXPECT_EQ(599, status_code);
653 
654   // Invalid status codes.
655   headers_[":status"] = "010";
656   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
657 
658   headers_[":status"] = "600";
659   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
660 
661   headers_[":status"] = "200 ok";
662   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
663 
664   headers_[":status"] = "2000";
665   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
666 
667   headers_[":status"] = "+200";
668   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
669 
670   headers_[":status"] = "+20";
671   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
672 
673   headers_[":status"] = "-10";
674   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
675 
676   headers_[":status"] = "-100";
677   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
678 
679   // Leading or trailing spaces are also invalid.
680   headers_[":status"] = " 200";
681   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
682 
683   headers_[":status"] = "200 ";
684   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
685 
686   headers_[":status"] = " 200 ";
687   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
688 
689   headers_[":status"] = "  ";
690   EXPECT_FALSE(stream_->ParseHeaderStatusCode(headers_, &status_code));
691 }
692 
TEST_P(QuicSpdyStreamTest,MarkHeadersConsumed)693 TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) {
694   Initialize(kShouldProcessData);
695 
696   std::string body = "this is the body";
697   QuicHeaderList headers = ProcessHeaders(false, headers_);
698   EXPECT_EQ(headers, stream_->header_list());
699 
700   stream_->ConsumeHeaderList();
701   EXPECT_EQ(QuicHeaderList(), stream_->header_list());
702 }
703 
TEST_P(QuicSpdyStreamTest,ProcessWrongFramesOnSpdyStream)704 TEST_P(QuicSpdyStreamTest, ProcessWrongFramesOnSpdyStream) {
705   if (!UsesHttp3()) {
706     return;
707   }
708 
709   Initialize(kShouldProcessData);
710   testing::InSequence s;
711   connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
712   GoAwayFrame goaway;
713   goaway.id = 0x1;
714   std::string goaway_frame = HttpEncoder::SerializeGoAwayFrame(goaway);
715 
716   EXPECT_EQ("", stream_->data());
717   QuicHeaderList headers = ProcessHeaders(false, headers_);
718   EXPECT_EQ(headers, stream_->header_list());
719   stream_->ConsumeHeaderList();
720   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
721                         goaway_frame);
722 
723   EXPECT_CALL(*connection_,
724               CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
725       .WillOnce(
726           (Invoke([this](QuicErrorCode error, const std::string& error_details,
727                          ConnectionCloseBehavior connection_close_behavior) {
728             connection_->ReallyCloseConnection(error, error_details,
729                                                connection_close_behavior);
730           })));
731   EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
732   EXPECT_CALL(*session_, OnConnectionClosed(_, _))
733       .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
734                               ConnectionCloseSource source) {
735         session_->ReallyOnConnectionClosed(frame, source);
736       }));
737   EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
738 
739   stream_->OnStreamFrame(frame);
740 }
741 
TEST_P(QuicSpdyStreamTest,Http3FrameError)742 TEST_P(QuicSpdyStreamTest, Http3FrameError) {
743   if (!UsesHttp3()) {
744     return;
745   }
746 
747   Initialize(kShouldProcessData);
748 
749   // PUSH_PROMISE frame is considered invalid.
750   std::string invalid_http3_frame;
751   ASSERT_TRUE(absl::HexStringToBytes("0500", &invalid_http3_frame));
752   QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
753                                /* offset = */ 0, invalid_http3_frame);
754 
755   EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR, _, _));
756   stream_->OnStreamFrame(stream_frame);
757 }
758 
TEST_P(QuicSpdyStreamTest,UnexpectedHttp3Frame)759 TEST_P(QuicSpdyStreamTest, UnexpectedHttp3Frame) {
760   if (!UsesHttp3()) {
761     return;
762   }
763 
764   Initialize(kShouldProcessData);
765 
766   // SETTINGS frame with empty payload.
767   std::string settings;
768   ASSERT_TRUE(absl::HexStringToBytes("0400", &settings));
769   QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
770                                /* offset = */ 0, settings);
771 
772   EXPECT_CALL(*connection_,
773               CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _));
774   stream_->OnStreamFrame(stream_frame);
775 }
776 
TEST_P(QuicSpdyStreamTest,ProcessHeadersAndBody)777 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) {
778   Initialize(kShouldProcessData);
779 
780   std::string body = "this is the body";
781   std::string data = UsesHttp3() ? DataFrame(body) : body;
782 
783   EXPECT_EQ("", stream_->data());
784   QuicHeaderList headers = ProcessHeaders(false, headers_);
785   EXPECT_EQ(headers, stream_->header_list());
786   stream_->ConsumeHeaderList();
787   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
788                         absl::string_view(data));
789   stream_->OnStreamFrame(frame);
790   EXPECT_EQ(QuicHeaderList(), stream_->header_list());
791   EXPECT_EQ(body, stream_->data());
792 }
793 
TEST_P(QuicSpdyStreamTest,ProcessHeadersAndBodyFragments)794 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) {
795   std::string body = "this is the body";
796   std::string data = UsesHttp3() ? DataFrame(body) : body;
797 
798   for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
799     Initialize(kShouldProcessData);
800     QuicHeaderList headers = ProcessHeaders(false, headers_);
801     ASSERT_EQ(headers, stream_->header_list());
802     stream_->ConsumeHeaderList();
803     for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
804       size_t remaining_data = data.size() - offset;
805       absl::string_view fragment(data.data() + offset,
806                                  std::min(fragment_size, remaining_data));
807       QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false,
808                             offset, absl::string_view(fragment));
809       stream_->OnStreamFrame(frame);
810     }
811     ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size;
812   }
813 }
814 
TEST_P(QuicSpdyStreamTest,ProcessHeadersAndBodyFragmentsSplit)815 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
816   std::string body = "this is the body";
817   std::string data = UsesHttp3() ? DataFrame(body) : body;
818 
819   for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
820     Initialize(kShouldProcessData);
821     QuicHeaderList headers = ProcessHeaders(false, headers_);
822     ASSERT_EQ(headers, stream_->header_list());
823     stream_->ConsumeHeaderList();
824 
825     absl::string_view fragment1(data.data(), split_point);
826     QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
827                            absl::string_view(fragment1));
828     stream_->OnStreamFrame(frame1);
829 
830     absl::string_view fragment2(data.data() + split_point,
831                                 data.size() - split_point);
832     QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
833                            split_point, absl::string_view(fragment2));
834     stream_->OnStreamFrame(frame2);
835 
836     ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point;
837   }
838 }
839 
TEST_P(QuicSpdyStreamTest,ProcessHeadersAndBodyReadv)840 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) {
841   Initialize(!kShouldProcessData);
842 
843   std::string body = "this is the body";
844   std::string data = UsesHttp3() ? DataFrame(body) : body;
845 
846   ProcessHeaders(false, headers_);
847   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
848                         absl::string_view(data));
849   stream_->OnStreamFrame(frame);
850   stream_->ConsumeHeaderList();
851 
852   char buffer[2048];
853   ASSERT_LT(data.length(), ABSL_ARRAYSIZE(buffer));
854   struct iovec vec;
855   vec.iov_base = buffer;
856   vec.iov_len = ABSL_ARRAYSIZE(buffer);
857 
858   size_t bytes_read = stream_->Readv(&vec, 1);
859   QuicStreamPeer::CloseReadSide(stream_);
860   EXPECT_EQ(body.length(), bytes_read);
861   EXPECT_EQ(body, std::string(buffer, bytes_read));
862 }
863 
TEST_P(QuicSpdyStreamTest,ProcessHeadersAndLargeBodySmallReadv)864 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndLargeBodySmallReadv) {
865   Initialize(kShouldProcessData);
866   std::string body(12 * 1024, 'a');
867   std::string data = UsesHttp3() ? DataFrame(body) : body;
868 
869   ProcessHeaders(false, headers_);
870   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
871                         absl::string_view(data));
872   stream_->OnStreamFrame(frame);
873   stream_->ConsumeHeaderList();
874   char buffer[2048];
875   char buffer2[2048];
876   struct iovec vec[2];
877   vec[0].iov_base = buffer;
878   vec[0].iov_len = ABSL_ARRAYSIZE(buffer);
879   vec[1].iov_base = buffer2;
880   vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
881   size_t bytes_read = stream_->Readv(vec, 2);
882   EXPECT_EQ(2048u * 2, bytes_read);
883   EXPECT_EQ(body.substr(0, 2048), std::string(buffer, 2048));
884   EXPECT_EQ(body.substr(2048, 2048), std::string(buffer2, 2048));
885 }
886 
TEST_P(QuicSpdyStreamTest,ProcessHeadersAndBodyMarkConsumed)887 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) {
888   Initialize(!kShouldProcessData);
889 
890   std::string body = "this is the body";
891   std::string data = UsesHttp3() ? DataFrame(body) : body;
892 
893   ProcessHeaders(false, headers_);
894   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
895                         absl::string_view(data));
896   stream_->OnStreamFrame(frame);
897   stream_->ConsumeHeaderList();
898 
899   struct iovec vec;
900 
901   EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1));
902   EXPECT_EQ(body.length(), vec.iov_len);
903   EXPECT_EQ(body, std::string(static_cast<char*>(vec.iov_base), vec.iov_len));
904 
905   stream_->MarkConsumed(body.length());
906   EXPECT_EQ(data.length(), QuicStreamPeer::bytes_consumed(stream_));
907 }
908 
TEST_P(QuicSpdyStreamTest,ProcessHeadersAndConsumeMultipleBody)909 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) {
910   Initialize(!kShouldProcessData);
911   std::string body1 = "this is body 1";
912   std::string data1 = UsesHttp3() ? DataFrame(body1) : body1;
913   std::string body2 = "body 2";
914   std::string data2 = UsesHttp3() ? DataFrame(body2) : body2;
915 
916   ProcessHeaders(false, headers_);
917   QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
918                          absl::string_view(data1));
919   QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
920                          data1.length(), absl::string_view(data2));
921   stream_->OnStreamFrame(frame1);
922   stream_->OnStreamFrame(frame2);
923   stream_->ConsumeHeaderList();
924 
925   stream_->MarkConsumed(body1.length() + body2.length());
926   EXPECT_EQ(data1.length() + data2.length(),
927             QuicStreamPeer::bytes_consumed(stream_));
928 }
929 
TEST_P(QuicSpdyStreamTest,ProcessHeadersAndBodyIncrementalReadv)930 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
931   Initialize(!kShouldProcessData);
932 
933   std::string body = "this is the body";
934   std::string data = UsesHttp3() ? DataFrame(body) : body;
935 
936   ProcessHeaders(false, headers_);
937   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
938                         absl::string_view(data));
939   stream_->OnStreamFrame(frame);
940   stream_->ConsumeHeaderList();
941 
942   char buffer[1];
943   struct iovec vec;
944   vec.iov_base = buffer;
945   vec.iov_len = ABSL_ARRAYSIZE(buffer);
946 
947   for (size_t i = 0; i < body.length(); ++i) {
948     size_t bytes_read = stream_->Readv(&vec, 1);
949     ASSERT_EQ(1u, bytes_read);
950     EXPECT_EQ(body.data()[i], buffer[0]);
951   }
952 }
953 
TEST_P(QuicSpdyStreamTest,ProcessHeadersUsingReadvWithMultipleIovecs)954 TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
955   Initialize(!kShouldProcessData);
956 
957   std::string body = "this is the body";
958   std::string data = UsesHttp3() ? DataFrame(body) : body;
959 
960   ProcessHeaders(false, headers_);
961   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
962                         absl::string_view(data));
963   stream_->OnStreamFrame(frame);
964   stream_->ConsumeHeaderList();
965 
966   char buffer1[1];
967   char buffer2[1];
968   struct iovec vec[2];
969   vec[0].iov_base = buffer1;
970   vec[0].iov_len = ABSL_ARRAYSIZE(buffer1);
971   vec[1].iov_base = buffer2;
972   vec[1].iov_len = ABSL_ARRAYSIZE(buffer2);
973 
974   for (size_t i = 0; i < body.length(); i += 2) {
975     size_t bytes_read = stream_->Readv(vec, 2);
976     ASSERT_EQ(2u, bytes_read) << i;
977     ASSERT_EQ(body.data()[i], buffer1[0]) << i;
978     ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i;
979   }
980 }
981 
982 // Tests that we send a BLOCKED frame to the peer when we attempt to write, but
983 // are flow control blocked.
TEST_P(QuicSpdyStreamTest,StreamFlowControlBlocked)984 TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
985   Initialize(kShouldProcessData);
986   testing::InSequence seq;
987 
988   // Set a small flow control limit.
989   const uint64_t kWindow = 36;
990   QuicStreamPeer::SetSendWindowOffset(stream_, kWindow);
991   EXPECT_EQ(kWindow, QuicStreamPeer::SendWindowOffset(stream_));
992 
993   // Try to send more data than the flow control limit allows.
994   const uint64_t kOverflow = 15;
995   std::string body(kWindow + kOverflow, 'a');
996 
997   const uint64_t kHeaderLength = UsesHttp3() ? 2 : 0;
998   if (UsesHttp3()) {
999     EXPECT_CALL(*session_, WritevData(_, kHeaderLength, _, NO_FIN, _, _));
1000   }
1001   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
1002       .WillOnce(Return(QuicConsumedData(kWindow - kHeaderLength, true)));
1003   EXPECT_CALL(*session_, SendBlocked(_, _));
1004   EXPECT_CALL(*connection_, SendControlFrame(_));
1005   stream_->WriteOrBufferBody(body, false);
1006 
1007   // Should have sent as much as possible, resulting in no send window left.
1008   EXPECT_EQ(0u, QuicStreamPeer::SendWindowSize(stream_));
1009 
1010   // And we should have queued the overflowed data.
1011   EXPECT_EQ(kOverflow + kHeaderLength, stream_->BufferedDataBytes());
1012 }
1013 
1014 // The flow control receive window decreases whenever we add new bytes to the
1015 // sequencer, whether they are consumed immediately or buffered. However we only
1016 // send WINDOW_UPDATE frames based on increasing number of bytes consumed.
TEST_P(QuicSpdyStreamTest,StreamFlowControlNoWindowUpdateIfNotConsumed)1017 TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
1018   // Don't process data - it will be buffered instead.
1019   Initialize(!kShouldProcessData);
1020 
1021   // Expect no WINDOW_UPDATE frames to be sent.
1022   EXPECT_CALL(*session_, SendWindowUpdate(_, _)).Times(0);
1023 
1024   // Set a small flow control receive window.
1025   const uint64_t kWindow = 36;
1026   QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
1027   QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
1028 
1029   // Stream receives enough data to fill a fraction of the receive window.
1030   std::string body(kWindow / 3, 'a');
1031   QuicByteCount header_length = 0;
1032   std::string data;
1033 
1034   if (UsesHttp3()) {
1035     quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
1036         body.length(), quiche::SimpleBufferAllocator::Get());
1037     data = absl::StrCat(header.AsStringView(), body);
1038     header_length = header.size();
1039   } else {
1040     data = body;
1041   }
1042 
1043   ProcessHeaders(false, headers_);
1044 
1045   QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
1046                          absl::string_view(data));
1047   stream_->OnStreamFrame(frame1);
1048   EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
1049             QuicStreamPeer::ReceiveWindowSize(stream_));
1050 
1051   // Now receive another frame which results in the receive window being over
1052   // half full. This should all be buffered, decreasing the receive window but
1053   // not sending WINDOW_UPDATE.
1054   QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
1055                          kWindow / 3 + header_length, absl::string_view(data));
1056   stream_->OnStreamFrame(frame2);
1057   EXPECT_EQ(kWindow - (2 * kWindow / 3) - 2 * header_length,
1058             QuicStreamPeer::ReceiveWindowSize(stream_));
1059 }
1060 
1061 // Tests that on receipt of data, the stream updates its receive window offset
1062 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops
1063 // too low.
TEST_P(QuicSpdyStreamTest,StreamFlowControlWindowUpdate)1064 TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
1065   Initialize(kShouldProcessData);
1066 
1067   // Set a small flow control limit.
1068   const uint64_t kWindow = 36;
1069   QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
1070   QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
1071 
1072   // Stream receives enough data to fill a fraction of the receive window.
1073   std::string body(kWindow / 3, 'a');
1074   QuicByteCount header_length = 0;
1075   std::string data;
1076 
1077   if (UsesHttp3()) {
1078     quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
1079         body.length(), quiche::SimpleBufferAllocator::Get());
1080     data = absl::StrCat(header.AsStringView(), body);
1081     header_length = header.size();
1082   } else {
1083     data = body;
1084   }
1085 
1086   ProcessHeaders(false, headers_);
1087   stream_->ConsumeHeaderList();
1088 
1089   QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
1090                          absl::string_view(data));
1091   stream_->OnStreamFrame(frame1);
1092   EXPECT_EQ(kWindow - (kWindow / 3) - header_length,
1093             QuicStreamPeer::ReceiveWindowSize(stream_));
1094 
1095   // Now receive another frame which results in the receive window being over
1096   // half full.  This will trigger the stream to increase its receive window
1097   // offset and send a WINDOW_UPDATE. The result will be again an available
1098   // window of kWindow bytes.
1099   QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(0), false,
1100                          kWindow / 3 + header_length, absl::string_view(data));
1101   EXPECT_CALL(*session_, SendWindowUpdate(_, _));
1102   EXPECT_CALL(*connection_, SendControlFrame(_));
1103   stream_->OnStreamFrame(frame2);
1104   EXPECT_EQ(kWindow, QuicStreamPeer::ReceiveWindowSize(stream_));
1105 }
1106 
1107 // Tests that on receipt of data, the connection updates its receive window
1108 // offset appropriately, and sends WINDOW_UPDATE frames when its receive window
1109 // drops too low.
TEST_P(QuicSpdyStreamTest,ConnectionFlowControlWindowUpdate)1110 TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
1111   Initialize(kShouldProcessData);
1112 
1113   // Set a small flow control limit for streams and connection.
1114   const uint64_t kWindow = 36;
1115   QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
1116   QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow);
1117   QuicStreamPeer::SetReceiveWindowOffset(stream2_, kWindow);
1118   QuicStreamPeer::SetMaxReceiveWindow(stream2_, kWindow);
1119   QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
1120                                                  kWindow);
1121   QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
1122                                               kWindow);
1123 
1124   // Supply headers to both streams so that they are happy to receive data.
1125   auto headers = AsHeaderList(headers_);
1126   stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
1127                               headers);
1128   stream_->ConsumeHeaderList();
1129   stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
1130                                headers);
1131   stream2_->ConsumeHeaderList();
1132 
1133   // Each stream gets a quarter window of data. This should not trigger a
1134   // WINDOW_UPDATE for either stream, nor for the connection.
1135   QuicByteCount header_length = 0;
1136   std::string body;
1137   std::string data;
1138   std::string data2;
1139   std::string body2(1, 'a');
1140 
1141   if (UsesHttp3()) {
1142     body = std::string(kWindow / 4 - 2, 'a');
1143     quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
1144         body.length(), quiche::SimpleBufferAllocator::Get());
1145     data = absl::StrCat(header.AsStringView(), body);
1146     header_length = header.size();
1147     quiche::QuicheBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
1148         body.length(), quiche::SimpleBufferAllocator::Get());
1149     data2 = absl::StrCat(header2.AsStringView(), body2);
1150   } else {
1151     body = std::string(kWindow / 4, 'a');
1152     data = body;
1153     data2 = body2;
1154   }
1155 
1156   QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0,
1157                          absl::string_view(data));
1158   stream_->OnStreamFrame(frame1);
1159   QuicStreamFrame frame2(GetNthClientInitiatedBidirectionalId(1), false, 0,
1160                          absl::string_view(data));
1161   stream2_->OnStreamFrame(frame2);
1162 
1163   // Now receive a further single byte on one stream - again this does not
1164   // trigger a stream WINDOW_UPDATE, but now the connection flow control window
1165   // is over half full and thus a connection WINDOW_UPDATE is sent.
1166   EXPECT_CALL(*session_, SendWindowUpdate(_, _));
1167   EXPECT_CALL(*connection_, SendControlFrame(_));
1168   QuicStreamFrame frame3(GetNthClientInitiatedBidirectionalId(0), false,
1169                          body.length() + header_length,
1170                          absl::string_view(data2));
1171   stream_->OnStreamFrame(frame3);
1172 }
1173 
1174 // Tests that on if the peer sends too much data (i.e. violates the flow control
1175 // protocol), then we terminate the connection.
TEST_P(QuicSpdyStreamTest,StreamFlowControlViolation)1176 TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) {
1177   // Stream should not process data, so that data gets buffered in the
1178   // sequencer, triggering flow control limits.
1179   Initialize(!kShouldProcessData);
1180 
1181   // Set a small flow control limit.
1182   const uint64_t kWindow = 50;
1183   QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow);
1184 
1185   ProcessHeaders(false, headers_);
1186 
1187   // Receive data to overflow the window, violating flow control.
1188   std::string body(kWindow + 1, 'a');
1189   std::string data = UsesHttp3() ? DataFrame(body) : body;
1190   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
1191                         absl::string_view(data));
1192   EXPECT_CALL(*connection_,
1193               CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
1194   stream_->OnStreamFrame(frame);
1195 }
1196 
TEST_P(QuicSpdyStreamTest,TestHandlingQuicRstStreamNoError)1197 TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) {
1198   Initialize(kShouldProcessData);
1199   ProcessHeaders(false, headers_);
1200 
1201   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
1202 
1203   stream_->OnStreamReset(QuicRstStreamFrame(
1204       kInvalidControlFrameId, stream_->id(), QUIC_STREAM_NO_ERROR, 0));
1205 
1206   if (UsesHttp3()) {
1207     // RESET_STREAM should close the read side but not the write side.
1208     EXPECT_TRUE(stream_->read_side_closed());
1209     EXPECT_FALSE(stream_->write_side_closed());
1210   } else {
1211     EXPECT_TRUE(stream_->write_side_closed());
1212     EXPECT_FALSE(stream_->reading_stopped());
1213   }
1214 }
1215 
1216 // Tests that on if the peer sends too much data (i.e. violates the flow control
1217 // protocol), at the connection level (rather than the stream level) then we
1218 // terminate the connection.
TEST_P(QuicSpdyStreamTest,ConnectionFlowControlViolation)1219 TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) {
1220   // Stream should not process data, so that data gets buffered in the
1221   // sequencer, triggering flow control limits.
1222   Initialize(!kShouldProcessData);
1223 
1224   // Set a small flow control window on streams, and connection.
1225   const uint64_t kStreamWindow = 50;
1226   const uint64_t kConnectionWindow = 10;
1227   QuicStreamPeer::SetReceiveWindowOffset(stream_, kStreamWindow);
1228   QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
1229                                                  kConnectionWindow);
1230 
1231   ProcessHeaders(false, headers_);
1232 
1233   // Send enough data to overflow the connection level flow control window.
1234   std::string body(kConnectionWindow + 1, 'a');
1235   std::string data = UsesHttp3() ? DataFrame(body) : body;
1236 
1237   EXPECT_LT(data.size(), kStreamWindow);
1238   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), false, 0,
1239                         absl::string_view(data));
1240 
1241   EXPECT_CALL(*connection_,
1242               CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
1243   stream_->OnStreamFrame(frame);
1244 }
1245 
1246 // An attempt to write a FIN with no data should not be flow control blocked,
1247 // even if the send window is 0.
TEST_P(QuicSpdyStreamTest,StreamFlowControlFinNotBlocked)1248 TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) {
1249   Initialize(kShouldProcessData);
1250 
1251   // Set a flow control limit of zero.
1252   QuicStreamPeer::SetReceiveWindowOffset(stream_, 0);
1253 
1254   // Send a frame with a FIN but no data. This should not be blocked.
1255   std::string body = "";
1256   bool fin = true;
1257 
1258   EXPECT_CALL(*session_,
1259               SendBlocked(GetNthClientInitiatedBidirectionalId(0), _))
1260       .Times(0);
1261   EXPECT_CALL(*session_, WritevData(_, 0, _, FIN, _, _));
1262 
1263   stream_->WriteOrBufferBody(body, fin);
1264 }
1265 
1266 // Test that receiving trailing headers from the peer via OnStreamHeaderList()
1267 // works, and can be read from the stream and consumed.
TEST_P(QuicSpdyStreamTest,ReceivingTrailersViaHeaderList)1268 TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) {
1269   Initialize(kShouldProcessData);
1270 
1271   // Receive initial headers.
1272   size_t total_bytes = 0;
1273   QuicHeaderList headers;
1274   for (const auto& p : headers_) {
1275     headers.OnHeader(p.first, p.second);
1276     total_bytes += p.first.size() + p.second.size();
1277   }
1278 
1279   stream_->OnStreamHeadersPriority(
1280       spdy::SpdyStreamPrecedence(kV3HighestPriority));
1281   stream_->OnStreamHeaderList(/*fin=*/false, total_bytes, headers);
1282   stream_->ConsumeHeaderList();
1283 
1284   // Receive trailing headers.
1285   Http2HeaderBlock trailers_block;
1286   trailers_block["key1"] = "value1";
1287   trailers_block["key2"] = "value2";
1288   trailers_block["key3"] = "value3";
1289   Http2HeaderBlock trailers_block_with_final_offset = trailers_block.Clone();
1290   if (!UsesHttp3()) {
1291     // :final-offset pseudo-header is only added if trailers are sent
1292     // on the headers stream.
1293     trailers_block_with_final_offset[kFinalOffsetHeaderKey] = "0";
1294   }
1295   total_bytes = 0;
1296   QuicHeaderList trailers;
1297   for (const auto& p : trailers_block_with_final_offset) {
1298     trailers.OnHeader(p.first, p.second);
1299     total_bytes += p.first.size() + p.second.size();
1300   }
1301   stream_->OnStreamHeaderList(/*fin=*/true, total_bytes, trailers);
1302 
1303   // The trailers should be decompressed, and readable from the stream.
1304   EXPECT_TRUE(stream_->trailers_decompressed());
1305   EXPECT_EQ(trailers_block, stream_->received_trailers());
1306 
1307   // IsDoneReading() returns false until trailers marked consumed.
1308   EXPECT_FALSE(stream_->IsDoneReading());
1309   stream_->MarkTrailersConsumed();
1310   EXPECT_TRUE(stream_->IsDoneReading());
1311 }
1312 
1313 // Test that when receiving trailing headers with an offset before response
1314 // body, stream is closed at the right offset.
TEST_P(QuicSpdyStreamTest,ReceivingTrailersWithOffset)1315 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithOffset) {
1316   // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
1317   // request/response stream.
1318   if (UsesHttp3()) {
1319     return;
1320   }
1321 
1322   Initialize(kShouldProcessData);
1323 
1324   // Receive initial headers.
1325   QuicHeaderList headers = ProcessHeaders(false, headers_);
1326   stream_->ConsumeHeaderList();
1327 
1328   const std::string body = "this is the body";
1329   std::string data = UsesHttp3() ? DataFrame(body) : body;
1330 
1331   // Receive trailing headers.
1332   Http2HeaderBlock trailers_block;
1333   trailers_block["key1"] = "value1";
1334   trailers_block["key2"] = "value2";
1335   trailers_block["key3"] = "value3";
1336   trailers_block[kFinalOffsetHeaderKey] = absl::StrCat(data.size());
1337 
1338   QuicHeaderList trailers = ProcessHeaders(true, trailers_block);
1339 
1340   // The trailers should be decompressed, and readable from the stream.
1341   EXPECT_TRUE(stream_->trailers_decompressed());
1342 
1343   // The final offset trailer will be consumed by QUIC.
1344   trailers_block.erase(kFinalOffsetHeaderKey);
1345   EXPECT_EQ(trailers_block, stream_->received_trailers());
1346 
1347   // Consuming the trailers erases them from the stream.
1348   stream_->MarkTrailersConsumed();
1349   EXPECT_TRUE(stream_->FinishedReadingTrailers());
1350 
1351   EXPECT_FALSE(stream_->IsDoneReading());
1352   // Receive and consume body.
1353   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/false,
1354                         0, data);
1355   stream_->OnStreamFrame(frame);
1356   EXPECT_EQ(body, stream_->data());
1357   EXPECT_TRUE(stream_->IsDoneReading());
1358 }
1359 
1360 // Test that receiving trailers without a final offset field is an error.
TEST_P(QuicSpdyStreamTest,ReceivingTrailersWithoutOffset)1361 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) {
1362   // kFinalOffsetHeaderKey is not used when HEADERS are sent on the
1363   // request/response stream.
1364   if (UsesHttp3()) {
1365     return;
1366   }
1367 
1368   Initialize(kShouldProcessData);
1369 
1370   // Receive initial headers.
1371   ProcessHeaders(false, headers_);
1372   stream_->ConsumeHeaderList();
1373 
1374   // Receive trailing headers, without kFinalOffsetHeaderKey.
1375   Http2HeaderBlock trailers_block;
1376   trailers_block["key1"] = "value1";
1377   trailers_block["key2"] = "value2";
1378   trailers_block["key3"] = "value3";
1379   auto trailers = AsHeaderList(trailers_block);
1380 
1381   // Verify that the trailers block didn't contain a final offset.
1382   EXPECT_EQ("", trailers_block[kFinalOffsetHeaderKey].as_string());
1383 
1384   // Receipt of the malformed trailers will close the connection.
1385   EXPECT_CALL(*connection_,
1386               CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1387       .Times(1);
1388   stream_->OnStreamHeaderList(/*fin=*/true,
1389                               trailers.uncompressed_header_bytes(), trailers);
1390 }
1391 
1392 // Test that received Trailers must always have the FIN set.
TEST_P(QuicSpdyStreamTest,ReceivingTrailersWithoutFin)1393 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutFin) {
1394   // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
1395   // HEADERS frame.
1396   if (UsesHttp3()) {
1397     return;
1398   }
1399 
1400   Initialize(kShouldProcessData);
1401 
1402   // Receive initial headers.
1403   auto headers = AsHeaderList(headers_);
1404   stream_->OnStreamHeaderList(/*fin=*/false,
1405                               headers.uncompressed_header_bytes(), headers);
1406   stream_->ConsumeHeaderList();
1407 
1408   // Receive trailing headers with FIN deliberately set to false.
1409   Http2HeaderBlock trailers_block;
1410   trailers_block["foo"] = "bar";
1411   auto trailers = AsHeaderList(trailers_block);
1412 
1413   EXPECT_CALL(*connection_,
1414               CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1415       .Times(1);
1416   stream_->OnStreamHeaderList(/*fin=*/false,
1417                               trailers.uncompressed_header_bytes(), trailers);
1418 }
1419 
TEST_P(QuicSpdyStreamTest,ReceivingTrailersAfterHeadersWithFin)1420 TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterHeadersWithFin) {
1421   // If headers are received with a FIN, no trailers should then arrive.
1422   Initialize(kShouldProcessData);
1423 
1424   // If HEADERS frames are sent on the request/response stream, then the
1425   // sequencer will signal an error if any stream data arrives after a FIN,
1426   // so QuicSpdyStream does not need to.
1427   if (UsesHttp3()) {
1428     return;
1429   }
1430 
1431   // Receive initial headers with FIN set.
1432   ProcessHeaders(true, headers_);
1433   stream_->ConsumeHeaderList();
1434 
1435   // Receive trailing headers after FIN already received.
1436   Http2HeaderBlock trailers_block;
1437   trailers_block["foo"] = "bar";
1438   EXPECT_CALL(*connection_,
1439               CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1440       .Times(1);
1441   ProcessHeaders(true, trailers_block);
1442 }
1443 
1444 // If body data are received with a FIN, no trailers should then arrive.
TEST_P(QuicSpdyStreamTest,ReceivingTrailersAfterBodyWithFin)1445 TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) {
1446   // If HEADERS frames are sent on the request/response stream,
1447   // then the sequencer will block them from reaching QuicSpdyStream
1448   // after the stream is closed.
1449   if (UsesHttp3()) {
1450     return;
1451   }
1452 
1453   Initialize(kShouldProcessData);
1454 
1455   // Receive initial headers without FIN set.
1456   ProcessHeaders(false, headers_);
1457   stream_->ConsumeHeaderList();
1458 
1459   // Receive body data, with FIN.
1460   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
1461                         0, "body");
1462   stream_->OnStreamFrame(frame);
1463 
1464   // Receive trailing headers after FIN already received.
1465   Http2HeaderBlock trailers_block;
1466   trailers_block["foo"] = "bar";
1467   EXPECT_CALL(*connection_,
1468               CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _))
1469       .Times(1);
1470   ProcessHeaders(true, trailers_block);
1471 }
1472 
TEST_P(QuicSpdyStreamTest,ClosingStreamWithNoTrailers)1473 TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) {
1474   // Verify that a stream receiving headers, body, and no trailers is correctly
1475   // marked as done reading on consumption of headers and body.
1476   Initialize(kShouldProcessData);
1477 
1478   // Receive and consume initial headers with FIN not set.
1479   auto h = AsHeaderList(headers_);
1480   stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h);
1481   stream_->ConsumeHeaderList();
1482 
1483   // Receive and consume body with FIN set, and no trailers.
1484   std::string body(1024, 'x');
1485   std::string data = UsesHttp3() ? DataFrame(body) : body;
1486 
1487   QuicStreamFrame frame(GetNthClientInitiatedBidirectionalId(0), /*fin=*/true,
1488                         0, data);
1489   stream_->OnStreamFrame(frame);
1490 
1491   EXPECT_TRUE(stream_->IsDoneReading());
1492 }
1493 
1494 // Test that writing trailers will send a FIN, as Trailers are the last thing to
1495 // be sent on a stream.
TEST_P(QuicSpdyStreamTest,WritingTrailersSendsAFin)1496 TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) {
1497   Initialize(kShouldProcessData);
1498 
1499   if (UsesHttp3()) {
1500     // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
1501     // Four writes on the request stream: HEADERS frame header and payload both
1502     // for headers and trailers.
1503     EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
1504   }
1505 
1506   // Write the initial headers, without a FIN.
1507   EXPECT_CALL(*stream_, WriteHeadersMock(false));
1508   stream_->WriteHeaders(Http2HeaderBlock(), /*fin=*/false, nullptr);
1509 
1510   // Writing trailers implicitly sends a FIN.
1511   Http2HeaderBlock trailers;
1512   trailers["trailer key"] = "trailer value";
1513   EXPECT_CALL(*stream_, WriteHeadersMock(true));
1514   stream_->WriteTrailers(std::move(trailers), nullptr);
1515   EXPECT_TRUE(stream_->fin_sent());
1516 }
1517 
TEST_P(QuicSpdyStreamTest,DoNotSendPriorityUpdateWithDefaultUrgency)1518 TEST_P(QuicSpdyStreamTest, DoNotSendPriorityUpdateWithDefaultUrgency) {
1519   if (!UsesHttp3()) {
1520     return;
1521   }
1522 
1523   InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
1524   StrictMock<MockHttp3DebugVisitor> debug_visitor;
1525   session_->set_debug_visitor(&debug_visitor);
1526 
1527   // Four writes on the request stream: HEADERS frame header and payload both
1528   // for headers and trailers.
1529   EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(2);
1530 
1531   // No PRIORITY_UPDATE frames on the control stream,
1532   // because the stream has default priority.
1533   auto send_control_stream =
1534       QuicSpdySessionPeer::GetSendControlStream(session_.get());
1535   EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _))
1536       .Times(0);
1537 
1538   // Write the initial headers, without a FIN.
1539   EXPECT_CALL(*stream_, WriteHeadersMock(false));
1540   EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
1541   stream_->WriteHeaders(Http2HeaderBlock(), /*fin=*/false, nullptr);
1542 
1543   // Writing trailers implicitly sends a FIN.
1544   Http2HeaderBlock trailers;
1545   trailers["trailer key"] = "trailer value";
1546   EXPECT_CALL(*stream_, WriteHeadersMock(true));
1547   EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
1548   stream_->WriteTrailers(std::move(trailers), nullptr);
1549   EXPECT_TRUE(stream_->fin_sent());
1550 }
1551 
TEST_P(QuicSpdyStreamTest,ChangePriority)1552 TEST_P(QuicSpdyStreamTest, ChangePriority) {
1553   if (!UsesHttp3()) {
1554     return;
1555   }
1556 
1557   InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
1558   StrictMock<MockHttp3DebugVisitor> debug_visitor;
1559   session_->set_debug_visitor(&debug_visitor);
1560 
1561   EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(1);
1562   EXPECT_CALL(*stream_, WriteHeadersMock(false));
1563   EXPECT_CALL(debug_visitor, OnHeadersFrameSent(stream_->id(), _));
1564   stream_->WriteHeaders(Http2HeaderBlock(), /*fin=*/false, nullptr);
1565   testing::Mock::VerifyAndClearExpectations(&debug_visitor);
1566 
1567   // PRIORITY_UPDATE frame on the control stream.
1568   auto send_control_stream =
1569       QuicSpdySessionPeer::GetSendControlStream(session_.get());
1570   EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
1571   PriorityUpdateFrame priority_update1{stream_->id(), "u=0"};
1572   EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameSent(priority_update1));
1573   const HttpStreamPriority priority1{kV3HighestPriority,
1574                                      HttpStreamPriority::kDefaultIncremental};
1575   stream_->SetPriority(QuicStreamPriority(priority1));
1576   testing::Mock::VerifyAndClearExpectations(&debug_visitor);
1577 
1578   // Send another PRIORITY_UPDATE frame with incremental flag set to true.
1579   EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
1580   PriorityUpdateFrame priority_update2{stream_->id(), "u=2, i"};
1581   EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameSent(priority_update2));
1582   const HttpStreamPriority priority2{2, true};
1583   stream_->SetPriority(QuicStreamPriority(priority2));
1584   testing::Mock::VerifyAndClearExpectations(&debug_visitor);
1585 
1586   // Calling SetPriority() with the same priority does not trigger sending
1587   // another PRIORITY_UPDATE frame.
1588   stream_->SetPriority(QuicStreamPriority(priority2));
1589 }
1590 
TEST_P(QuicSpdyStreamTest,ChangePriorityBeforeWritingHeaders)1591 TEST_P(QuicSpdyStreamTest, ChangePriorityBeforeWritingHeaders) {
1592   if (!UsesHttp3()) {
1593     return;
1594   }
1595 
1596   InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
1597 
1598   // PRIORITY_UPDATE frame sent on the control stream as soon as SetPriority()
1599   // is called, before HEADERS frame is sent.
1600   auto send_control_stream =
1601       QuicSpdySessionPeer::GetSendControlStream(session_.get());
1602   EXPECT_CALL(*session_, WritevData(send_control_stream->id(), _, _, _, _, _));
1603 
1604   stream_->SetPriority(QuicStreamPriority(HttpStreamPriority{
1605       kV3HighestPriority, HttpStreamPriority::kDefaultIncremental}));
1606   testing::Mock::VerifyAndClearExpectations(session_.get());
1607 
1608   // Two writes on the request stream: HEADERS frame header and payload.
1609   // PRIORITY_UPDATE frame is not sent this time, because one is already sent.
1610   EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(1);
1611   EXPECT_CALL(*stream_, WriteHeadersMock(true));
1612   stream_->WriteHeaders(Http2HeaderBlock(), /*fin=*/true, nullptr);
1613 }
1614 
1615 // Test that when writing trailers, the trailers that are actually sent to the
1616 // peer contain the final offset field indicating last byte of data.
TEST_P(QuicSpdyStreamTest,WritingTrailersFinalOffset)1617 TEST_P(QuicSpdyStreamTest, WritingTrailersFinalOffset) {
1618   Initialize(kShouldProcessData);
1619 
1620   if (UsesHttp3()) {
1621     // In this case, TestStream::WriteHeadersImpl() does not prevent writes.
1622     // HEADERS frame header and payload on the request stream.
1623     EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _)).Times(1);
1624   }
1625 
1626   // Write the initial headers.
1627   EXPECT_CALL(*stream_, WriteHeadersMock(false));
1628   stream_->WriteHeaders(Http2HeaderBlock(), /*fin=*/false, nullptr);
1629 
1630   // Write non-zero body data to force a non-zero final offset.
1631   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
1632   std::string body(1024, 'x');  // 1 kB
1633   QuicByteCount header_length = 0;
1634   if (UsesHttp3()) {
1635     header_length = HttpEncoder::SerializeDataFrameHeader(
1636                         body.length(), quiche::SimpleBufferAllocator::Get())
1637                         .size();
1638   }
1639 
1640   stream_->WriteOrBufferBody(body, false);
1641 
1642   // The final offset field in the trailing headers is populated with the
1643   // number of body bytes written (including queued bytes).
1644   Http2HeaderBlock trailers;
1645   trailers["trailer key"] = "trailer value";
1646 
1647   Http2HeaderBlock expected_trailers(trailers.Clone());
1648   // :final-offset pseudo-header is only added if trailers are sent
1649   // on the headers stream.
1650   if (!UsesHttp3()) {
1651     expected_trailers[kFinalOffsetHeaderKey] =
1652         absl::StrCat(body.length() + header_length);
1653   }
1654 
1655   EXPECT_CALL(*stream_, WriteHeadersMock(true));
1656   stream_->WriteTrailers(std::move(trailers), nullptr);
1657   EXPECT_EQ(expected_trailers, stream_->saved_headers());
1658 }
1659 
1660 // Test that if trailers are written after all other data has been written
1661 // (headers and body), that this closes the stream for writing.
TEST_P(QuicSpdyStreamTest,WritingTrailersClosesWriteSide)1662 TEST_P(QuicSpdyStreamTest, WritingTrailersClosesWriteSide) {
1663   Initialize(kShouldProcessData);
1664 
1665   // Expect data being written on the stream.  In addition to that, headers are
1666   // also written on the stream in case of IETF QUIC.
1667   EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
1668       .Times(AtLeast(1));
1669 
1670   // Write the initial headers.
1671   EXPECT_CALL(*stream_, WriteHeadersMock(false));
1672   stream_->WriteHeaders(Http2HeaderBlock(), /*fin=*/false, nullptr);
1673 
1674   // Write non-zero body data.
1675   const int kBodySize = 1 * 1024;  // 1 kB
1676   stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
1677   EXPECT_EQ(0u, stream_->BufferedDataBytes());
1678 
1679   // Headers and body have been fully written, there is no queued data. Writing
1680   // trailers marks the end of this stream, and thus the write side is closed.
1681   EXPECT_CALL(*stream_, WriteHeadersMock(true));
1682   stream_->WriteTrailers(Http2HeaderBlock(), nullptr);
1683   EXPECT_TRUE(stream_->write_side_closed());
1684 }
1685 
1686 // Test that the stream is not closed for writing when trailers are sent while
1687 // there are still body bytes queued.
TEST_P(QuicSpdyStreamTest,WritingTrailersWithQueuedBytes)1688 TEST_P(QuicSpdyStreamTest, WritingTrailersWithQueuedBytes) {
1689   // This test exercises sending trailers on the headers stream while data is
1690   // still queued on the response/request stream.  In IETF QUIC, data and
1691   // trailers are sent on the same stream, so this test does not apply.
1692   if (UsesHttp3()) {
1693     return;
1694   }
1695 
1696   testing::InSequence seq;
1697   Initialize(kShouldProcessData);
1698 
1699   // Write the initial headers.
1700   EXPECT_CALL(*stream_, WriteHeadersMock(false));
1701   stream_->WriteHeaders(Http2HeaderBlock(), /*fin=*/false, nullptr);
1702 
1703   // Write non-zero body data, but only consume partially, ensuring queueing.
1704   const int kBodySize = 1 * 1024;  // 1 kB
1705   if (UsesHttp3()) {
1706     EXPECT_CALL(*session_, WritevData(_, 3, _, NO_FIN, _, _));
1707   }
1708   EXPECT_CALL(*session_, WritevData(_, kBodySize, _, NO_FIN, _, _))
1709       .WillOnce(Return(QuicConsumedData(kBodySize - 1, false)));
1710   stream_->WriteOrBufferBody(std::string(kBodySize, 'x'), false);
1711   EXPECT_EQ(1u, stream_->BufferedDataBytes());
1712 
1713   // Writing trailers will send a FIN, but not close the write side of the
1714   // stream as there are queued bytes.
1715   EXPECT_CALL(*stream_, WriteHeadersMock(true));
1716   stream_->WriteTrailers(Http2HeaderBlock(), nullptr);
1717   EXPECT_TRUE(stream_->fin_sent());
1718   EXPECT_FALSE(stream_->write_side_closed());
1719 
1720   // Writing the queued bytes will close the write side of the stream.
1721   EXPECT_CALL(*session_, WritevData(_, 1, _, NO_FIN, _, _));
1722   stream_->OnCanWrite();
1723   EXPECT_TRUE(stream_->write_side_closed());
1724 }
1725 
1726 // Test that it is not possible to write Trailers after a FIN has been sent.
TEST_P(QuicSpdyStreamTest,WritingTrailersAfterFIN)1727 TEST_P(QuicSpdyStreamTest, WritingTrailersAfterFIN) {
1728   // In IETF QUIC, there is no such thing as FIN flag on HTTP/3 frames like the
1729   // HEADERS frame.
1730   if (UsesHttp3()) {
1731     return;
1732   }
1733 
1734   Initialize(kShouldProcessData);
1735 
1736   // Write the initial headers, with a FIN.
1737   EXPECT_CALL(*stream_, WriteHeadersMock(true));
1738   stream_->WriteHeaders(Http2HeaderBlock(), /*fin=*/true, nullptr);
1739   EXPECT_TRUE(stream_->fin_sent());
1740 
1741   // Writing Trailers should fail, as the FIN has already been sent.
1742   // populated with the number of body bytes written.
1743   EXPECT_QUIC_BUG(stream_->WriteTrailers(Http2HeaderBlock(), nullptr),
1744                   "Trailers cannot be sent after a FIN");
1745 }
1746 
TEST_P(QuicSpdyStreamTest,HeaderStreamNotiferCorrespondingSpdyStream)1747 TEST_P(QuicSpdyStreamTest, HeaderStreamNotiferCorrespondingSpdyStream) {
1748   // There is no headers stream if QPACK is used.
1749   if (UsesHttp3()) {
1750     return;
1751   }
1752 
1753   const char kHeader1[] = "Header1";
1754   const char kHeader2[] = "Header2";
1755   const char kBody1[] = "Test1";
1756   const char kBody2[] = "Test2";
1757 
1758   Initialize(kShouldProcessData);
1759   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
1760   testing::InSequence s;
1761   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener1(
1762       new MockAckListener());
1763   quiche::QuicheReferenceCountedPointer<MockAckListener> ack_listener2(
1764       new MockAckListener());
1765   stream_->set_ack_listener(ack_listener1);
1766   stream2_->set_ack_listener(ack_listener2);
1767 
1768   session_->headers_stream()->WriteOrBufferData(kHeader1, false, ack_listener1);
1769   stream_->WriteOrBufferBody(kBody1, true);
1770 
1771   session_->headers_stream()->WriteOrBufferData(kHeader2, false, ack_listener2);
1772   stream2_->WriteOrBufferBody(kBody2, false);
1773 
1774   QuicStreamFrame frame1(
1775       QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 0,
1776       kHeader1);
1777 
1778   std::string data1 = UsesHttp3() ? DataFrame(kBody1) : kBody1;
1779   QuicStreamFrame frame2(stream_->id(), true, 0, data1);
1780   QuicStreamFrame frame3(
1781       QuicUtils::GetHeadersStreamId(connection_->transport_version()), false, 7,
1782       kHeader2);
1783   std::string data2 = UsesHttp3() ? DataFrame(kBody2) : kBody2;
1784   QuicStreamFrame frame4(stream2_->id(), false, 0, data2);
1785 
1786   EXPECT_CALL(*ack_listener1, OnPacketRetransmitted(7));
1787   session_->OnStreamFrameRetransmitted(frame1);
1788 
1789   EXPECT_CALL(*ack_listener1, OnPacketAcked(7, _));
1790   EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame1), QuicTime::Delta::Zero(),
1791                                      QuicTime::Zero()));
1792   EXPECT_CALL(*ack_listener1, OnPacketAcked(5, _));
1793   EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
1794                                      QuicTime::Zero()));
1795   EXPECT_CALL(*ack_listener2, OnPacketAcked(7, _));
1796   EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
1797                                      QuicTime::Zero()));
1798   EXPECT_CALL(*ack_listener2, OnPacketAcked(5, _));
1799   EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame4), QuicTime::Delta::Zero(),
1800                                      QuicTime::Zero()));
1801 }
1802 
TEST_P(QuicSpdyStreamTest,OnPriorityFrame)1803 TEST_P(QuicSpdyStreamTest, OnPriorityFrame) {
1804   Initialize(kShouldProcessData);
1805   stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
1806   EXPECT_EQ(QuicStreamPriority(HttpStreamPriority{
1807                 kV3HighestPriority, HttpStreamPriority::kDefaultIncremental}),
1808             stream_->priority());
1809 }
1810 
TEST_P(QuicSpdyStreamTest,OnPriorityFrameAfterSendingData)1811 TEST_P(QuicSpdyStreamTest, OnPriorityFrameAfterSendingData) {
1812   Initialize(kShouldProcessData);
1813   testing::InSequence seq;
1814 
1815   if (UsesHttp3()) {
1816     EXPECT_CALL(*session_, WritevData(_, 2, _, NO_FIN, _, _));
1817   }
1818   EXPECT_CALL(*session_, WritevData(_, 4, _, FIN, _, _));
1819   stream_->WriteOrBufferBody("data", true);
1820   stream_->OnPriorityFrame(spdy::SpdyStreamPrecedence(kV3HighestPriority));
1821   EXPECT_EQ(QuicStreamPriority(HttpStreamPriority{
1822                 kV3HighestPriority, HttpStreamPriority::kDefaultIncremental}),
1823             stream_->priority());
1824 }
1825 
TEST_P(QuicSpdyStreamTest,SetPriorityBeforeUpdateStreamPriority)1826 TEST_P(QuicSpdyStreamTest, SetPriorityBeforeUpdateStreamPriority) {
1827   MockQuicConnection* connection = new StrictMock<MockQuicConnection>(
1828       &helper_, &alarm_factory_, Perspective::IS_SERVER,
1829       SupportedVersions(GetParam()));
1830   std::unique_ptr<TestMockUpdateStreamSession> session(
1831       new StrictMock<TestMockUpdateStreamSession>(connection));
1832   auto stream =
1833       new StrictMock<TestStream>(GetNthClientInitiatedBidirectionalStreamId(
1834                                      session->transport_version(), 0),
1835                                  session.get(),
1836                                  /*should_process_data=*/true);
1837   session->ActivateStream(absl::WrapUnique(stream));
1838 
1839   // QuicSpdyStream::SetPriority() should eventually call UpdateStreamPriority()
1840   // on the session. Make sure stream->priority() returns the updated priority
1841   // if called within UpdateStreamPriority(). This expectation is enforced in
1842   // TestMockUpdateStreamSession::UpdateStreamPriority().
1843   session->SetExpectedStream(stream);
1844   session->SetExpectedPriority(HttpStreamPriority{kV3HighestPriority});
1845   stream->SetPriority(
1846       QuicStreamPriority(HttpStreamPriority{kV3HighestPriority}));
1847 
1848   session->SetExpectedPriority(HttpStreamPriority{kV3LowestPriority});
1849   stream->SetPriority(
1850       QuicStreamPriority(HttpStreamPriority{kV3LowestPriority}));
1851 }
1852 
TEST_P(QuicSpdyStreamTest,StreamWaitsForAcks)1853 TEST_P(QuicSpdyStreamTest, StreamWaitsForAcks) {
1854   Initialize(kShouldProcessData);
1855   quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
1856       new StrictMock<MockAckListener>);
1857   stream_->set_ack_listener(mock_ack_listener);
1858   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
1859   // Stream is not waiting for acks initially.
1860   EXPECT_FALSE(stream_->IsWaitingForAcks());
1861   EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1862 
1863   // Send kData1.
1864   stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1865   EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1866   EXPECT_TRUE(stream_->IsWaitingForAcks());
1867   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
1868   QuicByteCount newly_acked_length = 0;
1869   EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
1870                                           QuicTime::Zero(),
1871                                           &newly_acked_length));
1872   // Stream is not waiting for acks as all sent data is acked.
1873   EXPECT_FALSE(stream_->IsWaitingForAcks());
1874   EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1875 
1876   // Send kData2.
1877   stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1878   EXPECT_TRUE(stream_->IsWaitingForAcks());
1879   EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1880   // Send FIN.
1881   stream_->WriteOrBufferData("", true, nullptr);
1882   // Fin only frame is not stored in send buffer.
1883   EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1884 
1885   // kData2 is retransmitted.
1886   EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(9));
1887   stream_->OnStreamFrameRetransmitted(9, 9, false);
1888 
1889   // kData2 is acked.
1890   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
1891   EXPECT_TRUE(stream_->OnStreamFrameAcked(9, 9, false, QuicTime::Delta::Zero(),
1892                                           QuicTime::Zero(),
1893                                           &newly_acked_length));
1894   // Stream is waiting for acks as FIN is not acked.
1895   EXPECT_TRUE(stream_->IsWaitingForAcks());
1896   EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1897 
1898   // FIN is acked.
1899   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
1900   EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 0, true, QuicTime::Delta::Zero(),
1901                                           QuicTime::Zero(),
1902                                           &newly_acked_length));
1903   EXPECT_FALSE(stream_->IsWaitingForAcks());
1904   EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1905 }
1906 
TEST_P(QuicSpdyStreamTest,StreamDataGetAckedMultipleTimes)1907 TEST_P(QuicSpdyStreamTest, StreamDataGetAckedMultipleTimes) {
1908   Initialize(kShouldProcessData);
1909   quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
1910       new StrictMock<MockAckListener>);
1911   stream_->set_ack_listener(mock_ack_listener);
1912   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
1913   // Send [0, 27) and fin.
1914   stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1915   stream_->WriteOrBufferData("FooAndBar", false, nullptr);
1916   stream_->WriteOrBufferData("FooAndBar", true, nullptr);
1917 
1918   // Ack [0, 9), [5, 22) and [18, 26)
1919   // Verify [0, 9) 9 bytes are acked.
1920   QuicByteCount newly_acked_length = 0;
1921   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(9, _));
1922   EXPECT_TRUE(stream_->OnStreamFrameAcked(0, 9, false, QuicTime::Delta::Zero(),
1923                                           QuicTime::Zero(),
1924                                           &newly_acked_length));
1925   EXPECT_EQ(2u, QuicStreamPeer::SendBuffer(stream_).size());
1926   // Verify [9, 22) 13 bytes are acked.
1927   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(13, _));
1928   EXPECT_TRUE(stream_->OnStreamFrameAcked(5, 17, false, QuicTime::Delta::Zero(),
1929                                           QuicTime::Zero(),
1930                                           &newly_acked_length));
1931   EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1932   // Verify [22, 26) 4 bytes are acked.
1933   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(4, _));
1934   EXPECT_TRUE(stream_->OnStreamFrameAcked(18, 8, false, QuicTime::Delta::Zero(),
1935                                           QuicTime::Zero(),
1936                                           &newly_acked_length));
1937   EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
1938   EXPECT_TRUE(stream_->IsWaitingForAcks());
1939 
1940   // Ack [0, 27).
1941   // Verify [26, 27) 1 byte is acked.
1942   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(1, _));
1943   EXPECT_TRUE(stream_->OnStreamFrameAcked(26, 1, false, QuicTime::Delta::Zero(),
1944                                           QuicTime::Zero(),
1945                                           &newly_acked_length));
1946   EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1947   EXPECT_TRUE(stream_->IsWaitingForAcks());
1948 
1949   // Ack Fin. Verify OnPacketAcked is called.
1950   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
1951   EXPECT_TRUE(stream_->OnStreamFrameAcked(27, 0, true, QuicTime::Delta::Zero(),
1952                                           QuicTime::Zero(),
1953                                           &newly_acked_length));
1954   EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1955   EXPECT_FALSE(stream_->IsWaitingForAcks());
1956 
1957   // Ack [10, 27) and fin.
1958   // No new data is acked, verify OnPacketAcked is not called.
1959   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(_, _)).Times(0);
1960   EXPECT_FALSE(
1961       stream_->OnStreamFrameAcked(10, 17, true, QuicTime::Delta::Zero(),
1962                                   QuicTime::Zero(), &newly_acked_length));
1963   EXPECT_EQ(0u, QuicStreamPeer::SendBuffer(stream_).size());
1964   EXPECT_FALSE(stream_->IsWaitingForAcks());
1965 }
1966 
1967 // HTTP/3 only.
TEST_P(QuicSpdyStreamTest,HeadersAckNotReportedWriteOrBufferBody)1968 TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteOrBufferBody) {
1969   if (!UsesHttp3()) {
1970     return;
1971   }
1972 
1973   Initialize(kShouldProcessData);
1974   quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
1975       new StrictMock<MockAckListener>);
1976   stream_->set_ack_listener(mock_ack_listener);
1977   std::string body = "Test1";
1978   std::string body2(100, 'x');
1979 
1980   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
1981   stream_->WriteOrBufferBody(body, false);
1982   stream_->WriteOrBufferBody(body2, true);
1983 
1984   quiche::QuicheBuffer header = HttpEncoder::SerializeDataFrameHeader(
1985       body.length(), quiche::SimpleBufferAllocator::Get());
1986   quiche::QuicheBuffer header2 = HttpEncoder::SerializeDataFrameHeader(
1987       body2.length(), quiche::SimpleBufferAllocator::Get());
1988 
1989   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body.length(), _));
1990   QuicStreamFrame frame(stream_->id(), false, 0,
1991                         absl::StrCat(header.AsStringView(), body));
1992   EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
1993                                      QuicTime::Zero()));
1994 
1995   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(0, _));
1996   QuicStreamFrame frame2(stream_->id(), false, header.size() + body.length(),
1997                          header2.AsStringView());
1998   EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame2), QuicTime::Delta::Zero(),
1999                                      QuicTime::Zero()));
2000 
2001   EXPECT_CALL(*mock_ack_listener, OnPacketAcked(body2.length(), _));
2002   QuicStreamFrame frame3(stream_->id(), true,
2003                          header.size() + body.length() + header2.size(), body2);
2004   EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame3), QuicTime::Delta::Zero(),
2005                                      QuicTime::Zero()));
2006 
2007   EXPECT_TRUE(
2008       QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
2009 }
2010 
2011 // HTTP/3 only.
TEST_P(QuicSpdyStreamTest,HeadersAckNotReportedWriteBodySlices)2012 TEST_P(QuicSpdyStreamTest, HeadersAckNotReportedWriteBodySlices) {
2013   if (!UsesHttp3()) {
2014     return;
2015   }
2016 
2017   Initialize(kShouldProcessData);
2018   quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
2019       new StrictMock<MockAckListener>);
2020   stream_->set_ack_listener(mock_ack_listener);
2021   std::string body1 = "Test1";
2022   std::string body2(100, 'x');
2023   struct iovec body1_iov = {const_cast<char*>(body1.data()), body1.length()};
2024   struct iovec body2_iov = {const_cast<char*>(body2.data()), body2.length()};
2025   quiche::QuicheMemSliceStorage storage(
2026       &body1_iov, 1, helper_.GetStreamSendBufferAllocator(), 1024);
2027   quiche::QuicheMemSliceStorage storage2(
2028       &body2_iov, 1, helper_.GetStreamSendBufferAllocator(), 1024);
2029   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
2030   stream_->WriteBodySlices(storage.ToSpan(), false);
2031   stream_->WriteBodySlices(storage2.ToSpan(), true);
2032 
2033   std::string data1 = DataFrame(body1);
2034   std::string data2 = DataFrame(body2);
2035 
2036   EXPECT_CALL(*mock_ack_listener,
2037               OnPacketAcked(body1.length() + body2.length(), _));
2038   QuicStreamFrame frame(stream_->id(), true, 0, data1 + data2);
2039   EXPECT_TRUE(session_->OnFrameAcked(QuicFrame(frame), QuicTime::Delta::Zero(),
2040                                      QuicTime::Zero()));
2041 
2042   EXPECT_TRUE(
2043       QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
2044 }
2045 
2046 // HTTP/3 only.
TEST_P(QuicSpdyStreamTest,HeaderBytesNotReportedOnRetransmission)2047 TEST_P(QuicSpdyStreamTest, HeaderBytesNotReportedOnRetransmission) {
2048   if (!UsesHttp3()) {
2049     return;
2050   }
2051 
2052   Initialize(kShouldProcessData);
2053   quiche::QuicheReferenceCountedPointer<MockAckListener> mock_ack_listener(
2054       new StrictMock<MockAckListener>);
2055   stream_->set_ack_listener(mock_ack_listener);
2056   std::string body1 = "Test1";
2057   std::string body2(100, 'x');
2058 
2059   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AtLeast(1));
2060   stream_->WriteOrBufferBody(body1, false);
2061   stream_->WriteOrBufferBody(body2, true);
2062 
2063   std::string data1 = DataFrame(body1);
2064   std::string data2 = DataFrame(body2);
2065 
2066   EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body1.length()));
2067   QuicStreamFrame frame(stream_->id(), false, 0, data1);
2068   session_->OnStreamFrameRetransmitted(frame);
2069 
2070   EXPECT_CALL(*mock_ack_listener, OnPacketRetransmitted(body2.length()));
2071   QuicStreamFrame frame2(stream_->id(), true, data1.length(), data2);
2072   session_->OnStreamFrameRetransmitted(frame2);
2073 
2074   EXPECT_FALSE(
2075       QuicSpdyStreamPeer::unacked_frame_headers_offsets(stream_).Empty());
2076 }
2077 
TEST_P(QuicSpdyStreamTest,HeadersFrameOnRequestStream)2078 TEST_P(QuicSpdyStreamTest, HeadersFrameOnRequestStream) {
2079   if (!UsesHttp3()) {
2080     return;
2081   }
2082 
2083   Initialize(kShouldProcessData);
2084 
2085   std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
2086   std::string data = DataFrame(kDataFramePayload);
2087   std::string trailers =
2088       HeadersFrame({std::make_pair("custom-key", "custom-value")});
2089 
2090   std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
2091   QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
2092   stream_->OnStreamFrame(frame);
2093 
2094   EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
2095 
2096   // QuicSpdyStream only calls OnBodyAvailable()
2097   // after the header list has been consumed.
2098   EXPECT_EQ("", stream_->data());
2099   stream_->ConsumeHeaderList();
2100   EXPECT_EQ(kDataFramePayload, stream_->data());
2101 
2102   EXPECT_THAT(stream_->received_trailers(),
2103               ElementsAre(Pair("custom-key", "custom-value")));
2104 }
2105 
TEST_P(QuicSpdyStreamTest,ProcessBodyAfterTrailers)2106 TEST_P(QuicSpdyStreamTest, ProcessBodyAfterTrailers) {
2107   if (!UsesHttp3()) {
2108     return;
2109   }
2110 
2111   Initialize(!kShouldProcessData);
2112 
2113   std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
2114   std::string data = DataFrame(kDataFramePayload);
2115 
2116   // A header block that will take more than one block of sequencer buffer.
2117   // This ensures that when the trailers are consumed, some buffer buckets will
2118   // be freed.
2119   Http2HeaderBlock trailers_block;
2120   trailers_block["key1"] = std::string(10000, 'x');
2121   std::string trailers = HeadersFrame(trailers_block);
2122 
2123   // Feed all three HTTP/3 frames in a single stream frame.
2124   std::string stream_frame_payload = absl::StrCat(headers, data, trailers);
2125   QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
2126   stream_->OnStreamFrame(frame);
2127 
2128   stream_->ConsumeHeaderList();
2129   stream_->MarkTrailersConsumed();
2130 
2131   EXPECT_TRUE(stream_->trailers_decompressed());
2132   EXPECT_EQ(trailers_block, stream_->received_trailers());
2133 
2134   EXPECT_TRUE(stream_->HasBytesToRead());
2135 
2136   // Consume data.
2137   char buffer[2048];
2138   struct iovec vec;
2139   vec.iov_base = buffer;
2140   vec.iov_len = ABSL_ARRAYSIZE(buffer);
2141   size_t bytes_read = stream_->Readv(&vec, 1);
2142   EXPECT_EQ(kDataFramePayload, absl::string_view(buffer, bytes_read));
2143 
2144   EXPECT_FALSE(stream_->HasBytesToRead());
2145 }
2146 
2147 // The test stream will receive a stream frame containing malformed headers and
2148 // normal body. Make sure the http decoder stops processing body after the
2149 // connection shuts down.
TEST_P(QuicSpdyStreamTest,MalformedHeadersStopHttpDecoder)2150 TEST_P(QuicSpdyStreamTest, MalformedHeadersStopHttpDecoder) {
2151   if (!UsesHttp3()) {
2152     return;
2153   }
2154 
2155   Initialize(kShouldProcessData);
2156   testing::InSequence s;
2157   connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
2158 
2159   // Random bad headers.
2160   std::string headers_bytes;
2161   ASSERT_TRUE(absl::HexStringToBytes("00002a94e7036261", &headers_bytes));
2162   std::string headers = HeadersFrame(headers_bytes);
2163   std::string data = DataFrame(kDataFramePayload);
2164 
2165   std::string stream_frame_payload = absl::StrCat(headers, data);
2166   QuicStreamFrame frame(stream_->id(), false, 0, stream_frame_payload);
2167 
2168   EXPECT_CALL(
2169       *connection_,
2170       CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
2171                       MatchesRegex("Error decoding headers on stream \\d+: "
2172                                    "Incomplete header block."),
2173                       _))
2174       .WillOnce(
2175           (Invoke([this](QuicErrorCode error, const std::string& error_details,
2176                          ConnectionCloseBehavior connection_close_behavior) {
2177             connection_->ReallyCloseConnection(error, error_details,
2178                                                connection_close_behavior);
2179           })));
2180   EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
2181   EXPECT_CALL(*session_, OnConnectionClosed(_, _))
2182       .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
2183                               ConnectionCloseSource source) {
2184         session_->ReallyOnConnectionClosed(frame, source);
2185       }));
2186   EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _)).Times(2);
2187   stream_->OnStreamFrame(frame);
2188 }
2189 
2190 // Regression test for https://crbug.com/1027895: a HEADERS frame triggers an
2191 // error in QuicSpdyStream::OnHeadersFramePayload().  This closes the
2192 // connection, freeing the buffer of QuicStreamSequencer.  Therefore
2193 // QuicStreamSequencer::MarkConsumed() must not be called from
2194 // QuicSpdyStream::OnHeadersFramePayload().
TEST_P(QuicSpdyStreamTest,DoNotMarkConsumedAfterQpackDecodingError)2195 TEST_P(QuicSpdyStreamTest, DoNotMarkConsumedAfterQpackDecodingError) {
2196   if (!UsesHttp3()) {
2197     return;
2198   }
2199 
2200   Initialize(kShouldProcessData);
2201   connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
2202 
2203   {
2204     testing::InSequence s;
2205     EXPECT_CALL(
2206         *connection_,
2207         CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
2208                         MatchesRegex("Error decoding headers on stream \\d+: "
2209                                      "Invalid relative index."),
2210                         _))
2211         .WillOnce((
2212             Invoke([this](QuicErrorCode error, const std::string& error_details,
2213                           ConnectionCloseBehavior connection_close_behavior) {
2214               connection_->ReallyCloseConnection(error, error_details,
2215                                                  connection_close_behavior);
2216             })));
2217     EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
2218     EXPECT_CALL(*session_, OnConnectionClosed(_, _))
2219         .WillOnce(Invoke([this](const QuicConnectionCloseFrame& frame,
2220                                 ConnectionCloseSource source) {
2221           session_->ReallyOnConnectionClosed(frame, source);
2222         }));
2223   }
2224   EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream_->id(), _, _));
2225   EXPECT_CALL(*session_, MaybeSendRstStreamFrame(stream2_->id(), _, _));
2226 
2227   // Invalid headers: Required Insert Count is zero, but the header block
2228   // contains a dynamic table reference.
2229   std::string headers_bytes;
2230   ASSERT_TRUE(absl::HexStringToBytes("000080", &headers_bytes));
2231   std::string headers = HeadersFrame(headers_bytes);
2232   QuicStreamFrame frame(stream_->id(), false, 0, headers);
2233   stream_->OnStreamFrame(frame);
2234 }
2235 
TEST_P(QuicSpdyStreamTest,ImmediateHeaderDecodingWithDynamicTableEntries)2236 TEST_P(QuicSpdyStreamTest, ImmediateHeaderDecodingWithDynamicTableEntries) {
2237   if (!UsesHttp3()) {
2238     return;
2239   }
2240 
2241   Initialize(kShouldProcessData);
2242   testing::InSequence s;
2243   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
2244   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2245   session_->set_debug_visitor(&debug_visitor);
2246 
2247   auto decoder_send_stream =
2248       QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
2249 
2250   // Deliver dynamic table entry to decoder.
2251   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
2252 
2253   // HEADERS frame referencing first dynamic table entry.
2254   std::string encoded_headers;
2255   ASSERT_TRUE(absl::HexStringToBytes("020080", &encoded_headers));
2256   std::string headers = HeadersFrame(encoded_headers);
2257   EXPECT_CALL(debug_visitor,
2258               OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
2259   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
2260     // Decoder stream type.
2261     EXPECT_CALL(*session_,
2262                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2263                            /* offset = */ 0, _, _, _));
2264     // Header acknowledgement.
2265     EXPECT_CALL(*session_,
2266                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2267                            /* offset = */ 1, _, _, _));
2268   }
2269   EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
2270   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
2271 
2272   // Headers can be decoded immediately.
2273   EXPECT_TRUE(stream_->headers_decompressed());
2274 
2275   // Verify headers.
2276   EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
2277   stream_->ConsumeHeaderList();
2278 
2279   // DATA frame.
2280   std::string data = DataFrame(kDataFramePayload);
2281   EXPECT_CALL(debug_visitor,
2282               OnDataFrameReceived(stream_->id(), kDataFramePayload.length()));
2283   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
2284                                          headers.length(), data));
2285   EXPECT_EQ(kDataFramePayload, stream_->data());
2286 
2287   // Deliver second dynamic table entry to decoder.
2288   session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
2289 
2290   // Trailing HEADERS frame referencing second dynamic table entry.
2291   std::string encoded_trailers;
2292   ASSERT_TRUE(absl::HexStringToBytes("030080", &encoded_trailers));
2293   std::string trailers = HeadersFrame(encoded_trailers);
2294   EXPECT_CALL(debug_visitor,
2295               OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
2296   // Header acknowledgement.
2297   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
2298     EXPECT_CALL(*session_,
2299                 WritevData(decoder_send_stream->id(), _, _, _, _, _));
2300   }
2301   EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
2302   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
2303                                          headers.length() + data.length(),
2304                                          trailers));
2305 
2306   // Trailers can be decoded immediately.
2307   EXPECT_TRUE(stream_->trailers_decompressed());
2308 
2309   // Verify trailers.
2310   EXPECT_THAT(stream_->received_trailers(),
2311               ElementsAre(Pair("trailing", "foobar")));
2312   stream_->MarkTrailersConsumed();
2313 }
2314 
TEST_P(QuicSpdyStreamTest,BlockedHeaderDecoding)2315 TEST_P(QuicSpdyStreamTest, BlockedHeaderDecoding) {
2316   if (!UsesHttp3()) {
2317     return;
2318   }
2319 
2320   Initialize(kShouldProcessData);
2321   testing::InSequence s;
2322   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
2323   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2324   session_->set_debug_visitor(&debug_visitor);
2325 
2326   // HEADERS frame referencing first dynamic table entry.
2327   std::string encoded_headers;
2328   ASSERT_TRUE(absl::HexStringToBytes("020080", &encoded_headers));
2329   std::string headers = HeadersFrame(encoded_headers);
2330   EXPECT_CALL(debug_visitor,
2331               OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
2332   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
2333 
2334   // Decoding is blocked because dynamic table entry has not been received yet.
2335   EXPECT_FALSE(stream_->headers_decompressed());
2336 
2337   auto decoder_send_stream =
2338       QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
2339 
2340   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
2341     // Decoder stream type.
2342     EXPECT_CALL(*session_,
2343                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2344                            /* offset = */ 0, _, _, _));
2345     // Header acknowledgement.
2346     EXPECT_CALL(*session_,
2347                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2348                            /* offset = */ 1, _, _, _));
2349   }
2350   EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
2351   // Deliver dynamic table entry to decoder.
2352   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
2353   EXPECT_TRUE(stream_->headers_decompressed());
2354 
2355   // Verify headers.
2356   EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
2357   stream_->ConsumeHeaderList();
2358 
2359   // DATA frame.
2360   std::string data = DataFrame(kDataFramePayload);
2361   EXPECT_CALL(debug_visitor,
2362               OnDataFrameReceived(stream_->id(), kDataFramePayload.length()));
2363   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
2364                                          headers.length(), data));
2365   EXPECT_EQ(kDataFramePayload, stream_->data());
2366 
2367   // Trailing HEADERS frame referencing second dynamic table entry.
2368   std::string encoded_trailers;
2369   ASSERT_TRUE(absl::HexStringToBytes("030080", &encoded_trailers));
2370   std::string trailers = HeadersFrame(encoded_trailers);
2371   EXPECT_CALL(debug_visitor,
2372               OnHeadersFrameReceived(stream_->id(), encoded_trailers.length()));
2373   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
2374                                          headers.length() + data.length(),
2375                                          trailers));
2376 
2377   // Decoding is blocked because dynamic table entry has not been received yet.
2378   EXPECT_FALSE(stream_->trailers_decompressed());
2379 
2380   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
2381     // Header acknowledgement.
2382     EXPECT_CALL(*session_,
2383                 WritevData(decoder_send_stream->id(), _, _, _, _, _));
2384   }
2385   EXPECT_CALL(debug_visitor, OnHeadersDecoded(stream_->id(), _));
2386   // Deliver second dynamic table entry to decoder.
2387   session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
2388   EXPECT_TRUE(stream_->trailers_decompressed());
2389 
2390   // Verify trailers.
2391   EXPECT_THAT(stream_->received_trailers(),
2392               ElementsAre(Pair("trailing", "foobar")));
2393   stream_->MarkTrailersConsumed();
2394 }
2395 
TEST_P(QuicSpdyStreamTest,AsyncErrorDecodingHeaders)2396 TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingHeaders) {
2397   if (!UsesHttp3()) {
2398     return;
2399   }
2400 
2401   Initialize(kShouldProcessData);
2402   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
2403 
2404   // HEADERS frame only referencing entry with absolute index 0 but with
2405   // Required Insert Count = 2, which is incorrect.
2406   std::string headers_bytes;
2407   ASSERT_TRUE(absl::HexStringToBytes("030081", &headers_bytes));
2408   std::string headers = HeadersFrame(headers_bytes);
2409   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
2410 
2411   // Even though entire header block is received and every referenced entry is
2412   // available, decoding is blocked until insert count reaches the Required
2413   // Insert Count value advertised in the header block prefix.
2414   EXPECT_FALSE(stream_->headers_decompressed());
2415 
2416   EXPECT_CALL(
2417       *connection_,
2418       CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
2419                       MatchesRegex("Error decoding headers on stream \\d+: "
2420                                    "Required Insert Count too large."),
2421                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
2422 
2423   // Deliver two dynamic table entries to decoder
2424   // to trigger decoding of header block.
2425   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
2426   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
2427 }
2428 
2429 // Regression test for https://crbug.com/1024263 and for
2430 // https://crbug.com/1025209#c11.
TEST_P(QuicSpdyStreamTest,BlockedHeaderDecodingUnblockedWithBufferedError)2431 TEST_P(QuicSpdyStreamTest, BlockedHeaderDecodingUnblockedWithBufferedError) {
2432   if (!UsesHttp3()) {
2433     return;
2434   }
2435 
2436   Initialize(kShouldProcessData);
2437   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
2438 
2439   // Relative index 2 is invalid because it is larger than or equal to the Base.
2440   std::string headers_bytes;
2441   ASSERT_TRUE(absl::HexStringToBytes("020082", &headers_bytes));
2442   std::string headers = HeadersFrame(headers_bytes);
2443   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
2444 
2445   // Decoding is blocked.
2446   EXPECT_FALSE(stream_->headers_decompressed());
2447 
2448   EXPECT_CALL(
2449       *connection_,
2450       CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
2451                       MatchesRegex("Error decoding headers on stream \\d+: "
2452                                    "Invalid relative index."),
2453                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
2454 
2455   // Deliver one dynamic table entry to decoder
2456   // to trigger decoding of header block.
2457   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
2458 }
2459 
TEST_P(QuicSpdyStreamTest,AsyncErrorDecodingTrailers)2460 TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingTrailers) {
2461   if (!UsesHttp3()) {
2462     return;
2463   }
2464 
2465   Initialize(kShouldProcessData);
2466   testing::InSequence s;
2467   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
2468 
2469   // HEADERS frame referencing first dynamic table entry.
2470   std::string headers_bytes;
2471   ASSERT_TRUE(absl::HexStringToBytes("020080", &headers_bytes));
2472   std::string headers = HeadersFrame(headers_bytes);
2473   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
2474 
2475   // Decoding is blocked because dynamic table entry has not been received yet.
2476   EXPECT_FALSE(stream_->headers_decompressed());
2477 
2478   auto decoder_send_stream =
2479       QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
2480 
2481   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
2482     // Decoder stream type.
2483     EXPECT_CALL(*session_,
2484                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2485                            /* offset = */ 0, _, _, _));
2486     // Header acknowledgement.
2487     EXPECT_CALL(*session_,
2488                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2489                            /* offset = */ 1, _, _, _));
2490   }
2491   // Deliver dynamic table entry to decoder.
2492   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
2493   EXPECT_TRUE(stream_->headers_decompressed());
2494 
2495   // Verify headers.
2496   EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
2497   stream_->ConsumeHeaderList();
2498 
2499   // DATA frame.
2500   std::string data = DataFrame(kDataFramePayload);
2501   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */
2502                                          headers.length(), data));
2503   EXPECT_EQ(kDataFramePayload, stream_->data());
2504 
2505   // Trailing HEADERS frame only referencing entry with absolute index 0 but
2506   // with Required Insert Count = 2, which is incorrect.
2507   std::string trailers_bytes;
2508   ASSERT_TRUE(absl::HexStringToBytes("030081", &trailers_bytes));
2509   std::string trailers = HeadersFrame(trailers_bytes);
2510   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */
2511                                          headers.length() + data.length(),
2512                                          trailers));
2513 
2514   // Even though entire header block is received and every referenced entry is
2515   // available, decoding is blocked until insert count reaches the Required
2516   // Insert Count value advertised in the header block prefix.
2517   EXPECT_FALSE(stream_->trailers_decompressed());
2518 
2519   EXPECT_CALL(
2520       *connection_,
2521       CloseConnection(QUIC_QPACK_DECOMPRESSION_FAILED,
2522                       MatchesRegex("Error decoding trailers on stream \\d+: "
2523                                    "Required Insert Count too large."),
2524                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
2525 
2526   // Deliver second dynamic table entry to decoder
2527   // to trigger decoding of trailing header block.
2528   session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar");
2529 }
2530 
2531 // Regression test for b/132603592: QPACK decoding unblocked after stream is
2532 // closed.
TEST_P(QuicSpdyStreamTest,HeaderDecodingUnblockedAfterStreamClosed)2533 TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterStreamClosed) {
2534   if (!UsesHttp3()) {
2535     return;
2536   }
2537 
2538   Initialize(kShouldProcessData);
2539   testing::InSequence s;
2540   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
2541   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2542   session_->set_debug_visitor(&debug_visitor);
2543 
2544   // HEADERS frame referencing first dynamic table entry.
2545   std::string encoded_headers;
2546   ASSERT_TRUE(absl::HexStringToBytes("020080", &encoded_headers));
2547   std::string headers = HeadersFrame(encoded_headers);
2548   EXPECT_CALL(debug_visitor,
2549               OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
2550   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
2551 
2552   // Decoding is blocked because dynamic table entry has not been received yet.
2553   EXPECT_FALSE(stream_->headers_decompressed());
2554 
2555   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
2556     // Decoder stream type and stream cancellation instruction.
2557     auto decoder_send_stream =
2558         QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
2559     EXPECT_CALL(*session_,
2560                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2561                            /* offset = */ 0, _, _, _));
2562     EXPECT_CALL(*session_,
2563                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2564                            /* offset = */ 1, _, _, _));
2565   }
2566 
2567   // Reset stream by this endpoint, for example, due to stream cancellation.
2568   EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
2569                              stream_->id(), QuicResetStreamError::FromInternal(
2570                                                 QUIC_STREAM_CANCELLED)));
2571   EXPECT_CALL(
2572       *session_,
2573       MaybeSendRstStreamFrame(
2574           stream_->id(),
2575           QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
2576   stream_->Reset(QUIC_STREAM_CANCELLED);
2577 
2578   // Deliver dynamic table entry to decoder.
2579   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
2580 
2581   EXPECT_FALSE(stream_->headers_decompressed());
2582 }
2583 
TEST_P(QuicSpdyStreamTest,HeaderDecodingUnblockedAfterResetReceived)2584 TEST_P(QuicSpdyStreamTest, HeaderDecodingUnblockedAfterResetReceived) {
2585   if (!UsesHttp3()) {
2586     return;
2587   }
2588 
2589   Initialize(kShouldProcessData);
2590   testing::InSequence s;
2591   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
2592   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2593   session_->set_debug_visitor(&debug_visitor);
2594 
2595   // HEADERS frame referencing first dynamic table entry.
2596   std::string encoded_headers;
2597   ASSERT_TRUE(absl::HexStringToBytes("020080", &encoded_headers));
2598   std::string headers = HeadersFrame(encoded_headers);
2599   EXPECT_CALL(debug_visitor,
2600               OnHeadersFrameReceived(stream_->id(), encoded_headers.length()));
2601   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
2602 
2603   // Decoding is blocked because dynamic table entry has not been received yet.
2604   EXPECT_FALSE(stream_->headers_decompressed());
2605 
2606   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
2607     // Decoder stream type and stream cancellation instruction.
2608     auto decoder_send_stream =
2609         QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
2610     EXPECT_CALL(*session_,
2611                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2612                            /* offset = */ 0, _, _, _));
2613     EXPECT_CALL(*session_,
2614                 WritevData(decoder_send_stream->id(), /* write_length = */ 1,
2615                            /* offset = */ 1, _, _, _));
2616   }
2617 
2618   // OnStreamReset() is called when RESET_STREAM frame is received from peer.
2619   // This aborts header decompression.
2620   stream_->OnStreamReset(QuicRstStreamFrame(
2621       kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
2622 
2623   // Deliver dynamic table entry to decoder.
2624   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
2625   EXPECT_FALSE(stream_->headers_decompressed());
2626 }
2627 
2628 class QuicSpdyStreamIncrementalConsumptionTest : public QuicSpdyStreamTest {
2629  protected:
QuicSpdyStreamIncrementalConsumptionTest()2630   QuicSpdyStreamIncrementalConsumptionTest() : offset_(0), consumed_bytes_(0) {}
2631   ~QuicSpdyStreamIncrementalConsumptionTest() override = default;
2632 
2633   // Create QuicStreamFrame with |payload|
2634   // and pass it to stream_->OnStreamFrame().
OnStreamFrame(absl::string_view payload)2635   void OnStreamFrame(absl::string_view payload) {
2636     QuicStreamFrame frame(stream_->id(), /* fin = */ false, offset_, payload);
2637     stream_->OnStreamFrame(frame);
2638     offset_ += payload.size();
2639   }
2640 
2641   // Return number of bytes marked consumed with sequencer
2642   // since last NewlyConsumedBytes() call.
NewlyConsumedBytes()2643   QuicStreamOffset NewlyConsumedBytes() {
2644     QuicStreamOffset previously_consumed_bytes = consumed_bytes_;
2645     consumed_bytes_ = stream_->sequencer()->NumBytesConsumed();
2646     return consumed_bytes_ - previously_consumed_bytes;
2647   }
2648 
2649   // Read |size| bytes from the stream.
ReadFromStream(QuicByteCount size)2650   std::string ReadFromStream(QuicByteCount size) {
2651     std::string buffer;
2652     buffer.resize(size);
2653 
2654     struct iovec vec;
2655     vec.iov_base = const_cast<char*>(buffer.data());
2656     vec.iov_len = size;
2657 
2658     size_t bytes_read = stream_->Readv(&vec, 1);
2659     EXPECT_EQ(bytes_read, size);
2660 
2661     return buffer;
2662   }
2663 
2664  private:
2665   QuicStreamOffset offset_;
2666   QuicStreamOffset consumed_bytes_;
2667 };
2668 
2669 INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdyStreamIncrementalConsumptionTest,
2670                          ::testing::ValuesIn(AllSupportedVersions()),
2671                          ::testing::PrintToStringParamName());
2672 
2673 // Test that stream bytes are consumed (by calling
2674 // sequencer()->MarkConsumed()) incrementally, as soon as possible.
TEST_P(QuicSpdyStreamIncrementalConsumptionTest,OnlyKnownFrames)2675 TEST_P(QuicSpdyStreamIncrementalConsumptionTest, OnlyKnownFrames) {
2676   if (!UsesHttp3()) {
2677     return;
2678   }
2679 
2680   Initialize(!kShouldProcessData);
2681 
2682   std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
2683 
2684   // All HEADERS frame bytes are consumed even if the frame is not received
2685   // completely.
2686   OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
2687   EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
2688 
2689   // The rest of the HEADERS frame is also consumed immediately.
2690   OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
2691   EXPECT_EQ(1u, NewlyConsumedBytes());
2692 
2693   // Verify headers.
2694   EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
2695   stream_->ConsumeHeaderList();
2696 
2697   // DATA frame.
2698   absl::string_view data_payload(kDataFramePayload);
2699   std::string data_frame = DataFrame(data_payload);
2700   QuicByteCount data_frame_header_length =
2701       data_frame.size() - data_payload.size();
2702 
2703   // DATA frame header is consumed.
2704   // DATA frame payload is not consumed because payload has to be buffered.
2705   OnStreamFrame(data_frame);
2706   EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
2707 
2708   // Consume all but last byte of data.
2709   EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
2710             ReadFromStream(data_payload.size() - 1));
2711   EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
2712 
2713   std::string trailers =
2714       HeadersFrame({std::make_pair("custom-key", "custom-value")});
2715 
2716   // No bytes are consumed, because last byte of DATA payload is still buffered.
2717   OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
2718   EXPECT_EQ(0u, NewlyConsumedBytes());
2719 
2720   // Reading last byte of DATA payload triggers consumption of all data received
2721   // so far, even though last HEADERS frame has not been received completely.
2722   EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
2723   EXPECT_EQ(1 + trailers.size() - 1, NewlyConsumedBytes());
2724 
2725   // Last byte of trailers is immediately consumed.
2726   OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
2727   EXPECT_EQ(1u, NewlyConsumedBytes());
2728 
2729   // Verify trailers.
2730   EXPECT_THAT(stream_->received_trailers(),
2731               ElementsAre(Pair("custom-key", "custom-value")));
2732 }
2733 
TEST_P(QuicSpdyStreamIncrementalConsumptionTest,ReceiveUnknownFrame)2734 TEST_P(QuicSpdyStreamIncrementalConsumptionTest, ReceiveUnknownFrame) {
2735   if (!UsesHttp3()) {
2736     return;
2737   }
2738 
2739   Initialize(kShouldProcessData);
2740   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2741   session_->set_debug_visitor(&debug_visitor);
2742 
2743   EXPECT_CALL(debug_visitor,
2744               OnUnknownFrameReceived(stream_->id(), /* frame_type = */ 0x21,
2745                                      /* payload_length = */ 3));
2746   std::string unknown_frame = UnknownFrame(0x21, "foo");
2747   OnStreamFrame(unknown_frame);
2748 }
2749 
TEST_P(QuicSpdyStreamIncrementalConsumptionTest,ReceiveUnsupportedMetadataFrame)2750 TEST_P(QuicSpdyStreamIncrementalConsumptionTest,
2751        ReceiveUnsupportedMetadataFrame) {
2752   if (!UsesHttp3()) {
2753     return;
2754   }
2755 
2756   Initialize(kShouldProcessData);
2757   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2758   session_->set_debug_visitor(&debug_visitor);
2759 
2760   quiche::HttpHeaderBlock headers;
2761   headers.AppendValueOrAddHeader("key1", "val1");
2762   headers.AppendValueOrAddHeader("key2", "val2");
2763   quic::NoopDecoderStreamErrorDelegate delegate;
2764   QpackEncoder qpack_encoder(&delegate, quic::HuffmanEncoding::kDisabled);
2765   std::string metadata_frame_payload = qpack_encoder.EncodeHeaderList(
2766       stream_->id(), headers,
2767       /* encoder_stream_sent_byte_count = */ nullptr);
2768   std::string metadata_frame_header =
2769       quic::HttpEncoder::SerializeMetadataFrameHeader(
2770           metadata_frame_payload.size());
2771   std::string metadata_frame = metadata_frame_header + metadata_frame_payload;
2772 
2773   EXPECT_CALL(debug_visitor,
2774               OnUnknownFrameReceived(
2775                   stream_->id(), /* frame_type = */ 0x4d,
2776                   /* payload_length = */ metadata_frame_payload.length()));
2777   OnStreamFrame(metadata_frame);
2778 }
2779 
2780 class MockMetadataVisitor : public QuicSpdyStream::MetadataVisitor {
2781  public:
2782   ~MockMetadataVisitor() override = default;
2783   MOCK_METHOD(void, OnMetadataComplete,
2784               (size_t frame_len, const QuicHeaderList& header_list),
2785               (override));
2786 };
2787 
TEST_P(QuicSpdyStreamIncrementalConsumptionTest,ReceiveMetadataFrame)2788 TEST_P(QuicSpdyStreamIncrementalConsumptionTest, ReceiveMetadataFrame) {
2789   if (!UsesHttp3() ||
2790       !GetQuicReloadableFlag(quic_enable_http3_metadata_decoding)) {
2791     return;
2792   }
2793   StrictMock<MockMetadataVisitor> metadata_visitor;
2794   Initialize(kShouldProcessData);
2795   stream_->RegisterMetadataVisitor(&metadata_visitor);
2796   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2797   session_->set_debug_visitor(&debug_visitor);
2798 
2799   quiche::HttpHeaderBlock headers;
2800   headers.AppendValueOrAddHeader("key1", "val1");
2801   headers.AppendValueOrAddHeader("key2", "val2");
2802   quic::NoopDecoderStreamErrorDelegate delegate;
2803   QpackEncoder qpack_encoder(&delegate, quic::HuffmanEncoding::kDisabled);
2804   std::string metadata_frame_payload = qpack_encoder.EncodeHeaderList(
2805       stream_->id(), headers,
2806       /* encoder_stream_sent_byte_count = */ nullptr);
2807   std::string metadata_frame_header =
2808       quic::HttpEncoder::SerializeMetadataFrameHeader(
2809           metadata_frame_payload.size());
2810   std::string metadata_frame = metadata_frame_header + metadata_frame_payload;
2811 
2812   EXPECT_CALL(metadata_visitor, OnMetadataComplete(metadata_frame.size(), _))
2813       .WillOnce(testing::WithArgs<1>(
2814           Invoke([&headers](const QuicHeaderList& header_list) {
2815             quiche::HttpHeaderBlock actual_headers;
2816             for (const auto& header : header_list) {
2817               actual_headers.AppendValueOrAddHeader(header.first,
2818                                                     header.second);
2819             }
2820             EXPECT_EQ(headers, actual_headers);
2821           })));
2822   OnStreamFrame(metadata_frame);
2823 }
2824 
TEST_P(QuicSpdyStreamIncrementalConsumptionTest,ResetDuringMultipleMetadataFrames)2825 TEST_P(QuicSpdyStreamIncrementalConsumptionTest,
2826        ResetDuringMultipleMetadataFrames) {
2827   if (!UsesHttp3() ||
2828       !GetQuicReloadableFlag(quic_enable_http3_metadata_decoding)) {
2829     return;
2830   }
2831   StrictMock<MockMetadataVisitor> metadata_visitor;
2832   Initialize(kShouldProcessData);
2833   stream_->RegisterMetadataVisitor(&metadata_visitor);
2834   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2835   session_->set_debug_visitor(&debug_visitor);
2836 
2837   quiche::HttpHeaderBlock headers;
2838   headers.AppendValueOrAddHeader("key1", "val1");
2839   headers.AppendValueOrAddHeader("key2", "val2");
2840   quic::NoopDecoderStreamErrorDelegate delegate;
2841   QpackEncoder qpack_encoder(&delegate, quic::HuffmanEncoding::kDisabled);
2842   std::string metadata_frame_payload = qpack_encoder.EncodeHeaderList(
2843       stream_->id(), headers,
2844       /* encoder_stream_sent_byte_count = */ nullptr);
2845   std::string metadata_frame_header =
2846       quic::HttpEncoder::SerializeMetadataFrameHeader(
2847           metadata_frame_payload.size());
2848   std::string metadata_frame = metadata_frame_header + metadata_frame_payload;
2849 
2850   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
2851   EXPECT_CALL(*session_, MaybeSendStopSendingFrame(_, _));
2852   EXPECT_CALL(*session_, MaybeSendRstStreamFrame(_, _, _));
2853   // Reset the stream while processing the first frame and do not
2854   // receive a callback about the second.
2855   EXPECT_CALL(metadata_visitor, OnMetadataComplete(metadata_frame.size(), _))
2856       .WillOnce(testing::WithArgs<1>(
2857           Invoke([&headers, this](const QuicHeaderList& header_list) {
2858             quiche::HttpHeaderBlock actual_headers;
2859             for (const auto& header : header_list) {
2860               actual_headers.AppendValueOrAddHeader(header.first,
2861                                                     header.second);
2862             }
2863             EXPECT_EQ(headers, actual_headers);
2864             stream_->Reset(QUIC_STREAM_CANCELLED);
2865           })));
2866   std::string data = metadata_frame + metadata_frame;
2867   OnStreamFrame(data);
2868 }
2869 
TEST_P(QuicSpdyStreamIncrementalConsumptionTest,UnknownFramesInterleaved)2870 TEST_P(QuicSpdyStreamIncrementalConsumptionTest, UnknownFramesInterleaved) {
2871   if (!UsesHttp3()) {
2872     return;
2873   }
2874 
2875   Initialize(!kShouldProcessData);
2876 
2877   // Unknown frame of reserved type before HEADERS is consumed immediately.
2878   std::string unknown_frame1 = UnknownFrame(0x21, "foo");
2879   OnStreamFrame(unknown_frame1);
2880   EXPECT_EQ(unknown_frame1.size(), NewlyConsumedBytes());
2881 
2882   std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
2883 
2884   // All HEADERS frame bytes are consumed even if the frame is not received
2885   // completely.
2886   OnStreamFrame(absl::string_view(headers).substr(0, headers.size() - 1));
2887   EXPECT_EQ(headers.size() - 1, NewlyConsumedBytes());
2888 
2889   // The rest of the HEADERS frame is also consumed immediately.
2890   OnStreamFrame(absl::string_view(headers).substr(headers.size() - 1));
2891   EXPECT_EQ(1u, NewlyConsumedBytes());
2892 
2893   // Verify headers.
2894   EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
2895   stream_->ConsumeHeaderList();
2896 
2897   // Frame of unknown, not reserved type between HEADERS and DATA is consumed
2898   // immediately.
2899   std::string unknown_frame2 = UnknownFrame(0x3a, "");
2900   OnStreamFrame(unknown_frame2);
2901   EXPECT_EQ(unknown_frame2.size(), NewlyConsumedBytes());
2902 
2903   // DATA frame.
2904   absl::string_view data_payload(kDataFramePayload);
2905   std::string data_frame = DataFrame(data_payload);
2906   QuicByteCount data_frame_header_length =
2907       data_frame.size() - data_payload.size();
2908 
2909   // DATA frame header is consumed.
2910   // DATA frame payload is not consumed because payload has to be buffered.
2911   OnStreamFrame(data_frame);
2912   EXPECT_EQ(data_frame_header_length, NewlyConsumedBytes());
2913 
2914   // Frame of unknown, not reserved type is not consumed because DATA payload is
2915   // still buffered.
2916   std::string unknown_frame3 = UnknownFrame(0x39, "bar");
2917   OnStreamFrame(unknown_frame3);
2918   EXPECT_EQ(0u, NewlyConsumedBytes());
2919 
2920   // Consume all but last byte of data.
2921   EXPECT_EQ(data_payload.substr(0, data_payload.size() - 1),
2922             ReadFromStream(data_payload.size() - 1));
2923   EXPECT_EQ(data_payload.size() - 1, NewlyConsumedBytes());
2924 
2925   std::string trailers =
2926       HeadersFrame({std::make_pair("custom-key", "custom-value")});
2927 
2928   // No bytes are consumed, because last byte of DATA payload is still buffered.
2929   OnStreamFrame(absl::string_view(trailers).substr(0, trailers.size() - 1));
2930   EXPECT_EQ(0u, NewlyConsumedBytes());
2931 
2932   // Reading last byte of DATA payload triggers consumption of all data received
2933   // so far, even though last HEADERS frame has not been received completely.
2934   EXPECT_EQ(data_payload.substr(data_payload.size() - 1), ReadFromStream(1));
2935   EXPECT_EQ(1 + unknown_frame3.size() + trailers.size() - 1,
2936             NewlyConsumedBytes());
2937 
2938   // Last byte of trailers is immediately consumed.
2939   OnStreamFrame(absl::string_view(trailers).substr(trailers.size() - 1));
2940   EXPECT_EQ(1u, NewlyConsumedBytes());
2941 
2942   // Verify trailers.
2943   EXPECT_THAT(stream_->received_trailers(),
2944               ElementsAre(Pair("custom-key", "custom-value")));
2945 
2946   // Unknown frame of reserved type after trailers is consumed immediately.
2947   std::string unknown_frame4 = UnknownFrame(0x40, "");
2948   OnStreamFrame(unknown_frame4);
2949   EXPECT_EQ(unknown_frame4.size(), NewlyConsumedBytes());
2950 }
2951 
2952 // Close connection if a DATA frame is received before a HEADERS frame.
TEST_P(QuicSpdyStreamTest,DataBeforeHeaders)2953 TEST_P(QuicSpdyStreamTest, DataBeforeHeaders) {
2954   if (!UsesHttp3()) {
2955     return;
2956   }
2957 
2958   Initialize(kShouldProcessData);
2959 
2960   // Closing the connection is mocked out in tests.  Instead, simply stop
2961   // reading data at the stream level to prevent QuicSpdyStream from blowing up.
2962   EXPECT_CALL(
2963       *connection_,
2964       CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
2965                       "Unexpected DATA frame received.",
2966                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
2967       .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
2968 
2969   std::string data = DataFrame(kDataFramePayload);
2970   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, data));
2971 }
2972 
2973 // Close connection if a HEADERS frame is received after the trailing HEADERS.
TEST_P(QuicSpdyStreamTest,TrailersAfterTrailers)2974 TEST_P(QuicSpdyStreamTest, TrailersAfterTrailers) {
2975   if (!UsesHttp3()) {
2976     return;
2977   }
2978 
2979   Initialize(kShouldProcessData);
2980 
2981   // Receive and consume headers.
2982   std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
2983   QuicStreamOffset offset = 0;
2984   stream_->OnStreamFrame(
2985       QuicStreamFrame(stream_->id(), false, offset, headers));
2986   offset += headers.size();
2987 
2988   EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
2989   stream_->ConsumeHeaderList();
2990 
2991   // Receive data.  It is consumed by TestStream.
2992   std::string data = DataFrame(kDataFramePayload);
2993   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data));
2994   offset += data.size();
2995 
2996   EXPECT_EQ(kDataFramePayload, stream_->data());
2997 
2998   // Receive and consume trailers.
2999   std::string trailers1 =
3000       HeadersFrame({std::make_pair("custom-key", "custom-value")});
3001   stream_->OnStreamFrame(
3002       QuicStreamFrame(stream_->id(), false, offset, trailers1));
3003   offset += trailers1.size();
3004 
3005   EXPECT_TRUE(stream_->trailers_decompressed());
3006   EXPECT_THAT(stream_->received_trailers(),
3007               ElementsAre(Pair("custom-key", "custom-value")));
3008 
3009   // Closing the connection is mocked out in tests.  Instead, simply stop
3010   // reading data at the stream level to prevent QuicSpdyStream from blowing up.
3011   EXPECT_CALL(
3012       *connection_,
3013       CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
3014                       "HEADERS frame received after trailing HEADERS.",
3015                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
3016       .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
3017 
3018   // Receive another HEADERS frame, with no header fields.
3019   std::string trailers2 = HeadersFrame(Http2HeaderBlock());
3020   stream_->OnStreamFrame(
3021       QuicStreamFrame(stream_->id(), false, offset, trailers2));
3022 }
3023 
3024 // Regression test for https://crbug.com/978733.
3025 // Close connection if a DATA frame is received after the trailing HEADERS.
TEST_P(QuicSpdyStreamTest,DataAfterTrailers)3026 TEST_P(QuicSpdyStreamTest, DataAfterTrailers) {
3027   if (!UsesHttp3()) {
3028     return;
3029   }
3030 
3031   Initialize(kShouldProcessData);
3032 
3033   // Receive and consume headers.
3034   std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
3035   QuicStreamOffset offset = 0;
3036   stream_->OnStreamFrame(
3037       QuicStreamFrame(stream_->id(), false, offset, headers));
3038   offset += headers.size();
3039 
3040   EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar")));
3041   stream_->ConsumeHeaderList();
3042 
3043   // Receive data.  It is consumed by TestStream.
3044   std::string data1 = DataFrame(kDataFramePayload);
3045   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data1));
3046   offset += data1.size();
3047   EXPECT_EQ(kDataFramePayload, stream_->data());
3048 
3049   // Receive trailers, with single header field "custom-key: custom-value".
3050   std::string trailers =
3051       HeadersFrame({std::make_pair("custom-key", "custom-value")});
3052   stream_->OnStreamFrame(
3053       QuicStreamFrame(stream_->id(), false, offset, trailers));
3054   offset += trailers.size();
3055 
3056   EXPECT_THAT(stream_->received_trailers(),
3057               ElementsAre(Pair("custom-key", "custom-value")));
3058 
3059   // Closing the connection is mocked out in tests.  Instead, simply stop
3060   // reading data at the stream level to prevent QuicSpdyStream from blowing up.
3061   EXPECT_CALL(
3062       *connection_,
3063       CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
3064                       "Unexpected DATA frame received.",
3065                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET))
3066       .WillOnce(InvokeWithoutArgs([this]() { stream_->StopReading(); }));
3067 
3068   // Receive more data.
3069   std::string data2 = DataFrame("This payload should not be proccessed.");
3070   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, offset, data2));
3071 }
3072 
3073 // SETTINGS frames are invalid on bidirectional streams.  If one is received,
3074 // the connection is closed.  No more data should be processed.
TEST_P(QuicSpdyStreamTest,StopProcessingIfConnectionClosed)3075 TEST_P(QuicSpdyStreamTest, StopProcessingIfConnectionClosed) {
3076   if (!UsesHttp3()) {
3077     return;
3078   }
3079 
3080   Initialize(kShouldProcessData);
3081 
3082   // SETTINGS frame with empty payload.
3083   std::string settings;
3084   ASSERT_TRUE(absl::HexStringToBytes("0400", &settings));
3085 
3086   // HEADERS frame.
3087   // Since it arrives after a SETTINGS frame, it should never be read.
3088   std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
3089 
3090   // Combine the two frames to make sure they are processed in a single
3091   // QuicSpdyStream::OnDataAvailable() call.
3092   std::string frames = absl::StrCat(settings, headers);
3093 
3094   EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
3095 
3096   EXPECT_CALL(*connection_,
3097               CloseConnection(QUIC_HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM, _, _))
3098       .WillOnce(
3099           Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
3100   EXPECT_CALL(*connection_, SendConnectionClosePacket(_, _, _));
3101   EXPECT_CALL(*session_, OnConnectionClosed(_, _));
3102 
3103   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), /* fin = */ false,
3104                                          /* offset = */ 0, frames));
3105 
3106   EXPECT_EQ(0u, stream_->sequencer()->NumBytesConsumed());
3107 }
3108 
3109 // Stream Cancellation instruction is sent on QPACK decoder stream
3110 // when stream is reset.
TEST_P(QuicSpdyStreamTest,StreamCancellationWhenStreamReset)3111 TEST_P(QuicSpdyStreamTest, StreamCancellationWhenStreamReset) {
3112   if (!UsesHttp3()) {
3113     return;
3114   }
3115 
3116   Initialize(kShouldProcessData);
3117 
3118   auto qpack_decoder_stream =
3119       QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
3120   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
3121     // Stream type.
3122     EXPECT_CALL(*session_,
3123                 WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
3124                            /* offset = */ 0, _, _, _));
3125     // Stream cancellation.
3126     EXPECT_CALL(*session_,
3127                 WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
3128                            /* offset = */ 1, _, _, _));
3129   }
3130   EXPECT_CALL(*session_, MaybeSendStopSendingFrame(
3131                              stream_->id(), QuicResetStreamError::FromInternal(
3132                                                 QUIC_STREAM_CANCELLED)));
3133   EXPECT_CALL(
3134       *session_,
3135       MaybeSendRstStreamFrame(
3136           stream_->id(),
3137           QuicResetStreamError::FromInternal(QUIC_STREAM_CANCELLED), _));
3138 
3139   stream_->Reset(QUIC_STREAM_CANCELLED);
3140 }
3141 
3142 // Stream Cancellation instruction is sent on QPACK decoder stream
3143 // when RESET_STREAM frame is received.
TEST_P(QuicSpdyStreamTest,StreamCancellationOnResetReceived)3144 TEST_P(QuicSpdyStreamTest, StreamCancellationOnResetReceived) {
3145   if (!UsesHttp3()) {
3146     return;
3147   }
3148 
3149   Initialize(kShouldProcessData);
3150 
3151   auto qpack_decoder_stream =
3152       QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
3153   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
3154     // Stream type.
3155     EXPECT_CALL(*session_,
3156                 WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
3157                            /* offset = */ 0, _, _, _));
3158     // Stream cancellation.
3159     EXPECT_CALL(*session_,
3160                 WritevData(qpack_decoder_stream->id(), /* write_length = */ 1,
3161                            /* offset = */ 1, _, _, _));
3162   }
3163 
3164   stream_->OnStreamReset(QuicRstStreamFrame(
3165       kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
3166 }
3167 
TEST_P(QuicSpdyStreamTest,WriteHeadersReturnValue)3168 TEST_P(QuicSpdyStreamTest, WriteHeadersReturnValue) {
3169   if (!UsesHttp3()) {
3170     return;
3171   }
3172 
3173   Initialize(kShouldProcessData);
3174   testing::InSequence s;
3175 
3176   // Enable QPACK dynamic table.
3177   session_->OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024);
3178   session_->OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 1);
3179 
3180   EXPECT_CALL(*stream_, WriteHeadersMock(true));
3181 
3182   QpackSendStream* encoder_stream =
3183       QuicSpdySessionPeer::GetQpackEncoderSendStream(session_.get());
3184   EXPECT_CALL(*session_, WritevData(encoder_stream->id(), _, _, _, _, _))
3185       .Times(AnyNumber());
3186 
3187   size_t bytes_written = 0;
3188   EXPECT_CALL(*session_,
3189               WritevData(stream_->id(), _, /* offset = */ 0, _, _, _))
3190       .WillOnce(
3191           DoAll(SaveArg<1>(&bytes_written),
3192                 Invoke(session_.get(), &MockQuicSpdySession::ConsumeData)));
3193 
3194   Http2HeaderBlock request_headers;
3195   request_headers["foo"] = "bar";
3196   size_t write_headers_return_value =
3197       stream_->WriteHeaders(std::move(request_headers), /*fin=*/true, nullptr);
3198   EXPECT_TRUE(stream_->fin_sent());
3199   // bytes_written includes HEADERS frame header.
3200   EXPECT_GT(bytes_written, write_headers_return_value);
3201 }
3202 
3203 // Regression test for https://crbug.com/1177662.
3204 // RESET_STREAM with QUIC_STREAM_NO_ERROR should not be treated in a special
3205 // way: it should close the read side but not the write side.
TEST_P(QuicSpdyStreamTest,TwoResetStreamFrames)3206 TEST_P(QuicSpdyStreamTest, TwoResetStreamFrames) {
3207   if (!UsesHttp3()) {
3208     return;
3209   }
3210 
3211   Initialize(kShouldProcessData);
3212 
3213   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(AnyNumber());
3214 
3215   QuicRstStreamFrame rst_frame1(kInvalidControlFrameId, stream_->id(),
3216                                 QUIC_STREAM_CANCELLED, /* bytes_written = */ 0);
3217   stream_->OnStreamReset(rst_frame1);
3218   EXPECT_TRUE(stream_->read_side_closed());
3219   EXPECT_FALSE(stream_->write_side_closed());
3220 
3221   QuicRstStreamFrame rst_frame2(kInvalidControlFrameId, stream_->id(),
3222                                 QUIC_STREAM_NO_ERROR, /* bytes_written = */ 0);
3223   stream_->OnStreamReset(rst_frame2);
3224   EXPECT_TRUE(stream_->read_side_closed());
3225   EXPECT_FALSE(stream_->write_side_closed());
3226 }
3227 
TEST_P(QuicSpdyStreamTest,ProcessOutgoingWebTransportHeaders)3228 TEST_P(QuicSpdyStreamTest, ProcessOutgoingWebTransportHeaders) {
3229   if (!UsesHttp3()) {
3230     return;
3231   }
3232 
3233   InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
3234   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3235   session_->EnableWebTransport();
3236   session_->OnSetting(SETTINGS_ENABLE_CONNECT_PROTOCOL, 1);
3237   QuicSpdySessionPeer::EnableWebTransport(session_.get());
3238   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
3239                                               HttpDatagramSupport::kRfc);
3240 
3241   EXPECT_CALL(*stream_, WriteHeadersMock(false));
3242   EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
3243       .Times(AnyNumber());
3244 
3245   spdy::Http2HeaderBlock headers;
3246   headers[":method"] = "CONNECT";
3247   headers[":protocol"] = "webtransport";
3248   stream_->WriteHeaders(std::move(headers), /*fin=*/false, nullptr);
3249   ASSERT_TRUE(stream_->web_transport() != nullptr);
3250   EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
3251 }
3252 
TEST_P(QuicSpdyStreamTest,ProcessIncomingWebTransportHeaders)3253 TEST_P(QuicSpdyStreamTest, ProcessIncomingWebTransportHeaders) {
3254   if (!UsesHttp3()) {
3255     return;
3256   }
3257 
3258   Initialize(kShouldProcessData);
3259   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3260   session_->EnableWebTransport();
3261   QuicSpdySessionPeer::EnableWebTransport(session_.get());
3262   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
3263                                               HttpDatagramSupport::kRfc);
3264 
3265   headers_[":method"] = "CONNECT";
3266   headers_[":protocol"] = "webtransport";
3267 
3268   stream_->OnStreamHeadersPriority(
3269       spdy::SpdyStreamPrecedence(kV3HighestPriority));
3270   ProcessHeaders(false, headers_);
3271   EXPECT_EQ("", stream_->data());
3272   EXPECT_FALSE(stream_->header_list().empty());
3273   EXPECT_FALSE(stream_->IsDoneReading());
3274   ASSERT_TRUE(stream_->web_transport() != nullptr);
3275   EXPECT_EQ(stream_->id(), stream_->web_transport()->id());
3276 }
3277 
TEST_P(QuicSpdyStreamTest,IncomingWebTransportStreamWhenUnsupported)3278 TEST_P(QuicSpdyStreamTest, IncomingWebTransportStreamWhenUnsupported) {
3279   if (!UsesHttp3()) {
3280     return;
3281   }
3282 
3283   Initialize(kShouldProcessData);
3284   // Support WebTransport locally, but not by the peer.
3285   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3286   session_->EnableWebTransport();
3287   session_->OnSettingsFrame(SettingsFrame());
3288 
3289   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3290   session_->set_debug_visitor(&debug_visitor);
3291 
3292   std::string webtransport_stream_frame;
3293   ASSERT_TRUE(
3294       absl::HexStringToBytes("40410400000000", &webtransport_stream_frame));
3295   QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
3296                                /* offset = */ 0, webtransport_stream_frame);
3297 
3298   EXPECT_CALL(debug_visitor, OnUnknownFrameReceived(stream_->id(), 0x41, 4));
3299   stream_->OnStreamFrame(stream_frame);
3300   EXPECT_TRUE(stream_->web_transport_stream() == nullptr);
3301 }
3302 
TEST_P(QuicSpdyStreamTest,IncomingWebTransportStream)3303 TEST_P(QuicSpdyStreamTest, IncomingWebTransportStream) {
3304   if (!UsesHttp3()) {
3305     return;
3306   }
3307 
3308   Initialize(kShouldProcessData);
3309   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3310   session_->EnableWebTransport();
3311   SettingsFrame settings;
3312   settings.values[SETTINGS_WEBTRANS_MAX_SESSIONS_DRAFT07] = 10;
3313   settings.values[SETTINGS_H3_DATAGRAM] = 1;
3314   session_->OnSettingsFrame(settings);
3315 
3316   std::string webtransport_stream_frame;
3317   ASSERT_TRUE(absl::HexStringToBytes("404110", &webtransport_stream_frame));
3318   QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
3319                                /* offset = */ 0, webtransport_stream_frame);
3320 
3321   EXPECT_CALL(*session_, CreateIncomingStream(0x10));
3322   stream_->OnStreamFrame(stream_frame);
3323   EXPECT_TRUE(stream_->web_transport_stream() != nullptr);
3324 }
3325 
TEST_P(QuicSpdyStreamTest,IncomingWebTransportStreamWithPaddingDraft02)3326 TEST_P(QuicSpdyStreamTest, IncomingWebTransportStreamWithPaddingDraft02) {
3327   if (!UsesHttp3()) {
3328     return;
3329   }
3330 
3331   Initialize(kShouldProcessData);
3332   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3333   session_->EnableWebTransport();
3334   SettingsFrame settings;
3335   settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
3336   settings.values[SETTINGS_H3_DATAGRAM] = 1;
3337   session_->OnSettingsFrame(settings);
3338 
3339   std::string webtransport_stream_frame;
3340   ASSERT_TRUE(absl::HexStringToBytes("2100404110", &webtransport_stream_frame));
3341   QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
3342                                /* offset = */ 0, webtransport_stream_frame);
3343 
3344   EXPECT_CALL(*session_, CreateIncomingStream(0x10));
3345   stream_->OnStreamFrame(stream_frame);
3346   EXPECT_TRUE(stream_->web_transport_stream() != nullptr);
3347 }
3348 
TEST_P(QuicSpdyStreamTest,IncomingWebTransportStreamWithPaddingDraft07)3349 TEST_P(QuicSpdyStreamTest, IncomingWebTransportStreamWithPaddingDraft07) {
3350   if (!UsesHttp3()) {
3351     return;
3352   }
3353 
3354   Initialize(kShouldProcessData);
3355   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3356   session_->EnableWebTransport();
3357   SettingsFrame settings;
3358   settings.values[SETTINGS_WEBTRANS_MAX_SESSIONS_DRAFT07] = 10;
3359   settings.values[SETTINGS_H3_DATAGRAM] = 1;
3360   session_->OnSettingsFrame(settings);
3361 
3362   std::string webtransport_stream_frame;
3363   ASSERT_TRUE(absl::HexStringToBytes("2100404110", &webtransport_stream_frame));
3364   QuicStreamFrame stream_frame(stream_->id(), /* fin = */ false,
3365                                /* offset = */ 0, webtransport_stream_frame);
3366 
3367   EXPECT_CALL(*connection_,
3368               CloseConnection(QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM,
3369                               HasSubstr("non-zero offset"), _));
3370   stream_->OnStreamFrame(stream_frame);
3371   EXPECT_TRUE(stream_->web_transport_stream() == nullptr);
3372 }
3373 
TEST_P(QuicSpdyStreamTest,ReceiveHttpDatagram)3374 TEST_P(QuicSpdyStreamTest, ReceiveHttpDatagram) {
3375   if (!UsesHttp3()) {
3376     return;
3377   }
3378   InitializeWithPerspective(kShouldProcessData, Perspective::IS_CLIENT);
3379   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3380   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
3381                                               HttpDatagramSupport::kRfc);
3382   headers_[":method"] = "CONNECT";
3383   headers_[":protocol"] = "webtransport";
3384   ProcessHeaders(false, headers_);
3385   SavingHttp3DatagramVisitor h3_datagram_visitor;
3386   ASSERT_EQ(QuicDataWriter::GetVarInt62Len(stream_->id()), 1);
3387   std::array<char, 256> datagram;
3388   datagram[0] = stream_->id();
3389   for (size_t i = 1; i < datagram.size(); i++) {
3390     datagram[i] = i;
3391   }
3392 
3393   stream_->RegisterHttp3DatagramVisitor(&h3_datagram_visitor);
3394   session_->OnMessageReceived(
3395       absl::string_view(datagram.data(), datagram.size()));
3396   EXPECT_THAT(
3397       h3_datagram_visitor.received_h3_datagrams(),
3398       ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
3399           stream_->id(), std::string(&datagram[1], datagram.size() - 1)}));
3400   // Test move.
3401   SavingHttp3DatagramVisitor h3_datagram_visitor2;
3402   stream_->ReplaceHttp3DatagramVisitor(&h3_datagram_visitor2);
3403   EXPECT_TRUE(h3_datagram_visitor2.received_h3_datagrams().empty());
3404   session_->OnMessageReceived(
3405       absl::string_view(datagram.data(), datagram.size()));
3406   EXPECT_THAT(
3407       h3_datagram_visitor2.received_h3_datagrams(),
3408       ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
3409           stream_->id(), std::string(&datagram[1], datagram.size() - 1)}));
3410   // Cleanup.
3411   stream_->UnregisterHttp3DatagramVisitor();
3412 }
3413 
TEST_P(QuicSpdyStreamTest,SendHttpDatagram)3414 TEST_P(QuicSpdyStreamTest, SendHttpDatagram) {
3415   if (!UsesHttp3()) {
3416     return;
3417   }
3418   Initialize(kShouldProcessData);
3419   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3420   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
3421                                               HttpDatagramSupport::kRfc);
3422   std::string http_datagram_payload = {1, 2, 3, 4, 5, 6};
3423   EXPECT_CALL(*connection_, SendMessage(1, _, false))
3424       .WillOnce(Return(MESSAGE_STATUS_SUCCESS));
3425   EXPECT_EQ(stream_->SendHttp3Datagram(http_datagram_payload),
3426             MESSAGE_STATUS_SUCCESS);
3427 }
3428 
TEST_P(QuicSpdyStreamTest,GetMaxDatagramSize)3429 TEST_P(QuicSpdyStreamTest, GetMaxDatagramSize) {
3430   if (!UsesHttp3()) {
3431     return;
3432   }
3433   Initialize(kShouldProcessData);
3434   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3435   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
3436                                               HttpDatagramSupport::kRfc);
3437   EXPECT_GT(stream_->GetMaxDatagramSize(), 512u);
3438 }
3439 
TEST_P(QuicSpdyStreamTest,Capsules)3440 TEST_P(QuicSpdyStreamTest, Capsules) {
3441   if (!UsesHttp3()) {
3442     return;
3443   }
3444   Initialize(kShouldProcessData);
3445   session_->set_local_http_datagram_support(HttpDatagramSupport::kRfc);
3446   QuicSpdySessionPeer::SetHttpDatagramSupport(session_.get(),
3447                                               HttpDatagramSupport::kRfc);
3448   SavingHttp3DatagramVisitor h3_datagram_visitor;
3449   stream_->RegisterHttp3DatagramVisitor(&h3_datagram_visitor);
3450   SavingConnectIpVisitor connect_ip_visitor;
3451   stream_->RegisterConnectIpVisitor(&connect_ip_visitor);
3452   headers_[":method"] = "CONNECT";
3453   headers_[":protocol"] = "fake-capsule-protocol";
3454   ProcessHeaders(/*fin=*/false, headers_);
3455   // Datagram capsule.
3456   std::string http_datagram_payload = {1, 2, 3, 4, 5, 6};
3457   stream_->OnCapsule(Capsule::Datagram(http_datagram_payload));
3458   EXPECT_THAT(h3_datagram_visitor.received_h3_datagrams(),
3459               ElementsAre(SavingHttp3DatagramVisitor::SavedHttp3Datagram{
3460                   stream_->id(), http_datagram_payload}));
3461   // Address assign capsule.
3462   quiche::PrefixWithId ip_prefix_with_id;
3463   ip_prefix_with_id.request_id = 1;
3464   quiche::QuicheIpAddress ip_address;
3465   ip_address.FromString("::");
3466   ip_prefix_with_id.ip_prefix =
3467       quiche::QuicheIpPrefix(ip_address, /*prefix_length=*/96);
3468   Capsule address_assign_capsule = Capsule::AddressAssign();
3469   address_assign_capsule.address_assign_capsule().assigned_addresses.push_back(
3470       ip_prefix_with_id);
3471   stream_->OnCapsule(address_assign_capsule);
3472   EXPECT_THAT(connect_ip_visitor.received_address_assign_capsules(),
3473               ElementsAre(address_assign_capsule.address_assign_capsule()));
3474   // Address request capsule.
3475   Capsule address_request_capsule = Capsule::AddressRequest();
3476   address_request_capsule.address_request_capsule()
3477       .requested_addresses.push_back(ip_prefix_with_id);
3478   stream_->OnCapsule(address_request_capsule);
3479   EXPECT_THAT(connect_ip_visitor.received_address_request_capsules(),
3480               ElementsAre(address_request_capsule.address_request_capsule()));
3481   // Route advertisement capsule.
3482   Capsule route_advertisement_capsule = Capsule::RouteAdvertisement();
3483   IpAddressRange ip_address_range;
3484   ip_address_range.start_ip_address.FromString("192.0.2.24");
3485   ip_address_range.end_ip_address.FromString("192.0.2.42");
3486   ip_address_range.ip_protocol = 0;
3487   route_advertisement_capsule.route_advertisement_capsule()
3488       .ip_address_ranges.push_back(ip_address_range);
3489   stream_->OnCapsule(route_advertisement_capsule);
3490   EXPECT_THAT(
3491       connect_ip_visitor.received_route_advertisement_capsules(),
3492       ElementsAre(route_advertisement_capsule.route_advertisement_capsule()));
3493   // Unknown capsule.
3494   uint64_t capsule_type = 0x17u;
3495   std::string capsule_payload = {1, 2, 3, 4};
3496   Capsule unknown_capsule = Capsule::Unknown(capsule_type, capsule_payload);
3497   stream_->OnCapsule(unknown_capsule);
3498   EXPECT_THAT(h3_datagram_visitor.received_unknown_capsules(),
3499               ElementsAre(SavingHttp3DatagramVisitor::SavedUnknownCapsule{
3500                   stream_->id(), capsule_type, capsule_payload}));
3501   // Cleanup.
3502   stream_->UnregisterHttp3DatagramVisitor();
3503   stream_->UnregisterConnectIpVisitor();
3504 }
3505 
TEST_P(QuicSpdyStreamTest,QUIC_TEST_DISABLED_IN_CHROME (HeadersAccumulatorNullptr))3506 TEST_P(QuicSpdyStreamTest,
3507        QUIC_TEST_DISABLED_IN_CHROME(HeadersAccumulatorNullptr)) {
3508   if (!UsesHttp3()) {
3509     return;
3510   }
3511 
3512   Initialize(kShouldProcessData);
3513 
3514   // Creates QpackDecodedHeadersAccumulator in
3515   // `qpack_decoded_headers_accumulator_`.
3516   std::string headers = HeadersFrame({std::make_pair("foo", "bar")});
3517   stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers));
3518 
3519   // Resets `qpack_decoded_headers_accumulator_`.
3520   stream_->OnHeadersDecoded({}, false);
3521 
3522   EXPECT_QUIC_BUG(
3523       {
3524         EXPECT_CALL(*connection_, CloseConnection(_, _, _));
3525         // This private method should never be called when
3526         // `qpack_decoded_headers_accumulator_` is nullptr.
3527         EXPECT_FALSE(QuicSpdyStreamPeer::OnHeadersFrameEnd(stream_));
3528       },
3529       "b215142466_OnHeadersFrameEnd");
3530 }
3531 
3532 // Regression test for https://crbug.com/1465224.
TEST_P(QuicSpdyStreamTest,ReadAfterReset)3533 TEST_P(QuicSpdyStreamTest, ReadAfterReset) {
3534   if (!UsesHttp3()) {
3535     return;
3536   }
3537 
3538   Initialize(!kShouldProcessData);
3539 
3540   ProcessHeaders(false, headers_);
3541   stream_->ConsumeHeaderList();
3542 
3543   std::string data_frame = DataFrame(kDataFramePayload);
3544   QuicStreamFrame frame(stream_->id(), /* fin = */ false, 0, data_frame);
3545   stream_->OnStreamFrame(frame);
3546 
3547   if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
3548     // As a result of resetting the stream, stream type and stream cancellation
3549     // are sent on the QPACK decoder stream.
3550     auto qpack_decoder_stream =
3551         QuicSpdySessionPeer::GetQpackDecoderSendStream(session_.get());
3552     EXPECT_CALL(*session_,
3553                 WritevData(qpack_decoder_stream->id(), _, _, NO_FIN, _, _))
3554         .Times(2);
3555   }
3556 
3557   stream_->OnStreamReset(QuicRstStreamFrame(
3558       kInvalidControlFrameId, stream_->id(), QUIC_STREAM_NO_ERROR, 0));
3559 
3560   char buffer[100];
3561   struct iovec vec;
3562   vec.iov_base = buffer;
3563   vec.iov_len = ABSL_ARRAYSIZE(buffer);
3564 
3565   size_t bytes_read = stream_->Readv(&vec, 1);
3566   EXPECT_EQ(0u, bytes_read);
3567 }
3568 
TEST_P(QuicSpdyStreamTest,ColonDisallowedInHeaderName)3569 TEST_P(QuicSpdyStreamTest, ColonDisallowedInHeaderName) {
3570   if (!UsesHttp3()) {
3571     return;
3572   }
3573 
3574   Initialize(kShouldProcessData);
3575 
3576   headers_["foo:bar"] = "invalid";
3577   EXPECT_FALSE(stream_->ValidateReceivedHeaders(AsHeaderList(headers_)));
3578   EXPECT_EQ("Invalid character in header name foo:bar",
3579             stream_->invalid_request_details());
3580 }
3581 
3582 }  // namespace
3583 }  // namespace test
3584 }  // namespace quic
3585