Add header_list_size_limit_exceeded argument to OnHeadersDecoded().
The motivation is to allow tests to call OnHeadersDecoded() directly without
QuicSpdyStream having a QpackDecodedHeadersAccumulator object. This happens in
Envoy at
https://github.com/envoyproxy/envoy/blob/master/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc#L110,
which crashes since cr/282822239 added a reference to
|qpack_decoded_headers_accumulator_| in QuicSpdyStream::OnHeadersDecoded().
gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 284213476
Change-Id: I71737f85d8a00db900565dd16c69510844ef3999
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc
index f7a13f6..78d8593 100644
--- a/quic/core/http/quic_spdy_stream.cc
+++ b/quic/core/http/quic_spdy_stream.cc
@@ -538,9 +538,9 @@
}
}
-void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers) {
- header_list_size_limit_exceeded_ =
- qpack_decoded_headers_accumulator_->header_list_size_limit_exceeded();
+void QuicSpdyStream::OnHeadersDecoded(QuicHeaderList headers,
+ bool header_list_size_limit_exceeded) {
+ header_list_size_limit_exceeded_ = header_list_size_limit_exceeded;
qpack_decoded_headers_accumulator_.reset();
QuicSpdySession::LogHeaderCompressionRatioHistogram(
diff --git a/quic/core/http/quic_spdy_stream.h b/quic/core/http/quic_spdy_stream.h
index 8610dbb..c4333f3 100644
--- a/quic/core/http/quic_spdy_stream.h
+++ b/quic/core/http/quic_spdy_stream.h
@@ -214,7 +214,8 @@
bool IsClosed() { return sequencer()->IsClosed(); }
// QpackDecodedHeadersAccumulator::Visitor implementation.
- void OnHeadersDecoded(QuicHeaderList headers) override;
+ void OnHeadersDecoded(QuicHeaderList headers,
+ bool header_list_size_limit_exceeded) override;
void OnHeaderDecodingError(QuicStringPiece error_message) override;
protected:
diff --git a/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc b/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
index 43a637d..018bf09 100644
--- a/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
+++ b/quic/core/qpack/fuzzer/qpack_round_trip_fuzzer.cc
@@ -264,8 +264,10 @@
virtual ~VerifyingDecoder() = default;
// QpackDecodedHeadersAccumulator::Visitor implementation.
- void OnHeadersDecoded(QuicHeaderList headers) override {
+ void OnHeadersDecoded(QuicHeaderList headers,
+ bool header_list_size_limit_exceeded) override {
// Verify headers.
+ CHECK(!header_list_size_limit_exceeded);
CHECK(expected_header_list_ == headers);
// Might destroy |this|.
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator.cc b/quic/core/qpack/qpack_decoded_headers_accumulator.cc
index e16aa5a..b1f8012 100644
--- a/quic/core/qpack/qpack_decoded_headers_accumulator.cc
+++ b/quic/core/qpack/qpack_decoded_headers_accumulator.cc
@@ -62,7 +62,8 @@
uncompressed_header_bytes_without_overhead_, compressed_header_bytes_);
// Might destroy |this|.
- visitor_->OnHeadersDecoded(std::move(quic_header_list_));
+ visitor_->OnHeadersDecoded(std::move(quic_header_list_),
+ header_list_size_limit_exceeded_);
}
void QpackDecodedHeadersAccumulator::OnDecodingErrorDetected(
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator.h b/quic/core/qpack/qpack_decoded_headers_accumulator.h
index 0a2db6a..96b527e 100644
--- a/quic/core/qpack/qpack_decoded_headers_accumulator.h
+++ b/quic/core/qpack/qpack_decoded_headers_accumulator.h
@@ -34,13 +34,15 @@
public:
virtual ~Visitor() = default;
- // Called when headers are successfully decoded. If header list size
- // exceeds the limit specified via |max_header_list_size| in
- // QpackDecodedHeadersAccumulator constructor, then |headers| will be empty,
- // but will still have the correct compressed and uncompressed size
- // information. However, header_list_size_limit_exceeded() is recommended
- // instead of headers.empty() to check whether header size exceeds limit.
- virtual void OnHeadersDecoded(QuicHeaderList headers) = 0;
+ // Called when headers are successfully decoded. If the uncompressed header
+ // list size including an overhead for each header field exceeds the limit
+ // specified via |max_header_list_size| in QpackDecodedHeadersAccumulator
+ // constructor, then |header_list_size_limit_exceeded| will be true, and
+ // |headers| will be empty but will still have the correct compressed and
+ // uncompressed size
+ // information.
+ virtual void OnHeadersDecoded(QuicHeaderList headers,
+ bool header_list_size_limit_exceeded) = 0;
// Called when an error has occurred.
virtual void OnHeaderDecodingError(QuicStringPiece error_message) = 0;
@@ -68,13 +70,6 @@
// Must not be called more that once.
void EndHeaderBlock();
- // Returns true if the uncompressed size of the header list, including an
- // overhead for each header field, exceeds |max_header_list_size| passed in
- // the constructor.
- bool header_list_size_limit_exceeded() const {
- return header_list_size_limit_exceeded_;
- }
-
private:
std::unique_ptr<QpackProgressiveDecoder> decoder_;
Visitor* visitor_;
diff --git a/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc b/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
index 6616517..2334e89 100644
--- a/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
+++ b/quic/core/qpack/qpack_decoded_headers_accumulator_test.cc
@@ -41,7 +41,9 @@
class MockVisitor : public QpackDecodedHeadersAccumulator::Visitor {
public:
~MockVisitor() override = default;
- MOCK_METHOD1(OnHeadersDecoded, void(QuicHeaderList headers));
+ MOCK_METHOD2(OnHeadersDecoded,
+ void(QuicHeaderList headers,
+ bool header_list_size_limit_exceeded));
MOCK_METHOD1(OnHeaderDecodingError, void(QuicStringPiece error_message));
};
@@ -89,9 +91,9 @@
accumulator_.Decode(encoded_data);
QuicHeaderList header_list;
- EXPECT_CALL(visitor_, OnHeadersDecoded(_)).WillOnce(SaveArg<0>(&header_list));
+ EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+ .WillOnce(SaveArg<0>(&header_list));
accumulator_.EndHeaderBlock();
- EXPECT_FALSE(accumulator_.header_list_size_limit_exceeded());
EXPECT_EQ(0u, header_list.uncompressed_header_bytes());
EXPECT_EQ(encoded_data.size(), header_list.compressed_header_bytes());
@@ -119,9 +121,9 @@
accumulator_.Decode(encoded_data);
QuicHeaderList header_list;
- EXPECT_CALL(visitor_, OnHeadersDecoded(_)).WillOnce(SaveArg<0>(&header_list));
+ EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+ .WillOnce(SaveArg<0>(&header_list));
accumulator_.EndHeaderBlock();
- EXPECT_FALSE(accumulator_.header_list_size_limit_exceeded());
EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
EXPECT_EQ(strlen("foo") + strlen("bar"),
@@ -145,9 +147,8 @@
"0f" // second byte of a two-byte long Indexed Header Field instruction
));
- EXPECT_CALL(visitor_, OnHeadersDecoded(_));
+ EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
accumulator_.EndHeaderBlock();
- EXPECT_TRUE(accumulator_.header_list_size_limit_exceeded());
}
// Test that header list limit enforcement works with blocked encoding.
@@ -169,9 +170,8 @@
EXPECT_CALL(decoder_stream_sender_delegate_,
WriteStreamData(Eq(kHeaderAcknowledgement)));
- EXPECT_CALL(visitor_, OnHeadersDecoded(_));
+ EXPECT_CALL(visitor_, OnHeadersDecoded(_, true));
qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
- EXPECT_TRUE(accumulator_.header_list_size_limit_exceeded());
}
TEST_F(QpackDecodedHeadersAccumulatorTest, BlockedDecoding) {
@@ -187,10 +187,10 @@
WriteStreamData(Eq(kHeaderAcknowledgement)));
QuicHeaderList header_list;
- EXPECT_CALL(visitor_, OnHeadersDecoded(_)).WillOnce(SaveArg<0>(&header_list));
+ EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+ .WillOnce(SaveArg<0>(&header_list));
qpack_decoder_.OnInsertWithoutNameReference("foo", "bar");
- EXPECT_FALSE(accumulator_.header_list_size_limit_exceeded());
EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar")));
EXPECT_EQ(strlen("foo") + strlen("bar"),
header_list.uncompressed_header_bytes());
@@ -213,9 +213,9 @@
accumulator_.Decode(QuicTextUtils::HexDecode("80"));
QuicHeaderList header_list;
- EXPECT_CALL(visitor_, OnHeadersDecoded(_)).WillOnce(SaveArg<0>(&header_list));
+ EXPECT_CALL(visitor_, OnHeadersDecoded(_, false))
+ .WillOnce(SaveArg<0>(&header_list));
accumulator_.EndHeaderBlock();
- EXPECT_FALSE(accumulator_.header_list_size_limit_exceeded());
EXPECT_THAT(header_list, ElementsAre(Pair("foo", "bar"), Pair("foo", "bar")));
}