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) {