blob: 6ad14057c249d1b2b94a5ed182bd3a188d63485e [file] [log] [blame]
// 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 <vector>
#include "testing/gtest/include/gtest/gtest.h"
#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_collector.h"
#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_decoder_listener.h"
#include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h"
#include "net/third_party/quiche/src/http2/hpack/tools/hpack_block_builder.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_string.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_string_piece.h"
#include "net/third_party/quiche/src/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 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(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,
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<HpackEntryCollector> entries_;
};
} // namespace test
} // namespace http2
#endif // QUICHE_HTTP2_HPACK_DECODER_HPACK_BLOCK_COLLECTOR_H_