Introduce QuicStreamSequencer::IsAllDataAvailable() This is useful in situations where the stream consumer reads data from the stream in chunks, and will not actually mark an incomplete chunk as consumed. PiperOrigin-RevId: 452598666
diff --git a/quiche/quic/core/http/web_transport_http3.cc b/quiche/quic/core/http/web_transport_http3.cc index 6c9cbff..a9babe8 100644 --- a/quiche/quic/core/http/web_transport_http3.cc +++ b/quiche/quic/core/http/web_transport_http3.cc
@@ -347,8 +347,7 @@ // If all of the data has been received, and we still cannot associate the // stream with a session, consume all of the data so that the stream can // be closed. - if (sequencer()->NumBytesConsumed() + sequencer()->NumBytesBuffered() >= - sequencer()->close_offset()) { + if (sequencer()->IsAllDataAvailable()) { QUIC_DLOG(WARNING) << ENDPOINT << "Failed to associate WebTransport stream " << id() << " with a session because the stream ended prematurely.";
diff --git a/quiche/quic/core/quic_stream_sequencer.cc b/quiche/quic/core/quic_stream_sequencer.cc index 03fd990..fa76841 100644 --- a/quiche/quic/core/quic_stream_sequencer.cc +++ b/quiche/quic/core/quic_stream_sequencer.cc
@@ -292,6 +292,11 @@ return buffered_frames_.BytesConsumed(); } +bool QuicStreamSequencer::IsAllDataAvailable() const { + QUICHE_DCHECK_LE(NumBytesConsumed() + NumBytesBuffered(), close_offset_); + return NumBytesConsumed() + NumBytesBuffered() >= close_offset_; +} + const std::string QuicStreamSequencer::DebugString() const { // clang-format off return absl::StrCat("QuicStreamSequencer:",
diff --git a/quiche/quic/core/quic_stream_sequencer.h b/quiche/quic/core/quic_stream_sequencer.h index e201cc1..9953c75 100644 --- a/quiche/quic/core/quic_stream_sequencer.h +++ b/quiche/quic/core/quic_stream_sequencer.h
@@ -139,6 +139,10 @@ // Number of bytes has been consumed. QuicStreamOffset NumBytesConsumed() const; + // Returns true if all of the data within the stream up until the FIN is + // available. + bool IsAllDataAvailable() const; + QuicStreamOffset close_offset() const { return close_offset_; } int num_frames_received() const { return num_frames_received_; }
diff --git a/quiche/quic/core/quic_stream_sequencer_test.cc b/quiche/quic/core/quic_stream_sequencer_test.cc index bfac366..3ac6d88 100644 --- a/quiche/quic/core/quic_stream_sequencer_test.cc +++ b/quiche/quic/core/quic_stream_sequencer_test.cc
@@ -223,8 +223,10 @@ ConsumeData(3); })); EXPECT_FALSE(sequencer_->IsClosed()); + EXPECT_FALSE(sequencer_->IsAllDataAvailable()); OnFinFrame(3, "def"); EXPECT_TRUE(sequencer_->IsClosed()); + EXPECT_TRUE(sequencer_->IsAllDataAvailable()); } TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) { @@ -239,6 +241,7 @@ ConsumeData(3); })); EXPECT_FALSE(sequencer_->IsClosed()); + EXPECT_TRUE(sequencer_->IsAllDataAvailable()); sequencer_->SetUnblocked(); EXPECT_TRUE(sequencer_->IsClosed()); EXPECT_EQ(0u, NumBufferedBytes()); @@ -260,6 +263,7 @@ OnFinFrame(0, ""); EXPECT_EQ(0u, NumBufferedBytes()); EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); + EXPECT_TRUE(sequencer_->IsAllDataAvailable()); } TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {