xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2012 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_session.h"
6 
7 #include <cstdint>
8 #include <limits>
9 #include <set>
10 #include <string>
11 #include <utility>
12 
13 #include "absl/base/macros.h"
14 #include "absl/memory/memory.h"
15 #include "absl/strings/escaping.h"
16 #include "absl/strings/str_cat.h"
17 #include "absl/strings/string_view.h"
18 #include "quiche/quic/core/crypto/crypto_protocol.h"
19 #include "quiche/quic/core/frames/quic_stream_frame.h"
20 #include "quiche/quic/core/frames/quic_streams_blocked_frame.h"
21 #include "quiche/quic/core/http/http_constants.h"
22 #include "quiche/quic/core/http/http_encoder.h"
23 #include "quiche/quic/core/http/quic_header_list.h"
24 #include "quiche/quic/core/http/web_transport_http3.h"
25 #include "quiche/quic/core/qpack/qpack_header_table.h"
26 #include "quiche/quic/core/quic_config.h"
27 #include "quiche/quic/core/quic_crypto_stream.h"
28 #include "quiche/quic/core/quic_data_writer.h"
29 #include "quiche/quic/core/quic_error_codes.h"
30 #include "quiche/quic/core/quic_packets.h"
31 #include "quiche/quic/core/quic_stream.h"
32 #include "quiche/quic/core/quic_stream_priority.h"
33 #include "quiche/quic/core/quic_types.h"
34 #include "quiche/quic/core/quic_utils.h"
35 #include "quiche/quic/core/quic_versions.h"
36 #include "quiche/quic/platform/api/quic_expect_bug.h"
37 #include "quiche/quic/platform/api/quic_flags.h"
38 #include "quiche/quic/platform/api/quic_test.h"
39 #include "quiche/quic/test_tools/qpack/qpack_encoder_peer.h"
40 #include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
41 #include "quiche/quic/test_tools/quic_config_peer.h"
42 #include "quiche/quic/test_tools/quic_connection_peer.h"
43 #include "quiche/quic/test_tools/quic_flow_controller_peer.h"
44 #include "quiche/quic/test_tools/quic_session_peer.h"
45 #include "quiche/quic/test_tools/quic_spdy_session_peer.h"
46 #include "quiche/quic/test_tools/quic_stream_peer.h"
47 #include "quiche/quic/test_tools/quic_stream_send_buffer_peer.h"
48 #include "quiche/quic/test_tools/quic_test_utils.h"
49 #include "quiche/common/platform/api/quiche_mem_slice.h"
50 #include "quiche/common/quiche_endian.h"
51 #include "quiche/common/test_tools/quiche_test_utils.h"
52 #include "quiche/spdy/core/spdy_framer.h"
53 
54 using spdy::Http2HeaderBlock;
55 using spdy::kV3HighestPriority;
56 using spdy::Spdy3PriorityToHttp2Weight;
57 using spdy::SpdyFramer;
58 using spdy::SpdyPriority;
59 using spdy::SpdyPriorityIR;
60 using spdy::SpdySerializedFrame;
61 using ::testing::_;
62 using ::testing::AnyNumber;
63 using ::testing::AtLeast;
64 using ::testing::ElementsAre;
65 using ::testing::InSequence;
66 using ::testing::Invoke;
67 using ::testing::Return;
68 using ::testing::StrictMock;
69 
70 namespace quic {
71 namespace test {
72 namespace {
73 
VerifyAndClearStopSendingFrame(const QuicFrame & frame)74 bool VerifyAndClearStopSendingFrame(const QuicFrame& frame) {
75   EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
76   return ClearControlFrame(frame);
77 }
78 
79 class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
80  public:
TestCryptoStream(QuicSession * session)81   explicit TestCryptoStream(QuicSession* session)
82       : QuicCryptoStream(session),
83         QuicCryptoHandshaker(this, session),
84         encryption_established_(false),
85         one_rtt_keys_available_(false),
86         params_(new QuicCryptoNegotiatedParameters) {
87     // Simulate a negotiated cipher_suite with a fake value.
88     params_->cipher_suite = 1;
89   }
90 
EstablishZeroRttEncryption()91   void EstablishZeroRttEncryption() {
92     encryption_established_ = true;
93     session()->connection()->SetEncrypter(
94         ENCRYPTION_ZERO_RTT,
95         std::make_unique<TaggingEncrypter>(ENCRYPTION_ZERO_RTT));
96   }
97 
OnHandshakeMessage(const CryptoHandshakeMessage &)98   void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
99     encryption_established_ = true;
100     one_rtt_keys_available_ = true;
101     QuicErrorCode error;
102     std::string error_details;
103     session()->config()->SetInitialStreamFlowControlWindowToSend(
104         kInitialStreamFlowControlWindowForTest);
105     session()->config()->SetInitialSessionFlowControlWindowToSend(
106         kInitialSessionFlowControlWindowForTest);
107     if (session()->version().UsesTls()) {
108       if (session()->perspective() == Perspective::IS_CLIENT) {
109         session()->config()->SetOriginalConnectionIdToSend(
110             session()->connection()->connection_id());
111         session()->config()->SetInitialSourceConnectionIdToSend(
112             session()->connection()->connection_id());
113       } else {
114         session()->config()->SetInitialSourceConnectionIdToSend(
115             session()->connection()->client_connection_id());
116       }
117       TransportParameters transport_parameters;
118       EXPECT_TRUE(
119           session()->config()->FillTransportParameters(&transport_parameters));
120       error = session()->config()->ProcessTransportParameters(
121           transport_parameters, /* is_resumption = */ false, &error_details);
122     } else {
123       CryptoHandshakeMessage msg;
124       session()->config()->ToHandshakeMessage(&msg, transport_version());
125       error =
126           session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
127     }
128     EXPECT_THAT(error, IsQuicNoError());
129     session()->OnNewEncryptionKeyAvailable(
130         ENCRYPTION_FORWARD_SECURE,
131         std::make_unique<TaggingEncrypter>(ENCRYPTION_FORWARD_SECURE));
132     session()->OnConfigNegotiated();
133     if (session()->connection()->version().handshake_protocol ==
134         PROTOCOL_TLS1_3) {
135       session()->OnTlsHandshakeComplete();
136     } else {
137       session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
138     }
139     session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
140   }
141 
142   // QuicCryptoStream implementation
EarlyDataReason() const143   ssl_early_data_reason_t EarlyDataReason() const override {
144     return ssl_early_data_unknown;
145   }
encryption_established() const146   bool encryption_established() const override {
147     return encryption_established_;
148   }
one_rtt_keys_available() const149   bool one_rtt_keys_available() const override {
150     return one_rtt_keys_available_;
151   }
GetHandshakeState() const152   HandshakeState GetHandshakeState() const override {
153     return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
154   }
SetServerApplicationStateForResumption(std::unique_ptr<ApplicationState>)155   void SetServerApplicationStateForResumption(
156       std::unique_ptr<ApplicationState> /*application_state*/) override {}
AdvanceKeysAndCreateCurrentOneRttDecrypter()157   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
158       override {
159     return nullptr;
160   }
CreateCurrentOneRttEncrypter()161   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
162     return nullptr;
163   }
crypto_negotiated_params() const164   const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
165       const override {
166     return *params_;
167   }
crypto_message_parser()168   CryptoMessageParser* crypto_message_parser() override {
169     return QuicCryptoHandshaker::crypto_message_parser();
170   }
OnPacketDecrypted(EncryptionLevel)171   void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
OnOneRttPacketAcknowledged()172   void OnOneRttPacketAcknowledged() override {}
OnHandshakePacketSent()173   void OnHandshakePacketSent() override {}
OnHandshakeDoneReceived()174   void OnHandshakeDoneReceived() override {}
OnNewTokenReceived(absl::string_view)175   void OnNewTokenReceived(absl::string_view /*token*/) override {}
GetAddressToken(const CachedNetworkParameters *) const176   std::string GetAddressToken(
177       const CachedNetworkParameters* /*cached_network_params*/) const override {
178     return "";
179   }
ValidateAddressToken(absl::string_view) const180   bool ValidateAddressToken(absl::string_view /*token*/) const override {
181     return true;
182   }
PreviousCachedNetworkParams() const183   const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
184     return nullptr;
185   }
SetPreviousCachedNetworkParams(CachedNetworkParameters)186   void SetPreviousCachedNetworkParams(
187       CachedNetworkParameters /*cached_network_params*/) override {}
188 
189   MOCK_METHOD(void, OnCanWrite, (), (override));
190 
HasPendingCryptoRetransmission() const191   bool HasPendingCryptoRetransmission() const override { return false; }
192 
193   MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
194 
OnConnectionClosed(QuicErrorCode,ConnectionCloseSource)195   void OnConnectionClosed(QuicErrorCode /*error*/,
196                           ConnectionCloseSource /*source*/) override {}
GetSsl() const197   SSL* GetSsl() const override { return nullptr; }
IsCryptoFrameExpectedForEncryptionLevel(EncryptionLevel level) const198   bool IsCryptoFrameExpectedForEncryptionLevel(
199       EncryptionLevel level) const override {
200     return level != ENCRYPTION_ZERO_RTT;
201   }
GetEncryptionLevelToSendCryptoDataOfSpace(PacketNumberSpace space) const202   EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
203       PacketNumberSpace space) const override {
204     switch (space) {
205       case INITIAL_DATA:
206         return ENCRYPTION_INITIAL;
207       case HANDSHAKE_DATA:
208         return ENCRYPTION_HANDSHAKE;
209       case APPLICATION_DATA:
210         return ENCRYPTION_FORWARD_SECURE;
211       default:
212         QUICHE_DCHECK(false);
213         return NUM_ENCRYPTION_LEVELS;
214     }
215   }
216 
ExportKeyingMaterial(absl::string_view,absl::string_view,size_t,std::string *)217   bool ExportKeyingMaterial(absl::string_view /*label*/,
218                             absl::string_view /*context*/,
219                             size_t /*result_len*/, std::string*
220                             /*result*/) override {
221     return false;
222   }
223 
224  private:
225   using QuicCryptoStream::session;
226 
227   bool encryption_established_;
228   bool one_rtt_keys_available_;
229   quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
230 };
231 
232 class TestHeadersStream : public QuicHeadersStream {
233  public:
TestHeadersStream(QuicSpdySession * session)234   explicit TestHeadersStream(QuicSpdySession* session)
235       : QuicHeadersStream(session) {}
236 
237   MOCK_METHOD(void, OnCanWrite, (), (override));
238 };
239 
240 class TestStream : public QuicSpdyStream {
241  public:
TestStream(QuicStreamId id,QuicSpdySession * session,StreamType type)242   TestStream(QuicStreamId id, QuicSpdySession* session, StreamType type)
243       : QuicSpdyStream(id, session, type) {}
244 
TestStream(PendingStream * pending,QuicSpdySession * session)245   TestStream(PendingStream* pending, QuicSpdySession* session)
246       : QuicSpdyStream(pending, session) {}
247 
248   using QuicStream::CloseWriteSide;
249 
OnBodyAvailable()250   void OnBodyAvailable() override {}
251 
252   MOCK_METHOD(void, OnCanWrite, (), (override));
253   MOCK_METHOD(bool, RetransmitStreamData,
254               (QuicStreamOffset, QuicByteCount, bool, TransmissionType),
255               (override));
256 
257   MOCK_METHOD(bool, HasPendingRetransmission, (), (const, override));
258 
259  protected:
ValidateReceivedHeaders(const QuicHeaderList &)260   bool ValidateReceivedHeaders(const QuicHeaderList& /*header_list*/) override {
261     return true;
262   }
263 };
264 
265 class TestSession : public QuicSpdySession {
266  public:
TestSession(QuicConnection * connection)267   explicit TestSession(QuicConnection* connection)
268       : QuicSpdySession(connection, nullptr, DefaultQuicConfig(),
269                         CurrentSupportedVersions()),
270         crypto_stream_(this),
271         writev_consumes_all_data_(false) {
272     this->connection()->SetEncrypter(
273         ENCRYPTION_FORWARD_SECURE,
274         std::make_unique<TaggingEncrypter>(ENCRYPTION_FORWARD_SECURE));
275     if (this->connection()->version().SupportsAntiAmplificationLimit()) {
276       QuicConnectionPeer::SetAddressValidated(this->connection());
277     }
278   }
279 
~TestSession()280   ~TestSession() override { DeleteConnection(); }
281 
GetMutableCryptoStream()282   TestCryptoStream* GetMutableCryptoStream() override {
283     return &crypto_stream_;
284   }
285 
GetCryptoStream() const286   const TestCryptoStream* GetCryptoStream() const override {
287     return &crypto_stream_;
288   }
289 
CreateOutgoingBidirectionalStream()290   TestStream* CreateOutgoingBidirectionalStream() override {
291     TestStream* stream = new TestStream(GetNextOutgoingBidirectionalStreamId(),
292                                         this, BIDIRECTIONAL);
293     ActivateStream(absl::WrapUnique(stream));
294     return stream;
295   }
296 
CreateOutgoingUnidirectionalStream()297   TestStream* CreateOutgoingUnidirectionalStream() override {
298     TestStream* stream = new TestStream(GetNextOutgoingUnidirectionalStreamId(),
299                                         this, WRITE_UNIDIRECTIONAL);
300     ActivateStream(absl::WrapUnique(stream));
301     return stream;
302   }
303 
CreateIncomingStream(QuicStreamId id)304   TestStream* CreateIncomingStream(QuicStreamId id) override {
305     // Enforce the limit on the number of open streams.
306     if (!VersionHasIetfQuicFrames(connection()->transport_version()) &&
307         stream_id_manager().num_open_incoming_streams() + 1 >
308             max_open_incoming_bidirectional_streams()) {
309       connection()->CloseConnection(
310           QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
311           ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
312       return nullptr;
313     } else {
314       TestStream* stream = new TestStream(
315           id, this,
316           DetermineStreamType(id, connection()->version(), perspective(),
317                               /*is_incoming=*/true, BIDIRECTIONAL));
318       ActivateStream(absl::WrapUnique(stream));
319       return stream;
320     }
321   }
322 
CreateIncomingStream(PendingStream * pending)323   TestStream* CreateIncomingStream(PendingStream* pending) override {
324     TestStream* stream = new TestStream(pending, this);
325     ActivateStream(absl::WrapUnique(stream));
326     return stream;
327   }
328 
ShouldCreateIncomingStream(QuicStreamId)329   bool ShouldCreateIncomingStream(QuicStreamId /*id*/) override { return true; }
330 
ShouldCreateOutgoingBidirectionalStream()331   bool ShouldCreateOutgoingBidirectionalStream() override { return true; }
ShouldCreateOutgoingUnidirectionalStream()332   bool ShouldCreateOutgoingUnidirectionalStream() override { return true; }
333 
IsClosedStream(QuicStreamId id)334   bool IsClosedStream(QuicStreamId id) {
335     return QuicSession::IsClosedStream(id);
336   }
337 
GetOrCreateStream(QuicStreamId stream_id)338   QuicStream* GetOrCreateStream(QuicStreamId stream_id) {
339     return QuicSpdySession::GetOrCreateStream(stream_id);
340   }
341 
WritevData(QuicStreamId id,size_t write_length,QuicStreamOffset offset,StreamSendingState state,TransmissionType type,EncryptionLevel level)342   QuicConsumedData WritevData(QuicStreamId id, size_t write_length,
343                               QuicStreamOffset offset, StreamSendingState state,
344                               TransmissionType type,
345                               EncryptionLevel level) override {
346     bool fin = state != NO_FIN;
347     QuicConsumedData consumed(write_length, fin);
348     if (!writev_consumes_all_data_) {
349       consumed =
350           QuicSession::WritevData(id, write_length, offset, state, type, level);
351     }
352     QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
353         id, consumed.bytes_consumed);
354     return consumed;
355   }
356 
set_writev_consumes_all_data(bool val)357   void set_writev_consumes_all_data(bool val) {
358     writev_consumes_all_data_ = val;
359   }
360 
SendStreamData(QuicStream * stream)361   QuicConsumedData SendStreamData(QuicStream* stream) {
362     if (!QuicUtils::IsCryptoStreamId(connection()->transport_version(),
363                                      stream->id()) &&
364         connection()->encryption_level() != ENCRYPTION_FORWARD_SECURE) {
365       this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
366     }
367     QuicStreamPeer::SendBuffer(stream).SaveStreamData("not empty");
368     QuicConsumedData consumed =
369         WritevData(stream->id(), 9, 0, FIN, NOT_RETRANSMISSION,
370                    GetEncryptionLevelToSendApplicationData());
371     QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
372         consumed.bytes_consumed);
373     return consumed;
374   }
375 
SendLargeFakeData(QuicStream * stream,int bytes)376   QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
377     QUICHE_DCHECK(writev_consumes_all_data_);
378     return WritevData(stream->id(), bytes, 0, FIN, NOT_RETRANSMISSION,
379                       GetEncryptionLevelToSendApplicationData());
380   }
381 
LocallySupportedWebTransportVersions() const382   WebTransportHttp3VersionSet LocallySupportedWebTransportVersions()
383       const override {
384     return locally_supported_web_transport_versions_;
385   }
set_supports_webtransport(bool value)386   void set_supports_webtransport(bool value) {
387     locally_supported_web_transport_versions_ =
388         value ? kDefaultSupportedWebTransportVersions
389               : WebTransportHttp3VersionSet();
390   }
set_locally_supported_web_transport_versions(WebTransportHttp3VersionSet versions)391   void set_locally_supported_web_transport_versions(
392       WebTransportHttp3VersionSet versions) {
393     locally_supported_web_transport_versions_ = std::move(versions);
394   }
395 
LocalHttpDatagramSupport()396   HttpDatagramSupport LocalHttpDatagramSupport() override {
397     return local_http_datagram_support_;
398   }
set_local_http_datagram_support(HttpDatagramSupport value)399   void set_local_http_datagram_support(HttpDatagramSupport value) {
400     local_http_datagram_support_ = value;
401   }
402 
403   MOCK_METHOD(void, OnAcceptChFrame, (const AcceptChFrame&), (override));
404 
405   using QuicSession::closed_streams;
406   using QuicSession::pending_streams_size;
407   using QuicSession::ShouldKeepConnectionAlive;
408   using QuicSpdySession::settings;
409   using QuicSpdySession::UsesPendingStreamForFrame;
410 
411  private:
412   StrictMock<TestCryptoStream> crypto_stream_;
413 
414   bool writev_consumes_all_data_;
415   WebTransportHttp3VersionSet locally_supported_web_transport_versions_;
416   HttpDatagramSupport local_http_datagram_support_ = HttpDatagramSupport::kNone;
417 };
418 
419 class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
420  public:
ClearMaxStreamsControlFrame(const QuicFrame & frame)421   bool ClearMaxStreamsControlFrame(const QuicFrame& frame) {
422     if (frame.type == MAX_STREAMS_FRAME) {
423       DeleteFrame(&const_cast<QuicFrame&>(frame));
424       return true;
425     }
426     return false;
427   }
428 
429  protected:
QuicSpdySessionTestBase(Perspective perspective,bool allow_extended_connect)430   explicit QuicSpdySessionTestBase(Perspective perspective,
431                                    bool allow_extended_connect)
432       : connection_(new StrictMock<MockQuicConnection>(
433             &helper_, &alarm_factory_, perspective,
434             SupportedVersions(GetParam()))),
435         allow_extended_connect_(allow_extended_connect) {}
436 
Initialize()437   void Initialize() {
438     session_.emplace(connection_);
439     if (qpack_maximum_dynamic_table_capacity_.has_value()) {
440       session_->set_qpack_maximum_dynamic_table_capacity(
441           *qpack_maximum_dynamic_table_capacity_);
442     }
443     if (connection_->perspective() == Perspective::IS_SERVER &&
444         VersionUsesHttp3(transport_version())) {
445       session_->set_allow_extended_connect(allow_extended_connect_);
446     }
447     session_->Initialize();
448     session_->config()->SetInitialStreamFlowControlWindowToSend(
449         kInitialStreamFlowControlWindowForTest);
450     session_->config()->SetInitialSessionFlowControlWindowToSend(
451         kInitialSessionFlowControlWindowForTest);
452     if (VersionUsesHttp3(transport_version())) {
453       QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(
454           session_->config(), kHttp3StaticUnidirectionalStreamCount);
455     }
456     QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(
457         session_->config(), kMinimumFlowControlSendWindow);
458     QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesUnidirectional(
459         session_->config(), kMinimumFlowControlSendWindow);
460     QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesIncomingBidirectional(
461         session_->config(), kMinimumFlowControlSendWindow);
462     QuicConfigPeer::SetReceivedInitialMaxStreamDataBytesOutgoingBidirectional(
463         session_->config(), kMinimumFlowControlSendWindow);
464     session_->OnConfigNegotiated();
465     connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
466     TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
467     EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
468         .Times(testing::AnyNumber());
469     writer_ = static_cast<MockPacketWriter*>(
470         QuicConnectionPeer::GetWriter(session_->connection()));
471   }
472 
CheckClosedStreams()473   void CheckClosedStreams() {
474     QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
475         transport_version(), Perspective::IS_CLIENT);
476     if (!QuicVersionUsesCryptoFrames(transport_version())) {
477       first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
478     }
479     for (QuicStreamId i = first_stream_id; i < 100; i++) {
480       if (closed_streams_.find(i) == closed_streams_.end()) {
481         EXPECT_FALSE(session_->IsClosedStream(i)) << " stream id: " << i;
482       } else {
483         EXPECT_TRUE(session_->IsClosedStream(i)) << " stream id: " << i;
484       }
485     }
486   }
487 
CloseStream(QuicStreamId id)488   void CloseStream(QuicStreamId id) {
489     if (!VersionHasIetfQuicFrames(transport_version())) {
490       EXPECT_CALL(*connection_, SendControlFrame(_))
491           .WillOnce(Invoke(&ClearControlFrame));
492     } else {
493       // IETF QUIC has two frames, RST_STREAM and STOP_SENDING
494       EXPECT_CALL(*connection_, SendControlFrame(_))
495           .Times(2)
496           .WillRepeatedly(Invoke(&ClearControlFrame));
497     }
498     EXPECT_CALL(*connection_, OnStreamReset(id, _));
499 
500     // QPACK streams might write data upon stream reset. Let the test session
501     // handle the data.
502     session_->set_writev_consumes_all_data(true);
503 
504     session_->ResetStream(id, QUIC_STREAM_CANCELLED);
505     closed_streams_.insert(id);
506   }
507 
version() const508   ParsedQuicVersion version() const { return connection_->version(); }
509 
transport_version() const510   QuicTransportVersion transport_version() const {
511     return connection_->transport_version();
512   }
513 
GetNthClientInitiatedBidirectionalId(int n)514   QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
515     return GetNthClientInitiatedBidirectionalStreamId(transport_version(), n);
516   }
517 
GetNthServerInitiatedBidirectionalId(int n)518   QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
519     return GetNthServerInitiatedBidirectionalStreamId(transport_version(), n);
520   }
521 
IdDelta()522   QuicStreamId IdDelta() {
523     return QuicUtils::StreamIdDelta(transport_version());
524   }
525 
StreamCountToId(QuicStreamCount stream_count,Perspective perspective,bool bidirectional)526   QuicStreamId StreamCountToId(QuicStreamCount stream_count,
527                                Perspective perspective, bool bidirectional) {
528     // Calculate and build up stream ID rather than use
529     // GetFirst... because the test that relies on this method
530     // needs to do the stream count where #1 is 0/1/2/3, and not
531     // take into account that stream 0 is special.
532     QuicStreamId id =
533         ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
534     if (!bidirectional) {
535       id |= 0x2;
536     }
537     if (perspective == Perspective::IS_SERVER) {
538       id |= 0x1;
539     }
540     return id;
541   }
542 
CompleteHandshake()543   void CompleteHandshake() {
544     if (VersionHasIetfQuicFrames(transport_version())) {
545       EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
546           .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
547     }
548     if (connection_->version().UsesTls() &&
549         connection_->perspective() == Perspective::IS_SERVER) {
550       // HANDSHAKE_DONE frame.
551       EXPECT_CALL(*connection_, SendControlFrame(_))
552           .WillOnce(Invoke(&ClearControlFrame));
553     }
554 
555     CryptoHandshakeMessage message;
556     session_->GetMutableCryptoStream()->OnHandshakeMessage(message);
557     testing::Mock::VerifyAndClearExpectations(writer_);
558     testing::Mock::VerifyAndClearExpectations(connection_);
559   }
560 
ReceiveWebTransportSettings(WebTransportHttp3VersionSet versions=kDefaultSupportedWebTransportVersions)561   void ReceiveWebTransportSettings(WebTransportHttp3VersionSet versions =
562                                        kDefaultSupportedWebTransportVersions) {
563     SettingsFrame settings;
564     settings.values[SETTINGS_H3_DATAGRAM] = 1;
565     if (versions.IsSet(WebTransportHttp3Version::kDraft02)) {
566       settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
567     }
568     if (versions.IsSet(WebTransportHttp3Version::kDraft07)) {
569       settings.values[SETTINGS_WEBTRANS_MAX_SESSIONS_DRAFT07] = 16;
570     }
571     settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
572     std::string data = std::string(1, kControlStream) +
573                        HttpEncoder::SerializeSettingsFrame(settings);
574     QuicStreamId control_stream_id =
575         session_->perspective() == Perspective::IS_SERVER
576             ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(),
577                                                           3)
578             : GetNthServerInitiatedUnidirectionalStreamId(transport_version(),
579                                                           3);
580     QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
581     session_->OnStreamFrame(frame);
582   }
583 
ReceiveWebTransportSession(WebTransportSessionId session_id)584   void ReceiveWebTransportSession(WebTransportSessionId session_id) {
585     QuicStreamFrame frame(session_id, /*fin=*/false, /*offset=*/0,
586                           absl::string_view());
587     session_->OnStreamFrame(frame);
588     QuicSpdyStream* stream =
589         static_cast<QuicSpdyStream*>(session_->GetOrCreateStream(session_id));
590     QuicHeaderList headers;
591     headers.OnHeaderBlockStart();
592     headers.OnHeader(":method", "CONNECT");
593     headers.OnHeader(":protocol", "webtransport");
594     stream->OnStreamHeaderList(/*fin=*/true, 0, headers);
595     WebTransportHttp3* web_transport =
596         session_->GetWebTransportSession(session_id);
597     ASSERT_TRUE(web_transport != nullptr);
598     spdy::Http2HeaderBlock header_block;
599     web_transport->HeadersReceived(header_block);
600   }
601 
ReceiveWebTransportUnidirectionalStream(WebTransportSessionId session_id,QuicStreamId stream_id)602   void ReceiveWebTransportUnidirectionalStream(WebTransportSessionId session_id,
603                                                QuicStreamId stream_id) {
604     char buffer[256];
605     QuicDataWriter data_writer(sizeof(buffer), buffer);
606     ASSERT_TRUE(data_writer.WriteVarInt62(kWebTransportUnidirectionalStream));
607     ASSERT_TRUE(data_writer.WriteVarInt62(session_id));
608     ASSERT_TRUE(data_writer.WriteStringPiece("test data"));
609     std::string data(buffer, data_writer.length());
610     QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
611     session_->OnStreamFrame(frame);
612   }
613 
614   void TestHttpDatagramSetting(HttpDatagramSupport local_support,
615                                HttpDatagramSupport remote_support,
616                                HttpDatagramSupport expected_support,
617                                bool expected_datagram_supported);
618 
619   MockQuicConnectionHelper helper_;
620   MockAlarmFactory alarm_factory_;
621   StrictMock<MockQuicConnection>* connection_;
622   bool allow_extended_connect_;
623   std::optional<TestSession> session_;
624   std::set<QuicStreamId> closed_streams_;
625   std::optional<uint64_t> qpack_maximum_dynamic_table_capacity_;
626   MockPacketWriter* writer_;
627 };
628 
629 class QuicSpdySessionTestServer : public QuicSpdySessionTestBase {
630  protected:
QuicSpdySessionTestServer()631   QuicSpdySessionTestServer()
632       : QuicSpdySessionTestBase(Perspective::IS_SERVER, true) {}
633 };
634 
635 INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServer,
636                          ::testing::ValuesIn(AllSupportedVersions()),
637                          ::testing::PrintToStringParamName());
638 
TEST_P(QuicSpdySessionTestServer,UsesPendingStreamsForFrame)639 TEST_P(QuicSpdySessionTestServer, UsesPendingStreamsForFrame) {
640   Initialize();
641   if (!VersionUsesHttp3(transport_version())) {
642     return;
643   }
644   EXPECT_TRUE(session_->UsesPendingStreamForFrame(
645       STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
646                         transport_version(), Perspective::IS_CLIENT)));
647   EXPECT_TRUE(session_->UsesPendingStreamForFrame(
648       RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
649                             transport_version(), Perspective::IS_CLIENT)));
650   EXPECT_FALSE(session_->UsesPendingStreamForFrame(
651       RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
652                             transport_version(), Perspective::IS_SERVER)));
653   EXPECT_FALSE(session_->UsesPendingStreamForFrame(
654       STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
655                               transport_version(), Perspective::IS_CLIENT)));
656   EXPECT_FALSE(session_->UsesPendingStreamForFrame(
657       RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
658                             transport_version(), Perspective::IS_CLIENT)));
659 }
660 
TEST_P(QuicSpdySessionTestServer,PeerAddress)661 TEST_P(QuicSpdySessionTestServer, PeerAddress) {
662   Initialize();
663   EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
664             session_->peer_address());
665 }
666 
TEST_P(QuicSpdySessionTestServer,SelfAddress)667 TEST_P(QuicSpdySessionTestServer, SelfAddress) {
668   Initialize();
669   EXPECT_TRUE(session_->self_address().IsInitialized());
670 }
671 
TEST_P(QuicSpdySessionTestServer,OneRttKeysAvailable)672 TEST_P(QuicSpdySessionTestServer, OneRttKeysAvailable) {
673   Initialize();
674   EXPECT_FALSE(session_->OneRttKeysAvailable());
675   CompleteHandshake();
676   EXPECT_TRUE(session_->OneRttKeysAvailable());
677 }
678 
TEST_P(QuicSpdySessionTestServer,IsClosedStreamDefault)679 TEST_P(QuicSpdySessionTestServer, IsClosedStreamDefault) {
680   Initialize();
681   // Ensure that no streams are initially closed.
682   QuicStreamId first_stream_id = QuicUtils::GetFirstBidirectionalStreamId(
683       transport_version(), Perspective::IS_CLIENT);
684   if (!QuicVersionUsesCryptoFrames(transport_version())) {
685     first_stream_id = QuicUtils::GetCryptoStreamId(transport_version());
686   }
687   for (QuicStreamId i = first_stream_id; i < 100; i++) {
688     EXPECT_FALSE(session_->IsClosedStream(i)) << "stream id: " << i;
689   }
690 }
691 
TEST_P(QuicSpdySessionTestServer,AvailableStreams)692 TEST_P(QuicSpdySessionTestServer, AvailableStreams) {
693   Initialize();
694   ASSERT_TRUE(session_->GetOrCreateStream(
695                   GetNthClientInitiatedBidirectionalId(2)) != nullptr);
696   // Both client initiated streams with smaller stream IDs are available.
697   EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
698       &*session_, GetNthClientInitiatedBidirectionalId(0)));
699   EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
700       &*session_, GetNthClientInitiatedBidirectionalId(1)));
701   ASSERT_TRUE(session_->GetOrCreateStream(
702                   GetNthClientInitiatedBidirectionalId(1)) != nullptr);
703   ASSERT_TRUE(session_->GetOrCreateStream(
704                   GetNthClientInitiatedBidirectionalId(0)) != nullptr);
705 }
706 
TEST_P(QuicSpdySessionTestServer,IsClosedStreamLocallyCreated)707 TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) {
708   Initialize();
709   CompleteHandshake();
710   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
711   EXPECT_EQ(GetNthServerInitiatedBidirectionalId(0), stream2->id());
712   QuicSpdyStream* stream4 = session_->CreateOutgoingBidirectionalStream();
713   EXPECT_EQ(GetNthServerInitiatedBidirectionalId(1), stream4->id());
714 
715   CheckClosedStreams();
716   CloseStream(GetNthServerInitiatedBidirectionalId(0));
717   CheckClosedStreams();
718   CloseStream(GetNthServerInitiatedBidirectionalId(1));
719   CheckClosedStreams();
720 }
721 
TEST_P(QuicSpdySessionTestServer,IsClosedStreamPeerCreated)722 TEST_P(QuicSpdySessionTestServer, IsClosedStreamPeerCreated) {
723   Initialize();
724   CompleteHandshake();
725   QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
726   QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
727   session_->GetOrCreateStream(stream_id1);
728   session_->GetOrCreateStream(stream_id2);
729 
730   CheckClosedStreams();
731   CloseStream(stream_id1);
732   CheckClosedStreams();
733   CloseStream(stream_id2);
734   // Create a stream, and make another available.
735   QuicStream* stream3 = session_->GetOrCreateStream(stream_id2 + 4);
736   CheckClosedStreams();
737   // Close one, but make sure the other is still not closed
738   CloseStream(stream3->id());
739   CheckClosedStreams();
740 }
741 
TEST_P(QuicSpdySessionTestServer,MaximumAvailableOpenedStreams)742 TEST_P(QuicSpdySessionTestServer, MaximumAvailableOpenedStreams) {
743   Initialize();
744   if (VersionHasIetfQuicFrames(transport_version())) {
745     // For IETF QUIC, we should be able to obtain the max allowed
746     // stream ID, the next ID should fail. Since the actual limit
747     // is not the number of open streams, we allocate the max and the max+2.
748     // Get the max allowed stream ID, this should succeed.
749     QuicStreamId stream_id = StreamCountToId(
750         QuicSessionPeer::ietf_streamid_manager(&*session_)
751             ->max_incoming_bidirectional_streams(),
752         Perspective::IS_CLIENT,  // Client initates stream, allocs stream id.
753         /*bidirectional=*/true);
754     EXPECT_NE(nullptr, session_->GetOrCreateStream(stream_id));
755     stream_id =
756         StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&*session_)
757                             ->max_incoming_unidirectional_streams(),
758                         Perspective::IS_CLIENT,
759                         /*bidirectional=*/false);
760     EXPECT_NE(nullptr, session_->GetOrCreateStream(stream_id));
761     EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(2);
762     // Get the (max allowed stream ID)++. These should all fail.
763     stream_id =
764         StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&*session_)
765                                 ->max_incoming_bidirectional_streams() +
766                             1,
767                         Perspective::IS_CLIENT,
768                         /*bidirectional=*/true);
769     EXPECT_EQ(nullptr, session_->GetOrCreateStream(stream_id));
770 
771     stream_id =
772         StreamCountToId(QuicSessionPeer::ietf_streamid_manager(&*session_)
773                                 ->max_incoming_unidirectional_streams() +
774                             1,
775                         Perspective::IS_CLIENT,
776                         /*bidirectional=*/false);
777     EXPECT_EQ(nullptr, session_->GetOrCreateStream(stream_id));
778   } else {
779     QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
780     session_->GetOrCreateStream(stream_id);
781     EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
782     EXPECT_NE(
783         nullptr,
784         session_->GetOrCreateStream(
785             stream_id +
786             IdDelta() *
787                 (session_->max_open_incoming_bidirectional_streams() - 1)));
788   }
789 }
790 
TEST_P(QuicSpdySessionTestServer,TooManyAvailableStreams)791 TEST_P(QuicSpdySessionTestServer, TooManyAvailableStreams) {
792   Initialize();
793   QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
794   QuicStreamId stream_id2;
795   EXPECT_NE(nullptr, session_->GetOrCreateStream(stream_id1));
796   // A stream ID which is too large to create.
797   stream_id2 = GetNthClientInitiatedBidirectionalId(
798       2 * session_->MaxAvailableBidirectionalStreams() + 4);
799   if (VersionHasIetfQuicFrames(transport_version())) {
800     EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
801   } else {
802     EXPECT_CALL(*connection_,
803                 CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
804   }
805   EXPECT_EQ(nullptr, session_->GetOrCreateStream(stream_id2));
806 }
807 
TEST_P(QuicSpdySessionTestServer,ManyAvailableStreams)808 TEST_P(QuicSpdySessionTestServer, ManyAvailableStreams) {
809   Initialize();
810   // When max_open_streams_ is 200, should be able to create 200 streams
811   // out-of-order, that is, creating the one with the largest stream ID first.
812   if (VersionHasIetfQuicFrames(transport_version())) {
813     QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&*session_, 200);
814   } else {
815     QuicSessionPeer::SetMaxOpenIncomingStreams(&*session_, 200);
816   }
817   QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
818   // Create one stream.
819   session_->GetOrCreateStream(stream_id);
820   EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
821   // Stream count is 200, GetNth... starts counting at 0, so the 200'th stream
822   // is 199. BUT actually we need to do 198 because the crypto stream (Stream
823   // ID 0) has not been registered, but GetNth... assumes that it has.
824   EXPECT_NE(nullptr, session_->GetOrCreateStream(
825                          GetNthClientInitiatedBidirectionalId(198)));
826 }
827 
TEST_P(QuicSpdySessionTestServer,DebugDFatalIfMarkingClosedStreamWriteBlocked)828 TEST_P(QuicSpdySessionTestServer,
829        DebugDFatalIfMarkingClosedStreamWriteBlocked) {
830   Initialize();
831   CompleteHandshake();
832   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
833       .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
834 
835   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
836   QuicStreamId closed_stream_id = stream2->id();
837   // Close the stream.
838   EXPECT_CALL(*connection_, SendControlFrame(_));
839   EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
840   stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
841   std::string msg =
842       absl::StrCat("Marking unknown stream ", closed_stream_id, " blocked.");
843   EXPECT_QUIC_BUG(session_->MarkConnectionLevelWriteBlocked(closed_stream_id),
844                   msg);
845 }
846 
TEST_P(QuicSpdySessionTestServer,TooLargeStreamBlocked)847 TEST_P(QuicSpdySessionTestServer, TooLargeStreamBlocked) {
848   Initialize();
849   // STREAMS_BLOCKED frame is IETF QUIC only.
850   if (!VersionUsesHttp3(transport_version())) {
851     return;
852   }
853 
854   CompleteHandshake();
855   StrictMock<MockHttp3DebugVisitor> debug_visitor;
856   session_->set_debug_visitor(&debug_visitor);
857 
858   // Simualte the situation where the incoming stream count is at its limit and
859   // the peer is blocked.
860   QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(
861       static_cast<QuicSession*>(&*session_), QuicUtils::GetMaxStreamCount());
862   QuicStreamsBlockedFrame frame;
863   frame.stream_count = QuicUtils::GetMaxStreamCount();
864   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
865       .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
866   EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(_));
867   session_->OnStreamsBlockedFrame(frame);
868 }
869 
TEST_P(QuicSpdySessionTestServer,OnCanWriteBundlesStreams)870 TEST_P(QuicSpdySessionTestServer, OnCanWriteBundlesStreams) {
871   Initialize();
872   // Encryption needs to be established before data can be sent.
873   CompleteHandshake();
874 
875   // Drive congestion control manually.
876   MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
877   QuicConnectionPeer::SetSendAlgorithm(session_->connection(), send_algorithm);
878 
879   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
880   TestStream* stream4 = session_->CreateOutgoingBidirectionalStream();
881   TestStream* stream6 = session_->CreateOutgoingBidirectionalStream();
882 
883   session_->MarkConnectionLevelWriteBlocked(stream2->id());
884   session_->MarkConnectionLevelWriteBlocked(stream6->id());
885   session_->MarkConnectionLevelWriteBlocked(stream4->id());
886 
887   EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
888   EXPECT_CALL(*send_algorithm, GetCongestionWindow())
889       .WillRepeatedly(Return(kMaxOutgoingPacketSize * 10));
890   EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
891   EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
892     session_->SendStreamData(stream2);
893   }));
894   EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
895     session_->SendStreamData(stream4);
896   }));
897   EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
898     session_->SendStreamData(stream6);
899   }));
900 
901   // Expect that we only send one packet, the writes from different streams
902   // should be bundled together.
903   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
904       .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
905   EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
906   EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
907   session_->OnCanWrite();
908   EXPECT_FALSE(session_->WillingAndAbleToWrite());
909 }
910 
TEST_P(QuicSpdySessionTestServer,OnCanWriteCongestionControlBlocks)911 TEST_P(QuicSpdySessionTestServer, OnCanWriteCongestionControlBlocks) {
912   Initialize();
913   CompleteHandshake();
914   session_->set_writev_consumes_all_data(true);
915   InSequence s;
916 
917   // Drive congestion control manually.
918   MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
919   QuicConnectionPeer::SetSendAlgorithm(session_->connection(), send_algorithm);
920 
921   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
922   TestStream* stream4 = session_->CreateOutgoingBidirectionalStream();
923   TestStream* stream6 = session_->CreateOutgoingBidirectionalStream();
924 
925   session_->MarkConnectionLevelWriteBlocked(stream2->id());
926   session_->MarkConnectionLevelWriteBlocked(stream6->id());
927   session_->MarkConnectionLevelWriteBlocked(stream4->id());
928 
929   EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
930   EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
931     session_->SendStreamData(stream2);
932   }));
933   EXPECT_CALL(*send_algorithm, GetCongestionWindow()).Times(AnyNumber());
934   EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
935   EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
936     session_->SendStreamData(stream6);
937   }));
938   EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
939   // stream4->OnCanWrite is not called.
940 
941   session_->OnCanWrite();
942   EXPECT_TRUE(session_->WillingAndAbleToWrite());
943 
944   // Still congestion-control blocked.
945   EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
946   session_->OnCanWrite();
947   EXPECT_TRUE(session_->WillingAndAbleToWrite());
948 
949   // stream4->OnCanWrite is called once the connection stops being
950   // congestion-control blocked.
951   EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
952   EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
953     session_->SendStreamData(stream4);
954   }));
955   EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
956   session_->OnCanWrite();
957   EXPECT_FALSE(session_->WillingAndAbleToWrite());
958 }
959 
TEST_P(QuicSpdySessionTestServer,OnCanWriteWriterBlocks)960 TEST_P(QuicSpdySessionTestServer, OnCanWriteWriterBlocks) {
961   Initialize();
962   CompleteHandshake();
963   // Drive congestion control manually in order to ensure that
964   // application-limited signaling is handled correctly.
965   MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
966   QuicConnectionPeer::SetSendAlgorithm(session_->connection(), send_algorithm);
967   EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
968 
969   // Drive packet writer manually.
970   EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
971   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _)).Times(0);
972 
973   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
974 
975   session_->MarkConnectionLevelWriteBlocked(stream2->id());
976 
977   EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
978   EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
979 
980   session_->OnCanWrite();
981   EXPECT_TRUE(session_->WillingAndAbleToWrite());
982 }
983 
TEST_P(QuicSpdySessionTestServer,BufferedHandshake)984 TEST_P(QuicSpdySessionTestServer, BufferedHandshake) {
985   Initialize();
986   // This tests prioritization of the crypto stream when flow control limits are
987   // reached. When CRYPTO frames are in use, there is no flow control for the
988   // crypto handshake, so this test is irrelevant.
989   if (QuicVersionUsesCryptoFrames(transport_version())) {
990     return;
991   }
992   session_->set_writev_consumes_all_data(true);
993   EXPECT_FALSE(session_->HasPendingHandshake());  // Default value.
994 
995   // Test that blocking other streams does not change our status.
996   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
997   session_->MarkConnectionLevelWriteBlocked(stream2->id());
998   EXPECT_FALSE(session_->HasPendingHandshake());
999 
1000   TestStream* stream3 = session_->CreateOutgoingBidirectionalStream();
1001   session_->MarkConnectionLevelWriteBlocked(stream3->id());
1002   EXPECT_FALSE(session_->HasPendingHandshake());
1003 
1004   // Blocking (due to buffering of) the Crypto stream is detected.
1005   session_->MarkConnectionLevelWriteBlocked(
1006       QuicUtils::GetCryptoStreamId(transport_version()));
1007   EXPECT_TRUE(session_->HasPendingHandshake());
1008 
1009   TestStream* stream4 = session_->CreateOutgoingBidirectionalStream();
1010   session_->MarkConnectionLevelWriteBlocked(stream4->id());
1011   EXPECT_TRUE(session_->HasPendingHandshake());
1012 
1013   InSequence s;
1014   // Force most streams to re-register, which is common scenario when we block
1015   // the Crypto stream, and only the crypto stream can "really" write.
1016 
1017   // Due to prioritization, we *should* be asked to write the crypto stream
1018   // first.
1019   // Don't re-register the crypto stream (which signals complete writing).
1020   TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
1021   EXPECT_CALL(*crypto_stream, OnCanWrite());
1022 
1023   EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
1024     session_->SendStreamData(stream2);
1025   }));
1026   EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
1027     session_->SendStreamData(stream3);
1028   }));
1029   EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
1030     session_->SendStreamData(stream4);
1031     session_->MarkConnectionLevelWriteBlocked(stream4->id());
1032   }));
1033 
1034   session_->OnCanWrite();
1035   EXPECT_TRUE(session_->WillingAndAbleToWrite());
1036   EXPECT_FALSE(session_->HasPendingHandshake());  // Crypto stream wrote.
1037 }
1038 
TEST_P(QuicSpdySessionTestServer,OnCanWriteWithClosedStream)1039 TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) {
1040   Initialize();
1041   CompleteHandshake();
1042   session_->set_writev_consumes_all_data(true);
1043   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
1044   TestStream* stream4 = session_->CreateOutgoingBidirectionalStream();
1045   TestStream* stream6 = session_->CreateOutgoingBidirectionalStream();
1046 
1047   session_->MarkConnectionLevelWriteBlocked(stream2->id());
1048   session_->MarkConnectionLevelWriteBlocked(stream6->id());
1049   session_->MarkConnectionLevelWriteBlocked(stream4->id());
1050   CloseStream(stream6->id());
1051 
1052   InSequence s;
1053   EXPECT_CALL(*connection_, SendControlFrame(_))
1054       .WillRepeatedly(Invoke(&ClearControlFrame));
1055   EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
1056     session_->SendStreamData(stream2);
1057   }));
1058   EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
1059     session_->SendStreamData(stream4);
1060   }));
1061   session_->OnCanWrite();
1062   EXPECT_FALSE(session_->WillingAndAbleToWrite());
1063 }
1064 
TEST_P(QuicSpdySessionTestServer,OnCanWriteLimitsNumWritesIfFlowControlBlocked)1065 TEST_P(QuicSpdySessionTestServer,
1066        OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
1067   Initialize();
1068   CompleteHandshake();
1069   // Drive congestion control manually in order to ensure that
1070   // application-limited signaling is handled correctly.
1071   MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
1072   QuicConnectionPeer::SetSendAlgorithm(session_->connection(), send_algorithm);
1073   EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
1074 
1075   // Ensure connection level flow control blockage.
1076   QuicFlowControllerPeer::SetSendWindowOffset(session_->flow_controller(), 0);
1077   EXPECT_TRUE(session_->flow_controller()->IsBlocked());
1078   EXPECT_TRUE(session_->IsConnectionFlowControlBlocked());
1079   EXPECT_FALSE(session_->IsStreamFlowControlBlocked());
1080 
1081   // Mark the crypto and headers streams as write blocked, we expect them to be
1082   // allowed to write later.
1083   if (!QuicVersionUsesCryptoFrames(transport_version())) {
1084     session_->MarkConnectionLevelWriteBlocked(
1085         QuicUtils::GetCryptoStreamId(transport_version()));
1086   }
1087 
1088   // Create a data stream, and although it is write blocked we never expect it
1089   // to be allowed to write as we are connection level flow control blocked.
1090   TestStream* stream = session_->CreateOutgoingBidirectionalStream();
1091   session_->MarkConnectionLevelWriteBlocked(stream->id());
1092   EXPECT_CALL(*stream, OnCanWrite()).Times(0);
1093 
1094   // The crypto and headers streams should be called even though we are
1095   // connection flow control blocked.
1096   if (!QuicVersionUsesCryptoFrames(transport_version())) {
1097     TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
1098     EXPECT_CALL(*crypto_stream, OnCanWrite());
1099   }
1100 
1101   if (!VersionUsesHttp3(transport_version())) {
1102     TestHeadersStream* headers_stream;
1103     QuicSpdySessionPeer::SetHeadersStream(&*session_, nullptr);
1104     headers_stream = new TestHeadersStream(&*session_);
1105     QuicSpdySessionPeer::SetHeadersStream(&*session_, headers_stream);
1106     session_->MarkConnectionLevelWriteBlocked(
1107         QuicUtils::GetHeadersStreamId(transport_version()));
1108     EXPECT_CALL(*headers_stream, OnCanWrite());
1109   }
1110 
1111   // After the crypto and header streams perform a write, the connection will be
1112   // blocked by the flow control, hence it should become application-limited.
1113   EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
1114 
1115   session_->OnCanWrite();
1116   EXPECT_FALSE(session_->WillingAndAbleToWrite());
1117 }
1118 
TEST_P(QuicSpdySessionTestServer,SendGoAway)1119 TEST_P(QuicSpdySessionTestServer, SendGoAway) {
1120   Initialize();
1121   CompleteHandshake();
1122   if (VersionHasIetfQuicFrames(transport_version())) {
1123     // HTTP/3 GOAWAY has different semantic and thus has its own test.
1124     return;
1125   }
1126   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
1127   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
1128       .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1129 
1130   EXPECT_CALL(*connection_, SendControlFrame(_))
1131       .WillOnce(
1132           Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
1133   session_->SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1134   EXPECT_TRUE(session_->goaway_sent());
1135 
1136   const QuicStreamId kTestStreamId = 5u;
1137   EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
1138   EXPECT_CALL(*connection_,
1139               OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
1140       .Times(0);
1141   EXPECT_TRUE(session_->GetOrCreateStream(kTestStreamId));
1142 }
1143 
TEST_P(QuicSpdySessionTestServer,SendGoAwayWithoutEncryption)1144 TEST_P(QuicSpdySessionTestServer, SendGoAwayWithoutEncryption) {
1145   Initialize();
1146   if (VersionHasIetfQuicFrames(transport_version())) {
1147     // HTTP/3 GOAWAY has different semantic and thus has its own test.
1148     return;
1149   }
1150   EXPECT_CALL(
1151       *connection_,
1152       CloseConnection(QUIC_PEER_GOING_AWAY, "Going Away.",
1153                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1154   EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
1155   session_->SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1156   EXPECT_FALSE(session_->goaway_sent());
1157 }
1158 
TEST_P(QuicSpdySessionTestServer,SendHttp3GoAway)1159 TEST_P(QuicSpdySessionTestServer, SendHttp3GoAway) {
1160   Initialize();
1161   if (!VersionUsesHttp3(transport_version())) {
1162     return;
1163   }
1164 
1165   CompleteHandshake();
1166   StrictMock<MockHttp3DebugVisitor> debug_visitor;
1167   session_->set_debug_visitor(&debug_visitor);
1168 
1169   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
1170       .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1171   // Send max stream id (currently 32 bits).
1172   EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
1173   session_->SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
1174   EXPECT_TRUE(session_->goaway_sent());
1175 
1176   // New incoming stream is not reset.
1177   const QuicStreamId kTestStreamId =
1178       GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
1179   EXPECT_CALL(*connection_, OnStreamReset(kTestStreamId, _)).Times(0);
1180   EXPECT_TRUE(session_->GetOrCreateStream(kTestStreamId));
1181 
1182   // No more GOAWAY frames are sent because they could not convey new
1183   // information to the client.
1184   session_->SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
1185 }
1186 
TEST_P(QuicSpdySessionTestServer,SendHttp3GoAwayAndNoMoreMaxStreams)1187 TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAndNoMoreMaxStreams) {
1188   Initialize();
1189   if (!VersionUsesHttp3(transport_version())) {
1190     return;
1191   }
1192 
1193   CompleteHandshake();
1194   StrictMock<MockHttp3DebugVisitor> debug_visitor;
1195   session_->set_debug_visitor(&debug_visitor);
1196 
1197   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
1198       .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1199   // Send max stream id (currently 32 bits).
1200   EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
1201   session_->SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
1202   EXPECT_TRUE(session_->goaway_sent());
1203 
1204   // No MAX_STREAMS frames should be sent, even after all available
1205   // streams are opened and then closed.
1206   EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
1207 
1208   const QuicStreamCount max_streams =
1209       QuicSessionPeer::ietf_streamid_manager(&*session_)
1210           ->max_incoming_bidirectional_streams();
1211   for (QuicStreamCount i = 0; i < max_streams; ++i) {
1212     QuicStreamId stream_id = StreamCountToId(
1213         i + 1,
1214         Perspective::IS_CLIENT,  // Client initates stream, allocs stream id.
1215         /*bidirectional=*/true);
1216     EXPECT_NE(nullptr, session_->GetOrCreateStream(stream_id));
1217 
1218     CloseStream(stream_id);
1219     QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
1220                                  QUIC_STREAM_CANCELLED,
1221                                  /* bytes_written = */ 0);
1222     session_->OnRstStream(rst_frame);
1223   }
1224   EXPECT_EQ(max_streams, QuicSessionPeer::ietf_streamid_manager(&*session_)
1225                              ->max_incoming_bidirectional_streams());
1226 }
1227 
TEST_P(QuicSpdySessionTestServer,SendHttp3GoAwayWithoutEncryption)1228 TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayWithoutEncryption) {
1229   Initialize();
1230   if (!VersionUsesHttp3(transport_version())) {
1231     return;
1232   }
1233   EXPECT_CALL(
1234       *connection_,
1235       CloseConnection(QUIC_PEER_GOING_AWAY, "Goaway",
1236                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1237   session_->SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
1238   EXPECT_FALSE(session_->goaway_sent());
1239 }
1240 
TEST_P(QuicSpdySessionTestServer,SendHttp3GoAwayAfterStreamIsCreated)1241 TEST_P(QuicSpdySessionTestServer, SendHttp3GoAwayAfterStreamIsCreated) {
1242   Initialize();
1243   if (!VersionUsesHttp3(transport_version())) {
1244     return;
1245   }
1246 
1247   CompleteHandshake();
1248   StrictMock<MockHttp3DebugVisitor> debug_visitor;
1249   session_->set_debug_visitor(&debug_visitor);
1250 
1251   const QuicStreamId kTestStreamId =
1252       GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
1253   EXPECT_TRUE(session_->GetOrCreateStream(kTestStreamId));
1254 
1255   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
1256       .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1257   // Send max stream id (currently 32 bits).
1258   EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
1259   session_->SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
1260   EXPECT_TRUE(session_->goaway_sent());
1261 
1262   // No more GOAWAY frames are sent because they could not convey new
1263   // information to the client.
1264   session_->SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "Goaway");
1265 }
1266 
TEST_P(QuicSpdySessionTestServer,DoNotSendGoAwayTwice)1267 TEST_P(QuicSpdySessionTestServer, DoNotSendGoAwayTwice) {
1268   Initialize();
1269   CompleteHandshake();
1270   if (VersionHasIetfQuicFrames(transport_version())) {
1271     // HTTP/3 GOAWAY doesn't have such restriction.
1272     return;
1273   }
1274   EXPECT_CALL(*connection_, SendControlFrame(_))
1275       .WillOnce(Invoke(&ClearControlFrame));
1276   session_->SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1277   EXPECT_TRUE(session_->goaway_sent());
1278   session_->SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
1279 }
1280 
TEST_P(QuicSpdySessionTestServer,InvalidGoAway)1281 TEST_P(QuicSpdySessionTestServer, InvalidGoAway) {
1282   Initialize();
1283   if (VersionHasIetfQuicFrames(transport_version())) {
1284     // HTTP/3 GOAWAY has different semantics and thus has its own test.
1285     return;
1286   }
1287   QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
1288                           session_->next_outgoing_bidirectional_stream_id(),
1289                           "");
1290   session_->OnGoAway(go_away);
1291 }
1292 
TEST_P(QuicSpdySessionTestServer,Http3GoAwayLargerIdThanBefore)1293 TEST_P(QuicSpdySessionTestServer, Http3GoAwayLargerIdThanBefore) {
1294   Initialize();
1295   if (!VersionUsesHttp3(transport_version())) {
1296     return;
1297   }
1298 
1299   EXPECT_FALSE(session_->goaway_received());
1300   session_->OnHttp3GoAway(/* id = */ 0);
1301   EXPECT_TRUE(session_->goaway_received());
1302 
1303   EXPECT_CALL(
1304       *connection_,
1305       CloseConnection(
1306           QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
1307           "GOAWAY received with ID 1 greater than previously received ID 0",
1308           _));
1309   session_->OnHttp3GoAway(/* id = */ 1);
1310 }
1311 
1312 // Test that server session will send a connectivity probe in response to a
1313 // connectivity probe on the same path.
TEST_P(QuicSpdySessionTestServer,ServerReplyToConnecitivityProbe)1314 TEST_P(QuicSpdySessionTestServer, ServerReplyToConnecitivityProbe) {
1315   Initialize();
1316   if (VersionHasIetfQuicFrames(transport_version()) ||
1317       GetQuicReloadableFlag(quic_ignore_gquic_probing)) {
1318     return;
1319   }
1320   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
1321   QuicSocketAddress old_peer_address =
1322       QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
1323   EXPECT_EQ(old_peer_address, session_->peer_address());
1324 
1325   QuicSocketAddress new_peer_address =
1326       QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
1327 
1328   EXPECT_CALL(*connection_,
1329               SendConnectivityProbingPacket(nullptr, new_peer_address));
1330 
1331   session_->OnPacketReceived(session_->self_address(), new_peer_address,
1332                              /*is_connectivity_probe=*/true);
1333   EXPECT_EQ(old_peer_address, session_->peer_address());
1334 }
1335 
TEST_P(QuicSpdySessionTestServer,IncreasedTimeoutAfterCryptoHandshake)1336 TEST_P(QuicSpdySessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
1337   Initialize();
1338   EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
1339             QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
1340   CompleteHandshake();
1341   EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
1342             QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
1343 }
1344 
TEST_P(QuicSpdySessionTestServer,RstStreamBeforeHeadersDecompressed)1345 TEST_P(QuicSpdySessionTestServer, RstStreamBeforeHeadersDecompressed) {
1346   Initialize();
1347   CompleteHandshake();
1348   // Send two bytes of payload.
1349   QuicStreamFrame data1(GetNthClientInitiatedBidirectionalId(0), false, 0,
1350                         absl::string_view("HT"));
1351   session_->OnStreamFrame(data1);
1352   EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&*session_));
1353 
1354   if (!VersionHasIetfQuicFrames(transport_version())) {
1355     // For version99, OnStreamReset gets called because of the STOP_SENDING,
1356     // below. EXPECT the call there.
1357     EXPECT_CALL(*connection_,
1358                 OnStreamReset(GetNthClientInitiatedBidirectionalId(0), _));
1359   }
1360 
1361   // In HTTP/3, Qpack stream will send data on stream reset and cause packet to
1362   // be flushed.
1363   if (VersionUsesHttp3(transport_version()) &&
1364       !GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
1365     EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
1366         .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1367   }
1368   EXPECT_CALL(*connection_, SendControlFrame(_));
1369   QuicRstStreamFrame rst1(kInvalidControlFrameId,
1370                           GetNthClientInitiatedBidirectionalId(0),
1371                           QUIC_ERROR_PROCESSING_STREAM, 0);
1372   session_->OnRstStream(rst1);
1373 
1374   // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
1375   // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
1376   // one-way close.
1377   if (VersionHasIetfQuicFrames(transport_version())) {
1378     // Only needed for version 99/IETF QUIC.
1379     QuicStopSendingFrame stop_sending(kInvalidControlFrameId,
1380                                       GetNthClientInitiatedBidirectionalId(0),
1381                                       QUIC_ERROR_PROCESSING_STREAM);
1382     // Expect the RESET_STREAM that is generated in response to receiving a
1383     // STOP_SENDING.
1384     EXPECT_CALL(*connection_,
1385                 OnStreamReset(GetNthClientInitiatedBidirectionalId(0),
1386                               QUIC_ERROR_PROCESSING_STREAM));
1387     session_->OnStopSendingFrame(stop_sending);
1388   }
1389 
1390   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&*session_));
1391   // Connection should remain alive.
1392   EXPECT_TRUE(connection_->connected());
1393 }
1394 
TEST_P(QuicSpdySessionTestServer,OnStreamFrameFinStaticStreamId)1395 TEST_P(QuicSpdySessionTestServer, OnStreamFrameFinStaticStreamId) {
1396   Initialize();
1397   QuicStreamId id;
1398   // Initialize HTTP/3 control stream.
1399   if (VersionUsesHttp3(transport_version())) {
1400     CompleteHandshake();
1401     id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
1402     char type[] = {kControlStream};
1403 
1404     QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
1405     session_->OnStreamFrame(data1);
1406   } else {
1407     id = QuicUtils::GetHeadersStreamId(transport_version());
1408   }
1409 
1410   // Send two bytes of payload.
1411   QuicStreamFrame data1(id, true, 0, absl::string_view("HT"));
1412   EXPECT_CALL(*connection_,
1413               CloseConnection(
1414                   QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
1415                   ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1416   session_->OnStreamFrame(data1);
1417 }
1418 
TEST_P(QuicSpdySessionTestServer,OnRstStreamStaticStreamId)1419 TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) {
1420   Initialize();
1421   QuicStreamId id;
1422   QuicErrorCode expected_error;
1423   std::string error_message;
1424   // Initialize HTTP/3 control stream.
1425   if (VersionUsesHttp3(transport_version())) {
1426     CompleteHandshake();
1427     id = GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
1428     char type[] = {kControlStream};
1429 
1430     QuicStreamFrame data1(id, false, 0, absl::string_view(type, 1));
1431     session_->OnStreamFrame(data1);
1432     expected_error = QUIC_HTTP_CLOSED_CRITICAL_STREAM;
1433     error_message = "RESET_STREAM received for receive control stream";
1434   } else {
1435     id = QuicUtils::GetHeadersStreamId(transport_version());
1436     expected_error = QUIC_INVALID_STREAM_ID;
1437     error_message = "Attempt to reset headers stream";
1438   }
1439 
1440   // Send two bytes of payload.
1441   QuicRstStreamFrame rst1(kInvalidControlFrameId, id,
1442                           QUIC_ERROR_PROCESSING_STREAM, 0);
1443   EXPECT_CALL(
1444       *connection_,
1445       CloseConnection(expected_error, error_message,
1446                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1447   session_->OnRstStream(rst1);
1448 }
1449 
TEST_P(QuicSpdySessionTestServer,OnStreamFrameInvalidStreamId)1450 TEST_P(QuicSpdySessionTestServer, OnStreamFrameInvalidStreamId) {
1451   Initialize();
1452   // Send two bytes of payload.
1453   QuicStreamFrame data1(QuicUtils::GetInvalidStreamId(transport_version()),
1454                         true, 0, absl::string_view("HT"));
1455   EXPECT_CALL(*connection_,
1456               CloseConnection(
1457                   QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
1458                   ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1459   session_->OnStreamFrame(data1);
1460 }
1461 
TEST_P(QuicSpdySessionTestServer,OnRstStreamInvalidStreamId)1462 TEST_P(QuicSpdySessionTestServer, OnRstStreamInvalidStreamId) {
1463   Initialize();
1464   // Send two bytes of payload.
1465   QuicRstStreamFrame rst1(kInvalidControlFrameId,
1466                           QuicUtils::GetInvalidStreamId(transport_version()),
1467                           QUIC_ERROR_PROCESSING_STREAM, 0);
1468   EXPECT_CALL(*connection_,
1469               CloseConnection(
1470                   QUIC_INVALID_STREAM_ID, "Received data for an invalid stream",
1471                   ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
1472   session_->OnRstStream(rst1);
1473 }
1474 
TEST_P(QuicSpdySessionTestServer,HandshakeUnblocksFlowControlBlockedStream)1475 TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
1476   Initialize();
1477   if (connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
1478     // This test requires Google QUIC crypto because it assumes streams start
1479     // off unblocked.
1480     return;
1481   }
1482   // Test that if a stream is flow control blocked, then on receipt of the SHLO
1483   // containing a suitable send window offset, the stream becomes unblocked.
1484 
1485   // Ensure that Writev consumes all the data it is given (simulate no socket
1486   // blocking).
1487   session_->GetMutableCryptoStream()->EstablishZeroRttEncryption();
1488   session_->set_writev_consumes_all_data(true);
1489 
1490   // Create a stream, and send enough data to make it flow control blocked.
1491   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
1492   std::string body(kMinimumFlowControlSendWindow, '.');
1493   EXPECT_FALSE(stream2->IsFlowControlBlocked());
1494   EXPECT_FALSE(session_->IsConnectionFlowControlBlocked());
1495   EXPECT_FALSE(session_->IsStreamFlowControlBlocked());
1496   EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
1497   stream2->WriteOrBufferBody(body, false);
1498   EXPECT_TRUE(stream2->IsFlowControlBlocked());
1499   EXPECT_TRUE(session_->IsConnectionFlowControlBlocked());
1500   EXPECT_TRUE(session_->IsStreamFlowControlBlocked());
1501 
1502   // Now complete the crypto handshake, resulting in an increased flow control
1503   // send window.
1504   CompleteHandshake();
1505   EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&*session_, stream2->id()));
1506   // Stream is now unblocked.
1507   EXPECT_FALSE(stream2->IsFlowControlBlocked());
1508   EXPECT_FALSE(session_->IsConnectionFlowControlBlocked());
1509   EXPECT_FALSE(session_->IsStreamFlowControlBlocked());
1510 }
1511 
1512 #if !defined(OS_IOS)
1513 // This test is failing flakily for iOS bots.
1514 // http://crbug.com/425050
1515 // NOTE: It's not possible to use the standard MAYBE_ convention to disable
1516 // this test on iOS because when this test gets instantiated it ends up with
1517 // various names that are dependent on the parameters passed.
TEST_P(QuicSpdySessionTestServer,HandshakeUnblocksFlowControlBlockedHeadersStream)1518 TEST_P(QuicSpdySessionTestServer,
1519        HandshakeUnblocksFlowControlBlockedHeadersStream) {
1520   Initialize();
1521   // This test depends on stream-level flow control for the crypto stream, which
1522   // doesn't exist when CRYPTO frames are used.
1523   if (QuicVersionUsesCryptoFrames(transport_version())) {
1524     return;
1525   }
1526 
1527   // This test depends on the headers stream, which does not exist when QPACK is
1528   // used.
1529   if (VersionUsesHttp3(transport_version())) {
1530     return;
1531   }
1532 
1533   // Test that if the header stream is flow control blocked, then if the SHLO
1534   // contains a larger send window offset, the stream becomes unblocked.
1535   session_->GetMutableCryptoStream()->EstablishZeroRttEncryption();
1536   session_->set_writev_consumes_all_data(true);
1537   TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
1538   EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
1539   EXPECT_FALSE(session_->IsConnectionFlowControlBlocked());
1540   EXPECT_FALSE(session_->IsStreamFlowControlBlocked());
1541   QuicHeadersStream* headers_stream =
1542       QuicSpdySessionPeer::GetHeadersStream(&*session_);
1543   EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
1544   EXPECT_FALSE(session_->IsConnectionFlowControlBlocked());
1545   EXPECT_FALSE(session_->IsStreamFlowControlBlocked());
1546   QuicStreamId stream_id = 5;
1547   // Write until the header stream is flow control blocked.
1548   EXPECT_CALL(*connection_, SendControlFrame(_))
1549       .WillOnce(Invoke(&ClearControlFrame));
1550   Http2HeaderBlock headers;
1551   SimpleRandom random;
1552   while (!headers_stream->IsFlowControlBlocked() && stream_id < 2000) {
1553     EXPECT_FALSE(session_->IsConnectionFlowControlBlocked());
1554     EXPECT_FALSE(session_->IsStreamFlowControlBlocked());
1555     headers["header"] = absl::StrCat(random.RandUint64(), random.RandUint64(),
1556                                      random.RandUint64());
1557     session_->WriteHeadersOnHeadersStream(stream_id, headers.Clone(), true,
1558                                           spdy::SpdyStreamPrecedence(0),
1559                                           nullptr);
1560     stream_id += IdDelta();
1561   }
1562   // Write once more to ensure that the headers stream has buffered data. The
1563   // random headers may have exactly filled the flow control window.
1564   session_->WriteHeadersOnHeadersStream(stream_id, std::move(headers), true,
1565                                         spdy::SpdyStreamPrecedence(0), nullptr);
1566   EXPECT_TRUE(headers_stream->HasBufferedData());
1567 
1568   EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
1569   EXPECT_FALSE(crypto_stream->IsFlowControlBlocked());
1570   EXPECT_FALSE(session_->IsConnectionFlowControlBlocked());
1571   EXPECT_TRUE(session_->IsStreamFlowControlBlocked());
1572   EXPECT_FALSE(session_->HasDataToWrite());
1573 
1574   // Now complete the crypto handshake, resulting in an increased flow control
1575   // send window.
1576   CompleteHandshake();
1577 
1578   // Stream is now unblocked and will no longer have buffered data.
1579   EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
1580   EXPECT_FALSE(session_->IsConnectionFlowControlBlocked());
1581   EXPECT_FALSE(session_->IsStreamFlowControlBlocked());
1582   EXPECT_TRUE(headers_stream->HasBufferedData());
1583   EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(
1584       &*session_, QuicUtils::GetHeadersStreamId(transport_version())));
1585 }
1586 #endif  // !defined(OS_IOS)
1587 
TEST_P(QuicSpdySessionTestServer,ConnectionFlowControlAccountingRstOutOfOrder)1588 TEST_P(QuicSpdySessionTestServer,
1589        ConnectionFlowControlAccountingRstOutOfOrder) {
1590   Initialize();
1591 
1592   EXPECT_CALL(*connection_, SendControlFrame(_))
1593       .WillRepeatedly(Invoke(&ClearControlFrame));
1594   CompleteHandshake();
1595   // Test that when we receive an out of order stream RST we correctly adjust
1596   // our connection level flow control receive window.
1597   // On close, the stream should mark as consumed all bytes between the highest
1598   // byte consumed so far and the final byte offset from the RST frame.
1599   TestStream* stream = session_->CreateOutgoingBidirectionalStream();
1600 
1601   const QuicStreamOffset kByteOffset =
1602       1 + kInitialSessionFlowControlWindowForTest / 2;
1603 
1604   if (!VersionHasIetfQuicFrames(transport_version())) {
1605     // For version99 the call to OnStreamReset happens as a result of receiving
1606     // the STOP_SENDING, so set up the EXPECT there.
1607     EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1608     EXPECT_CALL(*connection_, SendControlFrame(_));
1609   } else if (!GetQuicRestartFlag(quic_opport_bundle_qpack_decoder_data4)) {
1610     EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
1611         .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1612   }
1613   QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
1614                                QUIC_STREAM_CANCELLED, kByteOffset);
1615   session_->OnRstStream(rst_frame);
1616   // Create and inject a STOP_SENDING frame. In GOOGLE QUIC, receiving a
1617   // RST_STREAM frame causes a two-way close. For IETF QUIC, RST_STREAM causes a
1618   // one-way close.
1619   if (VersionHasIetfQuicFrames(transport_version())) {
1620     // Only needed for version 99/IETF QUIC.
1621     QuicStopSendingFrame stop_sending(kInvalidControlFrameId, stream->id(),
1622                                       QUIC_STREAM_CANCELLED);
1623     // Expect the RESET_STREAM that is generated in response to receiving a
1624     // STOP_SENDING.
1625     EXPECT_CALL(*connection_,
1626                 OnStreamReset(stream->id(), QUIC_STREAM_CANCELLED));
1627     EXPECT_CALL(*connection_, SendControlFrame(_));
1628     session_->OnStopSendingFrame(stop_sending);
1629   }
1630 
1631   EXPECT_EQ(kByteOffset, session_->flow_controller()->bytes_consumed());
1632 }
1633 
TEST_P(QuicSpdySessionTestServer,InvalidStreamFlowControlWindowInHandshake)1634 TEST_P(QuicSpdySessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
1635   Initialize();
1636   if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) {
1637     // IETF Quic doesn't require a minimum flow control window.
1638     return;
1639   }
1640   // Test that receipt of an invalid (< default) stream flow control window from
1641   // the peer results in the connection being torn down.
1642   const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
1643   QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_->config(),
1644                                                             kInvalidWindow);
1645 
1646   EXPECT_CALL(*connection_,
1647               CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
1648   session_->OnConfigNegotiated();
1649 }
1650 
TEST_P(QuicSpdySessionTestServer,TooLowUnidirectionalStreamLimitHttp3)1651 TEST_P(QuicSpdySessionTestServer, TooLowUnidirectionalStreamLimitHttp3) {
1652   Initialize();
1653   if (!VersionUsesHttp3(transport_version())) {
1654     return;
1655   }
1656   session_->GetMutableCryptoStream()->EstablishZeroRttEncryption();
1657   QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_->config(), 2u);
1658   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
1659 
1660   EXPECT_CALL(
1661       *connection_,
1662       CloseConnection(
1663           _, "new unidirectional limit 2 decreases the current limit: 3", _));
1664   session_->OnConfigNegotiated();
1665 }
1666 
1667 // Test negotiation of custom server initial flow control window.
TEST_P(QuicSpdySessionTestServer,CustomFlowControlWindow)1668 TEST_P(QuicSpdySessionTestServer, CustomFlowControlWindow) {
1669   Initialize();
1670   QuicTagVector copt;
1671   copt.push_back(kIFW7);
1672   QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
1673   connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
1674   session_->OnConfigNegotiated();
1675   EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
1676                              session_->flow_controller()));
1677 }
1678 
TEST_P(QuicSpdySessionTestServer,WindowUpdateUnblocksHeadersStream)1679 TEST_P(QuicSpdySessionTestServer, WindowUpdateUnblocksHeadersStream) {
1680   Initialize();
1681   if (VersionUsesHttp3(transport_version())) {
1682     // The test relies on headers stream, which no longer exists in IETF QUIC.
1683     return;
1684   }
1685 
1686   // Test that a flow control blocked headers stream gets unblocked on recipt of
1687   // a WINDOW_UPDATE frame.
1688 
1689   // Set the headers stream to be flow control blocked.
1690   QuicHeadersStream* headers_stream =
1691       QuicSpdySessionPeer::GetHeadersStream(&*session_);
1692   QuicStreamPeer::SetSendWindowOffset(headers_stream, 0);
1693   EXPECT_TRUE(headers_stream->IsFlowControlBlocked());
1694   EXPECT_FALSE(session_->IsConnectionFlowControlBlocked());
1695   EXPECT_TRUE(session_->IsStreamFlowControlBlocked());
1696 
1697   // Unblock the headers stream by supplying a WINDOW_UPDATE.
1698   QuicWindowUpdateFrame window_update_frame(kInvalidControlFrameId,
1699                                             headers_stream->id(),
1700                                             2 * kMinimumFlowControlSendWindow);
1701   session_->OnWindowUpdateFrame(window_update_frame);
1702   EXPECT_FALSE(headers_stream->IsFlowControlBlocked());
1703   EXPECT_FALSE(session_->IsConnectionFlowControlBlocked());
1704   EXPECT_FALSE(session_->IsStreamFlowControlBlocked());
1705 }
1706 
TEST_P(QuicSpdySessionTestServer,TooManyUnfinishedStreamsCauseServerRejectStream)1707 TEST_P(QuicSpdySessionTestServer,
1708        TooManyUnfinishedStreamsCauseServerRejectStream) {
1709   Initialize();
1710   // If a buggy/malicious peer creates too many streams that are not ended
1711   // with a FIN or RST then we send an RST to refuse streams for versions other
1712   // than version 99. In version 99 the connection gets closed.
1713   CompleteHandshake();
1714   const QuicStreamId kMaxStreams = 5;
1715   if (VersionHasIetfQuicFrames(transport_version())) {
1716     QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&*session_,
1717                                                             kMaxStreams);
1718   } else {
1719     QuicSessionPeer::SetMaxOpenIncomingStreams(&*session_, kMaxStreams);
1720   }
1721   // GetNth assumes that both the crypto and header streams have been
1722   // open, but the stream id manager, using GetFirstBidirectional... only
1723   // assumes that the crypto stream is open. This means that GetNth...(0)
1724   // Will return stream ID == 8 (with id ==0 for crypto and id==4 for headers).
1725   // It also means that GetNth(kMax..=5) returns 28 (streams 0/1/2/3/4 are ids
1726   // 8, 12, 16, 20, 24, respectively, so stream#5 is stream id 28).
1727   // However, the stream ID manager does not assume stream 4 is for headers.
1728   // The ID manager would assume that stream#5 is streamid 24.
1729   // In order to make this all work out properly, kFinalStreamId will
1730   // be set to GetNth...(kMaxStreams-1)... but only for IETF QUIC
1731   const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
1732   const QuicStreamId kFinalStreamId =
1733       GetNthClientInitiatedBidirectionalId(kMaxStreams);
1734   // Create kMaxStreams data streams, and close them all without receiving a
1735   // FIN or a RST_STREAM from the client.
1736   const QuicStreamId kNextId = QuicUtils::StreamIdDelta(transport_version());
1737   for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += kNextId) {
1738     QuicStreamFrame data1(i, false, 0, absl::string_view("HT"));
1739     session_->OnStreamFrame(data1);
1740     CloseStream(i);
1741   }
1742   // Try and open a stream that exceeds the limit.
1743   if (!VersionHasIetfQuicFrames(transport_version())) {
1744     // On versions other than 99, opening such a stream results in a
1745     // RST_STREAM.
1746     EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
1747     EXPECT_CALL(*connection_,
1748                 OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
1749         .Times(1);
1750   } else {
1751     // On version 99 opening such a stream results in a connection close.
1752     EXPECT_CALL(
1753         *connection_,
1754         CloseConnection(QUIC_INVALID_STREAM_ID,
1755                         testing::MatchesRegex(
1756                             "Stream id \\d+ would exceed stream count limit 5"),
1757                         _));
1758   }
1759   // Create one more data streams to exceed limit of open stream.
1760   QuicStreamFrame data1(kFinalStreamId, false, 0, absl::string_view("HT"));
1761   session_->OnStreamFrame(data1);
1762 }
1763 
TEST_P(QuicSpdySessionTestServer,DrainingStreamsDoNotCountAsOpened)1764 TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) {
1765   Initialize();
1766   // Verify that a draining stream (which has received a FIN but not consumed
1767   // it) does not count against the open quota (because it is closed from the
1768   // protocol point of view).
1769   CompleteHandshake();
1770   if (VersionHasIetfQuicFrames(transport_version())) {
1771     // Simulate receiving a config. so that MAX_STREAMS/etc frames may
1772     // be transmitted
1773     QuicSessionPeer::set_is_configured(&*session_, true);
1774     // Version 99 will result in a MAX_STREAMS frame as streams are consumed
1775     // (via the OnStreamFrame call) and then released (via
1776     // StreamDraining). Eventually this node will believe that the peer is
1777     // running low on available stream ids and then send a MAX_STREAMS frame,
1778     // caught by this EXPECT_CALL.
1779     EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
1780   } else {
1781     EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
1782   }
1783   EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
1784   const QuicStreamId kMaxStreams = 5;
1785   if (VersionHasIetfQuicFrames(transport_version())) {
1786     QuicSessionPeer::SetMaxOpenIncomingBidirectionalStreams(&*session_,
1787                                                             kMaxStreams);
1788   } else {
1789     QuicSessionPeer::SetMaxOpenIncomingStreams(&*session_, kMaxStreams);
1790   }
1791 
1792   // Create kMaxStreams + 1 data streams, and mark them draining.
1793   const QuicStreamId kFirstStreamId = GetNthClientInitiatedBidirectionalId(0);
1794   const QuicStreamId kFinalStreamId =
1795       GetNthClientInitiatedBidirectionalId(kMaxStreams + 1);
1796   for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += IdDelta()) {
1797     QuicStreamFrame data1(i, true, 0, absl::string_view("HT"));
1798     session_->OnStreamFrame(data1);
1799     EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&*session_));
1800     session_->StreamDraining(i, /*unidirectional=*/false);
1801     EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&*session_));
1802   }
1803 }
1804 
1805 class QuicSpdySessionTestClient : public QuicSpdySessionTestBase {
1806  protected:
QuicSpdySessionTestClient()1807   QuicSpdySessionTestClient()
1808       : QuicSpdySessionTestBase(Perspective::IS_CLIENT, false) {}
1809 };
1810 
1811 INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestClient,
1812                          ::testing::ValuesIn(AllSupportedVersions()),
1813                          ::testing::PrintToStringParamName());
1814 
TEST_P(QuicSpdySessionTestClient,UsesPendingStreamsForFrame)1815 TEST_P(QuicSpdySessionTestClient, UsesPendingStreamsForFrame) {
1816   Initialize();
1817   if (!VersionUsesHttp3(transport_version())) {
1818     return;
1819   }
1820   EXPECT_TRUE(session_->UsesPendingStreamForFrame(
1821       STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
1822                         transport_version(), Perspective::IS_SERVER)));
1823   EXPECT_TRUE(session_->UsesPendingStreamForFrame(
1824       RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
1825                             transport_version(), Perspective::IS_SERVER)));
1826   EXPECT_FALSE(session_->UsesPendingStreamForFrame(
1827       RST_STREAM_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
1828                             transport_version(), Perspective::IS_CLIENT)));
1829   EXPECT_FALSE(session_->UsesPendingStreamForFrame(
1830       STOP_SENDING_FRAME, QuicUtils::GetFirstUnidirectionalStreamId(
1831                               transport_version(), Perspective::IS_SERVER)));
1832   EXPECT_FALSE(session_->UsesPendingStreamForFrame(
1833       RST_STREAM_FRAME, QuicUtils::GetFirstBidirectionalStreamId(
1834                             transport_version(), Perspective::IS_SERVER)));
1835 }
1836 
1837 // Regression test for crbug.com/977581.
TEST_P(QuicSpdySessionTestClient,BadStreamFramePendingStream)1838 TEST_P(QuicSpdySessionTestClient, BadStreamFramePendingStream) {
1839   Initialize();
1840   if (!VersionUsesHttp3(transport_version())) {
1841     return;
1842   }
1843 
1844   CompleteHandshake();
1845   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&*session_));
1846   QuicStreamId stream_id1 =
1847       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
1848   // A bad stream frame with no data and no fin.
1849   QuicStreamFrame data1(stream_id1, false, 0, 0);
1850   session_->OnStreamFrame(data1);
1851 }
1852 
TEST_P(QuicSpdySessionTestClient,PendingStreamKeepsConnectionAlive)1853 TEST_P(QuicSpdySessionTestClient, PendingStreamKeepsConnectionAlive) {
1854   Initialize();
1855   if (!VersionUsesHttp3(transport_version())) {
1856     return;
1857   }
1858   CompleteHandshake();
1859   QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
1860       transport_version(), Perspective::IS_SERVER);
1861 
1862   QuicStreamFrame frame(stream_id, false, 1, "test");
1863   EXPECT_FALSE(session_->ShouldKeepConnectionAlive());
1864   session_->OnStreamFrame(frame);
1865   EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&*session_, stream_id));
1866   EXPECT_TRUE(session_->ShouldKeepConnectionAlive());
1867 }
1868 
TEST_P(QuicSpdySessionTestClient,AvailableStreamsClient)1869 TEST_P(QuicSpdySessionTestClient, AvailableStreamsClient) {
1870   Initialize();
1871   ASSERT_TRUE(session_->GetOrCreateStream(
1872                   GetNthServerInitiatedBidirectionalId(2)) != nullptr);
1873   // Both server initiated streams with smaller stream IDs should be available.
1874   EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
1875       &*session_, GetNthServerInitiatedBidirectionalId(0)));
1876   EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(
1877       &*session_, GetNthServerInitiatedBidirectionalId(1)));
1878   ASSERT_TRUE(session_->GetOrCreateStream(
1879                   GetNthServerInitiatedBidirectionalId(0)) != nullptr);
1880   ASSERT_TRUE(session_->GetOrCreateStream(
1881                   GetNthServerInitiatedBidirectionalId(1)) != nullptr);
1882   // And client initiated stream ID should be not available.
1883   EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(
1884       &*session_, GetNthClientInitiatedBidirectionalId(0)));
1885 }
1886 
1887 // Regression test for b/130740258 and https://crbug.com/971779.
1888 // If headers that are too large or empty are received (these cases are handled
1889 // the same way, as QuicHeaderList clears itself when headers exceed the limit),
1890 // then the stream is reset.  No more frames must be sent in this case.
TEST_P(QuicSpdySessionTestClient,TooLargeHeadersMustNotCauseWriteAfterReset)1891 TEST_P(QuicSpdySessionTestClient, TooLargeHeadersMustNotCauseWriteAfterReset) {
1892   Initialize();
1893   // In IETF QUIC, HEADERS do not carry FIN flag, and OnStreamHeaderList() is
1894   // never called after an error, including too large headers.
1895   if (VersionUsesHttp3(transport_version())) {
1896     return;
1897   }
1898   CompleteHandshake();
1899   TestStream* stream = session_->CreateOutgoingBidirectionalStream();
1900 
1901   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
1902       .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
1903   // Write headers with FIN set to close write side of stream.
1904   // Header block does not matter.
1905   stream->WriteHeaders(Http2HeaderBlock(), /* fin = */ true, nullptr);
1906 
1907   // Receive headers that are too large or empty, with FIN set.
1908   // This causes the stream to be reset.  No frames must be written after this.
1909   QuicHeaderList headers;
1910   EXPECT_CALL(*connection_, SendControlFrame(_));
1911   EXPECT_CALL(*connection_,
1912               OnStreamReset(stream->id(), QUIC_HEADERS_TOO_LARGE));
1913   stream->OnStreamHeaderList(/* fin = */ true,
1914                              headers.uncompressed_header_bytes(), headers);
1915 }
1916 
TEST_P(QuicSpdySessionTestClient,RecordFinAfterReadSideClosed)1917 TEST_P(QuicSpdySessionTestClient, RecordFinAfterReadSideClosed) {
1918   Initialize();
1919   // Verify that an incoming FIN is recorded in a stream object even if the read
1920   // side has been closed.  This prevents an entry from being made in
1921   // locally_closed_streams_highest_offset_ (which will never be deleted).
1922   CompleteHandshake();
1923   TestStream* stream = session_->CreateOutgoingBidirectionalStream();
1924   QuicStreamId stream_id = stream->id();
1925 
1926   // Close the read side manually.
1927   QuicStreamPeer::CloseReadSide(stream);
1928 
1929   // Receive a stream data frame with FIN.
1930   QuicStreamFrame frame(stream_id, true, 0, absl::string_view());
1931   session_->OnStreamFrame(frame);
1932   EXPECT_TRUE(stream->fin_received());
1933 
1934   // Reset stream locally.
1935   EXPECT_CALL(*connection_, SendControlFrame(_));
1936   EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
1937   stream->Reset(QUIC_STREAM_CANCELLED);
1938   EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
1939 
1940   EXPECT_TRUE(connection_->connected());
1941   EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&*session_, stream_id));
1942   EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&*session_, stream_id));
1943 
1944   // The stream is not waiting for the arrival of the peer's final offset as it
1945   // was received with the FIN earlier.
1946   EXPECT_EQ(
1947       0u,
1948       QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&*session_).size());
1949 }
1950 
TEST_P(QuicSpdySessionTestClient,WritePriority)1951 TEST_P(QuicSpdySessionTestClient, WritePriority) {
1952   Initialize();
1953   if (VersionUsesHttp3(transport_version())) {
1954     // IETF QUIC currently doesn't support PRIORITY.
1955     return;
1956   }
1957   CompleteHandshake();
1958 
1959   TestHeadersStream* headers_stream;
1960   QuicSpdySessionPeer::SetHeadersStream(&*session_, nullptr);
1961   headers_stream = new TestHeadersStream(&*session_);
1962   QuicSpdySessionPeer::SetHeadersStream(&*session_, headers_stream);
1963 
1964   // Make packet writer blocked so |headers_stream| will buffer its write data.
1965   EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
1966 
1967   const QuicStreamId id = 4;
1968   const QuicStreamId parent_stream_id = 9;
1969   const SpdyPriority priority = kV3HighestPriority;
1970   const bool exclusive = true;
1971   session_->WritePriority(id, parent_stream_id,
1972                           Spdy3PriorityToHttp2Weight(priority), exclusive);
1973 
1974   QuicStreamSendBuffer& send_buffer =
1975       QuicStreamPeer::SendBuffer(headers_stream);
1976   ASSERT_EQ(1u, send_buffer.size());
1977 
1978   SpdyPriorityIR priority_frame(
1979       id, parent_stream_id, Spdy3PriorityToHttp2Weight(priority), exclusive);
1980   SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
1981   SpdySerializedFrame frame = spdy_framer.SerializeFrame(priority_frame);
1982 
1983   const quiche::QuicheMemSlice& slice =
1984       QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
1985   EXPECT_EQ(absl::string_view(frame.data(), frame.size()),
1986             absl::string_view(slice.data(), slice.length()));
1987 }
1988 
TEST_P(QuicSpdySessionTestClient,Http3ServerPush)1989 TEST_P(QuicSpdySessionTestClient, Http3ServerPush) {
1990   Initialize();
1991   if (!VersionUsesHttp3(transport_version())) {
1992     return;
1993   }
1994 
1995   CompleteHandshake();
1996   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&*session_));
1997 
1998   // Push unidirectional stream is type 0x01.
1999   std::string frame_type1;
2000   ASSERT_TRUE(absl::HexStringToBytes("01", &frame_type1));
2001   QuicStreamId stream_id1 =
2002       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
2003   EXPECT_CALL(*connection_,
2004               CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
2005       .Times(1);
2006   session_->OnStreamFrame(QuicStreamFrame(stream_id1, /* fin = */ false,
2007                                           /* offset = */ 0, frame_type1));
2008 }
2009 
TEST_P(QuicSpdySessionTestClient,Http3ServerPushOutofOrderFrame)2010 TEST_P(QuicSpdySessionTestClient, Http3ServerPushOutofOrderFrame) {
2011   Initialize();
2012   if (!VersionUsesHttp3(transport_version())) {
2013     return;
2014   }
2015 
2016   CompleteHandshake();
2017   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&*session_));
2018 
2019   // Push unidirectional stream is type 0x01.
2020   std::string frame_type;
2021   ASSERT_TRUE(absl::HexStringToBytes("01", &frame_type));
2022   // The first field of a push stream is the Push ID.
2023   std::string push_id;
2024   ASSERT_TRUE(absl::HexStringToBytes("4000", &push_id));
2025 
2026   QuicStreamId stream_id =
2027       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
2028 
2029   QuicStreamFrame data1(stream_id,
2030                         /* fin = */ false, /* offset = */ 0, frame_type);
2031   QuicStreamFrame data2(stream_id,
2032                         /* fin = */ false, /* offset = */ frame_type.size(),
2033                         push_id);
2034 
2035   // Receiving some stream data without stream type does not open the stream.
2036   session_->OnStreamFrame(data2);
2037   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&*session_));
2038   EXPECT_CALL(*connection_,
2039               CloseConnection(QUIC_HTTP_RECEIVE_SERVER_PUSH, _, _))
2040       .Times(1);
2041   session_->OnStreamFrame(data1);
2042 }
2043 
TEST_P(QuicSpdySessionTestClient,ServerDisableQpackDynamicTable)2044 TEST_P(QuicSpdySessionTestClient, ServerDisableQpackDynamicTable) {
2045   SetQuicFlag(quic_server_disable_qpack_dynamic_table, true);
2046   Initialize();
2047   if (!VersionUsesHttp3(transport_version())) {
2048     return;
2049   }
2050   CompleteHandshake();
2051 
2052   // Use an arbitrary stream id for creating the receive control stream.
2053   QuicStreamId stream_id =
2054       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
2055   char type[] = {kControlStream};
2056   QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1));
2057   session_->OnStreamFrame(data1);
2058   EXPECT_EQ(stream_id,
2059             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
2060   // Receive the QPACK dynamic table capacity from the peer.
2061   const uint64_t capacity = 512;
2062   SettingsFrame settings;
2063   settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = capacity;
2064   std::string data = HttpEncoder::SerializeSettingsFrame(settings);
2065   QuicStreamFrame frame(stream_id, false, 1, data);
2066   session_->OnStreamFrame(frame);
2067 
2068   // Verify that the encoder's dynamic table capacity is limited to the
2069   // peer's value.
2070   QpackEncoder* qpack_encoder = session_->qpack_encoder();
2071   EXPECT_EQ(capacity, qpack_encoder->MaximumDynamicTableCapacity());
2072   QpackEncoderHeaderTable* encoder_header_table =
2073       QpackEncoderPeer::header_table(qpack_encoder);
2074   EXPECT_EQ(capacity, encoder_header_table->dynamic_table_capacity());
2075   EXPECT_EQ(capacity, encoder_header_table->maximum_dynamic_table_capacity());
2076 
2077   // Verify that the advertised capacity is the default.
2078   SettingsFrame outgoing_settings = session_->settings();
2079   EXPECT_EQ(kDefaultQpackMaxDynamicTableCapacity,
2080             outgoing_settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY]);
2081 }
2082 
TEST_P(QuicSpdySessionTestClient,DisableQpackDynamicTable)2083 TEST_P(QuicSpdySessionTestClient, DisableQpackDynamicTable) {
2084   SetQuicFlag(quic_server_disable_qpack_dynamic_table, false);
2085   qpack_maximum_dynamic_table_capacity_ = 0;
2086   Initialize();
2087   if (!VersionUsesHttp3(transport_version())) {
2088     return;
2089   }
2090   CompleteHandshake();
2091 
2092   // Use an arbitrary stream id for creating the receive control stream.
2093   QuicStreamId stream_id =
2094       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
2095   char type[] = {kControlStream};
2096   QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1));
2097   session_->OnStreamFrame(data1);
2098   EXPECT_EQ(stream_id,
2099             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
2100   // Receive the QPACK dynamic table capacity from the peer.
2101   const uint64_t capacity = 512;
2102   SettingsFrame settings;
2103   settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = capacity;
2104   std::string data = HttpEncoder::SerializeSettingsFrame(settings);
2105   QuicStreamFrame frame(stream_id, false, 1, data);
2106   session_->OnStreamFrame(frame);
2107 
2108   // Verify that the encoder's dynamic table capacity is 0.
2109   QpackEncoder* qpack_encoder = session_->qpack_encoder();
2110   EXPECT_EQ(capacity, qpack_encoder->MaximumDynamicTableCapacity());
2111   QpackEncoderHeaderTable* encoder_header_table =
2112       QpackEncoderPeer::header_table(qpack_encoder);
2113   EXPECT_EQ(0, encoder_header_table->dynamic_table_capacity());
2114   EXPECT_EQ(capacity, encoder_header_table->maximum_dynamic_table_capacity());
2115 
2116   // Verify that the advertised capacity is 0.
2117   SettingsFrame outgoing_settings = session_->settings();
2118   EXPECT_EQ(0, outgoing_settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY]);
2119 }
2120 
TEST_P(QuicSpdySessionTestServer,OnStreamFrameLost)2121 TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) {
2122   Initialize();
2123   CompleteHandshake();
2124   InSequence s;
2125 
2126   // Drive congestion control manually.
2127   MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
2128   QuicConnectionPeer::SetSendAlgorithm(session_->connection(), send_algorithm);
2129 
2130   TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
2131   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
2132   TestStream* stream4 = session_->CreateOutgoingBidirectionalStream();
2133 
2134   QuicStreamFrame frame2(stream2->id(), false, 0, 9);
2135   QuicStreamFrame frame3(stream4->id(), false, 0, 9);
2136 
2137   // Lost data on cryption stream, streams 2 and 4.
2138   EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
2139   if (!QuicVersionUsesCryptoFrames(transport_version())) {
2140     EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
2141         .WillOnce(Return(true));
2142   }
2143   EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
2144   session_->OnFrameLost(QuicFrame(frame3));
2145   if (!QuicVersionUsesCryptoFrames(transport_version())) {
2146     QuicStreamFrame frame1(QuicUtils::GetCryptoStreamId(transport_version()),
2147                            false, 0, 1300);
2148     session_->OnFrameLost(QuicFrame(frame1));
2149   } else {
2150     QuicCryptoFrame crypto_frame(ENCRYPTION_INITIAL, 0, 1300);
2151     session_->OnFrameLost(QuicFrame(&crypto_frame));
2152   }
2153   session_->OnFrameLost(QuicFrame(frame2));
2154   EXPECT_TRUE(session_->WillingAndAbleToWrite());
2155 
2156   // Mark streams 2 and 4 write blocked.
2157   session_->MarkConnectionLevelWriteBlocked(stream2->id());
2158   session_->MarkConnectionLevelWriteBlocked(stream4->id());
2159 
2160   // Lost data is retransmitted before new data, and retransmissions for crypto
2161   // stream go first.
2162   // Do not check congestion window when crypto stream has lost data.
2163   EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
2164   if (!QuicVersionUsesCryptoFrames(transport_version())) {
2165     EXPECT_CALL(*crypto_stream, OnCanWrite());
2166     EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
2167         .WillOnce(Return(false));
2168   }
2169   // Check congestion window for non crypto streams.
2170   EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
2171   EXPECT_CALL(*stream4, OnCanWrite());
2172   EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
2173   // Connection is blocked.
2174   EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
2175 
2176   session_->OnCanWrite();
2177   EXPECT_TRUE(session_->WillingAndAbleToWrite());
2178 
2179   // Unblock connection.
2180   // Stream 2 retransmits lost data.
2181   EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
2182   EXPECT_CALL(*stream2, OnCanWrite());
2183   EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
2184   EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
2185   // Stream 2 sends new data.
2186   EXPECT_CALL(*stream2, OnCanWrite());
2187   EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
2188   EXPECT_CALL(*stream4, OnCanWrite());
2189   EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
2190 
2191   session_->OnCanWrite();
2192   EXPECT_FALSE(session_->WillingAndAbleToWrite());
2193 }
2194 
TEST_P(QuicSpdySessionTestServer,DonotRetransmitDataOfClosedStreams)2195 TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) {
2196   Initialize();
2197   // Resetting a stream will send a QPACK Stream Cancellation instruction on the
2198   // decoder stream.  For simplicity, ignore writes on this stream.
2199   CompleteHandshake();
2200   NoopQpackStreamSenderDelegate qpack_stream_sender_delegate;
2201   if (VersionUsesHttp3(transport_version())) {
2202     session_->qpack_decoder()->set_qpack_stream_sender_delegate(
2203         &qpack_stream_sender_delegate);
2204   }
2205 
2206   InSequence s;
2207 
2208   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
2209   TestStream* stream4 = session_->CreateOutgoingBidirectionalStream();
2210   TestStream* stream6 = session_->CreateOutgoingBidirectionalStream();
2211 
2212   QuicStreamFrame frame1(stream2->id(), false, 0, 9);
2213   QuicStreamFrame frame2(stream4->id(), false, 0, 9);
2214   QuicStreamFrame frame3(stream6->id(), false, 0, 9);
2215 
2216   EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
2217   EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
2218   EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
2219   session_->OnFrameLost(QuicFrame(frame3));
2220   session_->OnFrameLost(QuicFrame(frame2));
2221   session_->OnFrameLost(QuicFrame(frame1));
2222 
2223   session_->MarkConnectionLevelWriteBlocked(stream2->id());
2224   session_->MarkConnectionLevelWriteBlocked(stream4->id());
2225   session_->MarkConnectionLevelWriteBlocked(stream6->id());
2226 
2227   // Reset stream 4 locally.
2228   EXPECT_CALL(*connection_, SendControlFrame(_));
2229   EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
2230   stream4->Reset(QUIC_STREAM_CANCELLED);
2231 
2232   // Verify stream 4 is removed from streams with lost data list.
2233   EXPECT_CALL(*stream6, OnCanWrite());
2234   EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
2235   EXPECT_CALL(*stream2, OnCanWrite());
2236   EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
2237   EXPECT_CALL(*connection_, SendControlFrame(_))
2238       .WillRepeatedly(Invoke(&ClearControlFrame));
2239   EXPECT_CALL(*stream2, OnCanWrite());
2240   EXPECT_CALL(*stream6, OnCanWrite());
2241   session_->OnCanWrite();
2242 }
2243 
TEST_P(QuicSpdySessionTestServer,RetransmitFrames)2244 TEST_P(QuicSpdySessionTestServer, RetransmitFrames) {
2245   Initialize();
2246   CompleteHandshake();
2247   MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
2248   QuicConnectionPeer::SetSendAlgorithm(session_->connection(), send_algorithm);
2249   InSequence s;
2250 
2251   TestStream* stream2 = session_->CreateOutgoingBidirectionalStream();
2252   TestStream* stream4 = session_->CreateOutgoingBidirectionalStream();
2253   TestStream* stream6 = session_->CreateOutgoingBidirectionalStream();
2254   EXPECT_CALL(*connection_, SendControlFrame(_))
2255       .WillOnce(Invoke(&ClearControlFrame));
2256   session_->SendWindowUpdate(stream2->id(), 9);
2257 
2258   QuicStreamFrame frame1(stream2->id(), false, 0, 9);
2259   QuicStreamFrame frame2(stream4->id(), false, 0, 9);
2260   QuicStreamFrame frame3(stream6->id(), false, 0, 9);
2261   QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
2262   QuicFrames frames;
2263   frames.push_back(QuicFrame(frame1));
2264   frames.push_back(QuicFrame(window_update));
2265   frames.push_back(QuicFrame(frame2));
2266   frames.push_back(QuicFrame(frame3));
2267   EXPECT_FALSE(session_->WillingAndAbleToWrite());
2268 
2269   EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _, _))
2270       .WillOnce(Return(true));
2271   EXPECT_CALL(*connection_, SendControlFrame(_))
2272       .WillOnce(Invoke(&ClearControlFrame));
2273   EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _, _))
2274       .WillOnce(Return(true));
2275   EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _, _))
2276       .WillOnce(Return(true));
2277   EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
2278   session_->RetransmitFrames(frames, PTO_RETRANSMISSION);
2279 }
2280 
TEST_P(QuicSpdySessionTestServer,OnPriorityFrame)2281 TEST_P(QuicSpdySessionTestServer, OnPriorityFrame) {
2282   Initialize();
2283   QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
2284   TestStream* stream = session_->CreateIncomingStream(stream_id);
2285   session_->OnPriorityFrame(stream_id,
2286                             spdy::SpdyStreamPrecedence(kV3HighestPriority));
2287 
2288   EXPECT_EQ((QuicStreamPriority(HttpStreamPriority{
2289                 kV3HighestPriority, HttpStreamPriority::kDefaultIncremental})),
2290             stream->priority());
2291 }
2292 
TEST_P(QuicSpdySessionTestServer,OnPriorityUpdateFrame)2293 TEST_P(QuicSpdySessionTestServer, OnPriorityUpdateFrame) {
2294   Initialize();
2295   if (!VersionUsesHttp3(transport_version())) {
2296     return;
2297   }
2298 
2299   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2300   session_->set_debug_visitor(&debug_visitor);
2301   EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
2302   CompleteHandshake();
2303 
2304   // Create control stream.
2305   QuicStreamId receive_control_stream_id =
2306       GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
2307   char type[] = {kControlStream};
2308   absl::string_view stream_type(type, 1);
2309   QuicStreamOffset offset = 0;
2310   QuicStreamFrame data1(receive_control_stream_id, false, offset, stream_type);
2311   offset += stream_type.length();
2312   EXPECT_CALL(debug_visitor,
2313               OnPeerControlStreamCreated(receive_control_stream_id));
2314   session_->OnStreamFrame(data1);
2315   EXPECT_EQ(receive_control_stream_id,
2316             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
2317 
2318   // Send SETTINGS frame.
2319   std::string serialized_settings = HttpEncoder::SerializeSettingsFrame({});
2320   QuicStreamFrame data2(receive_control_stream_id, false, offset,
2321                         serialized_settings);
2322   offset += serialized_settings.length();
2323   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
2324   session_->OnStreamFrame(data2);
2325 
2326   // PRIORITY_UPDATE frame for first request stream.
2327   const QuicStreamId stream_id1 = GetNthClientInitiatedBidirectionalId(0);
2328   PriorityUpdateFrame priority_update1{stream_id1, "u=2"};
2329   std::string serialized_priority_update1 =
2330       HttpEncoder::SerializePriorityUpdateFrame(priority_update1);
2331   QuicStreamFrame data3(receive_control_stream_id,
2332                         /* fin = */ false, offset, serialized_priority_update1);
2333   offset += serialized_priority_update1.size();
2334 
2335   // PRIORITY_UPDATE frame arrives after stream creation.
2336   TestStream* stream1 = session_->CreateIncomingStream(stream_id1);
2337   EXPECT_EQ(QuicStreamPriority(
2338                 HttpStreamPriority{HttpStreamPriority::kDefaultUrgency,
2339                                    HttpStreamPriority::kDefaultIncremental}),
2340             stream1->priority());
2341   EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update1));
2342   session_->OnStreamFrame(data3);
2343   EXPECT_EQ(QuicStreamPriority(HttpStreamPriority{
2344                 2u, HttpStreamPriority::kDefaultIncremental}),
2345             stream1->priority());
2346 
2347   // PRIORITY_UPDATE frame for second request stream.
2348   const QuicStreamId stream_id2 = GetNthClientInitiatedBidirectionalId(1);
2349   PriorityUpdateFrame priority_update2{stream_id2, "u=5, i"};
2350   std::string serialized_priority_update2 =
2351       HttpEncoder::SerializePriorityUpdateFrame(priority_update2);
2352   QuicStreamFrame stream_frame3(receive_control_stream_id,
2353                                 /* fin = */ false, offset,
2354                                 serialized_priority_update2);
2355 
2356   // PRIORITY_UPDATE frame arrives before stream creation,
2357   // priority value is buffered.
2358   EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update2));
2359   session_->OnStreamFrame(stream_frame3);
2360   // Priority is applied upon stream construction.
2361   TestStream* stream2 = session_->CreateIncomingStream(stream_id2);
2362   EXPECT_EQ(QuicStreamPriority(HttpStreamPriority{5u, true}),
2363             stream2->priority());
2364 }
2365 
TEST_P(QuicSpdySessionTestServer,OnInvalidPriorityUpdateFrame)2366 TEST_P(QuicSpdySessionTestServer, OnInvalidPriorityUpdateFrame) {
2367   Initialize();
2368   if (!VersionUsesHttp3(transport_version())) {
2369     return;
2370   }
2371 
2372   CompleteHandshake();
2373   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2374   session_->set_debug_visitor(&debug_visitor);
2375 
2376   // Create control stream.
2377   QuicStreamId receive_control_stream_id =
2378       GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
2379   char type[] = {kControlStream};
2380   absl::string_view stream_type(type, 1);
2381   QuicStreamOffset offset = 0;
2382   QuicStreamFrame data1(receive_control_stream_id, false, offset, stream_type);
2383   offset += stream_type.length();
2384   EXPECT_CALL(debug_visitor,
2385               OnPeerControlStreamCreated(receive_control_stream_id));
2386   session_->OnStreamFrame(data1);
2387   EXPECT_EQ(receive_control_stream_id,
2388             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
2389 
2390   // Send SETTINGS frame.
2391   std::string serialized_settings = HttpEncoder::SerializeSettingsFrame({});
2392   QuicStreamFrame data2(receive_control_stream_id, false, offset,
2393                         serialized_settings);
2394   offset += serialized_settings.length();
2395   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
2396   session_->OnStreamFrame(data2);
2397 
2398   // PRIORITY_UPDATE frame with Priority Field Value that is not valid
2399   // Structured Headers.
2400   const QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
2401   PriorityUpdateFrame priority_update{stream_id, "00"};
2402 
2403   EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update));
2404   EXPECT_CALL(*connection_,
2405               CloseConnection(QUIC_INVALID_PRIORITY_UPDATE,
2406                               "Invalid PRIORITY_UPDATE frame payload.", _));
2407 
2408   std::string serialized_priority_update =
2409       HttpEncoder::SerializePriorityUpdateFrame(priority_update);
2410   QuicStreamFrame data3(receive_control_stream_id,
2411                         /* fin = */ false, offset, serialized_priority_update);
2412   session_->OnStreamFrame(data3);
2413 }
2414 
TEST_P(QuicSpdySessionTestServer,OnPriorityUpdateFrameOutOfBoundsUrgency)2415 TEST_P(QuicSpdySessionTestServer, OnPriorityUpdateFrameOutOfBoundsUrgency) {
2416   Initialize();
2417   if (!VersionUsesHttp3(transport_version())) {
2418     return;
2419   }
2420 
2421   CompleteHandshake();
2422   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2423   session_->set_debug_visitor(&debug_visitor);
2424 
2425   // Create control stream.
2426   QuicStreamId receive_control_stream_id =
2427       GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
2428   char type[] = {kControlStream};
2429   absl::string_view stream_type(type, 1);
2430   QuicStreamOffset offset = 0;
2431   QuicStreamFrame data1(receive_control_stream_id, false, offset, stream_type);
2432   offset += stream_type.length();
2433   EXPECT_CALL(debug_visitor,
2434               OnPeerControlStreamCreated(receive_control_stream_id));
2435   session_->OnStreamFrame(data1);
2436   EXPECT_EQ(receive_control_stream_id,
2437             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
2438 
2439   // Send SETTINGS frame.
2440   std::string serialized_settings = HttpEncoder::SerializeSettingsFrame({});
2441   QuicStreamFrame data2(receive_control_stream_id, false, offset,
2442                         serialized_settings);
2443   offset += serialized_settings.length();
2444   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
2445   session_->OnStreamFrame(data2);
2446 
2447   // PRIORITY_UPDATE frame with urgency not in [0,7].
2448   const QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
2449   PriorityUpdateFrame priority_update{stream_id, "u=9"};
2450 
2451   EXPECT_CALL(debug_visitor, OnPriorityUpdateFrameReceived(priority_update));
2452   EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
2453 
2454   std::string serialized_priority_update =
2455       HttpEncoder::SerializePriorityUpdateFrame(priority_update);
2456   QuicStreamFrame data3(receive_control_stream_id,
2457                         /* fin = */ false, offset, serialized_priority_update);
2458   session_->OnStreamFrame(data3);
2459 }
2460 
TEST_P(QuicSpdySessionTestServer,SimplePendingStreamType)2461 TEST_P(QuicSpdySessionTestServer, SimplePendingStreamType) {
2462   Initialize();
2463   if (!VersionUsesHttp3(transport_version())) {
2464     return;
2465   }
2466   CompleteHandshake();
2467   char input[] = {0x04,            // type
2468                   'a', 'b', 'c'};  // data
2469   absl::string_view payload(input, ABSL_ARRAYSIZE(input));
2470 
2471   // This is a server test with a client-initiated unidirectional stream.
2472   QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
2473       transport_version(), Perspective::IS_CLIENT);
2474 
2475   for (bool fin : {true, false}) {
2476     QuicStreamFrame frame(stream_id, fin, /* offset = */ 0, payload);
2477 
2478     // A STOP_SENDING frame is sent in response to the unknown stream type.
2479     EXPECT_CALL(*connection_, SendControlFrame(_))
2480         .WillOnce(Invoke([stream_id](const QuicFrame& frame) {
2481           EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
2482 
2483           const QuicStopSendingFrame& stop_sending = frame.stop_sending_frame;
2484           EXPECT_EQ(stream_id, stop_sending.stream_id);
2485           EXPECT_EQ(QUIC_STREAM_STREAM_CREATION_ERROR, stop_sending.error_code);
2486           EXPECT_EQ(
2487               static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
2488               stop_sending.ietf_error_code);
2489 
2490           return ClearControlFrame(frame);
2491         }));
2492     session_->OnStreamFrame(frame);
2493 
2494     PendingStream* pending =
2495         QuicSessionPeer::GetPendingStream(&*session_, stream_id);
2496     if (fin) {
2497       // Stream is closed if FIN is received.
2498       EXPECT_FALSE(pending);
2499     } else {
2500       ASSERT_TRUE(pending);
2501       // The pending stream must ignore read data.
2502       EXPECT_TRUE(pending->sequencer()->ignore_read_data());
2503     }
2504 
2505     stream_id += QuicUtils::StreamIdDelta(transport_version());
2506   }
2507 }
2508 
TEST_P(QuicSpdySessionTestServer,SimplePendingStreamTypeOutOfOrderDelivery)2509 TEST_P(QuicSpdySessionTestServer, SimplePendingStreamTypeOutOfOrderDelivery) {
2510   Initialize();
2511   if (!VersionUsesHttp3(transport_version())) {
2512     return;
2513   }
2514   CompleteHandshake();
2515   char input[] = {0x04,            // type
2516                   'a', 'b', 'c'};  // data
2517   absl::string_view payload(input, ABSL_ARRAYSIZE(input));
2518 
2519   // This is a server test with a client-initiated unidirectional stream.
2520   QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
2521       transport_version(), Perspective::IS_CLIENT);
2522 
2523   for (bool fin : {true, false}) {
2524     QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
2525                            payload.substr(0, 1));
2526     QuicStreamFrame frame2(stream_id, fin, /* offset = */ 1, payload.substr(1));
2527 
2528     // Deliver frames out of order.
2529     session_->OnStreamFrame(frame2);
2530     // A STOP_SENDING frame is sent in response to the unknown stream type.
2531     EXPECT_CALL(*connection_, SendControlFrame(_))
2532         .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
2533     session_->OnStreamFrame(frame1);
2534 
2535     PendingStream* pending =
2536         QuicSessionPeer::GetPendingStream(&*session_, stream_id);
2537     if (fin) {
2538       // Stream is closed if FIN is received.
2539       EXPECT_FALSE(pending);
2540     } else {
2541       ASSERT_TRUE(pending);
2542       // The pending stream must ignore read data.
2543       EXPECT_TRUE(pending->sequencer()->ignore_read_data());
2544     }
2545 
2546     stream_id += QuicUtils::StreamIdDelta(transport_version());
2547   }
2548 }
2549 
TEST_P(QuicSpdySessionTestServer,MultipleBytesPendingStreamTypeOutOfOrderDelivery)2550 TEST_P(QuicSpdySessionTestServer,
2551        MultipleBytesPendingStreamTypeOutOfOrderDelivery) {
2552   Initialize();
2553   if (!VersionUsesHttp3(transport_version())) {
2554     return;
2555   }
2556   CompleteHandshake();
2557   char input[] = {0x41, 0x00,      // type (256)
2558                   'a', 'b', 'c'};  // data
2559   absl::string_view payload(input, ABSL_ARRAYSIZE(input));
2560 
2561   // This is a server test with a client-initiated unidirectional stream.
2562   QuicStreamId stream_id = QuicUtils::GetFirstUnidirectionalStreamId(
2563       transport_version(), Perspective::IS_CLIENT);
2564 
2565   for (bool fin : {true, false}) {
2566     QuicStreamFrame frame1(stream_id, /* fin = */ false, /* offset = */ 0,
2567                            payload.substr(0, 1));
2568     QuicStreamFrame frame2(stream_id, /* fin = */ false, /* offset = */ 1,
2569                            payload.substr(1, 1));
2570     QuicStreamFrame frame3(stream_id, fin, /* offset = */ 2, payload.substr(2));
2571 
2572     // Deliver frames out of order.
2573     session_->OnStreamFrame(frame3);
2574     // The first byte does not contain the entire type varint.
2575     session_->OnStreamFrame(frame1);
2576     // A STOP_SENDING frame is sent in response to the unknown stream type.
2577     EXPECT_CALL(*connection_, SendControlFrame(_))
2578         .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
2579     session_->OnStreamFrame(frame2);
2580 
2581     PendingStream* pending =
2582         QuicSessionPeer::GetPendingStream(&*session_, stream_id);
2583     if (fin) {
2584       // Stream is closed if FIN is received.
2585       EXPECT_FALSE(pending);
2586     } else {
2587       ASSERT_TRUE(pending);
2588       // The pending stream must ignore read data.
2589       EXPECT_TRUE(pending->sequencer()->ignore_read_data());
2590     }
2591 
2592     stream_id += QuicUtils::StreamIdDelta(transport_version());
2593   }
2594 }
2595 
TEST_P(QuicSpdySessionTestServer,ReceiveControlStream)2596 TEST_P(QuicSpdySessionTestServer, ReceiveControlStream) {
2597   Initialize();
2598   if (!VersionUsesHttp3(transport_version())) {
2599     return;
2600   }
2601 
2602   CompleteHandshake();
2603   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2604   session_->set_debug_visitor(&debug_visitor);
2605 
2606   // Use an arbitrary stream id.
2607   QuicStreamId stream_id =
2608       GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
2609   char type[] = {kControlStream};
2610 
2611   QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1));
2612   EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
2613   session_->OnStreamFrame(data1);
2614   EXPECT_EQ(stream_id,
2615             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
2616 
2617   SettingsFrame settings;
2618   settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 512;
2619   settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
2620   settings.values[SETTINGS_QPACK_BLOCKED_STREAMS] = 42;
2621   std::string data = HttpEncoder::SerializeSettingsFrame(settings);
2622   QuicStreamFrame frame(stream_id, false, 1, data);
2623 
2624   QpackEncoder* qpack_encoder = session_->qpack_encoder();
2625   QpackEncoderHeaderTable* header_table =
2626       QpackEncoderPeer::header_table(qpack_encoder);
2627 
2628   EXPECT_NE(512u, header_table->maximum_dynamic_table_capacity());
2629   EXPECT_NE(5u, session_->max_outbound_header_list_size());
2630   EXPECT_NE(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
2631 
2632   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
2633   session_->OnStreamFrame(frame);
2634 
2635   EXPECT_EQ(512u, header_table->maximum_dynamic_table_capacity());
2636   EXPECT_EQ(5u, session_->max_outbound_header_list_size());
2637   EXPECT_EQ(42u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
2638 }
2639 
TEST_P(QuicSpdySessionTestServer,ServerDisableQpackDynamicTable)2640 TEST_P(QuicSpdySessionTestServer, ServerDisableQpackDynamicTable) {
2641   SetQuicFlag(quic_server_disable_qpack_dynamic_table, true);
2642   Initialize();
2643   if (!VersionUsesHttp3(transport_version())) {
2644     return;
2645   }
2646   CompleteHandshake();
2647 
2648   // Use an arbitrary stream id for creating the receive control stream.
2649   QuicStreamId stream_id =
2650       GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
2651   char type[] = {kControlStream};
2652   QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1));
2653   session_->OnStreamFrame(data1);
2654   EXPECT_EQ(stream_id,
2655             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
2656   // Receive the QPACK dynamic table capacity from the peer.
2657   const uint64_t capacity = 512;
2658   SettingsFrame settings;
2659   settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = capacity;
2660   std::string data = HttpEncoder::SerializeSettingsFrame(settings);
2661   QuicStreamFrame frame(stream_id, false, 1, data);
2662   session_->OnStreamFrame(frame);
2663 
2664   // Verify that the encoder's dynamic table capacity is 0.
2665   QpackEncoder* qpack_encoder = session_->qpack_encoder();
2666   EXPECT_EQ(capacity, qpack_encoder->MaximumDynamicTableCapacity());
2667   QpackEncoderHeaderTable* encoder_header_table =
2668       QpackEncoderPeer::header_table(qpack_encoder);
2669   EXPECT_EQ(capacity, encoder_header_table->maximum_dynamic_table_capacity());
2670   EXPECT_EQ(0, encoder_header_table->dynamic_table_capacity());
2671 
2672   // Verify that the advertised capacity is 0.
2673   SettingsFrame outgoing_settings = session_->settings();
2674   EXPECT_EQ(0, outgoing_settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY]);
2675 }
2676 
TEST_P(QuicSpdySessionTestServer,DisableQpackDynamicTable)2677 TEST_P(QuicSpdySessionTestServer, DisableQpackDynamicTable) {
2678   SetQuicFlag(quic_server_disable_qpack_dynamic_table, false);
2679   qpack_maximum_dynamic_table_capacity_ = 0;
2680   Initialize();
2681   if (!VersionUsesHttp3(transport_version())) {
2682     return;
2683   }
2684   CompleteHandshake();
2685 
2686   // Use an arbitrary stream id for creating the receive control stream.
2687   QuicStreamId stream_id =
2688       GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
2689   char type[] = {kControlStream};
2690   QuicStreamFrame data1(stream_id, false, 0, absl::string_view(type, 1));
2691   session_->OnStreamFrame(data1);
2692   EXPECT_EQ(stream_id,
2693             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
2694   // Receive the QPACK dynamic table capacity from the peer.
2695   const uint64_t capacity = 512;
2696   SettingsFrame settings;
2697   settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = capacity;
2698   std::string data = HttpEncoder::SerializeSettingsFrame(settings);
2699   QuicStreamFrame frame(stream_id, false, 1, data);
2700   session_->OnStreamFrame(frame);
2701 
2702   // Verify that the encoder's dynamic table capacity is 0.
2703   QpackEncoder* qpack_encoder = session_->qpack_encoder();
2704   EXPECT_EQ(capacity, qpack_encoder->MaximumDynamicTableCapacity());
2705   QpackEncoderHeaderTable* encoder_header_table =
2706       QpackEncoderPeer::header_table(qpack_encoder);
2707   EXPECT_EQ(capacity, encoder_header_table->maximum_dynamic_table_capacity());
2708   EXPECT_EQ(0, encoder_header_table->dynamic_table_capacity());
2709 
2710   // Verify that the advertised capacity is 0.
2711   SettingsFrame outgoing_settings = session_->settings();
2712   EXPECT_EQ(0, outgoing_settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY]);
2713 }
2714 
TEST_P(QuicSpdySessionTestServer,ReceiveControlStreamOutOfOrderDelivery)2715 TEST_P(QuicSpdySessionTestServer, ReceiveControlStreamOutOfOrderDelivery) {
2716   Initialize();
2717   if (!VersionUsesHttp3(transport_version())) {
2718     return;
2719   }
2720   CompleteHandshake();
2721   // Use an arbitrary stream id.
2722   QuicStreamId stream_id =
2723       GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
2724   char type[] = {kControlStream};
2725   SettingsFrame settings;
2726   settings.values[10] = 2;
2727   settings.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
2728   std::string data = HttpEncoder::SerializeSettingsFrame(settings);
2729 
2730   QuicStreamFrame data1(stream_id, false, 1, data);
2731   QuicStreamFrame data2(stream_id, false, 0, absl::string_view(type, 1));
2732 
2733   session_->OnStreamFrame(data1);
2734   EXPECT_NE(5u, session_->max_outbound_header_list_size());
2735   session_->OnStreamFrame(data2);
2736   EXPECT_EQ(5u, session_->max_outbound_header_list_size());
2737 }
2738 
2739 // Regression test for https://crbug.com/1009551.
TEST_P(QuicSpdySessionTestServer,StreamClosedWhileHeaderDecodingBlocked)2740 TEST_P(QuicSpdySessionTestServer, StreamClosedWhileHeaderDecodingBlocked) {
2741   Initialize();
2742   if (!VersionUsesHttp3(transport_version())) {
2743     return;
2744   }
2745   CompleteHandshake();
2746   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
2747 
2748   QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
2749   TestStream* stream = session_->CreateIncomingStream(stream_id);
2750 
2751   // HEADERS frame referencing first dynamic table entry.
2752   std::string headers_frame_payload;
2753   ASSERT_TRUE(absl::HexStringToBytes("020080", &headers_frame_payload));
2754   std::string headers_frame_header =
2755       HttpEncoder::SerializeHeadersFrameHeader(headers_frame_payload.length());
2756   std::string headers_frame =
2757       absl::StrCat(headers_frame_header, headers_frame_payload);
2758   stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers_frame));
2759 
2760   // Decoding is blocked because dynamic table entry has not been received yet.
2761   EXPECT_FALSE(stream->headers_decompressed());
2762 
2763   // Stream is closed and destroyed.
2764   CloseStream(stream_id);
2765   session_->CleanUpClosedStreams();
2766 
2767   // Dynamic table entry arrived on the decoder stream.
2768   // The destroyed stream object must not be referenced.
2769   session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar");
2770 }
2771 
2772 // Regression test for https://crbug.com/1011294.
TEST_P(QuicSpdySessionTestServer,SessionDestroyedWhileHeaderDecodingBlocked)2773 TEST_P(QuicSpdySessionTestServer, SessionDestroyedWhileHeaderDecodingBlocked) {
2774   Initialize();
2775   if (!VersionUsesHttp3(transport_version())) {
2776     return;
2777   }
2778 
2779   session_->qpack_decoder()->OnSetDynamicTableCapacity(1024);
2780 
2781   QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
2782   TestStream* stream = session_->CreateIncomingStream(stream_id);
2783 
2784   // HEADERS frame referencing first dynamic table entry.
2785   std::string headers_frame_payload;
2786   ASSERT_TRUE(absl::HexStringToBytes("020080", &headers_frame_payload));
2787   std::string headers_frame_header =
2788       HttpEncoder::SerializeHeadersFrameHeader(headers_frame_payload.length());
2789   std::string headers_frame =
2790       absl::StrCat(headers_frame_header, headers_frame_payload);
2791   stream->OnStreamFrame(QuicStreamFrame(stream_id, false, 0, headers_frame));
2792 
2793   // Decoding is blocked because dynamic table entry has not been received yet.
2794   EXPECT_FALSE(stream->headers_decompressed());
2795 
2796   // |session_| gets destoyed.  That destroys QpackDecoder, a member of
2797   // QuicSpdySession (derived class), which destroys QpackDecoderHeaderTable.
2798   // Then |*stream|, owned by QuicSession (base class) get destroyed, which
2799   // destroys QpackProgessiveDecoder, a registered Observer of
2800   // QpackDecoderHeaderTable.  This must not cause a crash.
2801 }
2802 
TEST_P(QuicSpdySessionTestClient,ResetAfterInvalidIncomingStreamType)2803 TEST_P(QuicSpdySessionTestClient, ResetAfterInvalidIncomingStreamType) {
2804   Initialize();
2805   if (!VersionUsesHttp3(transport_version())) {
2806     return;
2807   }
2808   CompleteHandshake();
2809 
2810   const QuicStreamId stream_id =
2811       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
2812   ASSERT_TRUE(session_->UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
2813 
2814   // Payload consists of two bytes.  The first byte is an unknown unidirectional
2815   // stream type.  The second one would be the type of a push stream, but it
2816   // must not be interpreted as stream type.
2817   std::string payload;
2818   ASSERT_TRUE(absl::HexStringToBytes("3f01", &payload));
2819   QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
2820                         payload);
2821 
2822   // A STOP_SENDING frame is sent in response to the unknown stream type.
2823   EXPECT_CALL(*connection_, SendControlFrame(_))
2824       .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
2825   session_->OnStreamFrame(frame);
2826 
2827   // There are no active streams.
2828   EXPECT_EQ(0u, QuicSessionPeer::GetNumOpenDynamicStreams(&*session_));
2829 
2830   // The pending stream is still around, because it did not receive a FIN.
2831   PendingStream* pending =
2832       QuicSessionPeer::GetPendingStream(&*session_, stream_id);
2833   ASSERT_TRUE(pending);
2834 
2835   // The pending stream must ignore read data.
2836   EXPECT_TRUE(pending->sequencer()->ignore_read_data());
2837 
2838   // If the stream frame is received again, it should be ignored.
2839   session_->OnStreamFrame(frame);
2840 
2841   // Receive RESET_STREAM.
2842   QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
2843                                QUIC_STREAM_CANCELLED,
2844                                /* bytes_written = */ payload.size());
2845 
2846   session_->OnRstStream(rst_frame);
2847 
2848   // The stream is closed.
2849   EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&*session_, stream_id));
2850 }
2851 
TEST_P(QuicSpdySessionTestClient,FinAfterInvalidIncomingStreamType)2852 TEST_P(QuicSpdySessionTestClient, FinAfterInvalidIncomingStreamType) {
2853   Initialize();
2854   if (!VersionUsesHttp3(transport_version())) {
2855     return;
2856   }
2857   CompleteHandshake();
2858 
2859   const QuicStreamId stream_id =
2860       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
2861   ASSERT_TRUE(session_->UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
2862 
2863   // Payload consists of two bytes.  The first byte is an unknown unidirectional
2864   // stream type.  The second one would be the type of a push stream, but it
2865   // must not be interpreted as stream type.
2866   std::string payload;
2867   ASSERT_TRUE(absl::HexStringToBytes("3f01", &payload));
2868   QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
2869                         payload);
2870 
2871   // A STOP_SENDING frame is sent in response to the unknown stream type.
2872   EXPECT_CALL(*connection_, SendControlFrame(_))
2873       .WillOnce(Invoke(&VerifyAndClearStopSendingFrame));
2874   session_->OnStreamFrame(frame);
2875 
2876   // The pending stream is still around, because it did not receive a FIN.
2877   PendingStream* pending =
2878       QuicSessionPeer::GetPendingStream(&*session_, stream_id);
2879   EXPECT_TRUE(pending);
2880 
2881   // The pending stream must ignore read data.
2882   EXPECT_TRUE(pending->sequencer()->ignore_read_data());
2883 
2884   // If the stream frame is received again, it should be ignored.
2885   session_->OnStreamFrame(frame);
2886 
2887   // Receive FIN.
2888   session_->OnStreamFrame(QuicStreamFrame(stream_id, /* fin = */ true,
2889                                           /* offset = */ payload.size(), ""));
2890 
2891   EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&*session_, stream_id));
2892 }
2893 
TEST_P(QuicSpdySessionTestClient,ResetInMiddleOfStreamType)2894 TEST_P(QuicSpdySessionTestClient, ResetInMiddleOfStreamType) {
2895   Initialize();
2896   if (!VersionUsesHttp3(transport_version())) {
2897     return;
2898   }
2899 
2900   CompleteHandshake();
2901   const QuicStreamId stream_id =
2902       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
2903   ASSERT_TRUE(session_->UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
2904 
2905   // Payload is the first byte of a two byte varint encoding.
2906   std::string payload;
2907   ASSERT_TRUE(absl::HexStringToBytes("40", &payload));
2908   QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0,
2909                         payload);
2910 
2911   session_->OnStreamFrame(frame);
2912   EXPECT_TRUE(QuicSessionPeer::GetPendingStream(&*session_, stream_id));
2913 
2914   // Receive RESET_STREAM.
2915   QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_id,
2916                                QUIC_STREAM_CANCELLED,
2917                                /* bytes_written = */ payload.size());
2918 
2919   session_->OnRstStream(rst_frame);
2920 
2921   // The stream is closed.
2922   EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&*session_, stream_id));
2923 }
2924 
TEST_P(QuicSpdySessionTestClient,FinInMiddleOfStreamType)2925 TEST_P(QuicSpdySessionTestClient, FinInMiddleOfStreamType) {
2926   Initialize();
2927   if (!VersionUsesHttp3(transport_version())) {
2928     return;
2929   }
2930 
2931   CompleteHandshake();
2932   const QuicStreamId stream_id =
2933       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
2934   ASSERT_TRUE(session_->UsesPendingStreamForFrame(STREAM_FRAME, stream_id));
2935 
2936   // Payload is the first byte of a two byte varint encoding with a FIN.
2937   std::string payload;
2938   ASSERT_TRUE(absl::HexStringToBytes("40", &payload));
2939   QuicStreamFrame frame(stream_id, /* fin = */ true, /* offset = */ 0, payload);
2940 
2941   session_->OnStreamFrame(frame);
2942   EXPECT_FALSE(QuicSessionPeer::GetPendingStream(&*session_, stream_id));
2943 }
2944 
TEST_P(QuicSpdySessionTestClient,DuplicateHttp3UnidirectionalStreams)2945 TEST_P(QuicSpdySessionTestClient, DuplicateHttp3UnidirectionalStreams) {
2946   Initialize();
2947   if (!VersionUsesHttp3(transport_version())) {
2948     return;
2949   }
2950 
2951   CompleteHandshake();
2952   StrictMock<MockHttp3DebugVisitor> debug_visitor;
2953   session_->set_debug_visitor(&debug_visitor);
2954 
2955   QuicStreamId id1 =
2956       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
2957   char type1[] = {kControlStream};
2958 
2959   QuicStreamFrame data1(id1, false, 0, absl::string_view(type1, 1));
2960   EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id1));
2961   session_->OnStreamFrame(data1);
2962   QuicStreamId id2 =
2963       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 1);
2964   QuicStreamFrame data2(id2, false, 0, absl::string_view(type1, 1));
2965   EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(id2)).Times(0);
2966   EXPECT_QUIC_PEER_BUG(
2967       {
2968         EXPECT_CALL(*connection_,
2969                     CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
2970                                     "Control stream is received twice.", _));
2971         session_->OnStreamFrame(data2);
2972       },
2973       "Received a duplicate Control stream: Closing connection.");
2974 
2975   QuicStreamId id3 =
2976       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 2);
2977   char type2[]{kQpackEncoderStream};
2978 
2979   QuicStreamFrame data3(id3, false, 0, absl::string_view(type2, 1));
2980   EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id3));
2981   session_->OnStreamFrame(data3);
2982 
2983   QuicStreamId id4 =
2984       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
2985   QuicStreamFrame data4(id4, false, 0, absl::string_view(type2, 1));
2986   EXPECT_CALL(debug_visitor, OnPeerQpackEncoderStreamCreated(id4)).Times(0);
2987   EXPECT_QUIC_PEER_BUG(
2988       {
2989         EXPECT_CALL(
2990             *connection_,
2991             CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
2992                             "QPACK encoder stream is received twice.", _));
2993         session_->OnStreamFrame(data4);
2994       },
2995       "Received a duplicate QPACK encoder stream: Closing connection.");
2996 
2997   QuicStreamId id5 =
2998       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 4);
2999   char type3[]{kQpackDecoderStream};
3000 
3001   QuicStreamFrame data5(id5, false, 0, absl::string_view(type3, 1));
3002   EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id5));
3003   session_->OnStreamFrame(data5);
3004 
3005   QuicStreamId id6 =
3006       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 5);
3007   QuicStreamFrame data6(id6, false, 0, absl::string_view(type3, 1));
3008   EXPECT_CALL(debug_visitor, OnPeerQpackDecoderStreamCreated(id6)).Times(0);
3009   EXPECT_QUIC_PEER_BUG(
3010       {
3011         EXPECT_CALL(
3012             *connection_,
3013             CloseConnection(QUIC_HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM,
3014                             "QPACK decoder stream is received twice.", _));
3015         session_->OnStreamFrame(data6);
3016       },
3017       "Received a duplicate QPACK decoder stream: Closing connection.");
3018 }
3019 
TEST_P(QuicSpdySessionTestClient,EncoderStreamError)3020 TEST_P(QuicSpdySessionTestClient, EncoderStreamError) {
3021   Initialize();
3022   if (!VersionUsesHttp3(transport_version())) {
3023     return;
3024   }
3025 
3026   CompleteHandshake();
3027   std::string data;
3028   ASSERT_TRUE(
3029       absl::HexStringToBytes("02"   // Encoder stream.
3030                              "00",  // Duplicate entry 0, but no entries exist.
3031                              &data));
3032 
3033   QuicStreamId stream_id =
3034       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
3035 
3036   QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
3037 
3038   EXPECT_CALL(*connection_,
3039               CloseConnection(
3040                   QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX,
3041                   "Encoder stream error: Invalid relative index.", _));
3042   session_->OnStreamFrame(frame);
3043 }
3044 
TEST_P(QuicSpdySessionTestClient,DecoderStreamError)3045 TEST_P(QuicSpdySessionTestClient, DecoderStreamError) {
3046   Initialize();
3047   if (!VersionUsesHttp3(transport_version())) {
3048     return;
3049   }
3050 
3051   CompleteHandshake();
3052   std::string data;
3053   ASSERT_TRUE(absl::HexStringToBytes(
3054       "03"   // Decoder stream.
3055       "00",  // Insert Count Increment with forbidden increment value of zero.
3056       &data));
3057 
3058   QuicStreamId stream_id =
3059       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
3060 
3061   QuicStreamFrame frame(stream_id, /* fin = */ false, /* offset = */ 0, data);
3062 
3063   EXPECT_CALL(
3064       *connection_,
3065       CloseConnection(QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT,
3066                       "Decoder stream error: Invalid increment value 0.", _));
3067   session_->OnStreamFrame(frame);
3068 }
3069 
TEST_P(QuicSpdySessionTestClient,InvalidHttp3GoAway)3070 TEST_P(QuicSpdySessionTestClient, InvalidHttp3GoAway) {
3071   Initialize();
3072   if (!VersionUsesHttp3(transport_version())) {
3073     return;
3074   }
3075   EXPECT_CALL(*connection_,
3076               CloseConnection(QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
3077                               "GOAWAY with invalid stream ID", _));
3078   QuicStreamId stream_id =
3079       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
3080   session_->OnHttp3GoAway(stream_id);
3081 }
3082 
TEST_P(QuicSpdySessionTestClient,Http3GoAwayLargerIdThanBefore)3083 TEST_P(QuicSpdySessionTestClient, Http3GoAwayLargerIdThanBefore) {
3084   Initialize();
3085   if (!VersionUsesHttp3(transport_version())) {
3086     return;
3087   }
3088 
3089   EXPECT_FALSE(session_->goaway_received());
3090   QuicStreamId stream_id1 =
3091       GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
3092   session_->OnHttp3GoAway(stream_id1);
3093   EXPECT_TRUE(session_->goaway_received());
3094 
3095   EXPECT_CALL(
3096       *connection_,
3097       CloseConnection(
3098           QUIC_HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS,
3099           "GOAWAY received with ID 4 greater than previously received ID 0",
3100           _));
3101   QuicStreamId stream_id2 =
3102       GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
3103   session_->OnHttp3GoAway(stream_id2);
3104 }
3105 
TEST_P(QuicSpdySessionTestClient,CloseConnectionOnCancelPush)3106 TEST_P(QuicSpdySessionTestClient, CloseConnectionOnCancelPush) {
3107   Initialize();
3108   if (!VersionUsesHttp3(transport_version())) {
3109     return;
3110   }
3111 
3112   CompleteHandshake();
3113   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3114   session_->set_debug_visitor(&debug_visitor);
3115 
3116   // Create control stream.
3117   QuicStreamId receive_control_stream_id =
3118       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
3119   char type[] = {kControlStream};
3120   absl::string_view stream_type(type, 1);
3121   QuicStreamOffset offset = 0;
3122   QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
3123                         stream_type);
3124   offset += stream_type.length();
3125   EXPECT_CALL(debug_visitor,
3126               OnPeerControlStreamCreated(receive_control_stream_id));
3127   session_->OnStreamFrame(data1);
3128   EXPECT_EQ(receive_control_stream_id,
3129             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
3130 
3131   // First frame has to be SETTINGS.
3132   std::string serialized_settings = HttpEncoder::SerializeSettingsFrame({});
3133   QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
3134                         serialized_settings);
3135   offset += serialized_settings.length();
3136   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
3137   session_->OnStreamFrame(data2);
3138 
3139   std::string cancel_push_frame;
3140   ASSERT_TRUE(
3141       absl::HexStringToBytes("03"   // CANCEL_PUSH
3142                              "01"   // length
3143                              "00",  // push ID
3144                              &cancel_push_frame));
3145   QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
3146                         cancel_push_frame);
3147   EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
3148                                             "CANCEL_PUSH frame received.", _))
3149       .WillOnce(
3150           Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
3151   EXPECT_CALL(*connection_,
3152               SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
3153                                         "CANCEL_PUSH frame received."));
3154   session_->OnStreamFrame(data3);
3155 }
3156 
TEST_P(QuicSpdySessionTestServer,OnSetting)3157 TEST_P(QuicSpdySessionTestServer, OnSetting) {
3158   Initialize();
3159   CompleteHandshake();
3160   if (VersionUsesHttp3(transport_version())) {
3161     EXPECT_EQ(std::numeric_limits<size_t>::max(),
3162               session_->max_outbound_header_list_size());
3163     session_->OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
3164     EXPECT_EQ(5u, session_->max_outbound_header_list_size());
3165 
3166     EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
3167         .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
3168     QpackEncoder* qpack_encoder = session_->qpack_encoder();
3169     EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
3170     session_->OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 12);
3171     EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
3172 
3173     QpackEncoderHeaderTable* header_table =
3174         QpackEncoderPeer::header_table(qpack_encoder);
3175     EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
3176     session_->OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 37);
3177     EXPECT_EQ(37u, header_table->maximum_dynamic_table_capacity());
3178 
3179     return;
3180   }
3181 
3182   EXPECT_EQ(std::numeric_limits<size_t>::max(),
3183             session_->max_outbound_header_list_size());
3184   session_->OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
3185   EXPECT_EQ(5u, session_->max_outbound_header_list_size());
3186 
3187   spdy::HpackEncoder* hpack_encoder =
3188       QuicSpdySessionPeer::GetSpdyFramer(&*session_)->GetHpackEncoder();
3189   EXPECT_EQ(4096u, hpack_encoder->CurrentHeaderTableSizeSetting());
3190   session_->OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 59);
3191   EXPECT_EQ(59u, hpack_encoder->CurrentHeaderTableSizeSetting());
3192 }
3193 
TEST_P(QuicSpdySessionTestServer,FineGrainedHpackErrorCodes)3194 TEST_P(QuicSpdySessionTestServer, FineGrainedHpackErrorCodes) {
3195   Initialize();
3196   if (VersionUsesHttp3(transport_version())) {
3197     // HPACK is not used in HTTP/3.
3198     return;
3199   }
3200 
3201   QuicStreamId request_stream_id = 5;
3202   session_->CreateIncomingStream(request_stream_id);
3203 
3204   // Index 126 does not exist (static table has 61 entries and dynamic table is
3205   // empty).
3206   std::string headers_frame;
3207   ASSERT_TRUE(
3208       absl::HexStringToBytes("000006"    // length
3209                              "01"        // type
3210                              "24"        // flags: PRIORITY | END_HEADERS
3211                              "00000005"  // stream_id
3212                              "00000000"  // stream dependency
3213                              "10"        // weight
3214                              "fe",       // payload: reference to index 126.
3215                              &headers_frame));
3216   QuicStreamId headers_stream_id =
3217       QuicUtils::GetHeadersStreamId(transport_version());
3218   QuicStreamFrame data(headers_stream_id, false, 0, headers_frame);
3219 
3220   EXPECT_CALL(
3221       *connection_,
3222       CloseConnection(QUIC_HPACK_INVALID_INDEX,
3223                       "SPDY framing error: HPACK_INVALID_INDEX",
3224                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
3225   session_->OnStreamFrame(data);
3226 }
3227 
TEST_P(QuicSpdySessionTestServer,PeerClosesCriticalReceiveStream)3228 TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalReceiveStream) {
3229   Initialize();
3230   if (!VersionUsesHttp3(transport_version())) {
3231     return;
3232   }
3233   CompleteHandshake();
3234 
3235   struct {
3236     char type;
3237     const char* error_details;
3238   } kTestData[] = {
3239       {kControlStream, "RESET_STREAM received for receive control stream"},
3240       {kQpackEncoderStream, "RESET_STREAM received for QPACK receive stream"},
3241       {kQpackDecoderStream, "RESET_STREAM received for QPACK receive stream"},
3242   };
3243   for (size_t i = 0; i < ABSL_ARRAYSIZE(kTestData); ++i) {
3244     QuicStreamId stream_id =
3245         GetNthClientInitiatedUnidirectionalStreamId(transport_version(), i + 1);
3246     const QuicByteCount data_length = 1;
3247     QuicStreamFrame data(stream_id, false, 0,
3248                          absl::string_view(&kTestData[i].type, data_length));
3249     session_->OnStreamFrame(data);
3250 
3251     EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
3252                                               kTestData[i].error_details, _));
3253 
3254     QuicRstStreamFrame rst(kInvalidControlFrameId, stream_id,
3255                            QUIC_STREAM_CANCELLED, data_length);
3256     session_->OnRstStream(rst);
3257   }
3258 }
3259 
TEST_P(QuicSpdySessionTestServer,H3ControlStreamsLimitedByConnectionFlowControl)3260 TEST_P(QuicSpdySessionTestServer,
3261        H3ControlStreamsLimitedByConnectionFlowControl) {
3262   Initialize();
3263   if (!VersionUsesHttp3(transport_version())) {
3264     return;
3265   }
3266   // Ensure connection level flow control blockage.
3267   QuicFlowControllerPeer::SetSendWindowOffset(session_->flow_controller(), 0);
3268   EXPECT_TRUE(session_->IsConnectionFlowControlBlocked());
3269 
3270   QuicSendControlStream* send_control_stream =
3271       QuicSpdySessionPeer::GetSendControlStream(&*session_);
3272   // Mark send_control stream write blocked.
3273   session_->MarkConnectionLevelWriteBlocked(send_control_stream->id());
3274   EXPECT_FALSE(session_->WillingAndAbleToWrite());
3275 }
3276 
TEST_P(QuicSpdySessionTestServer,PeerClosesCriticalSendStream)3277 TEST_P(QuicSpdySessionTestServer, PeerClosesCriticalSendStream) {
3278   Initialize();
3279   if (!VersionUsesHttp3(transport_version())) {
3280     return;
3281   }
3282 
3283   QuicSendControlStream* control_stream =
3284       QuicSpdySessionPeer::GetSendControlStream(&*session_);
3285   ASSERT_TRUE(control_stream);
3286 
3287   QuicStopSendingFrame stop_sending_control_stream(
3288       kInvalidControlFrameId, control_stream->id(), QUIC_STREAM_CANCELLED);
3289   EXPECT_CALL(
3290       *connection_,
3291       CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
3292                       "STOP_SENDING received for send control stream", _));
3293   session_->OnStopSendingFrame(stop_sending_control_stream);
3294 
3295   QpackSendStream* decoder_stream =
3296       QuicSpdySessionPeer::GetQpackDecoderSendStream(&*session_);
3297   ASSERT_TRUE(decoder_stream);
3298 
3299   QuicStopSendingFrame stop_sending_decoder_stream(
3300       kInvalidControlFrameId, decoder_stream->id(), QUIC_STREAM_CANCELLED);
3301   EXPECT_CALL(
3302       *connection_,
3303       CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
3304                       "STOP_SENDING received for QPACK send stream", _));
3305   session_->OnStopSendingFrame(stop_sending_decoder_stream);
3306 
3307   QpackSendStream* encoder_stream =
3308       QuicSpdySessionPeer::GetQpackEncoderSendStream(&*session_);
3309   ASSERT_TRUE(encoder_stream);
3310 
3311   QuicStopSendingFrame stop_sending_encoder_stream(
3312       kInvalidControlFrameId, encoder_stream->id(), QUIC_STREAM_CANCELLED);
3313   EXPECT_CALL(
3314       *connection_,
3315       CloseConnection(QUIC_HTTP_CLOSED_CRITICAL_STREAM,
3316                       "STOP_SENDING received for QPACK send stream", _));
3317   session_->OnStopSendingFrame(stop_sending_encoder_stream);
3318 }
3319 
TEST_P(QuicSpdySessionTestServer,CloseConnectionOnCancelPush)3320 TEST_P(QuicSpdySessionTestServer, CloseConnectionOnCancelPush) {
3321   Initialize();
3322   if (!VersionUsesHttp3(transport_version())) {
3323     return;
3324   }
3325 
3326   CompleteHandshake();
3327   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3328   session_->set_debug_visitor(&debug_visitor);
3329 
3330   // Create control stream.
3331   QuicStreamId receive_control_stream_id =
3332       GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3);
3333   char type[] = {kControlStream};
3334   absl::string_view stream_type(type, 1);
3335   QuicStreamOffset offset = 0;
3336   QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
3337                         stream_type);
3338   offset += stream_type.length();
3339   EXPECT_CALL(debug_visitor,
3340               OnPeerControlStreamCreated(receive_control_stream_id));
3341   session_->OnStreamFrame(data1);
3342   EXPECT_EQ(receive_control_stream_id,
3343             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
3344 
3345   // First frame has to be SETTINGS.
3346   std::string serialized_settings = HttpEncoder::SerializeSettingsFrame({});
3347   QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
3348                         serialized_settings);
3349   offset += serialized_settings.length();
3350   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
3351   session_->OnStreamFrame(data2);
3352 
3353   std::string cancel_push_frame;
3354   ASSERT_TRUE(
3355       absl::HexStringToBytes("03"   // CANCEL_PUSH
3356                              "01"   // length
3357                              "00",  // push ID
3358                              &cancel_push_frame));
3359   QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
3360                         cancel_push_frame);
3361   EXPECT_CALL(*connection_, CloseConnection(QUIC_HTTP_FRAME_ERROR,
3362                                             "CANCEL_PUSH frame received.", _))
3363       .WillOnce(
3364           Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
3365   EXPECT_CALL(*connection_,
3366               SendConnectionClosePacket(QUIC_HTTP_FRAME_ERROR, _,
3367                                         "CANCEL_PUSH frame received."));
3368   session_->OnStreamFrame(data3);
3369 }
3370 
TEST_P(QuicSpdySessionTestServer,Http3GoAwayWhenClosingConnection)3371 TEST_P(QuicSpdySessionTestServer, Http3GoAwayWhenClosingConnection) {
3372   Initialize();
3373   if (!VersionUsesHttp3(transport_version())) {
3374     return;
3375   }
3376 
3377   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3378   session_->set_debug_visitor(&debug_visitor);
3379 
3380   EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
3381   CompleteHandshake();
3382 
3383   QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
3384 
3385   // Create stream by receiving some data (CreateIncomingStream() would not
3386   // update the session's largest peer created stream ID).
3387   const QuicByteCount headers_payload_length = 10;
3388   std::string headers_frame_header =
3389       HttpEncoder::SerializeHeadersFrameHeader(headers_payload_length);
3390   EXPECT_CALL(debug_visitor,
3391               OnHeadersFrameReceived(stream_id, headers_payload_length));
3392   session_->OnStreamFrame(
3393       QuicStreamFrame(stream_id, false, 0, headers_frame_header));
3394 
3395   EXPECT_EQ(stream_id, QuicSessionPeer::GetLargestPeerCreatedStreamId(
3396                            &*session_, /*unidirectional = */ false));
3397 
3398   // Stream with stream_id is already received and potentially processed,
3399   // therefore a GOAWAY frame is sent with the next stream ID.
3400   EXPECT_CALL(debug_visitor,
3401               OnGoAwayFrameSent(stream_id +
3402                                 QuicUtils::StreamIdDelta(transport_version())));
3403 
3404   // Close connection.
3405   EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
3406       .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
3407   EXPECT_CALL(*connection_, CloseConnection(QUIC_NO_ERROR, _, _))
3408       .WillOnce(
3409           Invoke(connection_, &MockQuicConnection::ReallyCloseConnection));
3410   EXPECT_CALL(*connection_, SendConnectionClosePacket(QUIC_NO_ERROR, _, _))
3411       .WillOnce(Invoke(connection_,
3412                        &MockQuicConnection::ReallySendConnectionClosePacket));
3413   connection_->CloseConnection(
3414       QUIC_NO_ERROR, "closing connection",
3415       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
3416 }
3417 
TEST_P(QuicSpdySessionTestClient,DoNotSendInitialMaxPushIdIfNotSet)3418 TEST_P(QuicSpdySessionTestClient, DoNotSendInitialMaxPushIdIfNotSet) {
3419   Initialize();
3420   if (!VersionUsesHttp3(transport_version())) {
3421     return;
3422   }
3423 
3424   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3425   session_->set_debug_visitor(&debug_visitor);
3426 
3427   InSequence s;
3428   EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
3429 
3430   CompleteHandshake();
3431 }
3432 
TEST_P(QuicSpdySessionTestClient,ReceiveSpdySettingInHttp3)3433 TEST_P(QuicSpdySessionTestClient, ReceiveSpdySettingInHttp3) {
3434   Initialize();
3435   if (!VersionUsesHttp3(transport_version())) {
3436     return;
3437   }
3438 
3439   SettingsFrame frame;
3440   frame.values[SETTINGS_MAX_FIELD_SECTION_SIZE] = 5;
3441   // https://datatracker.ietf.org/doc/html/draft-ietf-quic-http-30#section-7.2.4.1
3442   // specifies the presence of HTTP/2 setting as error.
3443   frame.values[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 100;
3444 
3445   CompleteHandshake();
3446 
3447   EXPECT_CALL(*connection_,
3448               CloseConnection(QUIC_HTTP_RECEIVE_SPDY_SETTING, _, _));
3449   session_->OnSettingsFrame(frame);
3450 }
3451 
TEST_P(QuicSpdySessionTestClient,ReceiveAcceptChFrame)3452 TEST_P(QuicSpdySessionTestClient, ReceiveAcceptChFrame) {
3453   Initialize();
3454   if (!VersionUsesHttp3(transport_version())) {
3455     return;
3456   }
3457 
3458   CompleteHandshake();
3459   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3460   session_->set_debug_visitor(&debug_visitor);
3461 
3462   // Create control stream.
3463   QuicStreamId receive_control_stream_id =
3464       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
3465   char type[] = {kControlStream};
3466   absl::string_view stream_type(type, 1);
3467   QuicStreamOffset offset = 0;
3468   QuicStreamFrame data1(receive_control_stream_id, /* fin = */ false, offset,
3469                         stream_type);
3470   offset += stream_type.length();
3471   EXPECT_CALL(debug_visitor,
3472               OnPeerControlStreamCreated(receive_control_stream_id));
3473 
3474   session_->OnStreamFrame(data1);
3475   EXPECT_EQ(receive_control_stream_id,
3476             QuicSpdySessionPeer::GetReceiveControlStream(&*session_)->id());
3477 
3478   // First frame has to be SETTINGS.
3479   std::string serialized_settings = HttpEncoder::SerializeSettingsFrame({});
3480   QuicStreamFrame data2(receive_control_stream_id, /* fin = */ false, offset,
3481                         serialized_settings);
3482   offset += serialized_settings.length();
3483   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(_));
3484 
3485   session_->OnStreamFrame(data2);
3486 
3487   // Receive ACCEPT_CH frame.
3488   AcceptChFrame accept_ch;
3489   accept_ch.entries.push_back({"foo", "bar"});
3490   std::string accept_ch_frame = HttpEncoder::SerializeAcceptChFrame(accept_ch);
3491   QuicStreamFrame data3(receive_control_stream_id, /* fin = */ false, offset,
3492                         accept_ch_frame);
3493 
3494   EXPECT_CALL(debug_visitor, OnAcceptChFrameReceived(accept_ch));
3495   EXPECT_CALL(*session_, OnAcceptChFrame(accept_ch));
3496 
3497   session_->OnStreamFrame(data3);
3498 }
3499 
TEST_P(QuicSpdySessionTestClient,AcceptChViaAlps)3500 TEST_P(QuicSpdySessionTestClient, AcceptChViaAlps) {
3501   Initialize();
3502   if (!VersionUsesHttp3(transport_version())) {
3503     return;
3504   }
3505 
3506   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3507   session_->set_debug_visitor(&debug_visitor);
3508 
3509   std::string serialized_accept_ch_frame;
3510   ASSERT_TRUE(
3511       absl::HexStringToBytes("4089"     // type (ACCEPT_CH)
3512                              "08"       // length
3513                              "03"       // length of origin
3514                              "666f6f"   // origin "foo"
3515                              "03"       // length of value
3516                              "626172",  // value "bar"
3517                              &serialized_accept_ch_frame));
3518 
3519   AcceptChFrame expected_accept_ch_frame{{{"foo", "bar"}}};
3520   EXPECT_CALL(debug_visitor,
3521               OnAcceptChFrameReceivedViaAlps(expected_accept_ch_frame));
3522 
3523   auto error = session_->OnAlpsData(
3524       reinterpret_cast<const uint8_t*>(serialized_accept_ch_frame.data()),
3525       serialized_accept_ch_frame.size());
3526   EXPECT_FALSE(error);
3527 }
3528 
TEST_P(QuicSpdySessionTestClient,AlpsForbiddenFrame)3529 TEST_P(QuicSpdySessionTestClient, AlpsForbiddenFrame) {
3530   Initialize();
3531   if (!VersionUsesHttp3(transport_version())) {
3532     return;
3533   }
3534 
3535   std::string forbidden_frame;
3536   ASSERT_TRUE(
3537       absl::HexStringToBytes("00"       // type (DATA)
3538                              "03"       // length
3539                              "66666f",  // "foo"
3540                              &forbidden_frame));
3541 
3542   auto error = session_->OnAlpsData(
3543       reinterpret_cast<const uint8_t*>(forbidden_frame.data()),
3544       forbidden_frame.size());
3545   ASSERT_TRUE(error);
3546   EXPECT_EQ("DATA frame forbidden", error.value());
3547 }
3548 
TEST_P(QuicSpdySessionTestClient,AlpsIncompleteFrame)3549 TEST_P(QuicSpdySessionTestClient, AlpsIncompleteFrame) {
3550   Initialize();
3551   if (!VersionUsesHttp3(transport_version())) {
3552     return;
3553   }
3554 
3555   std::string incomplete_frame;
3556   ASSERT_TRUE(
3557       absl::HexStringToBytes("04"   // type (SETTINGS)
3558                              "03",  // non-zero length but empty payload
3559                              &incomplete_frame));
3560 
3561   auto error = session_->OnAlpsData(
3562       reinterpret_cast<const uint8_t*>(incomplete_frame.data()),
3563       incomplete_frame.size());
3564   ASSERT_TRUE(error);
3565   EXPECT_EQ("incomplete HTTP/3 frame", error.value());
3566 }
3567 
3568 // After receiving a SETTINGS frame via ALPS,
3569 // another SETTINGS frame is still allowed on control frame.
TEST_P(QuicSpdySessionTestClient,SettingsViaAlpsThenOnControlStream)3570 TEST_P(QuicSpdySessionTestClient, SettingsViaAlpsThenOnControlStream) {
3571   Initialize();
3572   if (!VersionUsesHttp3(transport_version())) {
3573     return;
3574   }
3575 
3576   CompleteHandshake();
3577   QpackEncoder* qpack_encoder = session_->qpack_encoder();
3578   EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
3579   EXPECT_EQ(0u, qpack_encoder->maximum_blocked_streams());
3580 
3581   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3582   session_->set_debug_visitor(&debug_visitor);
3583 
3584   std::string serialized_settings_frame1;
3585   ASSERT_TRUE(
3586       absl::HexStringToBytes("04"    // type (SETTINGS)
3587                              "05"    // length
3588                              "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
3589                              "4400"  // 0x0400 = 1024
3590                              "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
3591                              "20",   // 0x20 = 32
3592                              &serialized_settings_frame1));
3593 
3594   SettingsFrame expected_settings_frame1{
3595       {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
3596        {SETTINGS_QPACK_BLOCKED_STREAMS, 32}}};
3597   EXPECT_CALL(debug_visitor,
3598               OnSettingsFrameReceivedViaAlps(expected_settings_frame1));
3599 
3600   auto error = session_->OnAlpsData(
3601       reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
3602       serialized_settings_frame1.size());
3603   EXPECT_FALSE(error);
3604 
3605   EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
3606   EXPECT_EQ(32u, qpack_encoder->maximum_blocked_streams());
3607 
3608   const QuicStreamId control_stream_id =
3609       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
3610   EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(control_stream_id));
3611 
3612   std::string stream_type;
3613   ASSERT_TRUE(absl::HexStringToBytes("00", &stream_type));
3614   session_->OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
3615                                           /* offset = */ 0, stream_type));
3616 
3617   // SETTINGS_QPACK_MAX_TABLE_CAPACITY, if advertised again, MUST have identical
3618   // value.
3619   // SETTINGS_QPACK_BLOCKED_STREAMS is a limit.  Limits MUST NOT be reduced, but
3620   // increasing is okay.
3621   SettingsFrame expected_settings_frame2{
3622       {{SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024},
3623        {SETTINGS_QPACK_BLOCKED_STREAMS, 48}}};
3624   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(expected_settings_frame2));
3625   std::string serialized_settings_frame2;
3626   ASSERT_TRUE(
3627       absl::HexStringToBytes("04"    // type (SETTINGS)
3628                              "05"    // length
3629                              "01"    // SETTINGS_QPACK_MAX_TABLE_CAPACITY
3630                              "4400"  // 0x0400 = 1024
3631                              "07"    // SETTINGS_QPACK_BLOCKED_STREAMS
3632                              "30",   // 0x30 = 48
3633                              &serialized_settings_frame2));
3634   session_->OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
3635                                           /* offset = */ stream_type.length(),
3636                                           serialized_settings_frame2));
3637 
3638   EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
3639   EXPECT_EQ(48u, qpack_encoder->maximum_blocked_streams());
3640 }
3641 
3642 // A SETTINGS frame received via ALPS and another one on the control stream
3643 // cannot have conflicting values.
TEST_P(QuicSpdySessionTestClient,SettingsViaAlpsConflictsSettingsViaControlStream)3644 TEST_P(QuicSpdySessionTestClient,
3645        SettingsViaAlpsConflictsSettingsViaControlStream) {
3646   Initialize();
3647   if (!VersionUsesHttp3(transport_version())) {
3648     return;
3649   }
3650 
3651   CompleteHandshake();
3652   QpackEncoder* qpack_encoder = session_->qpack_encoder();
3653   EXPECT_EQ(0u, qpack_encoder->MaximumDynamicTableCapacity());
3654 
3655   std::string serialized_settings_frame1;
3656   ASSERT_TRUE(
3657       absl::HexStringToBytes("04"     // type (SETTINGS)
3658                              "03"     // length
3659                              "01"     // SETTINGS_QPACK_MAX_TABLE_CAPACITY
3660                              "4400",  // 0x0400 = 1024
3661                              &serialized_settings_frame1));
3662 
3663   auto error = session_->OnAlpsData(
3664       reinterpret_cast<const uint8_t*>(serialized_settings_frame1.data()),
3665       serialized_settings_frame1.size());
3666   EXPECT_FALSE(error);
3667 
3668   EXPECT_EQ(1024u, qpack_encoder->MaximumDynamicTableCapacity());
3669 
3670   const QuicStreamId control_stream_id =
3671       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 0);
3672 
3673   std::string stream_type;
3674   ASSERT_TRUE(absl::HexStringToBytes("00", &stream_type));
3675   session_->OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
3676                                           /* offset = */ 0, stream_type));
3677 
3678   EXPECT_CALL(
3679       *connection_,
3680       CloseConnection(QUIC_HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH,
3681                       "Server sent an SETTINGS_QPACK_MAX_TABLE_CAPACITY: "
3682                       "32 while current value is: 1024",
3683                       ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
3684   std::string serialized_settings_frame2;
3685   ASSERT_TRUE(
3686       absl::HexStringToBytes("04"   // type (SETTINGS)
3687                              "02"   // length
3688                              "01"   // SETTINGS_QPACK_MAX_TABLE_CAPACITY
3689                              "20",  // 0x20 = 32
3690                              &serialized_settings_frame2));
3691   session_->OnStreamFrame(QuicStreamFrame(control_stream_id, /* fin = */ false,
3692                                           /* offset = */ stream_type.length(),
3693                                           serialized_settings_frame2));
3694 }
3695 
TEST_P(QuicSpdySessionTestClient,AlpsTwoSettingsFrame)3696 TEST_P(QuicSpdySessionTestClient, AlpsTwoSettingsFrame) {
3697   Initialize();
3698   if (!VersionUsesHttp3(transport_version())) {
3699     return;
3700   }
3701 
3702   std::string banned_frame;
3703   ASSERT_TRUE(
3704       absl::HexStringToBytes("04"   // type (SETTINGS)
3705                              "00"   // length
3706                              "04"   // type (SETTINGS)
3707                              "00",  // length
3708                              &banned_frame));
3709 
3710   auto error = session_->OnAlpsData(
3711       reinterpret_cast<const uint8_t*>(banned_frame.data()),
3712       banned_frame.size());
3713   ASSERT_TRUE(error);
3714   EXPECT_EQ("multiple SETTINGS frames", error.value());
3715 }
3716 
TestHttpDatagramSetting(HttpDatagramSupport local_support,HttpDatagramSupport remote_support,HttpDatagramSupport expected_support,bool expected_datagram_supported)3717 void QuicSpdySessionTestBase::TestHttpDatagramSetting(
3718     HttpDatagramSupport local_support, HttpDatagramSupport remote_support,
3719     HttpDatagramSupport expected_support, bool expected_datagram_supported) {
3720   if (!version().UsesHttp3()) {
3721     return;
3722   }
3723   CompleteHandshake();
3724   session_->set_local_http_datagram_support(local_support);
3725   // HTTP/3 datagrams aren't supported before SETTINGS are received.
3726   EXPECT_FALSE(session_->SupportsH3Datagram());
3727   EXPECT_EQ(session_->http_datagram_support(), HttpDatagramSupport::kNone);
3728   // Receive SETTINGS.
3729   SettingsFrame settings;
3730   switch (remote_support) {
3731     case HttpDatagramSupport::kNone:
3732       break;
3733     case HttpDatagramSupport::kDraft04:
3734       settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
3735       break;
3736     case HttpDatagramSupport::kRfc:
3737       settings.values[SETTINGS_H3_DATAGRAM] = 1;
3738       break;
3739     case HttpDatagramSupport::kRfcAndDraft04:
3740       settings.values[SETTINGS_H3_DATAGRAM] = 1;
3741       settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
3742       break;
3743   }
3744   std::string data = std::string(1, kControlStream) +
3745                      HttpEncoder::SerializeSettingsFrame(settings);
3746   QuicStreamId stream_id =
3747       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
3748   QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
3749   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3750   session_->set_debug_visitor(&debug_visitor);
3751   EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
3752   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(settings));
3753   session_->OnStreamFrame(frame);
3754   EXPECT_EQ(session_->http_datagram_support(), expected_support);
3755   EXPECT_EQ(session_->SupportsH3Datagram(), expected_datagram_supported);
3756 }
3757 
TEST_P(QuicSpdySessionTestClient,HttpDatagramSettingLocal04Remote04)3758 TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04) {
3759   Initialize();
3760   TestHttpDatagramSetting(
3761       /*local_support=*/HttpDatagramSupport::kDraft04,
3762       /*remote_support=*/HttpDatagramSupport::kDraft04,
3763       /*expected_support=*/HttpDatagramSupport::kDraft04,
3764       /*expected_datagram_supported=*/true);
3765 }
3766 
TEST_P(QuicSpdySessionTestClient,HttpDatagramSettingLocal04Remote09)3767 TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote09) {
3768   Initialize();
3769   TestHttpDatagramSetting(
3770       /*local_support=*/HttpDatagramSupport::kDraft04,
3771       /*remote_support=*/HttpDatagramSupport::kRfc,
3772       /*expected_support=*/HttpDatagramSupport::kNone,
3773       /*expected_datagram_supported=*/false);
3774 }
3775 
TEST_P(QuicSpdySessionTestClient,HttpDatagramSettingLocal04Remote04And09)3776 TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04Remote04And09) {
3777   Initialize();
3778   TestHttpDatagramSetting(
3779       /*local_support=*/HttpDatagramSupport::kDraft04,
3780       /*remote_support=*/HttpDatagramSupport::kRfcAndDraft04,
3781       /*expected_support=*/HttpDatagramSupport::kDraft04,
3782       /*expected_datagram_supported=*/true);
3783 }
3784 
TEST_P(QuicSpdySessionTestClient,HttpDatagramSettingLocal09Remote04)3785 TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal09Remote04) {
3786   Initialize();
3787   TestHttpDatagramSetting(
3788       /*local_support=*/HttpDatagramSupport::kRfc,
3789       /*remote_support=*/HttpDatagramSupport::kDraft04,
3790       /*expected_support=*/HttpDatagramSupport::kNone,
3791       /*expected_datagram_supported=*/false);
3792 }
3793 
TEST_P(QuicSpdySessionTestClient,HttpDatagramSettingLocal09Remote09)3794 TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal09Remote09) {
3795   Initialize();
3796   TestHttpDatagramSetting(
3797       /*local_support=*/HttpDatagramSupport::kRfc,
3798       /*remote_support=*/HttpDatagramSupport::kRfc,
3799       /*expected_support=*/HttpDatagramSupport::kRfc,
3800       /*expected_datagram_supported=*/true);
3801 }
3802 
TEST_P(QuicSpdySessionTestClient,HttpDatagramSettingLocal09Remote04And09)3803 TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal09Remote04And09) {
3804   Initialize();
3805   TestHttpDatagramSetting(
3806       /*local_support=*/HttpDatagramSupport::kRfc,
3807       /*remote_support=*/HttpDatagramSupport::kRfcAndDraft04,
3808       /*expected_support=*/HttpDatagramSupport::kRfc,
3809       /*expected_datagram_supported=*/true);
3810 }
3811 
TEST_P(QuicSpdySessionTestClient,HttpDatagramSettingLocal04And09Remote04)3812 TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04And09Remote04) {
3813   Initialize();
3814   TestHttpDatagramSetting(
3815       /*local_support=*/HttpDatagramSupport::kRfcAndDraft04,
3816       /*remote_support=*/HttpDatagramSupport::kDraft04,
3817       /*expected_support=*/HttpDatagramSupport::kDraft04,
3818       /*expected_datagram_supported=*/true);
3819 }
3820 
TEST_P(QuicSpdySessionTestClient,HttpDatagramSettingLocal04And09Remote09)3821 TEST_P(QuicSpdySessionTestClient, HttpDatagramSettingLocal04And09Remote09) {
3822   Initialize();
3823   TestHttpDatagramSetting(
3824       /*local_support=*/HttpDatagramSupport::kRfcAndDraft04,
3825       /*remote_support=*/HttpDatagramSupport::kRfc,
3826       /*expected_support=*/HttpDatagramSupport::kRfc,
3827       /*expected_datagram_supported=*/true);
3828 }
3829 
TEST_P(QuicSpdySessionTestClient,HttpDatagramSettingLocal04And09Remote04And09)3830 TEST_P(QuicSpdySessionTestClient,
3831        HttpDatagramSettingLocal04And09Remote04And09) {
3832   Initialize();
3833   TestHttpDatagramSetting(
3834       /*local_support=*/HttpDatagramSupport::kRfcAndDraft04,
3835       /*remote_support=*/HttpDatagramSupport::kRfcAndDraft04,
3836       /*expected_support=*/HttpDatagramSupport::kRfc,
3837       /*expected_datagram_supported=*/true);
3838 }
3839 
TEST_P(QuicSpdySessionTestClient,WebTransportSettingDraft02OnlyBothSides)3840 TEST_P(QuicSpdySessionTestClient, WebTransportSettingDraft02OnlyBothSides) {
3841   Initialize();
3842   if (!version().UsesHttp3()) {
3843     return;
3844   }
3845   session_->set_local_http_datagram_support(
3846       HttpDatagramSupport::kRfcAndDraft04);
3847   session_->set_locally_supported_web_transport_versions(
3848       WebTransportHttp3VersionSet({WebTransportHttp3Version::kDraft02}));
3849 
3850   EXPECT_FALSE(session_->SupportsWebTransport());
3851   CompleteHandshake();
3852   ReceiveWebTransportSettings(
3853       WebTransportHttp3VersionSet({WebTransportHttp3Version::kDraft02}));
3854   EXPECT_TRUE(session_->ShouldProcessIncomingRequests());
3855   EXPECT_TRUE(session_->SupportsWebTransport());
3856   EXPECT_EQ(session_->SupportedWebTransportVersion(),
3857             WebTransportHttp3Version::kDraft02);
3858 }
3859 
TEST_P(QuicSpdySessionTestClient,WebTransportSettingDraft07OnlyBothSides)3860 TEST_P(QuicSpdySessionTestClient, WebTransportSettingDraft07OnlyBothSides) {
3861   Initialize();
3862   if (!version().UsesHttp3()) {
3863     return;
3864   }
3865   session_->set_local_http_datagram_support(
3866       HttpDatagramSupport::kRfcAndDraft04);
3867   session_->set_locally_supported_web_transport_versions(
3868       WebTransportHttp3VersionSet({WebTransportHttp3Version::kDraft07}));
3869 
3870   EXPECT_FALSE(session_->SupportsWebTransport());
3871   CompleteHandshake();
3872   ReceiveWebTransportSettings(
3873       WebTransportHttp3VersionSet({WebTransportHttp3Version::kDraft07}));
3874   EXPECT_TRUE(session_->ShouldProcessIncomingRequests());
3875   EXPECT_TRUE(session_->SupportsWebTransport());
3876   EXPECT_EQ(session_->SupportedWebTransportVersion(),
3877             WebTransportHttp3Version::kDraft07);
3878 }
3879 
TEST_P(QuicSpdySessionTestClient,WebTransportSettingBothDraftsBothSides)3880 TEST_P(QuicSpdySessionTestClient, WebTransportSettingBothDraftsBothSides) {
3881   Initialize();
3882   if (!version().UsesHttp3()) {
3883     return;
3884   }
3885   session_->set_local_http_datagram_support(
3886       HttpDatagramSupport::kRfcAndDraft04);
3887   session_->set_locally_supported_web_transport_versions(
3888       WebTransportHttp3VersionSet({WebTransportHttp3Version::kDraft02,
3889                                    WebTransportHttp3Version::kDraft07}));
3890 
3891   EXPECT_FALSE(session_->SupportsWebTransport());
3892   CompleteHandshake();
3893   ReceiveWebTransportSettings(
3894       WebTransportHttp3VersionSet({WebTransportHttp3Version::kDraft02,
3895                                    WebTransportHttp3Version::kDraft07}));
3896   EXPECT_TRUE(session_->ShouldProcessIncomingRequests());
3897   EXPECT_TRUE(session_->SupportsWebTransport());
3898   EXPECT_EQ(session_->SupportedWebTransportVersion(),
3899             WebTransportHttp3Version::kDraft07);
3900 }
3901 
TEST_P(QuicSpdySessionTestClient,WebTransportSettingVersionMismatch)3902 TEST_P(QuicSpdySessionTestClient, WebTransportSettingVersionMismatch) {
3903   Initialize();
3904   if (!version().UsesHttp3()) {
3905     return;
3906   }
3907   session_->set_local_http_datagram_support(
3908       HttpDatagramSupport::kRfcAndDraft04);
3909   session_->set_locally_supported_web_transport_versions(
3910       WebTransportHttp3VersionSet({WebTransportHttp3Version::kDraft07}));
3911 
3912   EXPECT_FALSE(session_->SupportsWebTransport());
3913   CompleteHandshake();
3914   ReceiveWebTransportSettings(
3915       WebTransportHttp3VersionSet({WebTransportHttp3Version::kDraft02}));
3916   EXPECT_FALSE(session_->SupportsWebTransport());
3917   EXPECT_EQ(session_->SupportedWebTransportVersion(), std::nullopt);
3918 }
3919 
TEST_P(QuicSpdySessionTestClient,WebTransportSettingSetToZero)3920 TEST_P(QuicSpdySessionTestClient, WebTransportSettingSetToZero) {
3921   Initialize();
3922   if (!version().UsesHttp3()) {
3923     return;
3924   }
3925   session_->set_local_http_datagram_support(
3926       HttpDatagramSupport::kRfcAndDraft04);
3927   session_->set_supports_webtransport(true);
3928 
3929   EXPECT_FALSE(session_->SupportsWebTransport());
3930 
3931   StrictMock<MockHttp3DebugVisitor> debug_visitor;
3932   // Note that this does not actually fill out correct settings because the
3933   // settings are filled in at the construction time.
3934   EXPECT_CALL(debug_visitor, OnSettingsFrameSent(_));
3935   session_->set_debug_visitor(&debug_visitor);
3936   CompleteHandshake();
3937 
3938   SettingsFrame server_settings;
3939   server_settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
3940   server_settings.values[SETTINGS_WEBTRANS_DRAFT00] = 0;
3941   std::string data = std::string(1, kControlStream) +
3942                      HttpEncoder::SerializeSettingsFrame(server_settings);
3943   QuicStreamId stream_id =
3944       GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
3945   QuicStreamFrame frame(stream_id, /*fin=*/false, /*offset=*/0, data);
3946   EXPECT_CALL(debug_visitor, OnPeerControlStreamCreated(stream_id));
3947   EXPECT_CALL(debug_visitor, OnSettingsFrameReceived(server_settings));
3948   session_->OnStreamFrame(frame);
3949   EXPECT_FALSE(session_->SupportsWebTransport());
3950 }
3951 
TEST_P(QuicSpdySessionTestServer,WebTransportSetting)3952 TEST_P(QuicSpdySessionTestServer, WebTransportSetting) {
3953   Initialize();
3954   if (!version().UsesHttp3()) {
3955     return;
3956   }
3957   session_->set_local_http_datagram_support(
3958       HttpDatagramSupport::kRfcAndDraft04);
3959   session_->set_supports_webtransport(true);
3960 
3961   EXPECT_FALSE(session_->SupportsWebTransport());
3962   EXPECT_FALSE(session_->ShouldProcessIncomingRequests());
3963 
3964   CompleteHandshake();
3965 
3966   ReceiveWebTransportSettings();
3967   EXPECT_TRUE(session_->SupportsWebTransport());
3968   EXPECT_TRUE(session_->ShouldProcessIncomingRequests());
3969 }
3970 
TEST_P(QuicSpdySessionTestServer,BufferingIncomingStreams)3971 TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreams) {
3972   Initialize();
3973   if (!version().UsesHttp3()) {
3974     return;
3975   }
3976   session_->set_local_http_datagram_support(
3977       HttpDatagramSupport::kRfcAndDraft04);
3978   session_->set_supports_webtransport(true);
3979 
3980   CompleteHandshake();
3981   QuicStreamId session_id =
3982       GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
3983 
3984   QuicStreamId data_stream_id =
3985       GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4);
3986   ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
3987 
3988   ReceiveWebTransportSettings();
3989 
3990   ReceiveWebTransportSession(session_id);
3991   WebTransportHttp3* web_transport =
3992       session_->GetWebTransportSession(session_id);
3993   ASSERT_TRUE(web_transport != nullptr);
3994 
3995   EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
3996 
3997   EXPECT_CALL(*connection_, SendControlFrame(_))
3998       .WillRepeatedly(Invoke(&ClearControlFrame));
3999   EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
4000   EXPECT_CALL(
4001       *connection_,
4002       OnStreamReset(data_stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
4003   session_->ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
4004 }
4005 
TEST_P(QuicSpdySessionTestServer,BufferingIncomingStreamsLimit)4006 TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreamsLimit) {
4007   Initialize();
4008   if (!version().UsesHttp3()) {
4009     return;
4010   }
4011   session_->set_local_http_datagram_support(
4012       HttpDatagramSupport::kRfcAndDraft04);
4013   session_->set_supports_webtransport(true);
4014 
4015   CompleteHandshake();
4016   QuicStreamId session_id =
4017       GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
4018 
4019   const int streams_to_send = kMaxUnassociatedWebTransportStreams + 4;
4020   EXPECT_CALL(*connection_, SendControlFrame(_))
4021       .WillRepeatedly(Invoke(&ClearControlFrame));
4022   EXPECT_CALL(*connection_,
4023               OnStreamReset(
4024                   _, QUIC_STREAM_WEBTRANSPORT_BUFFERED_STREAMS_LIMIT_EXCEEDED))
4025       .Times(4);
4026   for (int i = 0; i < streams_to_send; i++) {
4027     QuicStreamId data_stream_id =
4028         GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4 + i);
4029     ReceiveWebTransportUnidirectionalStream(session_id, data_stream_id);
4030   }
4031 
4032   ReceiveWebTransportSettings();
4033 
4034   ReceiveWebTransportSession(session_id);
4035   WebTransportHttp3* web_transport =
4036       session_->GetWebTransportSession(session_id);
4037   ASSERT_TRUE(web_transport != nullptr);
4038 
4039   EXPECT_EQ(web_transport->NumberOfAssociatedStreams(),
4040             kMaxUnassociatedWebTransportStreams);
4041 
4042   EXPECT_CALL(*connection_, SendControlFrame(_))
4043       .WillRepeatedly(Invoke(&ClearControlFrame));
4044   EXPECT_CALL(*connection_, OnStreamReset(_, _))
4045       .Times(kMaxUnassociatedWebTransportStreams + 1);
4046   session_->ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
4047 }
4048 
TEST_P(QuicSpdySessionTestServer,BufferingIncomingStreamsWithFin)4049 TEST_P(QuicSpdySessionTestServer, BufferingIncomingStreamsWithFin) {
4050   Initialize();
4051   if (!version().UsesHttp3()) {
4052     return;
4053   }
4054 
4055   CompleteHandshake();
4056 
4057   const UberQuicStreamIdManager& stream_id_manager =
4058       *QuicSessionPeer::ietf_streamid_manager(&*session_);
4059   const QuicStreamId initial_advertized_max_streams =
4060       stream_id_manager.advertised_max_incoming_unidirectional_streams();
4061   const size_t num_streams_to_open =
4062       session_->max_open_incoming_unidirectional_streams();
4063   // The max_streams limit should be increased repeatedly.
4064   EXPECT_CALL(*connection_, SendControlFrame(_)).Times(testing::AnyNumber());
4065   for (size_t i = 0; i < num_streams_to_open; i++) {
4066     const QuicStreamId stream_id =
4067         GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 4 + i);
4068     QuicStreamFrame frame(stream_id, /*fin=*/true, /*offset=*/0, /*data=*/"");
4069     session_->OnStreamFrame(frame);
4070   }
4071   EXPECT_LT(initial_advertized_max_streams,
4072             stream_id_manager.advertised_max_incoming_unidirectional_streams());
4073   EXPECT_EQ(0, session_->pending_streams_size());
4074 }
4075 
TEST_P(QuicSpdySessionTestServer,ResetOutgoingWebTransportStreams)4076 TEST_P(QuicSpdySessionTestServer, ResetOutgoingWebTransportStreams) {
4077   Initialize();
4078   if (!version().UsesHttp3()) {
4079     return;
4080   }
4081   session_->set_local_http_datagram_support(
4082       HttpDatagramSupport::kRfcAndDraft04);
4083   session_->set_supports_webtransport(true);
4084 
4085   CompleteHandshake();
4086   QuicStreamId session_id =
4087       GetNthClientInitiatedBidirectionalStreamId(transport_version(), 1);
4088 
4089   ReceiveWebTransportSettings();
4090   ReceiveWebTransportSession(session_id);
4091   WebTransportHttp3* web_transport =
4092       session_->GetWebTransportSession(session_id);
4093   ASSERT_TRUE(web_transport != nullptr);
4094 
4095   session_->set_writev_consumes_all_data(true);
4096   EXPECT_TRUE(web_transport->CanOpenNextOutgoingUnidirectionalStream());
4097   EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
4098   WebTransportStream* stream =
4099       web_transport->OpenOutgoingUnidirectionalStream();
4100   EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 1u);
4101   ASSERT_TRUE(stream != nullptr);
4102   QuicStreamId stream_id = stream->GetStreamId();
4103 
4104   EXPECT_CALL(*connection_, SendControlFrame(_))
4105       .WillRepeatedly(Invoke(&ClearControlFrame));
4106   EXPECT_CALL(*connection_, OnStreamReset(session_id, _));
4107   EXPECT_CALL(*connection_,
4108               OnStreamReset(stream_id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE));
4109   session_->ResetStream(session_id, QUIC_STREAM_INTERNAL_ERROR);
4110   EXPECT_EQ(web_transport->NumberOfAssociatedStreams(), 0u);
4111 }
4112 
TEST_P(QuicSpdySessionTestClient,WebTransportWithoutExtendedConnect)4113 TEST_P(QuicSpdySessionTestClient, WebTransportWithoutExtendedConnect) {
4114   Initialize();
4115   if (!version().UsesHttp3()) {
4116     return;
4117   }
4118   SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
4119   session_->set_local_http_datagram_support(
4120       HttpDatagramSupport::kRfcAndDraft04);
4121   session_->set_supports_webtransport(true);
4122 
4123   EXPECT_FALSE(session_->SupportsWebTransport());
4124   CompleteHandshake();
4125 
4126   SettingsFrame settings;
4127   settings.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1;
4128   settings.values[SETTINGS_WEBTRANS_DRAFT00] = 1;
4129   // No SETTINGS_ENABLE_CONNECT_PROTOCOL here.
4130   std::string data = std::string(1, kControlStream) +
4131                      HttpEncoder::SerializeSettingsFrame(settings);
4132   QuicStreamId control_stream_id =
4133       session_->perspective() == Perspective::IS_SERVER
4134           ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
4135           : GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
4136   QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
4137   session_->OnStreamFrame(frame);
4138 
4139   EXPECT_TRUE(session_->SupportsWebTransport());
4140 }
4141 
4142 // Regression test for b/208997000.
TEST_P(QuicSpdySessionTestClient,LimitEncoderDynamicTableSize)4143 TEST_P(QuicSpdySessionTestClient, LimitEncoderDynamicTableSize) {
4144   Initialize();
4145   if (version().UsesHttp3()) {
4146     return;
4147   }
4148   CompleteHandshake();
4149 
4150   QuicSpdySessionPeer::SetHeadersStream(&*session_, nullptr);
4151   TestHeadersStream* headers_stream =
4152       new StrictMock<TestHeadersStream>(&*session_);
4153   QuicSpdySessionPeer::SetHeadersStream(&*session_, headers_stream);
4154   session_->MarkConnectionLevelWriteBlocked(headers_stream->id());
4155 
4156   // Peer sends very large value.
4157   session_->OnSetting(spdy::SETTINGS_HEADER_TABLE_SIZE, 1024 * 1024 * 1024);
4158 
4159   TestStream* stream = session_->CreateOutgoingBidirectionalStream();
4160   EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
4161   Http2HeaderBlock headers;
4162   headers[":method"] = "GET";  // entry with index 2 in HPACK static table
4163   stream->WriteHeaders(std::move(headers), /* fin = */ true, nullptr);
4164 
4165   EXPECT_TRUE(headers_stream->HasBufferedData());
4166   QuicStreamSendBuffer& send_buffer =
4167       QuicStreamPeer::SendBuffer(headers_stream);
4168   ASSERT_EQ(1u, send_buffer.size());
4169 
4170   const quiche::QuicheMemSlice& slice =
4171       QuicStreamSendBufferPeer::CurrentWriteSlice(&send_buffer)->slice;
4172   absl::string_view stream_data(slice.data(), slice.length());
4173 
4174   std::string expected_stream_data_1;
4175   ASSERT_TRUE(
4176       absl::HexStringToBytes("000009"  // frame length
4177                              "01"      // frame type HEADERS
4178                              "25",  // flags END_STREAM | END_HEADERS | PRIORITY
4179                              &expected_stream_data_1));
4180   EXPECT_EQ(expected_stream_data_1, stream_data.substr(0, 5));
4181   stream_data.remove_prefix(5);
4182 
4183   // Ignore stream ID as it might differ between QUIC versions.
4184   stream_data.remove_prefix(4);
4185 
4186   std::string expected_stream_data_2;
4187 
4188   ASSERT_TRUE(
4189       absl::HexStringToBytes("00000000"  // stream dependency
4190                              "92",       // stream weight
4191                              &expected_stream_data_2));
4192   EXPECT_EQ(expected_stream_data_2, stream_data.substr(0, 5));
4193   stream_data.remove_prefix(5);
4194 
4195   std::string expected_stream_data_3;
4196   ASSERT_TRUE(absl::HexStringToBytes(
4197       "3fe17f"  // Dynamic Table Size Update to 16384
4198       "82",     // Indexed Header Field Representation with index 2
4199       &expected_stream_data_3));
4200   EXPECT_EQ(expected_stream_data_3, stream_data);
4201 }
4202 
4203 class QuicSpdySessionTestServerNoExtendedConnect
4204     : public QuicSpdySessionTestBase {
4205  public:
QuicSpdySessionTestServerNoExtendedConnect()4206   QuicSpdySessionTestServerNoExtendedConnect()
4207       : QuicSpdySessionTestBase(Perspective::IS_SERVER, false) {}
4208 };
4209 
4210 INSTANTIATE_TEST_SUITE_P(Tests, QuicSpdySessionTestServerNoExtendedConnect,
4211                          ::testing::ValuesIn(AllSupportedVersions()),
4212                          ::testing::PrintToStringParamName());
4213 
4214 // Tests that receiving SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 doesn't enable
4215 // server session to support extended CONNECT.
TEST_P(QuicSpdySessionTestServerNoExtendedConnect,WebTransportSettingNoEffect)4216 TEST_P(QuicSpdySessionTestServerNoExtendedConnect,
4217        WebTransportSettingNoEffect) {
4218   Initialize();
4219   if (!version().UsesHttp3()) {
4220     return;
4221   }
4222 
4223   EXPECT_FALSE(session_->SupportsWebTransport());
4224   EXPECT_TRUE(session_->ShouldProcessIncomingRequests());
4225 
4226   CompleteHandshake();
4227 
4228   ReceiveWebTransportSettings();
4229   EXPECT_FALSE(session_->allow_extended_connect());
4230   EXPECT_FALSE(session_->SupportsWebTransport());
4231   EXPECT_TRUE(session_->ShouldProcessIncomingRequests());
4232 }
4233 
TEST_P(QuicSpdySessionTestServerNoExtendedConnect,BadExtendedConnectSetting)4234 TEST_P(QuicSpdySessionTestServerNoExtendedConnect, BadExtendedConnectSetting) {
4235   Initialize();
4236   if (!version().UsesHttp3()) {
4237     return;
4238   }
4239   SetQuicReloadableFlag(quic_act_upon_invalid_header, true);
4240 
4241   EXPECT_FALSE(session_->SupportsWebTransport());
4242   EXPECT_TRUE(session_->ShouldProcessIncomingRequests());
4243 
4244   CompleteHandshake();
4245 
4246   // ENABLE_CONNECT_PROTOCOL setting value has to be 1 or 0;
4247   SettingsFrame settings;
4248   settings.values[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 2;
4249   std::string data = std::string(1, kControlStream) +
4250                      HttpEncoder::SerializeSettingsFrame(settings);
4251   QuicStreamId control_stream_id =
4252       session_->perspective() == Perspective::IS_SERVER
4253           ? GetNthClientInitiatedUnidirectionalStreamId(transport_version(), 3)
4254           : GetNthServerInitiatedUnidirectionalStreamId(transport_version(), 3);
4255   QuicStreamFrame frame(control_stream_id, /*fin=*/false, /*offset=*/0, data);
4256   EXPECT_QUIC_PEER_BUG(
4257       {
4258         EXPECT_CALL(*connection_,
4259                     CloseConnection(QUIC_HTTP_INVALID_SETTING_VALUE, _, _));
4260         session_->OnStreamFrame(frame);
4261       },
4262       "Received SETTINGS_ENABLE_CONNECT_PROTOCOL with invalid value");
4263 }
4264 
4265 }  // namespace
4266 }  // namespace test
4267 }  // namespace quic
4268