blob: 079f82384f91bb2dd01aa0cbd16d05063f488e8c [file] [log] [blame]
// 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 QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_
#define QUICHE_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 QUICHE_DCHECKs. And of
// course the support for very large varints will not be needed in production
// code.
#include <stddef.h>
#include <cstdint>
#include <string>
#include "absl/strings/string_view.h"
#include "http2/hpack/http2_hpack_constants.h"
#include "common/platform/api/quiche_test.h"
namespace http2 {
namespace test {
class HpackBlockBuilder {
public:
explicit HpackBlockBuilder(absl::string_view initial_contents)
: buffer_(initial_contents.data(), initial_contents.size()) {}
HpackBlockBuilder() {}
~HpackBlockBuilder() {}
size_t size() const { return buffer_.size(); }
const std::string& 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,
absl::string_view 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,
absl::string_view name,
bool value_is_huffman_encoded,
absl::string_view 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, absl::string_view str);
private:
std::string buffer_;
};
} // namespace test
} // namespace http2
#endif // QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_