| // 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_DECODER_HPACK_BLOCK_COLLECTOR_H_ |
| #define QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_ |
| |
| // HpackBlockCollector implements HpackEntryDecoderListener in order to record |
| // the calls using HpackEntryCollector instances (one per HPACK entry). This |
| // supports testing of HpackBlockDecoder, which decodes entire HPACK blocks. |
| // |
| // In addition to implementing the callback methods, HpackBlockCollector also |
| // supports comparing two HpackBlockCollector instances (i.e. an expected and |
| // an actual), or a sole HPACK entry against an expected value. |
| |
| #include <stddef.h> |
| |
| #include <string> |
| #include <vector> |
| |
| #include "absl/strings/string_view.h" |
| #include "http2/hpack/decoder/hpack_entry_collector.h" |
| #include "http2/hpack/decoder/hpack_entry_decoder_listener.h" |
| #include "http2/hpack/http2_hpack_constants.h" |
| #include "http2/hpack/tools/hpack_block_builder.h" |
| #include "http2/test_tools/http2_random.h" |
| |
| namespace http2 { |
| namespace test { |
| |
| class HpackBlockCollector : public HpackEntryDecoderListener { |
| public: |
| HpackBlockCollector(); |
| HpackBlockCollector(const HpackBlockCollector& other); |
| ~HpackBlockCollector() override; |
| |
| // Implementations of HpackEntryDecoderListener, forwarding to pending_entry_, |
| // an HpackEntryCollector for the "in-progress" HPACK entry. OnIndexedHeader |
| // and OnDynamicTableSizeUpdate are pending only for that one call, while |
| // OnStartLiteralHeader is followed by many calls, ending with OnValueEnd. |
| // Once all the calls for one HPACK entry have been received, PushPendingEntry |
| // is used to append the pending_entry_ entry to the collected entries_. |
| void OnIndexedHeader(size_t index) override; |
| void OnDynamicTableSizeUpdate(size_t size) override; |
| void OnStartLiteralHeader(HpackEntryType header_type, |
| size_t maybe_name_index) override; |
| void OnNameStart(bool huffman_encoded, size_t len) override; |
| void OnNameData(const char* data, size_t len) override; |
| void OnNameEnd() override; |
| void OnValueStart(bool huffman_encoded, size_t len) override; |
| void OnValueData(const char* data, size_t len) override; |
| void OnValueEnd() override; |
| |
| // Methods for creating a set of expectations (i.e. HPACK entries to compare |
| // against those collected by another instance of HpackBlockCollector). |
| |
| // Add an HPACK entry for an indexed header. |
| void ExpectIndexedHeader(size_t index); |
| |
| // Add an HPACK entry for a dynamic table size update. |
| void ExpectDynamicTableSizeUpdate(size_t size); |
| |
| // Add an HPACK entry for a header entry with an index for the name, and a |
| // literal value. |
| void ExpectNameIndexAndLiteralValue(HpackEntryType type, |
| size_t index, |
| bool value_huffman, |
| const std::string& value); |
| |
| // Add an HPACK entry for a header entry with a literal name and value. |
| void ExpectLiteralNameAndValue(HpackEntryType type, |
| bool name_huffman, |
| const std::string& name, |
| bool value_huffman, |
| const std::string& value); |
| |
| // Shuffle the entries, in support of generating an HPACK block of entries |
| // in some random order. |
| void ShuffleEntries(Http2Random* rng); |
| |
| // Serialize entries_ to the HpackBlockBuilder. |
| void AppendToHpackBlockBuilder(HpackBlockBuilder* hbb) const; |
| |
| // Return AssertionSuccess if there is just one entry, and it is an |
| // Indexed Header with the specified index. |
| ::testing::AssertionResult ValidateSoleIndexedHeader(size_t ndx) const; |
| |
| // Return AssertionSuccess if there is just one entry, and it is a |
| // Dynamic Table Size Update with the specified size. |
| ::testing::AssertionResult ValidateSoleDynamicTableSizeUpdate( |
| size_t size) const; |
| |
| // Return AssertionSuccess if there is just one entry, and it is a Header |
| // entry with an index for the name and a literal value. |
| ::testing::AssertionResult ValidateSoleLiteralValueHeader( |
| HpackEntryType expected_type, |
| size_t expected_index, |
| bool expected_value_huffman, |
| absl::string_view expected_value) const; |
| |
| // Return AssertionSuccess if there is just one entry, and it is a Header |
| // with a literal name and literal value. |
| ::testing::AssertionResult ValidateSoleLiteralNameValueHeader( |
| HpackEntryType expected_type, |
| bool expected_name_huffman, |
| absl::string_view expected_name, |
| bool expected_value_huffman, |
| absl::string_view expected_value) const; |
| |
| bool IsNotPending() const { return pending_entry_.IsClear(); } |
| bool IsClear() const { return IsNotPending() && entries_.empty(); } |
| void Clear(); |
| |
| ::testing::AssertionResult VerifyEq(const HpackBlockCollector& that) const; |
| |
| private: |
| // Push the value of pending_entry_ onto entries_, and clear pending_entry_. |
| // The pending_entry_ must be complete. |
| void PushPendingEntry(); |
| |
| HpackEntryCollector pending_entry_; |
| std::vector<HpackEntryCollector> entries_; |
| }; |
| |
| } // namespace test |
| } // namespace http2 |
| |
| #endif // QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_ |