// 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 NET_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_ #define NET_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 #include #include "net/http2/hpack/decoder/hpack_entry_collector.h" #include "net/http2/hpack/decoder/hpack_entry_decoder_listener.h" #include "net/http2/hpack/http2_hpack_constants.h" #include "net/http2/hpack/tools/hpack_block_builder.h" #include "net/http2/platform/api/http2_string.h" #include "net/http2/platform/api/http2_string_piece.h" namespace net { namespace test { class RandomBase; class HpackBlockCollector : public HpackEntryDecoderListener { public: // 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_. HpackBlockCollector(); HpackBlockCollector(const HpackBlockCollector& other); ~HpackBlockCollector() override; 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 Http2String& value); // Add an HPACK entry for a header entry with a literal name and value. void ExpectLiteralNameAndValue(HpackEntryType type, bool name_huffman, const Http2String& name, bool value_huffman, const Http2String& value); // Shuffle the entries, in support of generating an HPACK block of entries // in some random order. void ShuffleEntries(RandomBase* 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, Http2StringPiece 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, Http2StringPiece expected_name, bool expected_value_huffman, Http2StringPiece 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 entries_; }; } // namespace test } // namespace net #endif // NET_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_