xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/test_tools/hpack_block_builder.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_HTTP2_TEST_TOOLS_HPACK_BLOCK_BUILDER_H_
6 #define QUICHE_HTTP2_TEST_TOOLS_HPACK_BLOCK_BUILDER_H_
7 
8 // HpackBlockBuilder builds wire-format HPACK blocks (or fragments thereof)
9 // from components.
10 
11 // Supports very large varints to enable tests to create HPACK blocks with
12 // values that the decoder should reject. For now, this is only intended for
13 // use in tests, and thus has EXPECT* in the code. If desired to use it in an
14 // encoder, it will need optimization work, especially w.r.t memory mgmt, and
15 // the EXPECT* will need to be removed or replaced with QUICHE_DCHECKs. And of
16 // course the support for very large varints will not be needed in production
17 // code.
18 
19 #include <stddef.h>
20 
21 #include <cstdint>
22 #include <string>
23 
24 #include "absl/strings/string_view.h"
25 #include "quiche/http2/hpack/http2_hpack_constants.h"
26 #include "quiche/common/platform/api/quiche_export.h"
27 #include "quiche/common/platform/api/quiche_test.h"
28 
29 namespace http2 {
30 namespace test {
31 
32 class QUICHE_NO_EXPORT HpackBlockBuilder {
33  public:
HpackBlockBuilder(absl::string_view initial_contents)34   explicit HpackBlockBuilder(absl::string_view initial_contents)
35       : buffer_(initial_contents.data(), initial_contents.size()) {}
HpackBlockBuilder()36   HpackBlockBuilder() {}
~HpackBlockBuilder()37   ~HpackBlockBuilder() {}
38 
size()39   size_t size() const { return buffer_.size(); }
buffer()40   const std::string& buffer() const { return buffer_; }
41 
42   //----------------------------------------------------------------------------
43   // Methods for appending a valid HPACK entry.
44 
AppendIndexedHeader(uint64_t index)45   void AppendIndexedHeader(uint64_t index) {
46     AppendEntryTypeAndVarint(HpackEntryType::kIndexedHeader, index);
47   }
48 
AppendDynamicTableSizeUpdate(uint64_t size)49   void AppendDynamicTableSizeUpdate(uint64_t size) {
50     AppendEntryTypeAndVarint(HpackEntryType::kDynamicTableSizeUpdate, size);
51   }
52 
AppendNameIndexAndLiteralValue(HpackEntryType entry_type,uint64_t name_index,bool value_is_huffman_encoded,absl::string_view value)53   void AppendNameIndexAndLiteralValue(HpackEntryType entry_type,
54                                       uint64_t name_index,
55                                       bool value_is_huffman_encoded,
56                                       absl::string_view value) {
57     // name_index==0 would indicate that the entry includes a literal name.
58     // Call AppendLiteralNameAndValue in that case.
59     EXPECT_NE(0u, name_index);
60     AppendEntryTypeAndVarint(entry_type, name_index);
61     AppendString(value_is_huffman_encoded, value);
62   }
63 
AppendLiteralNameAndValue(HpackEntryType entry_type,bool name_is_huffman_encoded,absl::string_view name,bool value_is_huffman_encoded,absl::string_view value)64   void AppendLiteralNameAndValue(HpackEntryType entry_type,
65                                  bool name_is_huffman_encoded,
66                                  absl::string_view name,
67                                  bool value_is_huffman_encoded,
68                                  absl::string_view value) {
69     AppendEntryTypeAndVarint(entry_type, 0);
70     AppendString(name_is_huffman_encoded, name);
71     AppendString(value_is_huffman_encoded, value);
72   }
73 
74   //----------------------------------------------------------------------------
75   // Primitive methods that are not guaranteed to write a valid HPACK entry.
76 
77   // Appends a varint, with the specified high_bits above the prefix of the
78   // varint.
79   void AppendHighBitsAndVarint(uint8_t high_bits, uint8_t prefix_length,
80                                uint64_t varint);
81 
82   // Append the start of an HPACK entry for the specified type, with the
83   // specified varint.
84   void AppendEntryTypeAndVarint(HpackEntryType entry_type, uint64_t varint);
85 
86   // Append a header string (i.e. a header name or value) in HPACK format.
87   // Does NOT perform Huffman encoding.
88   void AppendString(bool is_huffman_encoded, absl::string_view str);
89 
90  private:
91   std::string buffer_;
92 };
93 
94 }  // namespace test
95 }  // namespace http2
96 
97 #endif  // QUICHE_HTTP2_TEST_TOOLS_HPACK_BLOCK_BUILDER_H_
98