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