// Copyright 2016 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. #ifndef NET_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_ #define NET_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_ // HpackBlockBuilder builds wire-format HPACK blocks (or fragments thereof) // from components. // Supports very large varints to enable tests to create HPACK blocks with // values that the decoder should reject. For now, this is only intended for // use in tests, and thus has EXPECT* in the code. If desired to use it in an // encoder, it will need optimization work, especially w.r.t memory mgmt, and // the EXPECT* will need to be removed or replaced with DCHECKs. And of course // the support for very large varints will not be needed in production code. #include #include "net/http2/hpack/http2_hpack_constants.h" #include "net/http2/platform/api/http2_string.h" #include "net/http2/platform/api/http2_string_piece.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { namespace test { class HpackBlockBuilder { public: explicit HpackBlockBuilder(Http2StringPiece initial_contents) : buffer_(initial_contents.data(), initial_contents.size()) {} HpackBlockBuilder() {} ~HpackBlockBuilder() {} size_t size() const { return buffer_.size(); } const Http2String& buffer() const { return buffer_; } //---------------------------------------------------------------------------- // Methods for appending a valid HPACK entry. void AppendIndexedHeader(uint64_t index) { AppendEntryTypeAndVarint(HpackEntryType::kIndexedHeader, index); } void AppendDynamicTableSizeUpdate(uint64_t size) { AppendEntryTypeAndVarint(HpackEntryType::kDynamicTableSizeUpdate, size); } void AppendNameIndexAndLiteralValue(HpackEntryType entry_type, uint64_t name_index, bool value_is_huffman_encoded, Http2StringPiece value) { // name_index==0 would indicate that the entry includes a literal name. // Call AppendLiteralNameAndValue in that case. EXPECT_NE(0u, name_index); AppendEntryTypeAndVarint(entry_type, name_index); AppendString(value_is_huffman_encoded, value); } void AppendLiteralNameAndValue(HpackEntryType entry_type, bool name_is_huffman_encoded, Http2StringPiece name, bool value_is_huffman_encoded, Http2StringPiece value) { AppendEntryTypeAndVarint(entry_type, 0); AppendString(name_is_huffman_encoded, name); AppendString(value_is_huffman_encoded, value); } //---------------------------------------------------------------------------- // Primitive methods that are not guaranteed to write a valid HPACK entry. // Appends a varint, with the specified high_bits above the prefix of the // varint. void AppendHighBitsAndVarint(uint8_t high_bits, uint8_t prefix_length, uint64_t varint); // Append the start of an HPACK entry for the specified type, with the // specified varint. void AppendEntryTypeAndVarint(HpackEntryType entry_type, uint64_t varint); // Append a header string (i.e. a header name or value) in HPACK format. // Does NOT perform Huffman encoding. void AppendString(bool is_huffman_encoded, Http2StringPiece str); private: Http2String buffer_; }; } // namespace test } // namespace net #endif // NET_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_