Blocked decoding part 3: QpackDecodedHeadersAccumulator and QuicSpdyStream. gfe-relnote: n/a, QUIC v99-only change. PiperOrigin-RevId: 257172998 Change-Id: I93ba049c437383a29dd98c9c9d44695aa7754fbf
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc index 0c26de7..9e4178f 100644 --- a/quic/core/http/quic_spdy_session.cc +++ b/quic/core/http/quic_spdy_session.cc
@@ -369,6 +369,10 @@ QuicMakeUnique<QpackEncoder>(this, &encoder_stream_sender_delegate_); qpack_decoder_ = QuicMakeUnique<QpackDecoder>(this, &decoder_stream_sender_delegate_); + // TODO(b/112770235): Send SETTINGS_QPACK_MAX_TABLE_CAPACITY with value + // kDefaultQpackMaxDynamicTableCapacity. + qpack_decoder_->SetMaximumDynamicTableCapacity( + kDefaultQpackMaxDynamicTableCapacity); } headers_stream_ = QuicMakeUnique<QuicHeadersStream>((this));
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc index 96be207..0748d45 100644 --- a/quic/core/http/quic_spdy_stream.cc +++ b/quic/core/http/quic_spdy_stream.cc
@@ -170,7 +170,6 @@ trailers_consumed_(false), priority_sent_(false), headers_bytes_to_be_marked_consumed_(0), - pretend_blocked_decoding_for_tests_(false), http_decoder_visitor_(new HttpDecoderVisitor(this)), body_buffer_(sequencer()), sequencer_offset_(0), @@ -207,7 +206,6 @@ trailers_consumed_(false), priority_sent_(false), headers_bytes_to_be_marked_consumed_(0), - pretend_blocked_decoding_for_tests_(false), http_decoder_visitor_(new HttpDecoderVisitor(this)), body_buffer_(sequencer()), sequencer_offset_(sequencer()->NumBytesConsumed()), @@ -867,8 +865,7 @@ qpack_decoded_headers_accumulator_ = QuicMakeUnique<QpackDecodedHeadersAccumulator>( id(), spdy_session_->qpack_decoder(), this, - spdy_session_->max_inbound_header_list_size(), - pretend_blocked_decoding_for_tests_); + spdy_session_->max_inbound_header_list_size()); // Do not call MaybeMarkHeadersBytesConsumed() yet, because // HEADERS frame header bytes might not have been parsed completely.
diff --git a/quic/core/http/quic_spdy_stream.h b/quic/core/http/quic_spdy_stream.h index 0c2ba2d..452109a 100644 --- a/quic/core/http/quic_spdy_stream.h +++ b/quic/core/http/quic_spdy_stream.h
@@ -304,9 +304,6 @@ HttpEncoder encoder_; // Http decoder for processing raw incoming stream frames. HttpDecoder decoder_; - // TODO(b/112770235): Remove once blocked decoding is implemented - // and can be tested with delayed encoder stream data. - bool pretend_blocked_decoding_for_tests_; // Headers accumulator for decoding HEADERS frame payload. std::unique_ptr<QpackDecodedHeadersAccumulator> qpack_decoded_headers_accumulator_;
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc index b2fbc70..43a14d9 100644 --- a/quic/core/http/quic_spdy_stream_test.cc +++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -38,6 +38,7 @@ using testing::ElementsAre; using testing::Invoke; using testing::InvokeWithoutArgs; +using testing::MatchesRegex; using testing::Pair; using testing::Return; using testing::StrictMock; @@ -265,8 +266,7 @@ *connection_, CloseConnection( QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE, - testing::MatchesRegex("Too large headers received on stream \\d+"), - _)); + MatchesRegex("Too large headers received on stream \\d+"), _)); } else { EXPECT_CALL(*session_, SendRstStream(stream_->id(), QUIC_HEADERS_TOO_LARGE, 0)); @@ -1830,11 +1830,11 @@ EXPECT_CALL( *connection_, - CloseConnection(QUIC_DECOMPRESSION_FAILURE, - testing::MatchesRegex( - "Error decompressing header block on stream \\d+: " - "Incomplete header block."), - _)) + CloseConnection( + QUIC_DECOMPRESSION_FAILURE, + MatchesRegex("Error decompressing header block on stream \\d+: " + "Incomplete header block."), + _)) .WillOnce( (Invoke([this](QuicErrorCode error, const std::string& error_details, ConnectionCloseBehavior connection_close_behavior) { @@ -1852,59 +1852,95 @@ stream_->OnStreamFrame(frame); } +TEST_P(QuicSpdyStreamTest, ImmediateHeaderDecodingWithDynamicTableEntries) { + if (!VersionUsesQpack(GetParam().transport_version)) { + return; + } + + Initialize(kShouldProcessData); + + // Deliver dynamic table entry to decoder. + session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar"); + + // HEADERS frame referencing first dynamic table entry. + std::string headers = HeadersFrame(QuicTextUtils::HexDecode("020080")); + stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers)); + + // Headers can be decoded immediately. + EXPECT_TRUE(stream_->headers_decompressed()); + + // Verify headers. + EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar"))); + stream_->ConsumeHeaderList(); + + // DATA frame. + std::string data = DataFrame(kDataFramePayload); + stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */ + headers.length(), data)); + EXPECT_EQ(kDataFramePayload, stream_->data()); + + // Deliver second dynamic table entry to decoder. + session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar"); + + // Trailing HEADERS frame referencing second dynamic table entry. + std::string trailers = HeadersFrame(QuicTextUtils::HexDecode("030080")); + stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */ + headers.length() + data.length(), + trailers)); + + // Trailers can be decoded immediately. + EXPECT_TRUE(stream_->trailers_decompressed()); + + // Verify trailers. + EXPECT_THAT(stream_->received_trailers(), + ElementsAre(Pair("trailing", "foobar"))); + stream_->MarkTrailersConsumed(); +} + TEST_P(QuicSpdyStreamTest, BlockedHeaderDecoding) { if (!VersionUsesQpack(GetParam().transport_version)) { return; } Initialize(kShouldProcessData); - QuicSpdyStreamPeer::pretend_blocked_decoding(stream_); - // HEADERS frame with QPACK encoded single header field "foo: bar". - std::string headers = - HeadersFrame(QuicTextUtils::HexDecode("00002a94e703626172")); + // HEADERS frame referencing first dynamic table entry. + std::string headers = HeadersFrame(QuicTextUtils::HexDecode("020080")); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers)); - // Even though entire header block is received, it cannot be decoded. + // Decoding is blocked because dynamic table entry has not been received yet. EXPECT_FALSE(stream_->headers_decompressed()); - // Signal to QpackDecodedHeadersAccumulator that the header block has been - // decoded. (OnDecodingCompleted() has already been called by the QPACK - // decoder, so technically quic_header_list_.OnHeaderBlockEnd() is called - // twice, which is a no-op.) - QuicSpdyStreamPeer::qpack_decoded_headers_accumulator(stream_) - ->OnDecodingCompleted(); - + // Deliver dynamic table entry to decoder. + session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar"); EXPECT_TRUE(stream_->headers_decompressed()); + // Verify headers. EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar"))); stream_->ConsumeHeaderList(); + // DATA frame. std::string data = DataFrame(kDataFramePayload); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */ headers.length(), data)); EXPECT_EQ(kDataFramePayload, stream_->data()); - // Trailing HEADERS frame with QPACK encoded - // single header field "custom-key: custom-value". - std::string trailers = HeadersFrame( - QuicTextUtils::HexDecode("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf")); + // Trailing HEADERS frame referencing second dynamic table entry. + std::string trailers = HeadersFrame(QuicTextUtils::HexDecode("030080")); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */ headers.length() + data.length(), trailers)); - // Even though entire header block is received, it cannot be decoded. + // Decoding is blocked because dynamic table entry has not been received yet. EXPECT_FALSE(stream_->trailers_decompressed()); - // Signal to QpackDecodedHeadersAccumulator that the header block has been - // decoded. - QuicSpdyStreamPeer::qpack_decoded_headers_accumulator(stream_) - ->OnDecodingCompleted(); + // Deliver second dynamic table entry to decoder. + session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar"); EXPECT_TRUE(stream_->trailers_decompressed()); // Verify trailers. EXPECT_THAT(stream_->received_trailers(), - ElementsAre(Pair("custom-key", "custom-value"))); + ElementsAre(Pair("trailing", "foobar"))); stream_->MarkTrailersConsumed(); } @@ -1914,26 +1950,29 @@ } Initialize(kShouldProcessData); - QuicSpdyStreamPeer::pretend_blocked_decoding(stream_); - // HEADERS frame with QPACK encoded single header field "foo: bar". - std::string headers = - HeadersFrame(QuicTextUtils::HexDecode("00002a94e703626172")); + // HEADERS frame only referencing entry with absolute index 0 but with + // Required Insert Count = 2, which is incorrect. + std::string headers = HeadersFrame(QuicTextUtils::HexDecode("030081")); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers)); - // Even though entire header block is received, it cannot be decoded. + // Even though entire header block is received and every referenced entry is + // available, decoding is blocked until insert count reaches the Required + // Insert Count value advertised in the header block prefix. EXPECT_FALSE(stream_->headers_decompressed()); - // Signal a decoding error to QpackDecodedHeadersAccumulator. - std::string expected_error_message = - QuicStrCat("Error during async decoding of headers on stream ", - stream_->id(), ": unexpected error"); EXPECT_CALL( *connection_, - CloseConnection(QUIC_DECOMPRESSION_FAILURE, expected_error_message, - ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET)); - QuicSpdyStreamPeer::qpack_decoded_headers_accumulator(stream_) - ->OnDecodingErrorDetected("unexpected error"); + CloseConnection( + QUIC_DECOMPRESSION_FAILURE, + MatchesRegex("Error during async decoding of headers on stream \\d+: " + "Required Insert Count too large."), + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET)); + + // Deliver two dynamic table entries to decoder + // to trigger decoding of header block. + session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar"); + session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar"); } TEST_P(QuicSpdyStreamTest, AsyncErrorDecodingTrailers) { @@ -1942,54 +1981,51 @@ } Initialize(kShouldProcessData); - QuicSpdyStreamPeer::pretend_blocked_decoding(stream_); - // HEADERS frame with QPACK encoded single header field "foo: bar". - std::string headers = - HeadersFrame(QuicTextUtils::HexDecode("00002a94e703626172")); + // HEADERS frame referencing first dynamic table entry. + std::string headers = HeadersFrame(QuicTextUtils::HexDecode("020080")); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, 0, headers)); - // Even though entire header block is received, it cannot be decoded. + // Decoding is blocked because dynamic table entry has not been received yet. EXPECT_FALSE(stream_->headers_decompressed()); - // Signal to QpackDecodedHeadersAccumulator that the header block has been - // decoded. (OnDecodingCompleted() has already been called by the QPACK - // decoder, so technically quic_header_list_.OnHeaderBlockEnd() is called - // twice, which is a no-op.) - QuicSpdyStreamPeer::qpack_decoded_headers_accumulator(stream_) - ->OnDecodingCompleted(); - + // Deliver dynamic table entry to decoder. + session_->qpack_decoder()->OnInsertWithoutNameReference("foo", "bar"); EXPECT_TRUE(stream_->headers_decompressed()); + // Verify headers. EXPECT_THAT(stream_->header_list(), ElementsAre(Pair("foo", "bar"))); stream_->ConsumeHeaderList(); + // DATA frame. std::string data = DataFrame(kDataFramePayload); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), false, /* offset = */ headers.length(), data)); EXPECT_EQ(kDataFramePayload, stream_->data()); - // Trailing HEADERS frame with QPACK encoded - // single header field "custom-key: custom-value". - std::string trailers = HeadersFrame( - QuicTextUtils::HexDecode("00002f0125a849e95ba97d7f8925a849e95bb8e8b4bf")); + // Trailing HEADERS frame only referencing entry with absolute index 0 but + // with Required Insert Count = 2, which is incorrect. + std::string trailers = HeadersFrame(QuicTextUtils::HexDecode("030081")); stream_->OnStreamFrame(QuicStreamFrame(stream_->id(), true, /* offset = */ headers.length() + data.length(), trailers)); - // Even though entire header block is received, it cannot be decoded. + // Even though entire header block is received and every referenced entry is + // available, decoding is blocked until insert count reaches the Required + // Insert Count value advertised in the header block prefix. EXPECT_FALSE(stream_->trailers_decompressed()); - // Signal a decoding error to QpackDecodedHeadersAccumulator. - std::string expected_error_message = - QuicStrCat("Error during async decoding of trailers on stream ", - stream_->id(), ": unexpected error"); - EXPECT_CALL( - *connection_, - CloseConnection(QUIC_DECOMPRESSION_FAILURE, expected_error_message, - ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET)); - QuicSpdyStreamPeer::qpack_decoded_headers_accumulator(stream_) - ->OnDecodingErrorDetected("unexpected error"); + EXPECT_CALL(*connection_, + CloseConnection( + QUIC_DECOMPRESSION_FAILURE, + MatchesRegex( + "Error during async decoding of trailers on stream \\d+: " + "Required Insert Count too large."), + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET)); + + // Deliver second dynamic table entry to decoder + // to trigger decoding of trailing header block. + session_->qpack_decoder()->OnInsertWithoutNameReference("trailing", "foobar"); } class QuicSpdyStreamIncrementalConsumptionTest : public QuicSpdyStreamTest {
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator.cc b/quic/core/qpack/qpack_decoded_headers_accumulator.cc index 8ca28c9..9cce573 100644 --- a/quic/core/qpack/qpack_decoded_headers_accumulator.cc +++ b/quic/core/qpack/qpack_decoded_headers_accumulator.cc
@@ -12,14 +12,13 @@ QuicStreamId id, QpackDecoder* qpack_decoder, Visitor* visitor, - size_t max_header_list_size, - bool pretend_blocked_decoding_for_tests) + size_t max_header_list_size) : decoder_(qpack_decoder->CreateProgressiveDecoder(id, this)), visitor_(visitor), uncompressed_header_bytes_(0), compressed_header_bytes_(0), + headers_decoded_(false), blocked_(false), - pretend_blocked_decoding_for_tests_(pretend_blocked_decoding_for_tests), error_detected_(false) { quic_header_list_.set_max_header_list_size(max_header_list_size); quic_header_list_.OnHeaderBlockStart(); @@ -34,6 +33,10 @@ } void QpackDecodedHeadersAccumulator::OnDecodingCompleted() { + DCHECK(!headers_decoded_); + DCHECK(!error_detected_); + + headers_decoded_ = true; quic_header_list_.OnHeaderBlockEnd(uncompressed_header_bytes_, compressed_header_bytes_); @@ -45,6 +48,7 @@ void QpackDecodedHeadersAccumulator::OnDecodingErrorDetected( QuicStringPiece error_message) { DCHECK(!error_detected_); + DCHECK(!headers_decoded_); error_detected_ = true; // Copy error message to ensure it remains valid for the lifetime of |this|. @@ -67,15 +71,21 @@ QpackDecodedHeadersAccumulator::Status QpackDecodedHeadersAccumulator::EndHeaderBlock() { DCHECK(!error_detected_); + DCHECK(!headers_decoded_); decoder_->EndHeaderBlock(); - if (pretend_blocked_decoding_for_tests_) { - blocked_ = true; - return Status::kBlocked; + if (error_detected_) { + DCHECK(!headers_decoded_); + return Status::kError; } - return error_detected_ ? Status::kError : Status::kSuccess; + if (headers_decoded_) { + return Status::kSuccess; + } + + blocked_ = true; + return Status::kBlocked; } const QuicHeaderList& QpackDecodedHeadersAccumulator::quic_header_list() const {
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator.h b/quic/core/qpack/qpack_decoded_headers_accumulator.h index 59480db..c649322 100644 --- a/quic/core/qpack/qpack_decoded_headers_accumulator.h +++ b/quic/core/qpack/qpack_decoded_headers_accumulator.h
@@ -51,8 +51,7 @@ QpackDecodedHeadersAccumulator(QuicStreamId id, QpackDecoder* qpack_decoder, Visitor* visitor, - size_t max_header_list_size, - bool pretend_blocked_decoding_for_tests); + size_t max_header_list_size); virtual ~QpackDecodedHeadersAccumulator() = default; // QpackProgressiveDecoder::HeadersHandlerInterface implementation. @@ -91,11 +90,10 @@ QuicHeaderList quic_header_list_; size_t uncompressed_header_bytes_; size_t compressed_header_bytes_; + // Set to true when OnDecodingCompleted() is called. + bool headers_decoded_; // Set to true when EndHeaderBlock() returns kBlocked. bool blocked_; - // TODO(b/112770235): Remove once blocked decoding is implemented - // and can be tested with delayed encoder stream data. - bool pretend_blocked_decoding_for_tests_; bool error_detected_; std::string error_message_; };
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc b/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc index 6f424e4..0898327 100644 --- a/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc +++ b/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
@@ -28,6 +28,9 @@ // Limit on header list size. const size_t kMaxHeaderListSize = 100; +// Maximum dynamic table capacity. +const size_t kMaxDynamicTableCapacity = 100; + // Header Acknowledgement decoder stream instruction with stream_id = 1. const char* const kHeaderAcknowledgement = "\x81"; @@ -48,8 +51,7 @@ accumulator_(kTestStreamId, &qpack_decoder_, &visitor_, - kMaxHeaderListSize, - false) {} + kMaxHeaderListSize) {} NoopEncoderStreamErrorDelegate encoder_stream_error_delegate_; StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_; @@ -129,18 +131,39 @@ EXPECT_TRUE(accumulator_.quic_header_list().empty()); } -// TODO(b/112770235): Remove once blocked decoding is implemented -// and can be tested with delayed encoder stream data. -TEST_F(QpackDecodedHeadersAccumulatorTest, PretendBlockedEncoding) { - QpackDecodedHeadersAccumulator accumulator( - kTestStreamId, &qpack_decoder_, &visitor_, kMaxHeaderListSize, - /* pretend_blocked_decoding_for_tests = */ true); +TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecoding) { + qpack_decoder_.SetMaximumDynamicTableCapacity(kMaxDynamicTableCapacity); + // Reference to dynamic table entry not yet received. + EXPECT_TRUE(accumulator_.Decode(QuicTextUtils::HexDecode("020080"))); + EXPECT_EQ(Status::kBlocked, accumulator_.EndHeaderBlock()); + + // Adding dynamic table entry unblocks decoding. EXPECT_CALL(decoder_stream_sender_delegate_, WriteStreamData(Eq(kHeaderAcknowledgement))); + qpack_decoder_.OnInsertWithoutNameReference("foo", "bar"); - EXPECT_TRUE(accumulator.Decode(QuicTextUtils::HexDecode("0000"))); - EXPECT_EQ(Status::kBlocked, accumulator.EndHeaderBlock()); + EXPECT_THAT(accumulator_.quic_header_list(), ElementsAre(Pair("foo", "bar"))); +} + +TEST_F(QpackDecodedHeadersAccumulatorTest, + BlockedDecodingUnblockedBeforeEndOfHeaderBlock) { + qpack_decoder_.SetMaximumDynamicTableCapacity(kMaxDynamicTableCapacity); + + // Reference to dynamic table entry not yet received. + EXPECT_TRUE(accumulator_.Decode(QuicTextUtils::HexDecode("020080"))); + + // Adding dynamic table entry unblocks decoding. + qpack_decoder_.OnInsertWithoutNameReference("foo", "bar"); + + // Rest of header block: same entry again. + EXPECT_CALL(decoder_stream_sender_delegate_, + WriteStreamData(Eq(kHeaderAcknowledgement))); + EXPECT_TRUE(accumulator_.Decode(QuicTextUtils::HexDecode("80"))); + EXPECT_EQ(Status::kSuccess, accumulator_.EndHeaderBlock()); + + EXPECT_THAT(accumulator_.quic_header_list(), + ElementsAre(Pair("foo", "bar"), Pair("foo", "bar"))); } } // namespace test
diff --git a/quic/core/quic_constants.h b/quic/core/quic_constants.h index 913c063..e718602 100644 --- a/quic/core/quic_constants.h +++ b/quic/core/quic_constants.h
@@ -74,9 +74,16 @@ const QuicByteCount kStreamReceiveWindowLimit = 16 * 1024 * 1024; // 16 MB const QuicByteCount kSessionReceiveWindowLimit = 24 * 1024 * 1024; // 24 MB -// Default limit on the size of uncompressed headers. +// Default limit on the size of uncompressed headers, +// communicated via SETTINGS_MAX_HEADER_LIST_SIZE. +// TODO(bnc): Move this constant to quic/core/http/. const QuicByteCount kDefaultMaxUncompressedHeaderSize = 16 * 1024; // 16 KB +// Default maximum dynamic table capacity, communicated via +// SETTINGS_QPACK_MAX_TABLE_CAPACITY. +// TODO(bnc): Move this constant to quic/core/http/. +const QuicByteCount kDefaultQpackMaxDynamicTableCapacity = 64 * 1024; // 64 KB + // Minimum size of the CWND, in packets, when doing bandwidth resumption. const QuicPacketCount kMinCongestionWindowForBandwidthResumption = 10;
diff --git a/quic/test_tools/quic_spdy_stream_peer.cc b/quic/test_tools/quic_spdy_stream_peer.cc index b02c145..d7926bb 100644 --- a/quic/test_tools/quic_spdy_stream_peer.cc +++ b/quic/test_tools/quic_spdy_stream_peer.cc
@@ -23,16 +23,5 @@ return stream->unacked_frame_headers_offsets_; } -// static -void QuicSpdyStreamPeer::pretend_blocked_decoding(QuicSpdyStream* stream) { - stream->pretend_blocked_decoding_for_tests_ = true; -} - -// static -QpackDecodedHeadersAccumulator* -QuicSpdyStreamPeer::qpack_decoded_headers_accumulator(QuicSpdyStream* stream) { - return stream->qpack_decoded_headers_accumulator_.get(); -} - } // namespace test } // namespace quic
diff --git a/quic/test_tools/quic_spdy_stream_peer.h b/quic/test_tools/quic_spdy_stream_peer.h index bd93f37..6656df0 100644 --- a/quic/test_tools/quic_spdy_stream_peer.h +++ b/quic/test_tools/quic_spdy_stream_peer.h
@@ -24,12 +24,6 @@ QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); static const QuicIntervalSet<QuicStreamOffset>& unacked_frame_headers_offsets( QuicSpdyStream* stream); - - // TODO(b/112770235): Remove once blocked decoding is implemented - // and can be tested with delayed encoder stream data. - static void pretend_blocked_decoding(QuicSpdyStream* stream); - static QpackDecodedHeadersAccumulator* qpack_decoded_headers_accumulator( - QuicSpdyStream* stream); }; } // namespace test