|
| 1 | +#include <cstdint> |
| 2 | + |
1 | 3 | #include "envoy/http/metadata_interface.h" |
2 | 4 |
|
3 | 5 | #include "source/common/buffer/buffer_impl.h" |
@@ -32,6 +34,7 @@ absl::string_view toStringView(uint8_t* data, size_t length) { |
32 | 34 | } |
33 | 35 |
|
34 | 36 | static const uint64_t STREAM_ID = 1; |
| 37 | +static constexpr uint64_t kDefaultMaxPayloadSizeBound = 1024 * 1024; |
35 | 38 |
|
36 | 39 | // The buffer stores data sent by encoder and received by decoder. |
37 | 40 | struct TestBuffer { |
@@ -79,8 +82,9 @@ class MetadataUnpackingVisitor : public http2::adapter::test::MockHttp2Visitor { |
79 | 82 |
|
80 | 83 | class MetadataEncoderTest : public testing::Test { |
81 | 84 | public: |
82 | | - void initialize(MetadataCallback cb) { |
83 | | - decoder_ = std::make_unique<MetadataDecoder>(cb); |
| 85 | + void initialize(MetadataCallback cb, |
| 86 | + uint64_t max_payload_size_bound = kDefaultMaxPayloadSizeBound) { |
| 87 | + decoder_ = std::make_unique<MetadataDecoder>(cb, max_payload_size_bound); |
84 | 88 |
|
85 | 89 | // Enables extension frame. |
86 | 90 | nghttp2_option* option; |
@@ -197,6 +201,33 @@ TEST_F(MetadataEncoderTest, VerifyEncoderDecoderMultipleMetadataReachSizeLimit) |
197 | 201 | EXPECT_LE(decoder_->max_payload_size_bound_, decoder_->total_payload_size_); |
198 | 202 | } |
199 | 203 |
|
| 204 | +TEST_F(MetadataEncoderTest, VerifyAdjustingMetadataSizeLimit) { |
| 205 | + MetadataMap metadata_map_empty = {}; |
| 206 | + MetadataCallback cb = [](std::unique_ptr<MetadataMap>) -> void {}; |
| 207 | + initialize(cb, 10 * kDefaultMaxPayloadSizeBound); |
| 208 | + |
| 209 | + for (int i = 0; i < 1000; i++) { |
| 210 | + // Cleans up the output buffer. |
| 211 | + memset(output_buffer_.buf, 0, output_buffer_.length); |
| 212 | + output_buffer_.length = 0; |
| 213 | + |
| 214 | + MetadataMap metadata_map = { |
| 215 | + {"header_key", std::string(10000, 'a')}, |
| 216 | + }; |
| 217 | + MetadataMapPtr metadata_map_ptr = std::make_unique<MetadataMap>(metadata_map); |
| 218 | + MetadataMapVector metadata_map_vector; |
| 219 | + metadata_map_vector.push_back(std::move(metadata_map_ptr)); |
| 220 | + |
| 221 | + // Encode and decode the second MetadataMap. |
| 222 | + decoder_->callback_ = [this, &metadata_map_vector](MetadataMapPtr&& metadata_map_ptr) -> void { |
| 223 | + this->verifyMetadataMapVector(metadata_map_vector, std::move(metadata_map_ptr)); |
| 224 | + }; |
| 225 | + submitMetadata(metadata_map_vector); |
| 226 | + ASSERT_GT(session_->ProcessBytes(toStringView(output_buffer_.buf, output_buffer_.length)), 0); |
| 227 | + } |
| 228 | + EXPECT_GT(decoder_->max_payload_size_bound_, decoder_->total_payload_size_); |
| 229 | +} |
| 230 | + |
200 | 231 | // Tests encoding an empty map. |
201 | 232 | TEST_F(MetadataEncoderTest, EncodeMetadataMapEmpty) { |
202 | 233 | MetadataMap empty = {}; |
@@ -309,9 +340,11 @@ TEST_F(MetadataEncoderTest, EncodeDecodeFrameTest) { |
309 | 340 | metadata_map_vector.push_back(std::move(metadataMapPtr)); |
310 | 341 | Http2Frame http2FrameFromUltility = Http2Frame::makeMetadataFrameFromMetadataMap( |
311 | 342 | 1, metadataMap, Http2Frame::MetadataFlags::EndMetadata); |
312 | | - MetadataDecoder decoder([this, &metadata_map_vector](MetadataMapPtr&& metadata_map_ptr) -> void { |
313 | | - this->verifyMetadataMapVector(metadata_map_vector, std::move(metadata_map_ptr)); |
314 | | - }); |
| 343 | + MetadataDecoder decoder( |
| 344 | + [this, &metadata_map_vector](MetadataMapPtr&& metadata_map_ptr) -> void { |
| 345 | + this->verifyMetadataMapVector(metadata_map_vector, std::move(metadata_map_ptr)); |
| 346 | + }, |
| 347 | + kDefaultMaxPayloadSizeBound); |
315 | 348 | decoder.receiveMetadata(http2FrameFromUltility.data() + 9, http2FrameFromUltility.size() - 9); |
316 | 349 | decoder.onMetadataFrameComplete(true); |
317 | 350 | } |
|
0 commit comments