| // Copyright 2024 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "quiche/quic/core/http/metadata_decoder.h" | |
| #include <string> | |
| #include "absl/strings/escaping.h" | |
| #include "quiche/quic/core/qpack/qpack_encoder.h" | |
| #include "quiche/quic/platform/api/quic_test.h" | |
| #include "quiche/quic/test_tools/quic_test_utils.h" | |
| namespace quic { | |
| namespace test { | |
| namespace { | |
| class MetadataDecoderTest : public QuicTest { | |
| protected: | |
| std::string EncodeHeaders(quiche::HttpHeaderBlock& headers) { | |
| quic::NoopDecoderStreamErrorDelegate delegate; | |
| quic::QpackEncoder encoder(&delegate, quic::HuffmanEncoding::kDisabled, | |
| quic::CookieCrumbling::kDisabled); | |
| return encoder.EncodeHeaderList(id_, headers, | |
| /*encoder_stream_sent_byte_count=*/nullptr); | |
| } | |
| size_t max_header_list_size = 1 << 20; // 1 MB | |
| const QuicStreamId id_ = 1; | |
| }; | |
| TEST_F(MetadataDecoderTest, Initialize) { | |
| const size_t frame_header_len = 4; | |
| const size_t payload_len = 123; | |
| MetadataDecoder decoder(id_, max_header_list_size, frame_header_len, | |
| payload_len); | |
| EXPECT_EQ(frame_header_len + payload_len, decoder.frame_len()); | |
| EXPECT_EQ("", decoder.error_message()); | |
| EXPECT_TRUE(decoder.headers().empty()); | |
| } | |
| TEST_F(MetadataDecoderTest, Decode) { | |
| quiche::HttpHeaderBlock headers; | |
| headers["key1"] = "val1"; | |
| headers["key2"] = "val2"; | |
| headers["key3"] = "val3"; | |
| std::string data = EncodeHeaders(headers); | |
| const size_t frame_header_len = 4; | |
| MetadataDecoder decoder(id_, max_header_list_size, frame_header_len, | |
| data.length()); | |
| EXPECT_TRUE(decoder.Decode(data)); | |
| EXPECT_TRUE(decoder.EndHeaderBlock()); | |
| EXPECT_EQ(quic::test::AsHeaderList(headers), decoder.headers()); | |
| } | |
| TEST_F(MetadataDecoderTest, DecodeInvalidHeaders) { | |
| std::string data = "aaaaaaaaaa"; | |
| const size_t frame_header_len = 4; | |
| MetadataDecoder decoder(id_, max_header_list_size, frame_header_len, | |
| data.length()); | |
| EXPECT_FALSE(decoder.Decode(data)); | |
| EXPECT_EQ("Error decoding metadata: Error decoding Required Insert Count.", | |
| decoder.error_message()); | |
| } | |
| TEST_F(MetadataDecoderTest, TooLarge) { | |
| quiche::HttpHeaderBlock headers; | |
| for (int i = 0; i < 1024; ++i) { | |
| headers.AppendValueOrAddHeader(absl::StrCat(i), std::string(1024, 'a')); | |
| } | |
| std::string data = EncodeHeaders(headers); | |
| EXPECT_GT(data.length(), 1 << 20); | |
| const size_t frame_header_len = 4; | |
| MetadataDecoder decoder(id_, max_header_list_size, frame_header_len, | |
| data.length()); | |
| EXPECT_TRUE(decoder.Decode(data)); | |
| EXPECT_FALSE(decoder.EndHeaderBlock()); | |
| EXPECT_TRUE(decoder.error_message().empty()); | |
| } | |
| } // namespace | |
| } // namespace test | |
| } // namespace quic |