Removes a duplicate implementation of the HPACK static table.
Reuses the encoder's representation of the static table for decoding.
PiperOrigin-RevId: 839788990
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_state.cc b/quiche/http2/hpack/decoder/hpack_decoder_state.cc
index 34659d8..92505cd 100644
--- a/quiche/http2/hpack/decoder/hpack_decoder_state.cc
+++ b/quiche/http2/hpack/decoder/hpack_decoder_state.cc
@@ -88,9 +88,9 @@
return;
}
allow_dynamic_table_size_update_ = false;
- const HpackStringPair* entry = decoder_tables_.Lookup(index);
+ const HpackEntry* entry = decoder_tables_.Lookup(index);
if (entry != nullptr) {
- listener_->OnHeader(entry->name, entry->value);
+ listener_->OnHeader(entry->name(), entry->value());
} else {
ReportError(HpackDecodingError::kInvalidIndex);
}
@@ -110,12 +110,12 @@
return;
}
allow_dynamic_table_size_update_ = false;
- const HpackStringPair* entry = decoder_tables_.Lookup(name_index);
+ const HpackEntry* entry = decoder_tables_.Lookup(name_index);
if (entry != nullptr) {
std::string value(ExtractString(value_buffer));
- listener_->OnHeader(entry->name, value);
+ listener_->OnHeader(entry->name(), value);
if (entry_type == HpackEntryType::kIndexedLiteralHeader) {
- decoder_tables_.Insert(entry->name, std::move(value));
+ decoder_tables_.Insert(std::string(entry->name()), std::move(value));
}
} else {
ReportError(HpackDecodingError::kInvalidNameIndex);
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_state_test.cc b/quiche/http2/hpack/decoder/hpack_decoder_state_test.cc
index fe97c14..3e7da8f 100644
--- a/quiche/http2/hpack/decoder/hpack_decoder_state_test.cc
+++ b/quiche/http2/hpack/decoder/hpack_decoder_state_test.cc
@@ -11,6 +11,7 @@
#include "absl/strings/string_view.h"
#include "quiche/http2/core/http2_constants.h"
+#include "quiche/http2/hpack/hpack_entry.h"
#include "quiche/http2/hpack/http2_hpack_constants.h"
#include "quiche/http2/test_tools/verify_macros.h"
#include "quiche/common/platform/api/quiche_logging.h"
@@ -53,7 +54,7 @@
return HpackDecoderStatePeer::GetDecoderTables(&decoder_state_);
}
- const HpackStringPair* Lookup(size_t index) {
+ const HpackEntry* Lookup(size_t index) {
return GetDecoderTables()->Lookup(index);
}
@@ -140,15 +141,15 @@
// dynamic_index is one-based, because that is the way RFC 7541 shows it.
AssertionResult VerifyEntry(size_t dynamic_index, absl::string_view name,
absl::string_view value) {
- const HpackStringPair* entry =
+ const HpackEntry* entry =
Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
HTTP2_VERIFY_NE(entry, nullptr);
- HTTP2_VERIFY_EQ(entry->name, name);
- HTTP2_VERIFY_EQ(entry->value, value);
+ HTTP2_VERIFY_EQ(entry->name(), name);
+ HTTP2_VERIFY_EQ(entry->value(), value);
return AssertionSuccess();
}
AssertionResult VerifyNoEntry(size_t dynamic_index) {
- const HpackStringPair* entry =
+ const HpackEntry* entry =
Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
HTTP2_VERIFY_EQ(entry, nullptr);
return AssertionSuccess();
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_tables.cc b/quiche/http2/hpack/decoder/hpack_decoder_tables.cc
index 1fc505f..d07eb4e 100644
--- a/quiche/http2/hpack/decoder/hpack_decoder_tables.cc
+++ b/quiche/http2/hpack/decoder/hpack_decoder_tables.cc
@@ -10,66 +10,12 @@
#include <vector>
#include "absl/strings/str_cat.h"
+#include "quiche/http2/hpack/hpack_constants.h"
+#include "quiche/http2/hpack/hpack_static_table.h"
#include "quiche/http2/hpack/http2_hpack_constants.h"
#include "quiche/common/platform/api/quiche_logging.h"
namespace http2 {
-namespace {
-
-std::vector<HpackStringPair>* MakeStaticTable() {
- auto* ptr = new std::vector<HpackStringPair>();
- ptr->reserve(kFirstDynamicTableIndex);
- ptr->emplace_back("", "");
-
-#define STATIC_TABLE_ENTRY(name, value, index) \
- QUICHE_DCHECK_EQ(ptr->size(), static_cast<size_t>(index)); \
- ptr->emplace_back(name, value)
-
-#include "quiche/http2/hpack/hpack_static_table_entries.inc"
-
-#undef STATIC_TABLE_ENTRY
-
- return ptr;
-}
-
-const std::vector<HpackStringPair>* GetStaticTable() {
- static const std::vector<HpackStringPair>* const g_static_table =
- MakeStaticTable();
- return g_static_table;
-}
-
-} // namespace
-
-HpackStringPair::HpackStringPair(std::string name, std::string value)
- : name(std::move(name)), value(std::move(value)) {
- QUICHE_DVLOG(3) << DebugString() << " ctor";
-}
-
-HpackStringPair::~HpackStringPair() {
- QUICHE_DVLOG(3) << DebugString() << " dtor";
-}
-
-std::string HpackStringPair::DebugString() const {
- return absl::StrCat("HpackStringPair(name=", name, ", value=", value, ")");
-}
-
-std::ostream& operator<<(std::ostream& os, const HpackStringPair& p) {
- os << p.DebugString();
- return os;
-}
-
-HpackDecoderStaticTable::HpackDecoderStaticTable(
- const std::vector<HpackStringPair>* table)
- : table_(table) {}
-
-HpackDecoderStaticTable::HpackDecoderStaticTable() : table_(GetStaticTable()) {}
-
-const HpackStringPair* HpackDecoderStaticTable::Lookup(size_t index) const {
- if (0 < index && index < kFirstDynamicTableIndex) {
- return &((*table_)[index]);
- }
- return nullptr;
-}
void HpackDecoderDynamicTable::DynamicTableSizeUpdate(size_t size_limit) {
QUICHE_DVLOG(3) << "HpackDecoderDynamicTable::DynamicTableSizeUpdate "
@@ -82,11 +28,11 @@
// TODO(jamessynge): Check somewhere before here that names received from the
// peer are valid (e.g. are lower-case, no whitespace, etc.).
void HpackDecoderDynamicTable::Insert(std::string name, std::string value) {
- HpackStringPair entry(std::move(name), std::move(value));
- size_t entry_size = entry.size();
+ HpackEntry entry(std::move(name), std::move(value));
+ size_t entry_size = entry.Size();
QUICHE_DVLOG(2) << "InsertEntry of size=" << entry_size
- << "\n name: " << entry.name
- << "\n value: " << entry.value;
+ << "\n name: " << entry.name()
+ << "\n value: " << entry.value();
if (entry_size > size_limit_) {
QUICHE_DVLOG(2) << "InsertEntry: entry larger than table, removing "
<< table_.size() << " entries, of total size "
@@ -104,7 +50,7 @@
QUICHE_DCHECK_LE(current_size_, size_limit_);
}
-const HpackStringPair* HpackDecoderDynamicTable::Lookup(size_t index) const {
+const HpackEntry* HpackDecoderDynamicTable::Lookup(size_t index) const {
if (index < table_.size()) {
return &table_[index];
}
@@ -125,21 +71,23 @@
QUICHE_DCHECK(!table_.empty());
if (!table_.empty()) {
QUICHE_DVLOG(2) << "RemoveLastEntry current_size_=" << current_size_
- << ", last entry size=" << table_.back().size();
- QUICHE_DCHECK_GE(current_size_, table_.back().size());
- current_size_ -= table_.back().size();
+ << ", last entry size=" << table_.back().Size();
+ QUICHE_DCHECK_GE(current_size_, table_.back().Size());
+ current_size_ -= table_.back().Size();
table_.pop_back();
// Empty IFF current_size_ == 0.
QUICHE_DCHECK_EQ(table_.empty(), current_size_ == 0);
}
}
-HpackDecoderTables::HpackDecoderTables() = default;
-HpackDecoderTables::~HpackDecoderTables() = default;
+HpackDecoderTables::HpackDecoderTables()
+ : static_entries_(spdy::ObtainHpackStaticTable().GetStaticEntries()) {}
-const HpackStringPair* HpackDecoderTables::Lookup(size_t index) const {
- if (index < kFirstDynamicTableIndex) {
- return static_table_.Lookup(index);
+const HpackEntry* HpackDecoderTables::Lookup(size_t index) const {
+ if (index == 0) {
+ return nullptr;
+ } else if (index < kFirstDynamicTableIndex) {
+ return &static_entries_[index - 1];
} else {
return dynamic_table_.Lookup(index - kFirstDynamicTableIndex);
}
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_tables.h b/quiche/http2/hpack/decoder/hpack_decoder_tables.h
index c98064c..27f175f 100644
--- a/quiche/http2/hpack/decoder/hpack_decoder_tables.h
+++ b/quiche/http2/hpack/decoder/hpack_decoder_tables.h
@@ -25,6 +25,7 @@
#include <vector>
#include "quiche/http2/core/http2_constants.h"
+#include "quiche/http2/hpack/hpack_entry.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_circular_deque.h"
@@ -33,41 +34,6 @@
class HpackDecoderTablesPeer;
} // namespace test
-struct QUICHE_EXPORT HpackStringPair {
- HpackStringPair(std::string name, std::string value);
- ~HpackStringPair();
-
- // Returns the size of a header entry with this name and value, per the RFC:
- // http://httpwg.org/specs/rfc7541.html#calculating.table.size
- size_t size() const { return 32 + name.size() + value.size(); }
-
- std::string DebugString() const;
-
- const std::string name;
- const std::string value;
-};
-
-QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
- const HpackStringPair& p);
-
-// See http://httpwg.org/specs/rfc7541.html#static.table.definition for the
-// contents, and http://httpwg.org/specs/rfc7541.html#index.address.space for
-// info about accessing the static table.
-class QUICHE_EXPORT HpackDecoderStaticTable {
- public:
- explicit HpackDecoderStaticTable(const std::vector<HpackStringPair>* table);
- // Uses a global table shared by all threads.
- HpackDecoderStaticTable();
-
- // If index is valid, returns a pointer to the entry, otherwise returns
- // nullptr.
- const HpackStringPair* Lookup(size_t index) const;
-
- private:
- friend class test::HpackDecoderTablesPeer;
- const std::vector<HpackStringPair>* const table_;
-};
-
// HpackDecoderDynamicTable implements HPACK compression feature "indexed
// headers"; previously sent headers may be referenced later by their index
// in the dynamic table. See these sections of the RFC:
@@ -92,7 +58,7 @@
// If index is valid, returns a pointer to the entry, otherwise returns
// nullptr.
- const HpackStringPair* Lookup(size_t index) const;
+ const HpackEntry* Lookup(size_t index) const;
size_t size_limit() const { return size_limit_; }
size_t current_size() const { return current_size_; }
@@ -106,7 +72,7 @@
// Removes the oldest dynamic table entry.
void RemoveLastEntry();
- quiche::QuicheCircularDeque<HpackStringPair> table_;
+ quiche::QuicheCircularDeque<HpackEntry> table_;
// The last received DynamicTableSizeUpdate value, initialized to
// SETTINGS_HEADER_TABLE_SIZE.
@@ -118,7 +84,6 @@
class QUICHE_EXPORT HpackDecoderTables {
public:
HpackDecoderTables();
- ~HpackDecoderTables();
HpackDecoderTables(const HpackDecoderTables&) = delete;
HpackDecoderTables& operator=(const HpackDecoderTables&) = delete;
@@ -139,7 +104,7 @@
// If index is valid, returns a pointer to the entry, otherwise returns
// nullptr.
- const HpackStringPair* Lookup(size_t index) const;
+ const HpackEntry* Lookup(size_t index) const;
// The size limit that the peer (the HPACK encoder) has told the decoder it is
// currently operating with. Defaults to SETTINGS_HEADER_TABLE_SIZE, 4096.
@@ -152,7 +117,12 @@
private:
friend class test::HpackDecoderTablesPeer;
- HpackDecoderStaticTable static_table_;
+
+ // Use a lightweight, memory efficient container for the static table, which
+ // is initialized once and never changed after.
+ using StaticEntryTable = std::vector<HpackEntry>;
+ const StaticEntryTable& static_entries_;
+
HpackDecoderDynamicTable dynamic_table_;
};
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_tables_test.cc b/quiche/http2/hpack/decoder/hpack_decoder_tables_test.cc
index 10917da..3d3e965 100644
--- a/quiche/http2/hpack/decoder/hpack_decoder_tables_test.cc
+++ b/quiche/http2/hpack/decoder/hpack_decoder_tables_test.cc
@@ -9,6 +9,7 @@
#include <tuple>
#include <vector>
+#include "quiche/http2/hpack/hpack_entry.h"
#include "quiche/http2/hpack/http2_hpack_constants.h"
#include "quiche/http2/test_tools/http2_random.h"
#include "quiche/http2/test_tools/random_util.h"
@@ -29,71 +30,6 @@
};
namespace {
-struct StaticEntry {
- const char* name;
- const char* value;
- size_t index;
-};
-
-std::vector<StaticEntry> MakeSpecStaticEntries() {
- std::vector<StaticEntry> static_entries;
-
-#define STATIC_TABLE_ENTRY(name, value, index) \
- QUICHE_DCHECK_EQ(static_entries.size() + 1, static_cast<size_t>(index)); \
- static_entries.push_back({name, value, index});
-
-#include "quiche/http2/hpack/hpack_static_table_entries.inc"
-
-#undef STATIC_TABLE_ENTRY
-
- return static_entries;
-}
-
-template <class C>
-void ShuffleCollection(C* collection, Http2Random* r) {
- std::shuffle(collection->begin(), collection->end(), *r);
-}
-
-class HpackDecoderStaticTableTest : public quiche::test::QuicheTest {
- protected:
- HpackDecoderStaticTableTest() = default;
-
- std::vector<StaticEntry> shuffled_static_entries() {
- std::vector<StaticEntry> entries = MakeSpecStaticEntries();
- ShuffleCollection(&entries, &random_);
- return entries;
- }
-
- // This test is in a function so that it can be applied to both the static
- // table and the combined static+dynamic tables.
- AssertionResult VerifyStaticTableContents() {
- for (const auto& expected : shuffled_static_entries()) {
- const HpackStringPair* found = Lookup(expected.index);
- HTTP2_VERIFY_NE(found, nullptr);
- HTTP2_VERIFY_EQ(expected.name, found->name) << expected.index;
- HTTP2_VERIFY_EQ(expected.value, found->value) << expected.index;
- }
-
- // There should be no entry with index 0.
- HTTP2_VERIFY_EQ(nullptr, Lookup(0));
- return AssertionSuccess();
- }
-
- virtual const HpackStringPair* Lookup(size_t index) {
- return static_table_.Lookup(index);
- }
-
- Http2Random* RandomPtr() { return &random_; }
-
- Http2Random random_;
-
- private:
- HpackDecoderStaticTable static_table_;
-};
-
-TEST_F(HpackDecoderStaticTableTest, StaticTableContents) {
- EXPECT_TRUE(VerifyStaticTableContents());
-}
size_t Size(const std::string& name, const std::string& value) {
return name.size() + value.size() + 32;
@@ -113,11 +49,9 @@
}
size_t Size(const FakeHpackEntry& entry) { return std::get<2>(entry); }
-class HpackDecoderTablesTest : public HpackDecoderStaticTableTest {
+class HpackDecoderTablesTest : public quiche::test::QuicheTest {
protected:
- const HpackStringPair* Lookup(size_t index) override {
- return tables_.Lookup(index);
- }
+ const HpackEntry* Lookup(size_t index) { return tables_.Lookup(index); }
size_t dynamic_size_limit() const {
return tables_.header_table_size_limit();
@@ -170,12 +104,12 @@
HTTP2_VERIFY_EQ(num_dynamic_entries(), fake_dynamic_table_.size());
for (size_t ndx = 0; ndx < fake_dynamic_table_.size(); ++ndx) {
- const HpackStringPair* found = Lookup(ndx + kFirstDynamicTableIndex);
+ const HpackEntry* found = Lookup(ndx + kFirstDynamicTableIndex);
HTTP2_VERIFY_NE(found, nullptr);
const auto& expected = fake_dynamic_table_[ndx];
- HTTP2_VERIFY_EQ(Name(expected), found->name);
- HTTP2_VERIFY_EQ(Value(expected), found->value);
+ HTTP2_VERIFY_EQ(Name(expected), found->name());
+ HTTP2_VERIFY_EQ(Value(expected), found->value());
}
// Make sure there are no more entries.
@@ -212,22 +146,21 @@
return VerifyDynamicTableContents();
}
+ Http2Random* RandomPtr() { return &random_; }
+
+ Http2Random random_;
+
private:
HpackDecoderTables tables_;
std::vector<FakeHpackEntry> fake_dynamic_table_;
};
-TEST_F(HpackDecoderTablesTest, StaticTableContents) {
- EXPECT_TRUE(VerifyStaticTableContents());
-}
-
// Generate a bunch of random header entries, insert them, and confirm they
// present, as required by the RFC, using VerifyDynamicTableContents above on
// each Insert. Also apply various resizings of the dynamic table.
TEST_F(HpackDecoderTablesTest, RandomDynamicTable) {
EXPECT_EQ(0u, current_dynamic_size());
- EXPECT_TRUE(VerifyStaticTableContents());
EXPECT_TRUE(VerifyDynamicTableContents());
std::vector<size_t> table_sizes;
@@ -248,7 +181,6 @@
GenerateWebSafeString(random_.UniformInRange(2, 600), RandomPtr());
ASSERT_TRUE(Insert(name, value));
}
- EXPECT_TRUE(VerifyStaticTableContents());
}
}
diff --git a/quiche/http2/hpack/decoder/hpack_decoder_test.cc b/quiche/http2/hpack/decoder/hpack_decoder_test.cc
index 3221e2c..ed317dc 100644
--- a/quiche/http2/hpack/decoder/hpack_decoder_test.cc
+++ b/quiche/http2/hpack/decoder/hpack_decoder_test.cc
@@ -166,7 +166,7 @@
const HpackDecoderTables& GetDecoderTables() {
return *HpackDecoderPeer::GetDecoderTables(&decoder_);
}
- const HpackStringPair* Lookup(size_t index) {
+ const HpackEntry* Lookup(size_t index) {
return GetDecoderTables().Lookup(index);
}
size_t current_header_table_size() {
@@ -182,15 +182,15 @@
// dynamic_index is one-based, because that is the way RFC 7541 shows it.
AssertionResult VerifyEntry(size_t dynamic_index, const char* name,
const char* value) {
- const HpackStringPair* entry =
+ const HpackEntry* entry =
Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
HTTP2_VERIFY_NE(entry, nullptr);
- HTTP2_VERIFY_EQ(entry->name, name);
- HTTP2_VERIFY_EQ(entry->value, value);
+ HTTP2_VERIFY_EQ(entry->name(), name);
+ HTTP2_VERIFY_EQ(entry->value(), value);
return AssertionSuccess();
}
AssertionResult VerifyNoEntry(size_t dynamic_index) {
- const HpackStringPair* entry =
+ const HpackEntry* entry =
Lookup(dynamic_index + kFirstDynamicTableIndex - 1);
HTTP2_VERIFY_EQ(entry, nullptr);
return AssertionSuccess();
diff --git a/quiche/http2/hpack/hpack_decoder_adapter_test.cc b/quiche/http2/hpack/hpack_decoder_adapter_test.cc
index 82937a6..f4eb580 100644
--- a/quiche/http2/hpack/hpack_decoder_adapter_test.cc
+++ b/quiche/http2/hpack/hpack_decoder_adapter_test.cc
@@ -33,7 +33,6 @@
#include "quiche/common/quiche_text_utils.h"
using ::http2::HpackEntryType;
-using ::http2::HpackStringPair;
using ::http2::test::HpackBlockBuilder;
using ::http2::test::HpackDecoderPeer;
using ::testing::ElementsAre;
@@ -79,7 +78,7 @@
return HpackDecoderPeer::GetDecoderTables(&decoder_->hpack_decoder_);
}
- const HpackStringPair* GetTableEntry(uint32_t index) {
+ const HpackEntry* GetTableEntry(uint32_t index) {
return GetDecoderTables()->Lookup(index);
}
@@ -207,10 +206,10 @@
void expectEntry(size_t index, size_t size, const std::string& name,
const std::string& value) {
- const HpackStringPair* entry = decoder_peer_.GetTableEntry(index);
- EXPECT_EQ(name, entry->name) << "index " << index;
- EXPECT_EQ(value, entry->value);
- EXPECT_EQ(size, entry->size());
+ const HpackEntry* entry = decoder_peer_.GetTableEntry(index);
+ EXPECT_EQ(name, entry->name()) << "index " << index;
+ EXPECT_EQ(value, entry->value());
+ EXPECT_EQ(size, entry->Size());
}
quiche::HttpHeaderBlock MakeHeaderBlock(
diff --git a/quiche/http2/hpack/hpack_entry.h b/quiche/http2/hpack/hpack_entry.h
index 67749e9..b43f397 100644
--- a/quiche/http2/hpack/hpack_entry.h
+++ b/quiche/http2/hpack/hpack_entry.h
@@ -77,4 +77,8 @@
} // namespace spdy
+namespace http2 {
+using ::spdy::HpackEntry;
+} // namespace http2
+
#endif // QUICHE_HTTP2_HPACK_HPACK_ENTRY_H_
diff --git a/quiche/http2/hpack/hpack_static_table_entries.inc b/quiche/http2/hpack/hpack_static_table_entries.inc
deleted file mode 100644
index c6ae125..0000000
--- a/quiche/http2/hpack/hpack_static_table_entries.inc
+++ /dev/null
@@ -1,65 +0,0 @@
-// This file is designed to be included by C/C++ files which need the contents
-// of the HPACK static table. It may be included more than once if necessary.
-// See http://httpwg.org/specs/rfc7541.html#static.table.definition
-
-STATIC_TABLE_ENTRY(":authority", "", 1);
-STATIC_TABLE_ENTRY(":method", "GET", 2);
-STATIC_TABLE_ENTRY(":method", "POST", 3);
-STATIC_TABLE_ENTRY(":path", "/", 4);
-STATIC_TABLE_ENTRY(":path", "/index.html", 5);
-STATIC_TABLE_ENTRY(":scheme", "http", 6);
-STATIC_TABLE_ENTRY(":scheme", "https", 7);
-STATIC_TABLE_ENTRY(":status", "200", 8);
-STATIC_TABLE_ENTRY(":status", "204", 9);
-STATIC_TABLE_ENTRY(":status", "206", 10);
-STATIC_TABLE_ENTRY(":status", "304", 11);
-STATIC_TABLE_ENTRY(":status", "400", 12);
-STATIC_TABLE_ENTRY(":status", "404", 13);
-STATIC_TABLE_ENTRY(":status", "500", 14);
-STATIC_TABLE_ENTRY("accept-charset", "", 15);
-STATIC_TABLE_ENTRY("accept-encoding", "gzip, deflate", 16);
-STATIC_TABLE_ENTRY("accept-language", "", 17);
-STATIC_TABLE_ENTRY("accept-ranges", "", 18);
-STATIC_TABLE_ENTRY("accept", "", 19);
-STATIC_TABLE_ENTRY("access-control-allow-origin", "", 20);
-STATIC_TABLE_ENTRY("age", "", 21);
-STATIC_TABLE_ENTRY("allow", "", 22);
-STATIC_TABLE_ENTRY("authorization", "", 23);
-STATIC_TABLE_ENTRY("cache-control", "", 24);
-STATIC_TABLE_ENTRY("content-disposition", "", 25);
-STATIC_TABLE_ENTRY("content-encoding", "", 26);
-STATIC_TABLE_ENTRY("content-language", "", 27);
-STATIC_TABLE_ENTRY("content-length", "", 28);
-STATIC_TABLE_ENTRY("content-location", "", 29);
-STATIC_TABLE_ENTRY("content-range", "", 30);
-STATIC_TABLE_ENTRY("content-type", "", 31);
-STATIC_TABLE_ENTRY("cookie", "", 32);
-STATIC_TABLE_ENTRY("date", "", 33);
-STATIC_TABLE_ENTRY("etag", "", 34);
-STATIC_TABLE_ENTRY("expect", "", 35);
-STATIC_TABLE_ENTRY("expires", "", 36);
-STATIC_TABLE_ENTRY("from", "", 37);
-STATIC_TABLE_ENTRY("host", "", 38);
-STATIC_TABLE_ENTRY("if-match", "", 39);
-STATIC_TABLE_ENTRY("if-modified-since", "", 40);
-STATIC_TABLE_ENTRY("if-none-match", "", 41);
-STATIC_TABLE_ENTRY("if-range", "", 42);
-STATIC_TABLE_ENTRY("if-unmodified-since", "", 43);
-STATIC_TABLE_ENTRY("last-modified", "", 44);
-STATIC_TABLE_ENTRY("link", "", 45);
-STATIC_TABLE_ENTRY("location", "", 46);
-STATIC_TABLE_ENTRY("max-forwards", "", 47);
-STATIC_TABLE_ENTRY("proxy-authenticate", "", 48);
-STATIC_TABLE_ENTRY("proxy-authorization", "", 49);
-STATIC_TABLE_ENTRY("range", "", 50);
-STATIC_TABLE_ENTRY("referer", "", 51);
-STATIC_TABLE_ENTRY("refresh", "", 52);
-STATIC_TABLE_ENTRY("retry-after", "", 53);
-STATIC_TABLE_ENTRY("server", "", 54);
-STATIC_TABLE_ENTRY("set-cookie", "", 55);
-STATIC_TABLE_ENTRY("strict-transport-security", "", 56);
-STATIC_TABLE_ENTRY("transfer-encoding", "", 57);
-STATIC_TABLE_ENTRY("user-agent", "", 58);
-STATIC_TABLE_ENTRY("vary", "", 59);
-STATIC_TABLE_ENTRY("via", "", 60);
-STATIC_TABLE_ENTRY("www-authenticate", "", 61);