summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h
blob: 079f82384f91bb2dd01aa0cbd16d05063f488e8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// 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_