Rename spdy::Http2HeaderBlock into quiche::HttpHeaderBlock.
Http2HeaderBlock is used in HTTP/3 code too, thus this naming makes more sense.
PiperOrigin-RevId: 568272632
diff --git a/build/source_list.bzl b/build/source_list.bzl
index 4174621..bdb0b9e 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -11,6 +11,8 @@
quiche_core_hdrs = [
"common/btree_scheduler.h",
"common/capsule.h",
+ "common/http/http_header_block.h",
+ "common/http/http_header_storage.h",
"common/masque/connect_udp_datagram_payload.h",
"common/platform/api/quiche_bug_tracker.h",
"common/platform/api/quiche_client_stats.h",
@@ -47,6 +49,7 @@
"common/quiche_mem_slice_storage.h",
"common/quiche_protocol_flags_list.h",
"common/quiche_random.h",
+ "common/quiche_simple_arena.h",
"common/quiche_status_utils.h",
"common/quiche_stream.h",
"common/quiche_text_utils.h",
@@ -376,7 +379,6 @@
"spdy/core/http2_frame_decoder_adapter.h",
"spdy/core/http2_header_block.h",
"spdy/core/http2_header_block_hpack_listener.h",
- "spdy/core/http2_header_storage.h",
"spdy/core/metadata_extension.h",
"spdy/core/no_op_headers_handler.h",
"spdy/core/recording_headers_handler.h",
@@ -390,13 +392,14 @@
"spdy/core/spdy_pinnable_buffer_piece.h",
"spdy/core/spdy_prefixed_buffer_reader.h",
"spdy/core/spdy_protocol.h",
- "spdy/core/spdy_simple_arena.h",
"spdy/core/zero_copy_output_buffer.h",
"web_transport/complete_buffer_visitor.h",
"web_transport/web_transport.h",
]
quiche_core_srcs = [
"common/capsule.cc",
+ "common/http/http_header_block.cc",
+ "common/http/http_header_storage.cc",
"common/masque/connect_udp_datagram_payload.cc",
"common/platform/api/quiche_hostname_utils.cc",
"common/platform/api/quiche_mutex.cc",
@@ -408,6 +411,7 @@
"common/quiche_ip_address_family.cc",
"common/quiche_mem_slice_storage.cc",
"common/quiche_random.cc",
+ "common/quiche_simple_arena.cc",
"common/quiche_text_utils.cc",
"common/simple_buffer_allocator.cc",
"common/structured_headers.cc",
@@ -671,8 +675,6 @@
"spdy/core/hpack/hpack_output_stream.cc",
"spdy/core/hpack/hpack_static_table.cc",
"spdy/core/http2_frame_decoder_adapter.cc",
- "spdy/core/http2_header_block.cc",
- "spdy/core/http2_header_storage.cc",
"spdy/core/metadata_extension.cc",
"spdy/core/recording_headers_handler.cc",
"spdy/core/spdy_alt_svc_wire_format.cc",
@@ -682,7 +684,6 @@
"spdy/core/spdy_pinnable_buffer_piece.cc",
"spdy/core/spdy_prefixed_buffer_reader.cc",
"spdy/core/spdy_protocol.cc",
- "spdy/core/spdy_simple_arena.cc",
"web_transport/complete_buffer_visitor.cc",
]
quiche_tool_support_hdrs = [
@@ -1050,6 +1051,8 @@
"binary_http/binary_http_message_test.cc",
"common/btree_scheduler_test.cc",
"common/capsule_test.cc",
+ "common/http/http_header_block_test.cc",
+ "common/http/http_header_storage_test.cc",
"common/masque/connect_udp_datagram_payload_test.cc",
"common/platform/api/quiche_file_utils_test.cc",
"common/platform/api/quiche_hostname_utils_test.cc",
@@ -1070,6 +1073,7 @@
"common/quiche_linked_hash_map_test.cc",
"common/quiche_mem_slice_storage_test.cc",
"common/quiche_random_test.cc",
+ "common/quiche_simple_arena_test.cc",
"common/quiche_text_utils_test.cc",
"common/simple_buffer_allocator_test.cc",
"common/structured_headers_generated_test.cc",
@@ -1299,8 +1303,6 @@
"spdy/core/hpack/hpack_output_stream_test.cc",
"spdy/core/hpack/hpack_round_trip_test.cc",
"spdy/core/hpack/hpack_static_table_test.cc",
- "spdy/core/http2_header_block_test.cc",
- "spdy/core/http2_header_storage_test.cc",
"spdy/core/metadata_extension_test.cc",
"spdy/core/spdy_alt_svc_wire_format_test.cc",
"spdy/core/spdy_frame_builder_test.cc",
@@ -1309,7 +1311,6 @@
"spdy/core/spdy_pinnable_buffer_piece_test.cc",
"spdy/core/spdy_prefixed_buffer_reader_test.cc",
"spdy/core/spdy_protocol_test.cc",
- "spdy/core/spdy_simple_arena_test.cc",
]
io_tests_hdrs = [
]
diff --git a/build/source_list.gni b/build/source_list.gni
index 2681949..ce279c6 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -11,6 +11,8 @@
quiche_core_hdrs = [
"src/quiche/common/btree_scheduler.h",
"src/quiche/common/capsule.h",
+ "src/quiche/common/http/http_header_block.h",
+ "src/quiche/common/http/http_header_storage.h",
"src/quiche/common/masque/connect_udp_datagram_payload.h",
"src/quiche/common/platform/api/quiche_bug_tracker.h",
"src/quiche/common/platform/api/quiche_client_stats.h",
@@ -47,6 +49,7 @@
"src/quiche/common/quiche_mem_slice_storage.h",
"src/quiche/common/quiche_protocol_flags_list.h",
"src/quiche/common/quiche_random.h",
+ "src/quiche/common/quiche_simple_arena.h",
"src/quiche/common/quiche_status_utils.h",
"src/quiche/common/quiche_stream.h",
"src/quiche/common/quiche_text_utils.h",
@@ -376,7 +379,6 @@
"src/quiche/spdy/core/http2_frame_decoder_adapter.h",
"src/quiche/spdy/core/http2_header_block.h",
"src/quiche/spdy/core/http2_header_block_hpack_listener.h",
- "src/quiche/spdy/core/http2_header_storage.h",
"src/quiche/spdy/core/metadata_extension.h",
"src/quiche/spdy/core/no_op_headers_handler.h",
"src/quiche/spdy/core/recording_headers_handler.h",
@@ -390,13 +392,14 @@
"src/quiche/spdy/core/spdy_pinnable_buffer_piece.h",
"src/quiche/spdy/core/spdy_prefixed_buffer_reader.h",
"src/quiche/spdy/core/spdy_protocol.h",
- "src/quiche/spdy/core/spdy_simple_arena.h",
"src/quiche/spdy/core/zero_copy_output_buffer.h",
"src/quiche/web_transport/complete_buffer_visitor.h",
"src/quiche/web_transport/web_transport.h",
]
quiche_core_srcs = [
"src/quiche/common/capsule.cc",
+ "src/quiche/common/http/http_header_block.cc",
+ "src/quiche/common/http/http_header_storage.cc",
"src/quiche/common/masque/connect_udp_datagram_payload.cc",
"src/quiche/common/platform/api/quiche_hostname_utils.cc",
"src/quiche/common/platform/api/quiche_mutex.cc",
@@ -408,6 +411,7 @@
"src/quiche/common/quiche_ip_address_family.cc",
"src/quiche/common/quiche_mem_slice_storage.cc",
"src/quiche/common/quiche_random.cc",
+ "src/quiche/common/quiche_simple_arena.cc",
"src/quiche/common/quiche_text_utils.cc",
"src/quiche/common/simple_buffer_allocator.cc",
"src/quiche/common/structured_headers.cc",
@@ -671,8 +675,6 @@
"src/quiche/spdy/core/hpack/hpack_output_stream.cc",
"src/quiche/spdy/core/hpack/hpack_static_table.cc",
"src/quiche/spdy/core/http2_frame_decoder_adapter.cc",
- "src/quiche/spdy/core/http2_header_block.cc",
- "src/quiche/spdy/core/http2_header_storage.cc",
"src/quiche/spdy/core/metadata_extension.cc",
"src/quiche/spdy/core/recording_headers_handler.cc",
"src/quiche/spdy/core/spdy_alt_svc_wire_format.cc",
@@ -682,7 +684,6 @@
"src/quiche/spdy/core/spdy_pinnable_buffer_piece.cc",
"src/quiche/spdy/core/spdy_prefixed_buffer_reader.cc",
"src/quiche/spdy/core/spdy_protocol.cc",
- "src/quiche/spdy/core/spdy_simple_arena.cc",
"src/quiche/web_transport/complete_buffer_visitor.cc",
]
quiche_tool_support_hdrs = [
@@ -1051,6 +1052,8 @@
"src/quiche/binary_http/binary_http_message_test.cc",
"src/quiche/common/btree_scheduler_test.cc",
"src/quiche/common/capsule_test.cc",
+ "src/quiche/common/http/http_header_block_test.cc",
+ "src/quiche/common/http/http_header_storage_test.cc",
"src/quiche/common/masque/connect_udp_datagram_payload_test.cc",
"src/quiche/common/platform/api/quiche_file_utils_test.cc",
"src/quiche/common/platform/api/quiche_hostname_utils_test.cc",
@@ -1071,6 +1074,7 @@
"src/quiche/common/quiche_linked_hash_map_test.cc",
"src/quiche/common/quiche_mem_slice_storage_test.cc",
"src/quiche/common/quiche_random_test.cc",
+ "src/quiche/common/quiche_simple_arena_test.cc",
"src/quiche/common/quiche_text_utils_test.cc",
"src/quiche/common/simple_buffer_allocator_test.cc",
"src/quiche/common/structured_headers_generated_test.cc",
@@ -1300,8 +1304,6 @@
"src/quiche/spdy/core/hpack/hpack_output_stream_test.cc",
"src/quiche/spdy/core/hpack/hpack_round_trip_test.cc",
"src/quiche/spdy/core/hpack/hpack_static_table_test.cc",
- "src/quiche/spdy/core/http2_header_block_test.cc",
- "src/quiche/spdy/core/http2_header_storage_test.cc",
"src/quiche/spdy/core/metadata_extension_test.cc",
"src/quiche/spdy/core/spdy_alt_svc_wire_format_test.cc",
"src/quiche/spdy/core/spdy_frame_builder_test.cc",
@@ -1310,7 +1312,6 @@
"src/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc",
"src/quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc",
"src/quiche/spdy/core/spdy_protocol_test.cc",
- "src/quiche/spdy/core/spdy_simple_arena_test.cc",
]
io_tests_hdrs = [
diff --git a/build/source_list.json b/build/source_list.json
index ad9e6d4..5dffaf9 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -10,6 +10,8 @@
"quiche_core_hdrs": [
"quiche/common/btree_scheduler.h",
"quiche/common/capsule.h",
+ "quiche/common/http/http_header_block.h",
+ "quiche/common/http/http_header_storage.h",
"quiche/common/masque/connect_udp_datagram_payload.h",
"quiche/common/platform/api/quiche_bug_tracker.h",
"quiche/common/platform/api/quiche_client_stats.h",
@@ -46,6 +48,7 @@
"quiche/common/quiche_mem_slice_storage.h",
"quiche/common/quiche_protocol_flags_list.h",
"quiche/common/quiche_random.h",
+ "quiche/common/quiche_simple_arena.h",
"quiche/common/quiche_status_utils.h",
"quiche/common/quiche_stream.h",
"quiche/common/quiche_text_utils.h",
@@ -375,7 +378,6 @@
"quiche/spdy/core/http2_frame_decoder_adapter.h",
"quiche/spdy/core/http2_header_block.h",
"quiche/spdy/core/http2_header_block_hpack_listener.h",
- "quiche/spdy/core/http2_header_storage.h",
"quiche/spdy/core/metadata_extension.h",
"quiche/spdy/core/no_op_headers_handler.h",
"quiche/spdy/core/recording_headers_handler.h",
@@ -389,13 +391,14 @@
"quiche/spdy/core/spdy_pinnable_buffer_piece.h",
"quiche/spdy/core/spdy_prefixed_buffer_reader.h",
"quiche/spdy/core/spdy_protocol.h",
- "quiche/spdy/core/spdy_simple_arena.h",
"quiche/spdy/core/zero_copy_output_buffer.h",
"quiche/web_transport/complete_buffer_visitor.h",
"quiche/web_transport/web_transport.h"
],
"quiche_core_srcs": [
"quiche/common/capsule.cc",
+ "quiche/common/http/http_header_block.cc",
+ "quiche/common/http/http_header_storage.cc",
"quiche/common/masque/connect_udp_datagram_payload.cc",
"quiche/common/platform/api/quiche_hostname_utils.cc",
"quiche/common/platform/api/quiche_mutex.cc",
@@ -407,6 +410,7 @@
"quiche/common/quiche_ip_address_family.cc",
"quiche/common/quiche_mem_slice_storage.cc",
"quiche/common/quiche_random.cc",
+ "quiche/common/quiche_simple_arena.cc",
"quiche/common/quiche_text_utils.cc",
"quiche/common/simple_buffer_allocator.cc",
"quiche/common/structured_headers.cc",
@@ -670,8 +674,6 @@
"quiche/spdy/core/hpack/hpack_output_stream.cc",
"quiche/spdy/core/hpack/hpack_static_table.cc",
"quiche/spdy/core/http2_frame_decoder_adapter.cc",
- "quiche/spdy/core/http2_header_block.cc",
- "quiche/spdy/core/http2_header_storage.cc",
"quiche/spdy/core/metadata_extension.cc",
"quiche/spdy/core/recording_headers_handler.cc",
"quiche/spdy/core/spdy_alt_svc_wire_format.cc",
@@ -681,7 +683,6 @@
"quiche/spdy/core/spdy_pinnable_buffer_piece.cc",
"quiche/spdy/core/spdy_prefixed_buffer_reader.cc",
"quiche/spdy/core/spdy_protocol.cc",
- "quiche/spdy/core/spdy_simple_arena.cc",
"quiche/web_transport/complete_buffer_visitor.cc"
],
"quiche_tool_support_hdrs": [
@@ -1050,6 +1051,8 @@
"quiche/binary_http/binary_http_message_test.cc",
"quiche/common/btree_scheduler_test.cc",
"quiche/common/capsule_test.cc",
+ "quiche/common/http/http_header_block_test.cc",
+ "quiche/common/http/http_header_storage_test.cc",
"quiche/common/masque/connect_udp_datagram_payload_test.cc",
"quiche/common/platform/api/quiche_file_utils_test.cc",
"quiche/common/platform/api/quiche_hostname_utils_test.cc",
@@ -1070,6 +1073,7 @@
"quiche/common/quiche_linked_hash_map_test.cc",
"quiche/common/quiche_mem_slice_storage_test.cc",
"quiche/common/quiche_random_test.cc",
+ "quiche/common/quiche_simple_arena_test.cc",
"quiche/common/quiche_text_utils_test.cc",
"quiche/common/simple_buffer_allocator_test.cc",
"quiche/common/structured_headers_generated_test.cc",
@@ -1299,8 +1303,6 @@
"quiche/spdy/core/hpack/hpack_output_stream_test.cc",
"quiche/spdy/core/hpack/hpack_round_trip_test.cc",
"quiche/spdy/core/hpack/hpack_static_table_test.cc",
- "quiche/spdy/core/http2_header_block_test.cc",
- "quiche/spdy/core/http2_header_storage_test.cc",
"quiche/spdy/core/metadata_extension_test.cc",
"quiche/spdy/core/spdy_alt_svc_wire_format_test.cc",
"quiche/spdy/core/spdy_frame_builder_test.cc",
@@ -1308,8 +1310,7 @@
"quiche/spdy/core/spdy_intrusive_list_test.cc",
"quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc",
"quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc",
- "quiche/spdy/core/spdy_protocol_test.cc",
- "quiche/spdy/core/spdy_simple_arena_test.cc"
+ "quiche/spdy/core/spdy_protocol_test.cc"
],
"io_tests_hdrs": [
diff --git a/quiche/spdy/core/http2_header_block.cc b/quiche/common/http/http_header_block.cc
similarity index 71%
rename from quiche/spdy/core/http2_header_block.cc
rename to quiche/common/http/http_header_block.cc
index 8dddae5..eea94ff 100644
--- a/quiche/spdy/core/http2_header_block.cc
+++ b/quiche/common/http/http_header_block.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "quiche/spdy/core/http2_header_block.h"
+#include "quiche/common/http/http_header_block.h"
#include <string.h>
@@ -12,7 +12,7 @@
#include "absl/strings/str_cat.h"
#include "quiche/common/platform/api/quiche_logging.h"
-namespace spdy {
+namespace quiche {
namespace {
// By default, linked_hash_map's internal map allocates space for 100 map
@@ -37,23 +37,23 @@
} // namespace
-Http2HeaderBlock::HeaderValue::HeaderValue(Http2HeaderStorage* storage,
- absl::string_view key,
- absl::string_view initial_value)
+HttpHeaderBlock::HeaderValue::HeaderValue(HttpHeaderStorage* storage,
+ absl::string_view key,
+ absl::string_view initial_value)
: storage_(storage),
fragments_({initial_value}),
pair_({key, {}}),
size_(initial_value.size()),
separator_size_(SeparatorForKey(key).size()) {}
-Http2HeaderBlock::HeaderValue::HeaderValue(HeaderValue&& other)
+HttpHeaderBlock::HeaderValue::HeaderValue(HeaderValue&& other)
: storage_(other.storage_),
fragments_(std::move(other.fragments_)),
pair_(std::move(other.pair_)),
size_(other.size_),
separator_size_(other.separator_size_) {}
-Http2HeaderBlock::HeaderValue& Http2HeaderBlock::HeaderValue::operator=(
+HttpHeaderBlock::HeaderValue& HttpHeaderBlock::HeaderValue::operator=(
HeaderValue&& other) {
storage_ = other.storage_;
fragments_ = std::move(other.fragments_);
@@ -63,13 +63,13 @@
return *this;
}
-void Http2HeaderBlock::HeaderValue::set_storage(Http2HeaderStorage* storage) {
+void HttpHeaderBlock::HeaderValue::set_storage(HttpHeaderStorage* storage) {
storage_ = storage;
}
-Http2HeaderBlock::HeaderValue::~HeaderValue() = default;
+HttpHeaderBlock::HeaderValue::~HeaderValue() = default;
-absl::string_view Http2HeaderBlock::HeaderValue::ConsolidatedValue() const {
+absl::string_view HttpHeaderBlock::HeaderValue::ConsolidatedValue() const {
if (fragments_.empty()) {
return absl::string_view();
}
@@ -80,25 +80,25 @@
return fragments_[0];
}
-void Http2HeaderBlock::HeaderValue::Append(absl::string_view fragment) {
+void HttpHeaderBlock::HeaderValue::Append(absl::string_view fragment) {
size_ += (fragment.size() + separator_size_);
fragments_.push_back(fragment);
}
const std::pair<absl::string_view, absl::string_view>&
-Http2HeaderBlock::HeaderValue::as_pair() const {
+HttpHeaderBlock::HeaderValue::as_pair() const {
pair_.second = ConsolidatedValue();
return pair_;
}
-Http2HeaderBlock::iterator::iterator(MapType::const_iterator it) : it_(it) {}
+HttpHeaderBlock::iterator::iterator(MapType::const_iterator it) : it_(it) {}
-Http2HeaderBlock::iterator::iterator(const iterator& other) = default;
+HttpHeaderBlock::iterator::iterator(const iterator& other) = default;
-Http2HeaderBlock::iterator::~iterator() = default;
+HttpHeaderBlock::iterator::~iterator() = default;
-Http2HeaderBlock::ValueProxy::ValueProxy(
- Http2HeaderBlock* block, Http2HeaderBlock::MapType::iterator lookup_result,
+HttpHeaderBlock::ValueProxy::ValueProxy(
+ HttpHeaderBlock* block, HttpHeaderBlock::MapType::iterator lookup_result,
const absl::string_view key, size_t* spdy_header_block_value_size)
: block_(block),
lookup_result_(lookup_result),
@@ -106,7 +106,7 @@
spdy_header_block_value_size_(spdy_header_block_value_size),
valid_(true) {}
-Http2HeaderBlock::ValueProxy::ValueProxy(ValueProxy&& other)
+HttpHeaderBlock::ValueProxy::ValueProxy(ValueProxy&& other)
: block_(other.block_),
lookup_result_(other.lookup_result_),
key_(other.key_),
@@ -115,8 +115,8 @@
other.valid_ = false;
}
-Http2HeaderBlock::ValueProxy& Http2HeaderBlock::ValueProxy::operator=(
- Http2HeaderBlock::ValueProxy&& other) {
+HttpHeaderBlock::ValueProxy& HttpHeaderBlock::ValueProxy::operator=(
+ HttpHeaderBlock::ValueProxy&& other) {
block_ = other.block_;
lookup_result_ = other.lookup_result_;
key_ = other.key_;
@@ -126,20 +126,20 @@
return *this;
}
-Http2HeaderBlock::ValueProxy::~ValueProxy() {
+HttpHeaderBlock::ValueProxy::~ValueProxy() {
// If the ValueProxy is destroyed while lookup_result_ == block_->end(),
- // the assignment operator was never used, and the block's Http2HeaderStorage
+ // the assignment operator was never used, and the block's HttpHeaderStorage
// can reclaim the memory used by the key. This makes lookup-only access to
- // Http2HeaderBlock through operator[] memory-neutral.
+ // HttpHeaderBlock through operator[] memory-neutral.
if (valid_ && lookup_result_ == block_->map_.end()) {
block_->storage_.Rewind(key_);
}
}
-Http2HeaderBlock::ValueProxy& Http2HeaderBlock::ValueProxy::operator=(
+HttpHeaderBlock::ValueProxy& HttpHeaderBlock::ValueProxy::operator=(
absl::string_view value) {
*spdy_header_block_value_size_ += value.size();
- Http2HeaderStorage* storage = &block_->storage_;
+ HttpHeaderStorage* storage = &block_->storage_;
if (lookup_result_ == block_->map_.end()) {
QUICHE_DVLOG(1) << "Inserting: (" << key_ << ", " << value << ")";
lookup_result_ =
@@ -155,7 +155,7 @@
return *this;
}
-bool Http2HeaderBlock::ValueProxy::operator==(absl::string_view value) const {
+bool HttpHeaderBlock::ValueProxy::operator==(absl::string_view value) const {
if (lookup_result_ == block_->map_.end()) {
return false;
} else {
@@ -163,7 +163,7 @@
}
}
-std::string Http2HeaderBlock::ValueProxy::as_string() const {
+std::string HttpHeaderBlock::ValueProxy::as_string() const {
if (lookup_result_ == block_->map_.end()) {
return "";
} else {
@@ -171,9 +171,9 @@
}
}
-Http2HeaderBlock::Http2HeaderBlock() : map_(kInitialMapBuckets) {}
+HttpHeaderBlock::HttpHeaderBlock() : map_(kInitialMapBuckets) {}
-Http2HeaderBlock::Http2HeaderBlock(Http2HeaderBlock&& other)
+HttpHeaderBlock::HttpHeaderBlock(HttpHeaderBlock&& other)
: map_(kInitialMapBuckets) {
map_.swap(other.map_);
storage_ = std::move(other.storage_);
@@ -184,9 +184,9 @@
value_size_ = other.value_size_;
}
-Http2HeaderBlock::~Http2HeaderBlock() = default;
+HttpHeaderBlock::~HttpHeaderBlock() = default;
-Http2HeaderBlock& Http2HeaderBlock::operator=(Http2HeaderBlock&& other) {
+HttpHeaderBlock& HttpHeaderBlock::operator=(HttpHeaderBlock&& other) {
map_.swap(other.map_);
storage_ = std::move(other.storage_);
for (auto& p : map_) {
@@ -197,23 +197,23 @@
return *this;
}
-Http2HeaderBlock Http2HeaderBlock::Clone() const {
- Http2HeaderBlock copy;
+HttpHeaderBlock HttpHeaderBlock::Clone() const {
+ HttpHeaderBlock copy;
for (const auto& p : *this) {
copy.AppendHeader(p.first, p.second);
}
return copy;
}
-bool Http2HeaderBlock::operator==(const Http2HeaderBlock& other) const {
+bool HttpHeaderBlock::operator==(const HttpHeaderBlock& other) const {
return size() == other.size() && std::equal(begin(), end(), other.begin());
}
-bool Http2HeaderBlock::operator!=(const Http2HeaderBlock& other) const {
+bool HttpHeaderBlock::operator!=(const HttpHeaderBlock& other) const {
return !(operator==(other));
}
-std::string Http2HeaderBlock::DebugString() const {
+std::string HttpHeaderBlock::DebugString() const {
if (empty()) {
return "{}";
}
@@ -226,7 +226,7 @@
return output;
}
-void Http2HeaderBlock::erase(absl::string_view key) {
+void HttpHeaderBlock::erase(absl::string_view key) {
auto iter = map_.find(key);
if (iter != map_.end()) {
QUICHE_DVLOG(1) << "Erasing header with name: " << key;
@@ -236,14 +236,14 @@
}
}
-void Http2HeaderBlock::clear() {
+void HttpHeaderBlock::clear() {
key_size_ = 0;
value_size_ = 0;
map_.clear();
storage_.Clear();
}
-void Http2HeaderBlock::insert(const Http2HeaderBlock::value_type& value) {
+void HttpHeaderBlock::insert(const HttpHeaderBlock::value_type& value) {
// TODO(birenroy): Write new value in place of old value, if it fits.
value_size_ += value.second.size();
@@ -261,7 +261,7 @@
}
}
-Http2HeaderBlock::ValueProxy Http2HeaderBlock::operator[](
+HttpHeaderBlock::ValueProxy HttpHeaderBlock::operator[](
const absl::string_view key) {
QUICHE_DVLOG(2) << "Operator[] saw key: " << key;
absl::string_view out_key;
@@ -279,8 +279,8 @@
return ValueProxy(this, iter, out_key, &value_size_);
}
-void Http2HeaderBlock::AppendValueOrAddHeader(const absl::string_view key,
- const absl::string_view value) {
+void HttpHeaderBlock::AppendValueOrAddHeader(const absl::string_view key,
+ const absl::string_view value) {
value_size_ += value.size();
auto iter = map_.find(key);
@@ -296,20 +296,20 @@
iter->second.Append(storage_.Write(value));
}
-void Http2HeaderBlock::AppendHeader(const absl::string_view key,
- const absl::string_view value) {
+void HttpHeaderBlock::AppendHeader(const absl::string_view key,
+ const absl::string_view value) {
auto backed_key = WriteKey(key);
map_.emplace(std::make_pair(
backed_key, HeaderValue(&storage_, backed_key, storage_.Write(value))));
}
-absl::string_view Http2HeaderBlock::WriteKey(const absl::string_view key) {
+absl::string_view HttpHeaderBlock::WriteKey(const absl::string_view key) {
key_size_ += key.size();
return storage_.Write(key);
}
-size_t Http2HeaderBlock::bytes_allocated() const {
+size_t HttpHeaderBlock::bytes_allocated() const {
return storage_.bytes_allocated();
}
-} // namespace spdy
+} // namespace quiche
diff --git a/quiche/common/http/http_header_block.h b/quiche/common/http/http_header_block.h
new file mode 100644
index 0000000..bebf481
--- /dev/null
+++ b/quiche/common/http/http_header_block.h
@@ -0,0 +1,296 @@
+// Copyright (c) 2012 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_COMMON_HTTP_HTTP_HEADER_BLOCK_H_
+#define QUICHE_COMMON_HTTP_HTTP_HEADER_BLOCK_H_
+
+#include <stddef.h>
+
+#include <functional>
+#include <list>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/http/http_header_storage.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+#include "quiche/common/quiche_text_utils.h"
+
+namespace quiche {
+
+namespace test {
+class HttpHeaderBlockPeer;
+class ValueProxyPeer;
+} // namespace test
+
+#ifndef SPDY_HEADER_DEBUG
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define SPDY_HEADER_DEBUG 1
+#else // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define SPDY_HEADER_DEBUG 0
+#endif // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#endif // SPDY_HEADER_DEBUG
+
+// This class provides a key-value map that can be used to store SPDY header
+// names and values. This data structure preserves insertion order.
+//
+// Under the hood, this data structure uses large, contiguous blocks of memory
+// to store names and values. Lookups may be performed with absl::string_view
+// keys, and values are returned as absl::string_views (via ValueProxy, below).
+// Value absl::string_views are valid as long as the HttpHeaderBlock exists;
+// allocated memory is never freed until HttpHeaderBlock's destruction.
+//
+// This implementation does not make much of an effort to minimize wasted space.
+// It's expected that keys are rarely deleted from a HttpHeaderBlock.
+class QUICHE_EXPORT HttpHeaderBlock {
+ private:
+ // Stores a list of value fragments that can be joined later with a
+ // key-dependent separator.
+ class QUICHE_EXPORT HeaderValue {
+ public:
+ HeaderValue(HttpHeaderStorage* storage, absl::string_view key,
+ absl::string_view initial_value);
+
+ // Moves are allowed.
+ HeaderValue(HeaderValue&& other);
+ HeaderValue& operator=(HeaderValue&& other);
+
+ void set_storage(HttpHeaderStorage* storage);
+
+ // Copies are not.
+ HeaderValue(const HeaderValue& other) = delete;
+ HeaderValue& operator=(const HeaderValue& other) = delete;
+
+ ~HeaderValue();
+
+ // Consumes at most |fragment.size()| bytes of memory.
+ void Append(absl::string_view fragment);
+
+ absl::string_view value() const { return as_pair().second; }
+ const std::pair<absl::string_view, absl::string_view>& as_pair() const;
+
+ // Size estimate including separators. Used when keys are erased from
+ // HttpHeaderBlock.
+ size_t SizeEstimate() const { return size_; }
+
+ private:
+ // May allocate a large contiguous region of memory to hold the concatenated
+ // fragments and separators.
+ absl::string_view ConsolidatedValue() const;
+
+ mutable HttpHeaderStorage* storage_;
+ mutable std::vector<absl::string_view> fragments_;
+ // The first element is the key; the second is the consolidated value.
+ mutable std::pair<absl::string_view, absl::string_view> pair_;
+ size_t size_ = 0;
+ size_t separator_size_ = 0;
+ };
+
+ typedef quiche::QuicheLinkedHashMap<absl::string_view, HeaderValue,
+ quiche::StringPieceCaseHash,
+ quiche::StringPieceCaseEqual>
+ MapType;
+
+ public:
+ typedef std::pair<absl::string_view, absl::string_view> value_type;
+
+ // Provides iteration over a sequence of std::pair<absl::string_view,
+ // absl::string_view>, even though the underlying MapType::value_type is
+ // different. Dereferencing the iterator will result in memory allocation for
+ // multi-value headers.
+ class QUICHE_EXPORT iterator {
+ public:
+ // The following type definitions fulfill the requirements for iterator
+ // implementations.
+ typedef std::pair<absl::string_view, absl::string_view> value_type;
+ typedef value_type& reference;
+ typedef value_type* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef MapType::iterator::difference_type difference_type;
+
+ // In practice, this iterator only offers access to const value_type.
+ typedef const value_type& const_reference;
+ typedef const value_type* const_pointer;
+
+ explicit iterator(MapType::const_iterator it);
+ iterator(const iterator& other);
+ ~iterator();
+
+ // This will result in memory allocation if the value consists of multiple
+ // fragments.
+ const_reference operator*() const {
+#if SPDY_HEADER_DEBUG
+ QUICHE_CHECK(!dereference_forbidden_);
+#endif // SPDY_HEADER_DEBUG
+ return it_->second.as_pair();
+ }
+
+ const_pointer operator->() const { return &(this->operator*()); }
+ bool operator==(const iterator& it) const { return it_ == it.it_; }
+ bool operator!=(const iterator& it) const { return !(*this == it); }
+
+ iterator& operator++() {
+ it_++;
+ return *this;
+ }
+
+ iterator operator++(int) {
+ auto ret = *this;
+ this->operator++();
+ return ret;
+ }
+
+#if SPDY_HEADER_DEBUG
+ void forbid_dereference() { dereference_forbidden_ = true; }
+#endif // SPDY_HEADER_DEBUG
+
+ private:
+ MapType::const_iterator it_;
+#if SPDY_HEADER_DEBUG
+ bool dereference_forbidden_ = false;
+#endif // SPDY_HEADER_DEBUG
+ };
+ typedef iterator const_iterator;
+
+ HttpHeaderBlock();
+ HttpHeaderBlock(const HttpHeaderBlock& other) = delete;
+ HttpHeaderBlock(HttpHeaderBlock&& other);
+ ~HttpHeaderBlock();
+
+ HttpHeaderBlock& operator=(const HttpHeaderBlock& other) = delete;
+ HttpHeaderBlock& operator=(HttpHeaderBlock&& other);
+ HttpHeaderBlock Clone() const;
+
+ bool operator==(const HttpHeaderBlock& other) const;
+ bool operator!=(const HttpHeaderBlock& other) const;
+
+ // Provides a human readable multi-line representation of the stored header
+ // keys and values.
+ std::string DebugString() const;
+
+ iterator begin() { return wrap_iterator(map_.begin()); }
+ iterator end() { return wrap_iterator(map_.end()); }
+ const_iterator begin() const { return wrap_const_iterator(map_.begin()); }
+ const_iterator end() const { return wrap_const_iterator(map_.end()); }
+ bool empty() const { return map_.empty(); }
+ size_t size() const { return map_.size(); }
+ iterator find(absl::string_view key) { return wrap_iterator(map_.find(key)); }
+ const_iterator find(absl::string_view key) const {
+ return wrap_const_iterator(map_.find(key));
+ }
+ bool contains(absl::string_view key) const { return find(key) != end(); }
+ void erase(absl::string_view key);
+
+ // Clears both our MapType member and the memory used to hold headers.
+ void clear();
+
+ // The next few methods copy data into our backing storage.
+
+ // If key already exists in the block, replaces the value of that key. Else
+ // adds a new header to the end of the block.
+ void insert(const value_type& value);
+
+ // If a header with the key is already present, then append the value to the
+ // existing header value, NUL ("\0") separated unless the key is cookie, in
+ // which case the separator is "; ".
+ // If there is no such key, a new header with the key and value is added.
+ void AppendValueOrAddHeader(const absl::string_view key,
+ const absl::string_view value);
+
+ // This object provides automatic conversions that allow HttpHeaderBlock to
+ // be nearly a drop-in replacement for a linked hash map with string keys and
+ // values. It reads data from or writes data to a HttpHeaderStorage.
+ class QUICHE_EXPORT ValueProxy {
+ public:
+ ~ValueProxy();
+
+ // Moves are allowed.
+ ValueProxy(ValueProxy&& other);
+ ValueProxy& operator=(ValueProxy&& other);
+
+ // Copies are not.
+ ValueProxy(const ValueProxy& other) = delete;
+ ValueProxy& operator=(const ValueProxy& other) = delete;
+
+ // Assignment modifies the underlying HttpHeaderBlock.
+ ValueProxy& operator=(absl::string_view value);
+
+ // Provides easy comparison against absl::string_view.
+ bool operator==(absl::string_view value) const;
+
+ std::string as_string() const;
+
+ private:
+ friend class HttpHeaderBlock;
+ friend class test::ValueProxyPeer;
+
+ ValueProxy(HttpHeaderBlock* block,
+ HttpHeaderBlock::MapType::iterator lookup_result,
+ const absl::string_view key,
+ size_t* spdy_header_block_value_size);
+
+ HttpHeaderBlock* block_;
+ HttpHeaderBlock::MapType::iterator lookup_result_;
+ absl::string_view key_;
+ size_t* spdy_header_block_value_size_;
+ bool valid_;
+ };
+
+ // Allows either lookup or mutation of the value associated with a key.
+ ABSL_MUST_USE_RESULT ValueProxy operator[](const absl::string_view key);
+
+ size_t TotalBytesUsed() const { return key_size_ + value_size_; }
+
+ private:
+ friend class test::HttpHeaderBlockPeer;
+
+ inline iterator wrap_iterator(MapType::const_iterator inner_iterator) const {
+#if SPDY_HEADER_DEBUG
+ iterator outer_iterator(inner_iterator);
+ if (inner_iterator == map_.end()) {
+ outer_iterator.forbid_dereference();
+ }
+ return outer_iterator;
+#else // SPDY_HEADER_DEBUG
+ return iterator(inner_iterator);
+#endif // SPDY_HEADER_DEBUG
+ }
+
+ inline const_iterator wrap_const_iterator(
+ MapType::const_iterator inner_iterator) const {
+#if SPDY_HEADER_DEBUG
+ const_iterator outer_iterator(inner_iterator);
+ if (inner_iterator == map_.end()) {
+ outer_iterator.forbid_dereference();
+ }
+ return outer_iterator;
+#else // SPDY_HEADER_DEBUG
+ return iterator(inner_iterator);
+#endif // SPDY_HEADER_DEBUG
+ }
+
+ void AppendHeader(const absl::string_view key, const absl::string_view value);
+ absl::string_view WriteKey(const absl::string_view key);
+ size_t bytes_allocated() const;
+
+ // absl::string_views held by |map_| point to memory owned by |storage_|.
+ MapType map_;
+ HttpHeaderStorage storage_;
+
+ size_t key_size_ = 0;
+ size_t value_size_ = 0;
+};
+
+inline bool operator==(absl::string_view lhs,
+ const HttpHeaderBlock::ValueProxy& rhs) {
+ return rhs == lhs;
+}
+
+} // namespace quiche
+
+#endif // QUICHE_COMMON_HTTP_HTTP_HEADER_BLOCK_H_
diff --git a/quiche/spdy/core/http2_header_block_test.cc b/quiche/common/http/http_header_block_test.cc
similarity index 76%
rename from quiche/spdy/core/http2_header_block_test.cc
rename to quiche/common/http/http_header_block_test.cc
index ff6cfab..7efc197 100644
--- a/quiche/spdy/core/http2_header_block_test.cc
+++ b/quiche/common/http/http_header_block_test.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "quiche/spdy/core/http2_header_block.h"
+#include "quiche/common/http/http_header_block.h"
#include <memory>
#include <utility>
@@ -12,12 +12,12 @@
using ::testing::ElementsAre;
-namespace spdy {
+namespace quiche {
namespace test {
class ValueProxyPeer {
public:
- static absl::string_view key(Http2HeaderBlock::ValueProxy* p) {
+ static absl::string_view key(HttpHeaderBlock::ValueProxy* p) {
return p->key_;
}
};
@@ -27,9 +27,9 @@
return std::make_pair(k, v);
}
-// This test verifies that Http2HeaderBlock behaves correctly when empty.
-TEST(Http2HeaderBlockTest, EmptyBlock) {
- Http2HeaderBlock block;
+// This test verifies that HttpHeaderBlock behaves correctly when empty.
+TEST(HttpHeaderBlockTest, EmptyBlock) {
+ HttpHeaderBlock block;
EXPECT_TRUE(block.empty());
EXPECT_EQ(0u, block.size());
EXPECT_EQ(block.end(), block.find("foo"));
@@ -40,8 +40,8 @@
block.erase("bar");
}
-TEST(Http2HeaderBlockTest, KeyMemoryReclaimedOnLookup) {
- Http2HeaderBlock block;
+TEST(HttpHeaderBlockTest, KeyMemoryReclaimedOnLookup) {
+ HttpHeaderBlock block;
absl::string_view copied_key1;
{
auto proxy1 = block["some key name"];
@@ -63,7 +63,7 @@
block["some other key name"] = "some value";
}
// Nothing should blow up when proxy1 is destructed, and we should be able to
- // modify and access the Http2HeaderBlock.
+ // modify and access the HttpHeaderBlock.
block["key"] = "value";
EXPECT_EQ("value", block["key"]);
EXPECT_EQ("some value", block["some other key name"]);
@@ -71,8 +71,8 @@
}
// This test verifies that headers can be set in a variety of ways.
-TEST(Http2HeaderBlockTest, AddHeaders) {
- Http2HeaderBlock block;
+TEST(HttpHeaderBlockTest, AddHeaders) {
+ HttpHeaderBlock block;
block["foo"] = std::string(300, 'x');
block["bar"] = "baz";
block["qux"] = "qux1";
@@ -91,29 +91,29 @@
EXPECT_EQ(block.end(), block.find("key"));
}
-// This test verifies that Http2HeaderBlock can be copied using Clone().
-TEST(Http2HeaderBlockTest, CopyBlocks) {
- Http2HeaderBlock block1;
+// This test verifies that HttpHeaderBlock can be copied using Clone().
+TEST(HttpHeaderBlockTest, CopyBlocks) {
+ HttpHeaderBlock block1;
block1["foo"] = std::string(300, 'x');
block1["bar"] = "baz";
block1.insert(std::make_pair("qux", "qux1"));
- Http2HeaderBlock block2 = block1.Clone();
- Http2HeaderBlock block3(block1.Clone());
+ HttpHeaderBlock block2 = block1.Clone();
+ HttpHeaderBlock block3(block1.Clone());
EXPECT_EQ(block1, block2);
EXPECT_EQ(block1, block3);
}
-TEST(Http2HeaderBlockTest, Equality) {
+TEST(HttpHeaderBlockTest, Equality) {
// Test equality and inequality operators.
- Http2HeaderBlock block1;
+ HttpHeaderBlock block1;
block1["foo"] = "bar";
- Http2HeaderBlock block2;
+ HttpHeaderBlock block2;
block2["foo"] = "bar";
- Http2HeaderBlock block3;
+ HttpHeaderBlock block3;
block3["baz"] = "qux";
EXPECT_EQ(block1, block2);
@@ -123,28 +123,28 @@
EXPECT_NE(block1, block2);
}
-Http2HeaderBlock ReturnTestHeaderBlock() {
- Http2HeaderBlock block;
+HttpHeaderBlock ReturnTestHeaderBlock() {
+ HttpHeaderBlock block;
block["foo"] = "bar";
block.insert(std::make_pair("foo2", "baz"));
return block;
}
// Test that certain methods do not crash on moved-from instances.
-TEST(Http2HeaderBlockTest, MovedFromIsValid) {
- Http2HeaderBlock block1;
+TEST(HttpHeaderBlockTest, MovedFromIsValid) {
+ HttpHeaderBlock block1;
block1["foo"] = "bar";
- Http2HeaderBlock block2(std::move(block1));
+ HttpHeaderBlock block2(std::move(block1));
EXPECT_THAT(block2, ElementsAre(Pair("foo", "bar")));
block1["baz"] = "qux"; // NOLINT testing post-move behavior
- Http2HeaderBlock block3(std::move(block1));
+ HttpHeaderBlock block3(std::move(block1));
block1["foo"] = "bar"; // NOLINT testing post-move behavior
- Http2HeaderBlock block4(std::move(block1));
+ HttpHeaderBlock block4(std::move(block1));
block1.clear(); // NOLINT testing post-move behavior
EXPECT_TRUE(block1.empty());
@@ -152,7 +152,7 @@
block1["foo"] = "bar";
EXPECT_THAT(block1, ElementsAre(Pair("foo", "bar")));
- Http2HeaderBlock block5 = ReturnTestHeaderBlock();
+ HttpHeaderBlock block5 = ReturnTestHeaderBlock();
block5.AppendValueOrAddHeader("foo", "bar2");
EXPECT_THAT(block5, ElementsAre(Pair("foo", std::string("bar\0bar2", 8)),
Pair("foo2", "baz")));
@@ -160,8 +160,8 @@
// This test verifies that headers can be appended to no matter how they were
// added originally.
-TEST(Http2HeaderBlockTest, AppendHeaders) {
- Http2HeaderBlock block;
+TEST(HttpHeaderBlockTest, AppendHeaders) {
+ HttpHeaderBlock block;
block["foo"] = "foo";
block.AppendValueOrAddHeader("foo", "bar");
EXPECT_EQ(Pair("foo", std::string("foo\0bar", 7)), *block.find("foo"));
@@ -199,8 +199,8 @@
EXPECT_EQ(std::string("yummy\0scrumptious", 17), block["set-cookie"]);
}
-TEST(Http2HeaderBlockTest, CompareValueToStringPiece) {
- Http2HeaderBlock block;
+TEST(HttpHeaderBlockTest, CompareValueToStringPiece) {
+ HttpHeaderBlock block;
block["foo"] = "foo";
block.AppendValueOrAddHeader("foo", "bar");
const auto& val = block["foo"];
@@ -220,10 +220,10 @@
EXPECT_FALSE(val2 == absl::string_view(""));
}
-// This test demonstrates that the Http2HeaderBlock data structure does not
+// This test demonstrates that the HttpHeaderBlock data structure does not
// place any limitations on the characters present in the header names.
-TEST(Http2HeaderBlockTest, UpperCaseNames) {
- Http2HeaderBlock block;
+TEST(HttpHeaderBlockTest, UpperCaseNames) {
+ HttpHeaderBlock block;
block["Foo"] = "foo";
block.AppendValueOrAddHeader("Foo", "bar");
EXPECT_NE(block.end(), block.find("foo"));
@@ -237,7 +237,7 @@
}
namespace {
-size_t Http2HeaderBlockSize(const Http2HeaderBlock& block) {
+size_t HttpHeaderBlockSize(const HttpHeaderBlock& block) {
size_t size = 0;
for (const auto& pair : block) {
size += pair.first.size() + pair.second.size();
@@ -246,38 +246,38 @@
}
} // namespace
-// Tests Http2HeaderBlock SizeEstimate().
-TEST(Http2HeaderBlockTest, TotalBytesUsed) {
- Http2HeaderBlock block;
+// Tests HttpHeaderBlock SizeEstimate().
+TEST(HttpHeaderBlockTest, TotalBytesUsed) {
+ HttpHeaderBlock block;
const size_t value_size = 300;
block["foo"] = std::string(value_size, 'x');
- EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+ EXPECT_EQ(block.TotalBytesUsed(), HttpHeaderBlockSize(block));
block.insert(std::make_pair("key", std::string(value_size, 'x')));
- EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+ EXPECT_EQ(block.TotalBytesUsed(), HttpHeaderBlockSize(block));
block.AppendValueOrAddHeader("abc", std::string(value_size, 'x'));
- EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+ EXPECT_EQ(block.TotalBytesUsed(), HttpHeaderBlockSize(block));
// Replace value for existing key.
block["foo"] = std::string(value_size, 'x');
- EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+ EXPECT_EQ(block.TotalBytesUsed(), HttpHeaderBlockSize(block));
block.insert(std::make_pair("key", std::string(value_size, 'x')));
- EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+ EXPECT_EQ(block.TotalBytesUsed(), HttpHeaderBlockSize(block));
// Add value for existing key.
block.AppendValueOrAddHeader("abc", std::string(value_size, 'x'));
- EXPECT_EQ(block.TotalBytesUsed(), Http2HeaderBlockSize(block));
+ EXPECT_EQ(block.TotalBytesUsed(), HttpHeaderBlockSize(block));
- // Copies/clones Http2HeaderBlock.
+ // Copies/clones HttpHeaderBlock.
size_t block_size = block.TotalBytesUsed();
- Http2HeaderBlock block_copy = std::move(block);
+ HttpHeaderBlock block_copy = std::move(block);
EXPECT_EQ(block_size, block_copy.TotalBytesUsed());
// Erases key.
block_copy.erase("foo");
- EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy));
+ EXPECT_EQ(block_copy.TotalBytesUsed(), HttpHeaderBlockSize(block_copy));
block_copy.erase("key");
- EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy));
+ EXPECT_EQ(block_copy.TotalBytesUsed(), HttpHeaderBlockSize(block_copy));
block_copy.erase("abc");
- EXPECT_EQ(block_copy.TotalBytesUsed(), Http2HeaderBlockSize(block_copy));
+ EXPECT_EQ(block_copy.TotalBytesUsed(), HttpHeaderBlockSize(block_copy));
}
// The order of header fields is preserved. Note that all pseudo-header fields
@@ -286,8 +286,8 @@
// https://www.rfc-editor.org/rfc/rfc9114.html#name-http-control-data. It is
// the responsibility of the higher layer to add header fields in the correct
// order.
-TEST(Http2HeaderBlockTest, OrderPreserved) {
- Http2HeaderBlock block;
+TEST(HttpHeaderBlockTest, OrderPreserved) {
+ HttpHeaderBlock block;
block[":method"] = "GET";
block["foo"] = "bar";
block[":path"] = "/";
@@ -297,4 +297,4 @@
}
} // namespace test
-} // namespace spdy
+} // namespace quiche
diff --git a/quiche/spdy/core/http2_header_storage.cc b/quiche/common/http/http_header_storage.cc
similarity index 75%
rename from quiche/spdy/core/http2_header_storage.cc
rename to quiche/common/http/http_header_storage.cc
index 653a628..d15c40e 100644
--- a/quiche/spdy/core/http2_header_storage.cc
+++ b/quiche/common/http/http_header_storage.cc
@@ -1,28 +1,28 @@
-#include "quiche/spdy/core/http2_header_storage.h"
+#include "quiche/common/http/http_header_storage.h"
#include <cstring>
#include "quiche/common/platform/api/quiche_logging.h"
-namespace spdy {
+namespace quiche {
namespace {
-// Http2HeaderStorage allocates blocks of this size by default.
+// HttpHeaderStorage allocates blocks of this size by default.
const size_t kDefaultStorageBlockSize = 2048;
} // namespace
-Http2HeaderStorage::Http2HeaderStorage() : arena_(kDefaultStorageBlockSize) {}
+HttpHeaderStorage::HttpHeaderStorage() : arena_(kDefaultStorageBlockSize) {}
-absl::string_view Http2HeaderStorage::Write(const absl::string_view s) {
+absl::string_view HttpHeaderStorage::Write(const absl::string_view s) {
return absl::string_view(arena_.Memdup(s.data(), s.size()), s.size());
}
-void Http2HeaderStorage::Rewind(const absl::string_view s) {
+void HttpHeaderStorage::Rewind(const absl::string_view s) {
arena_.Free(const_cast<char*>(s.data()), s.size());
}
-absl::string_view Http2HeaderStorage::WriteFragments(
+absl::string_view HttpHeaderStorage::WriteFragments(
const std::vector<absl::string_view>& fragments,
absl::string_view separator) {
if (fragments.empty()) {
@@ -56,4 +56,4 @@
return dst - original_dst;
}
-} // namespace spdy
+} // namespace quiche
diff --git a/quiche/spdy/core/http2_header_storage.h b/quiche/common/http/http_header_storage.h
similarity index 65%
rename from quiche/spdy/core/http2_header_storage.h
rename to quiche/common/http/http_header_storage.h
index bc275b3..036fc1c 100644
--- a/quiche/spdy/core/http2_header_storage.h
+++ b/quiche/common/http/http_header_storage.h
@@ -1,30 +1,30 @@
-#ifndef QUICHE_SPDY_CORE_HTTP2_HEADER_STORAGE_H_
-#define QUICHE_SPDY_CORE_HTTP2_HEADER_STORAGE_H_
+#ifndef QUICHE_COMMON_HTTP_HTTP_HEADER_STORAGE_H_
+#define QUICHE_COMMON_HTTP_HTTP_HEADER_STORAGE_H_
#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_export.h"
-#include "quiche/spdy/core/spdy_simple_arena.h"
+#include "quiche/common/quiche_simple_arena.h"
-namespace spdy {
+namespace quiche {
// This class provides a backing store for absl::string_views. It previously
// used custom allocation logic, but now uses an UnsafeArena instead. It has the
-// property that absl::string_views that refer to data in Http2HeaderStorage are
-// never invalidated until the Http2HeaderStorage is deleted or Clear() is
+// property that absl::string_views that refer to data in HttpHeaderStorage are
+// never invalidated until the HttpHeaderStorage is deleted or Clear() is
// called.
//
// Write operations always append to the last block. If there is not enough
// space to perform the write, a new block is allocated, and any unused space
// is wasted.
-class QUICHE_EXPORT Http2HeaderStorage {
+class QUICHE_EXPORT HttpHeaderStorage {
public:
- Http2HeaderStorage();
+ HttpHeaderStorage();
- Http2HeaderStorage(const Http2HeaderStorage&) = delete;
- Http2HeaderStorage& operator=(const Http2HeaderStorage&) = delete;
+ HttpHeaderStorage(const HttpHeaderStorage&) = delete;
+ HttpHeaderStorage& operator=(const HttpHeaderStorage&) = delete;
- Http2HeaderStorage(Http2HeaderStorage&& other) = default;
- Http2HeaderStorage& operator=(Http2HeaderStorage&& other) = default;
+ HttpHeaderStorage(HttpHeaderStorage&& other) = default;
+ HttpHeaderStorage& operator=(HttpHeaderStorage&& other) = default;
absl::string_view Write(absl::string_view s);
@@ -44,7 +44,7 @@
size_t bytes_allocated() const { return arena_.status().bytes_allocated(); }
private:
- SpdySimpleArena arena_;
+ QuicheSimpleArena arena_;
};
// Writes |fragments| to |dst|, joined by |separator|. |dst| must be large
@@ -53,6 +53,6 @@
const std::vector<absl::string_view>& fragments,
absl::string_view separator);
-} // namespace spdy
+} // namespace quiche
-#endif // QUICHE_SPDY_CORE_HTTP2_HEADER_STORAGE_H_
+#endif // QUICHE_COMMON_HTTP_HTTP_HEADER_STORAGE_H_
diff --git a/quiche/spdy/core/http2_header_storage_test.cc b/quiche/common/http/http_header_storage_test.cc
similarity index 89%
rename from quiche/spdy/core/http2_header_storage_test.cc
rename to quiche/common/http/http_header_storage_test.cc
index bfe9b5e..daf19bd 100644
--- a/quiche/spdy/core/http2_header_storage_test.cc
+++ b/quiche/common/http/http_header_storage_test.cc
@@ -1,8 +1,8 @@
-#include "quiche/spdy/core/http2_header_storage.h"
+#include "quiche/common/http/http_header_storage.h"
#include "quiche/common/platform/api/quiche_test.h"
-namespace spdy {
+namespace quiche {
namespace test {
TEST(JoinTest, JoinEmpty) {
@@ -32,4 +32,4 @@
}
} // namespace test
-} // namespace spdy
+} // namespace quiche
diff --git a/quiche/spdy/core/spdy_simple_arena.cc b/quiche/common/quiche_simple_arena.cc
similarity index 63%
rename from quiche/spdy/core/spdy_simple_arena.cc
rename to quiche/common/quiche_simple_arena.cc
index 0b3b798..b8706a7 100644
--- a/quiche/spdy/core/spdy_simple_arena.cc
+++ b/quiche/common/quiche_simple_arena.cc
@@ -2,23 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "quiche/spdy/core/spdy_simple_arena.h"
+#include "quiche/common/quiche_simple_arena.h"
#include <algorithm>
#include <cstring>
#include "quiche/common/platform/api/quiche_logging.h"
-namespace spdy {
+namespace quiche {
-SpdySimpleArena::SpdySimpleArena(size_t block_size) : block_size_(block_size) {}
+QuicheSimpleArena::QuicheSimpleArena(size_t block_size)
+ : block_size_(block_size) {}
-SpdySimpleArena::~SpdySimpleArena() = default;
+QuicheSimpleArena::~QuicheSimpleArena() = default;
-SpdySimpleArena::SpdySimpleArena(SpdySimpleArena&& other) = default;
-SpdySimpleArena& SpdySimpleArena::operator=(SpdySimpleArena&& other) = default;
+QuicheSimpleArena::QuicheSimpleArena(QuicheSimpleArena&& other) = default;
+QuicheSimpleArena& QuicheSimpleArena::operator=(QuicheSimpleArena&& other) =
+ default;
-char* SpdySimpleArena::Alloc(size_t size) {
+char* QuicheSimpleArena::Alloc(size_t size) {
Reserve(size);
Block& b = blocks_.back();
QUICHE_DCHECK_GE(b.size, b.used + size);
@@ -27,7 +29,8 @@
return out;
}
-char* SpdySimpleArena::Realloc(char* original, size_t oldsize, size_t newsize) {
+char* QuicheSimpleArena::Realloc(char* original, size_t oldsize,
+ size_t newsize) {
QUICHE_DCHECK(!blocks_.empty());
Block& last = blocks_.back();
if (last.data.get() <= original && original < last.data.get() + last.size) {
@@ -47,13 +50,13 @@
return out;
}
-char* SpdySimpleArena::Memdup(const char* data, size_t size) {
+char* QuicheSimpleArena::Memdup(const char* data, size_t size) {
char* out = Alloc(size);
memcpy(out, data, size);
return out;
}
-void SpdySimpleArena::Free(char* data, size_t size) {
+void QuicheSimpleArena::Free(char* data, size_t size) {
if (blocks_.empty()) {
return;
}
@@ -65,12 +68,12 @@
}
}
-void SpdySimpleArena::Reset() {
+void QuicheSimpleArena::Reset() {
blocks_.clear();
status_.bytes_allocated_ = 0;
}
-void SpdySimpleArena::Reserve(size_t additional_space) {
+void QuicheSimpleArena::Reserve(size_t additional_space) {
if (blocks_.empty()) {
AllocBlock(std::max(additional_space, block_size_));
} else {
@@ -81,26 +84,27 @@
}
}
-void SpdySimpleArena::AllocBlock(size_t size) {
+void QuicheSimpleArena::AllocBlock(size_t size) {
blocks_.push_back(Block(size));
status_.bytes_allocated_ += size;
}
-SpdySimpleArena::Block::Block(size_t s) : data(new char[s]), size(s), used(0) {}
+QuicheSimpleArena::Block::Block(size_t s)
+ : data(new char[s]), size(s), used(0) {}
-SpdySimpleArena::Block::~Block() = default;
+QuicheSimpleArena::Block::~Block() = default;
-SpdySimpleArena::Block::Block(SpdySimpleArena::Block&& other)
+QuicheSimpleArena::Block::Block(QuicheSimpleArena::Block&& other)
: size(other.size), used(other.used) {
data = std::move(other.data);
}
-SpdySimpleArena::Block& SpdySimpleArena::Block::operator=(
- SpdySimpleArena::Block&& other) {
+QuicheSimpleArena::Block& QuicheSimpleArena::Block::operator=(
+ QuicheSimpleArena::Block&& other) {
size = other.size;
used = other.used;
data = std::move(other.data);
return *this;
}
-} // namespace spdy
+} // namespace quiche
diff --git a/quiche/spdy/core/spdy_simple_arena.h b/quiche/common/quiche_simple_arena.h
similarity index 70%
rename from quiche/spdy/core/spdy_simple_arena.h
rename to quiche/common/quiche_simple_arena.h
index dae6879..79e899a 100644
--- a/quiche/spdy/core/spdy_simple_arena.h
+++ b/quiche/common/quiche_simple_arena.h
@@ -2,23 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef QUICHE_SPDY_CORE_SPDY_SIMPLE_ARENA_H_
-#define QUICHE_SPDY_CORE_SPDY_SIMPLE_ARENA_H_
+#ifndef QUICHE_COMMON_QUICHE_SIMPLE_ARENA_H_
+#define QUICHE_COMMON_QUICHE_SIMPLE_ARENA_H_
#include <memory>
#include <vector>
#include "quiche/common/platform/api/quiche_export.h"
-namespace spdy {
+namespace quiche {
// Allocates large blocks of memory, and doles them out in smaller chunks.
// Not thread-safe.
-class QUICHE_EXPORT SpdySimpleArena {
+class QUICHE_EXPORT QuicheSimpleArena {
public:
class QUICHE_EXPORT Status {
private:
- friend class SpdySimpleArena;
+ friend class QuicheSimpleArena;
size_t bytes_allocated_;
public:
@@ -27,17 +27,17 @@
};
// Blocks allocated by this arena will be at least |block_size| bytes.
- explicit SpdySimpleArena(size_t block_size);
- ~SpdySimpleArena();
+ explicit QuicheSimpleArena(size_t block_size);
+ ~QuicheSimpleArena();
// Copy and assign are not allowed.
- SpdySimpleArena() = delete;
- SpdySimpleArena(const SpdySimpleArena&) = delete;
- SpdySimpleArena& operator=(const SpdySimpleArena&) = delete;
+ QuicheSimpleArena() = delete;
+ QuicheSimpleArena(const QuicheSimpleArena&) = delete;
+ QuicheSimpleArena& operator=(const QuicheSimpleArena&) = delete;
// Move is allowed.
- SpdySimpleArena(SpdySimpleArena&& other);
- SpdySimpleArena& operator=(SpdySimpleArena&& other);
+ QuicheSimpleArena(QuicheSimpleArena&& other);
+ QuicheSimpleArena& operator=(QuicheSimpleArena&& other);
char* Alloc(size_t size);
char* Realloc(char* original, size_t oldsize, size_t newsize);
@@ -72,6 +72,6 @@
Status status_;
};
-} // namespace spdy
+} // namespace quiche
-#endif // QUICHE_SPDY_CORE_SPDY_SIMPLE_ARENA_H_
+#endif // QUICHE_COMMON_QUICHE_SIMPLE_ARENA_H_
diff --git a/quiche/spdy/core/spdy_simple_arena_test.cc b/quiche/common/quiche_simple_arena_test.cc
similarity index 83%
rename from quiche/spdy/core/spdy_simple_arena_test.cc
rename to quiche/common/quiche_simple_arena_test.cc
index 9708375..91ab2e4 100644
--- a/quiche/spdy/core/spdy_simple_arena_test.cc
+++ b/quiche/common/quiche_simple_arena_test.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "quiche/spdy/core/spdy_simple_arena.h"
+#include "quiche/common/quiche_simple_arena.h"
#include <string>
#include <vector>
@@ -10,19 +10,19 @@
#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_test.h"
-namespace spdy {
+namespace quiche {
namespace {
size_t kDefaultBlockSize = 2048;
const char kTestString[] = "This is a decently long test string.";
-TEST(SpdySimpleArenaTest, NoAllocationOnConstruction) {
- SpdySimpleArena arena(kDefaultBlockSize);
+TEST(QuicheSimpleArenaTest, NoAllocationOnConstruction) {
+ QuicheSimpleArena arena(kDefaultBlockSize);
EXPECT_EQ(0u, arena.status().bytes_allocated());
}
-TEST(SpdySimpleArenaTest, Memdup) {
- SpdySimpleArena arena(kDefaultBlockSize);
+TEST(QuicheSimpleArenaTest, Memdup) {
+ QuicheSimpleArena arena(kDefaultBlockSize);
const size_t length = strlen(kTestString);
char* c = arena.Memdup(kTestString, length);
EXPECT_NE(nullptr, c);
@@ -30,8 +30,8 @@
EXPECT_EQ(absl::string_view(c, length), kTestString);
}
-TEST(SpdySimpleArenaTest, MemdupLargeString) {
- SpdySimpleArena arena(10 /* block size */);
+TEST(QuicheSimpleArenaTest, MemdupLargeString) {
+ QuicheSimpleArena arena(10 /* block size */);
const size_t length = strlen(kTestString);
char* c = arena.Memdup(kTestString, length);
EXPECT_NE(nullptr, c);
@@ -39,8 +39,8 @@
EXPECT_EQ(absl::string_view(c, length), kTestString);
}
-TEST(SpdySimpleArenaTest, MultipleBlocks) {
- SpdySimpleArena arena(40 /* block size */);
+TEST(QuicheSimpleArenaTest, MultipleBlocks) {
+ QuicheSimpleArena arena(40 /* block size */);
std::vector<std::string> strings = {
"One decently long string.", "Another string.",
"A third string that will surely go in a different block."};
@@ -55,8 +55,8 @@
}
}
-TEST(SpdySimpleArenaTest, UseAfterReset) {
- SpdySimpleArena arena(kDefaultBlockSize);
+TEST(QuicheSimpleArenaTest, UseAfterReset) {
+ QuicheSimpleArena arena(kDefaultBlockSize);
const size_t length = strlen(kTestString);
char* c = arena.Memdup(kTestString, length);
arena.Reset();
@@ -66,8 +66,8 @@
EXPECT_EQ(absl::string_view(c, length), kTestString);
}
-TEST(SpdySimpleArenaTest, Free) {
- SpdySimpleArena arena(kDefaultBlockSize);
+TEST(QuicheSimpleArenaTest, Free) {
+ QuicheSimpleArena arena(kDefaultBlockSize);
const size_t length = strlen(kTestString);
// Freeing memory not owned by the arena should be a no-op, and freeing
// before any allocations from the arena should be a no-op.
@@ -92,8 +92,8 @@
EXPECT_EQ(c4, c5);
}
-TEST(SpdySimpleArenaTest, Alloc) {
- SpdySimpleArena arena(kDefaultBlockSize);
+TEST(QuicheSimpleArenaTest, Alloc) {
+ QuicheSimpleArena arena(kDefaultBlockSize);
const size_t length = strlen(kTestString);
char* c1 = arena.Alloc(length);
char* c2 = arena.Alloc(2 * length);
@@ -105,8 +105,8 @@
EXPECT_EQ(absl::string_view(c4, length), kTestString);
}
-TEST(SpdySimpleArenaTest, Realloc) {
- SpdySimpleArena arena(kDefaultBlockSize);
+TEST(QuicheSimpleArenaTest, Realloc) {
+ QuicheSimpleArena arena(kDefaultBlockSize);
const size_t length = strlen(kTestString);
// Simple realloc that fits in the block.
char* c1 = arena.Memdup(kTestString, length);
@@ -138,4 +138,4 @@
}
} // namespace
-} // namespace spdy
+} // namespace quiche
diff --git a/quiche/spdy/core/hpack/hpack_encoder_test.cc b/quiche/spdy/core/hpack/hpack_encoder_test.cc
index fe80ffe..b342780 100644
--- a/quiche/spdy/core/hpack/hpack_encoder_test.cc
+++ b/quiche/spdy/core/hpack/hpack_encoder_test.cc
@@ -10,8 +10,8 @@
#include "quiche/http2/hpack/huffman/hpack_huffman_encoder.h"
#include "quiche/http2/test_tools/http2_random.h"
#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_simple_arena.h"
#include "quiche/spdy/core/hpack/hpack_static_table.h"
-#include "quiche/spdy/core/spdy_simple_arena.h"
namespace spdy {
@@ -267,7 +267,7 @@
size_t cookie_c_index_;
size_t dynamic_table_insertions_;
- SpdySimpleArena headers_storage_;
+ quiche::QuicheSimpleArena headers_storage_;
std::vector<std::pair<absl::string_view, absl::string_view>>
headers_observed_;
diff --git a/quiche/spdy/core/http2_header_block.h b/quiche/spdy/core/http2_header_block.h
index e0da8f5..09e17a9 100644
--- a/quiche/spdy/core/http2_header_block.h
+++ b/quiche/spdy/core/http2_header_block.h
@@ -5,287 +5,10 @@
#ifndef QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_H_
#define QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_H_
-#include <stddef.h>
-
-#include <functional>
-#include <list>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/attributes.h"
-#include "quiche/common/platform/api/quiche_export.h"
-#include "quiche/common/platform/api/quiche_logging.h"
-#include "quiche/common/quiche_linked_hash_map.h"
-#include "quiche/common/quiche_text_utils.h"
-#include "quiche/spdy/core/http2_header_storage.h"
+#include "quiche/common/http/http_header_block.h"
namespace spdy {
-
-namespace test {
-class Http2HeaderBlockPeer;
-class ValueProxyPeer;
-} // namespace test
-
-#ifndef SPDY_HEADER_DEBUG
-#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define SPDY_HEADER_DEBUG 1
-#else // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define SPDY_HEADER_DEBUG 0
-#endif // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#endif // SPDY_HEADER_DEBUG
-
-// This class provides a key-value map that can be used to store SPDY header
-// names and values. This data structure preserves insertion order.
-//
-// Under the hood, this data structure uses large, contiguous blocks of memory
-// to store names and values. Lookups may be performed with absl::string_view
-// keys, and values are returned as absl::string_views (via ValueProxy, below).
-// Value absl::string_views are valid as long as the Http2HeaderBlock exists;
-// allocated memory is never freed until Http2HeaderBlock's destruction.
-//
-// This implementation does not make much of an effort to minimize wasted space.
-// It's expected that keys are rarely deleted from a Http2HeaderBlock.
-class QUICHE_EXPORT Http2HeaderBlock {
- private:
- // Stores a list of value fragments that can be joined later with a
- // key-dependent separator.
- class QUICHE_EXPORT HeaderValue {
- public:
- HeaderValue(Http2HeaderStorage* storage, absl::string_view key,
- absl::string_view initial_value);
-
- // Moves are allowed.
- HeaderValue(HeaderValue&& other);
- HeaderValue& operator=(HeaderValue&& other);
-
- void set_storage(Http2HeaderStorage* storage);
-
- // Copies are not.
- HeaderValue(const HeaderValue& other) = delete;
- HeaderValue& operator=(const HeaderValue& other) = delete;
-
- ~HeaderValue();
-
- // Consumes at most |fragment.size()| bytes of memory.
- void Append(absl::string_view fragment);
-
- absl::string_view value() const { return as_pair().second; }
- const std::pair<absl::string_view, absl::string_view>& as_pair() const;
-
- // Size estimate including separators. Used when keys are erased from
- // Http2HeaderBlock.
- size_t SizeEstimate() const { return size_; }
-
- private:
- // May allocate a large contiguous region of memory to hold the concatenated
- // fragments and separators.
- absl::string_view ConsolidatedValue() const;
-
- mutable Http2HeaderStorage* storage_;
- mutable std::vector<absl::string_view> fragments_;
- // The first element is the key; the second is the consolidated value.
- mutable std::pair<absl::string_view, absl::string_view> pair_;
- size_t size_ = 0;
- size_t separator_size_ = 0;
- };
-
- typedef quiche::QuicheLinkedHashMap<absl::string_view, HeaderValue,
- quiche::StringPieceCaseHash,
- quiche::StringPieceCaseEqual>
- MapType;
-
- public:
- typedef std::pair<absl::string_view, absl::string_view> value_type;
-
- // Provides iteration over a sequence of std::pair<absl::string_view,
- // absl::string_view>, even though the underlying MapType::value_type is
- // different. Dereferencing the iterator will result in memory allocation for
- // multi-value headers.
- class QUICHE_EXPORT iterator {
- public:
- // The following type definitions fulfill the requirements for iterator
- // implementations.
- typedef std::pair<absl::string_view, absl::string_view> value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef MapType::iterator::difference_type difference_type;
-
- // In practice, this iterator only offers access to const value_type.
- typedef const value_type& const_reference;
- typedef const value_type* const_pointer;
-
- explicit iterator(MapType::const_iterator it);
- iterator(const iterator& other);
- ~iterator();
-
- // This will result in memory allocation if the value consists of multiple
- // fragments.
- const_reference operator*() const {
-#if SPDY_HEADER_DEBUG
- QUICHE_CHECK(!dereference_forbidden_);
-#endif // SPDY_HEADER_DEBUG
- return it_->second.as_pair();
- }
-
- const_pointer operator->() const { return &(this->operator*()); }
- bool operator==(const iterator& it) const { return it_ == it.it_; }
- bool operator!=(const iterator& it) const { return !(*this == it); }
-
- iterator& operator++() {
- it_++;
- return *this;
- }
-
- iterator operator++(int) {
- auto ret = *this;
- this->operator++();
- return ret;
- }
-
-#if SPDY_HEADER_DEBUG
- void forbid_dereference() { dereference_forbidden_ = true; }
-#endif // SPDY_HEADER_DEBUG
-
- private:
- MapType::const_iterator it_;
-#if SPDY_HEADER_DEBUG
- bool dereference_forbidden_ = false;
-#endif // SPDY_HEADER_DEBUG
- };
- typedef iterator const_iterator;
-
- Http2HeaderBlock();
- Http2HeaderBlock(const Http2HeaderBlock& other) = delete;
- Http2HeaderBlock(Http2HeaderBlock&& other);
- ~Http2HeaderBlock();
-
- Http2HeaderBlock& operator=(const Http2HeaderBlock& other) = delete;
- Http2HeaderBlock& operator=(Http2HeaderBlock&& other);
- Http2HeaderBlock Clone() const;
-
- bool operator==(const Http2HeaderBlock& other) const;
- bool operator!=(const Http2HeaderBlock& other) const;
-
- // Provides a human readable multi-line representation of the stored header
- // keys and values.
- std::string DebugString() const;
-
- iterator begin() { return wrap_iterator(map_.begin()); }
- iterator end() { return wrap_iterator(map_.end()); }
- const_iterator begin() const { return wrap_const_iterator(map_.begin()); }
- const_iterator end() const { return wrap_const_iterator(map_.end()); }
- bool empty() const { return map_.empty(); }
- size_t size() const { return map_.size(); }
- iterator find(absl::string_view key) { return wrap_iterator(map_.find(key)); }
- const_iterator find(absl::string_view key) const {
- return wrap_const_iterator(map_.find(key));
- }
- bool contains(absl::string_view key) const { return find(key) != end(); }
- void erase(absl::string_view key);
-
- // Clears both our MapType member and the memory used to hold headers.
- void clear();
-
- // The next few methods copy data into our backing storage.
-
- // If key already exists in the block, replaces the value of that key. Else
- // adds a new header to the end of the block.
- void insert(const value_type& value);
-
- // If a header with the key is already present, then append the value to the
- // existing header value, NUL ("\0") separated unless the key is cookie, in
- // which case the separator is "; ".
- // If there is no such key, a new header with the key and value is added.
- void AppendValueOrAddHeader(const absl::string_view key,
- const absl::string_view value);
-
- // This object provides automatic conversions that allow Http2HeaderBlock to
- // be nearly a drop-in replacement for
- // SpdyLinkedHashMap<std::string, std::string>.
- // It reads data from or writes data to a Http2HeaderStorage.
- class QUICHE_EXPORT ValueProxy {
- public:
- ~ValueProxy();
-
- // Moves are allowed.
- ValueProxy(ValueProxy&& other);
- ValueProxy& operator=(ValueProxy&& other);
-
- // Copies are not.
- ValueProxy(const ValueProxy& other) = delete;
- ValueProxy& operator=(const ValueProxy& other) = delete;
-
- // Assignment modifies the underlying Http2HeaderBlock.
- ValueProxy& operator=(absl::string_view value);
-
- // Provides easy comparison against absl::string_view.
- bool operator==(absl::string_view value) const;
-
- std::string as_string() const;
-
- private:
- friend class Http2HeaderBlock;
- friend class test::ValueProxyPeer;
-
- ValueProxy(Http2HeaderBlock* block,
- Http2HeaderBlock::MapType::iterator lookup_result,
- const absl::string_view key,
- size_t* spdy_header_block_value_size);
-
- Http2HeaderBlock* block_;
- Http2HeaderBlock::MapType::iterator lookup_result_;
- absl::string_view key_;
- size_t* spdy_header_block_value_size_;
- bool valid_;
- };
-
- // Allows either lookup or mutation of the value associated with a key.
- ABSL_MUST_USE_RESULT ValueProxy operator[](const absl::string_view key);
-
- size_t TotalBytesUsed() const { return key_size_ + value_size_; }
-
- private:
- friend class test::Http2HeaderBlockPeer;
-
- inline iterator wrap_iterator(MapType::const_iterator inner_iterator) const {
-#if SPDY_HEADER_DEBUG
- iterator outer_iterator(inner_iterator);
- if (inner_iterator == map_.end()) {
- outer_iterator.forbid_dereference();
- }
- return outer_iterator;
-#else // SPDY_HEADER_DEBUG
- return iterator(inner_iterator);
-#endif // SPDY_HEADER_DEBUG
- }
-
- inline const_iterator wrap_const_iterator(
- MapType::const_iterator inner_iterator) const {
-#if SPDY_HEADER_DEBUG
- const_iterator outer_iterator(inner_iterator);
- if (inner_iterator == map_.end()) {
- outer_iterator.forbid_dereference();
- }
- return outer_iterator;
-#else // SPDY_HEADER_DEBUG
- return iterator(inner_iterator);
-#endif // SPDY_HEADER_DEBUG
- }
-
- void AppendHeader(const absl::string_view key, const absl::string_view value);
- absl::string_view WriteKey(const absl::string_view key);
- size_t bytes_allocated() const;
-
- // absl::string_views held by |map_| point to memory owned by |storage_|.
- MapType map_;
- Http2HeaderStorage storage_;
-
- size_t key_size_ = 0;
- size_t value_size_ = 0;
-};
-
+using Http2HeaderBlock = ::quiche::HttpHeaderBlock;
} // namespace spdy
#endif // QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_H_