| // 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. |
| |
| #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_block_collector.h" |
| |
| #include <algorithm> |
| #include <memory> |
| |
| #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" |
| #include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h" |
| |
| using ::testing::AssertionResult; |
| using ::testing::AssertionSuccess; |
| |
| namespace http2 { |
| namespace test { |
| |
| HpackBlockCollector::HpackBlockCollector() = default; |
| HpackBlockCollector::HpackBlockCollector(const HpackBlockCollector& other) |
| : pending_entry_(other.pending_entry_), entries_(other.entries_) {} |
| HpackBlockCollector::~HpackBlockCollector() = default; |
| |
| void HpackBlockCollector::OnIndexedHeader(size_t index) { |
| pending_entry_.OnIndexedHeader(index); |
| PushPendingEntry(); |
| } |
| void HpackBlockCollector::OnDynamicTableSizeUpdate(size_t size) { |
| pending_entry_.OnDynamicTableSizeUpdate(size); |
| PushPendingEntry(); |
| } |
| void HpackBlockCollector::OnStartLiteralHeader(HpackEntryType header_type, |
| size_t maybe_name_index) { |
| pending_entry_.OnStartLiteralHeader(header_type, maybe_name_index); |
| } |
| void HpackBlockCollector::OnNameStart(bool huffman_encoded, size_t len) { |
| pending_entry_.OnNameStart(huffman_encoded, len); |
| } |
| void HpackBlockCollector::OnNameData(const char* data, size_t len) { |
| pending_entry_.OnNameData(data, len); |
| } |
| void HpackBlockCollector::OnNameEnd() { |
| pending_entry_.OnNameEnd(); |
| } |
| void HpackBlockCollector::OnValueStart(bool huffman_encoded, size_t len) { |
| pending_entry_.OnValueStart(huffman_encoded, len); |
| } |
| void HpackBlockCollector::OnValueData(const char* data, size_t len) { |
| pending_entry_.OnValueData(data, len); |
| } |
| void HpackBlockCollector::OnValueEnd() { |
| pending_entry_.OnValueEnd(); |
| PushPendingEntry(); |
| } |
| |
| void HpackBlockCollector::PushPendingEntry() { |
| EXPECT_TRUE(pending_entry_.IsComplete()); |
| HTTP2_DVLOG(2) << "PushPendingEntry: " << pending_entry_; |
| entries_.push_back(pending_entry_); |
| EXPECT_TRUE(entries_.back().IsComplete()); |
| pending_entry_.Clear(); |
| } |
| void HpackBlockCollector::Clear() { |
| pending_entry_.Clear(); |
| entries_.clear(); |
| } |
| |
| void HpackBlockCollector::ExpectIndexedHeader(size_t index) { |
| entries_.push_back( |
| HpackEntryCollector(HpackEntryType::kIndexedHeader, index)); |
| } |
| void HpackBlockCollector::ExpectDynamicTableSizeUpdate(size_t size) { |
| entries_.push_back( |
| HpackEntryCollector(HpackEntryType::kDynamicTableSizeUpdate, size)); |
| } |
| void HpackBlockCollector::ExpectNameIndexAndLiteralValue( |
| HpackEntryType type, |
| size_t index, |
| bool value_huffman, |
| const std::string& value) { |
| entries_.push_back(HpackEntryCollector(type, index, value_huffman, value)); |
| } |
| void HpackBlockCollector::ExpectLiteralNameAndValue(HpackEntryType type, |
| bool name_huffman, |
| const std::string& name, |
| bool value_huffman, |
| const std::string& value) { |
| entries_.push_back( |
| HpackEntryCollector(type, name_huffman, name, value_huffman, value)); |
| } |
| |
| void HpackBlockCollector::ShuffleEntries(Http2Random* rng) { |
| std::shuffle(entries_.begin(), entries_.end(), *rng); |
| } |
| |
| void HpackBlockCollector::AppendToHpackBlockBuilder( |
| HpackBlockBuilder* hbb) const { |
| CHECK(IsNotPending()); |
| for (const auto& entry : entries_) { |
| entry.AppendToHpackBlockBuilder(hbb); |
| } |
| } |
| |
| AssertionResult HpackBlockCollector::ValidateSoleIndexedHeader( |
| size_t ndx) const { |
| VERIFY_TRUE(pending_entry_.IsClear()); |
| VERIFY_EQ(1u, entries_.size()); |
| VERIFY_TRUE(entries_.front().ValidateIndexedHeader(ndx)); |
| return AssertionSuccess(); |
| } |
| AssertionResult HpackBlockCollector::ValidateSoleLiteralValueHeader( |
| HpackEntryType expected_type, |
| size_t expected_index, |
| bool expected_value_huffman, |
| quiche::QuicheStringPiece expected_value) const { |
| VERIFY_TRUE(pending_entry_.IsClear()); |
| VERIFY_EQ(1u, entries_.size()); |
| VERIFY_TRUE(entries_.front().ValidateLiteralValueHeader( |
| expected_type, expected_index, expected_value_huffman, expected_value)); |
| return AssertionSuccess(); |
| } |
| AssertionResult HpackBlockCollector::ValidateSoleLiteralNameValueHeader( |
| HpackEntryType expected_type, |
| bool expected_name_huffman, |
| quiche::QuicheStringPiece expected_name, |
| bool expected_value_huffman, |
| quiche::QuicheStringPiece expected_value) const { |
| VERIFY_TRUE(pending_entry_.IsClear()); |
| VERIFY_EQ(1u, entries_.size()); |
| VERIFY_TRUE(entries_.front().ValidateLiteralNameValueHeader( |
| expected_type, expected_name_huffman, expected_name, |
| expected_value_huffman, expected_value)); |
| return AssertionSuccess(); |
| } |
| AssertionResult HpackBlockCollector::ValidateSoleDynamicTableSizeUpdate( |
| size_t size) const { |
| VERIFY_TRUE(pending_entry_.IsClear()); |
| VERIFY_EQ(1u, entries_.size()); |
| VERIFY_TRUE(entries_.front().ValidateDynamicTableSizeUpdate(size)); |
| return AssertionSuccess(); |
| } |
| |
| AssertionResult HpackBlockCollector::VerifyEq( |
| const HpackBlockCollector& that) const { |
| VERIFY_EQ(pending_entry_, that.pending_entry_); |
| VERIFY_EQ(entries_, that.entries_); |
| return AssertionSuccess(); |
| } |
| |
| } // namespace test |
| } // namespace http2 |