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