QUICHE team | fd50a40 | 2018-12-07 22:54:05 -0500 | [diff] [blame] | 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_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 | |
| 29 | namespace http2 { |
| 30 | namespace test { |
| 31 | |
| 32 | class 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_ |