blob: 6ad14057c249d1b2b94a5ed182bd3a188d63485e [file] [log] [blame]
QUICHE teamfd50a402018-12-07 22:54:05 -05001// 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_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_
6#define QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_
7
8// HpackBlockCollector implements HpackEntryDecoderListener in order to record
9// the calls using HpackEntryCollector instances (one per HPACK entry). This
10// supports testing of HpackBlockDecoder, which decodes entire HPACK blocks.
11//
12// In addition to implementing the callback methods, HpackBlockCollector also
13// supports comparing two HpackBlockCollector instances (i.e. an expected and
14// an actual), or a sole HPACK entry against an expected value.
15
16#include <stddef.h>
17
18#include <vector>
19
20#include "testing/gtest/include/gtest/gtest.h"
21#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.h"
22#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_decoder_listener.h"
23#include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h"
24#include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h"
25#include "net/third_party/quiche/src/http2/platform/api/http2_string.h"
26#include "net/third_party/quiche/src/http2/platform/api/http2_string_piece.h"
27#include "net/third_party/quiche/src/http2/test_tools/http2_random.h"
28
29namespace http2 {
30namespace test {
31
32class HpackBlockCollector : public HpackEntryDecoderListener {
33 public:
34 HpackBlockCollector();
35 HpackBlockCollector(const HpackBlockCollector& other);
36 ~HpackBlockCollector() override;
37
38 // Implementations of HpackEntryDecoderListener, forwarding to pending_entry_,
39 // an HpackEntryCollector for the "in-progress" HPACK entry. OnIndexedHeader
40 // and OnDynamicTableSizeUpdate are pending only for that one call, while
41 // OnStartLiteralHeader is followed by many calls, ending with OnValueEnd.
42 // Once all the calls for one HPACK entry have been received, PushPendingEntry
43 // is used to append the pending_entry_ entry to the collected entries_.
44 void OnIndexedHeader(size_t index) override;
45 void OnDynamicTableSizeUpdate(size_t size) override;
46 void OnStartLiteralHeader(HpackEntryType header_type,
47 size_t maybe_name_index) override;
48 void OnNameStart(bool huffman_encoded, size_t len) override;
49 void OnNameData(const char* data, size_t len) override;
50 void OnNameEnd() override;
51 void OnValueStart(bool huffman_encoded, size_t len) override;
52 void OnValueData(const char* data, size_t len) override;
53 void OnValueEnd() override;
54
55 // Methods for creating a set of expectations (i.e. HPACK entries to compare
56 // against those collected by another instance of HpackBlockCollector).
57
58 // Add an HPACK entry for an indexed header.
59 void ExpectIndexedHeader(size_t index);
60
61 // Add an HPACK entry for a dynamic table size update.
62 void ExpectDynamicTableSizeUpdate(size_t size);
63
64 // Add an HPACK entry for a header entry with an index for the name, and a
65 // literal value.
66 void ExpectNameIndexAndLiteralValue(HpackEntryType type,
67 size_t index,
68 bool value_huffman,
69 const Http2String& value);
70
71 // Add an HPACK entry for a header entry with a literal name and value.
72 void ExpectLiteralNameAndValue(HpackEntryType type,
73 bool name_huffman,
74 const Http2String& name,
75 bool value_huffman,
76 const Http2String& value);
77
78 // Shuffle the entries, in support of generating an HPACK block of entries
79 // in some random order.
80 void ShuffleEntries(Http2Random* rng);
81
82 // Serialize entries_ to the HpackBlockBuilder.
83 void AppendToHpackBlockBuilder(HpackBlockBuilder* hbb) const;
84
85 // Return AssertionSuccess if there is just one entry, and it is an
86 // Indexed Header with the specified index.
87 ::testing::AssertionResult ValidateSoleIndexedHeader(size_t ndx) const;
88
89 // Return AssertionSuccess if there is just one entry, and it is a
90 // Dynamic Table Size Update with the specified size.
91 ::testing::AssertionResult ValidateSoleDynamicTableSizeUpdate(
92 size_t size) const;
93
94 // Return AssertionSuccess if there is just one entry, and it is a Header
95 // entry with an index for the name and a literal value.
96 ::testing::AssertionResult ValidateSoleLiteralValueHeader(
97 HpackEntryType expected_type,
98 size_t expected_index,
99 bool expected_value_huffman,
100 Http2StringPiece expected_value) const;
101
102 // Return AssertionSuccess if there is just one entry, and it is a Header
103 // with a literal name and literal value.
104 ::testing::AssertionResult ValidateSoleLiteralNameValueHeader(
105 HpackEntryType expected_type,
106 bool expected_name_huffman,
107 Http2StringPiece expected_name,
108 bool expected_value_huffman,
109 Http2StringPiece expected_value) const;
110
111 bool IsNotPending() const { return pending_entry_.IsClear(); }
112 bool IsClear() const { return IsNotPending() && entries_.empty(); }
113 void Clear();
114
115 ::testing::AssertionResult VerifyEq(const HpackBlockCollector& that) const;
116
117 private:
118 // Push the value of pending_entry_ onto entries_, and clear pending_entry_.
119 // The pending_entry_ must be complete.
120 void PushPendingEntry();
121
122 HpackEntryCollector pending_entry_;
123 std::vector<HpackEntryCollector> entries_;
124};
125
126} // namespace test
127} // namespace http2
128
129#endif // QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_