Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(863)

Unified Diff: net/http2/hpack/decoder/hpack_decoder_tables.h

Issue 2606733004: Add HpackDecoderTables, static and dynamic tables for decoding HPACK. (Closed)
Patch Set: Rebase. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | net/http2/hpack/decoder/hpack_decoder_tables.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http2/hpack/decoder/hpack_decoder_tables.h
diff --git a/net/http2/hpack/decoder/hpack_decoder_tables.h b/net/http2/hpack/decoder/hpack_decoder_tables.h
new file mode 100644
index 0000000000000000000000000000000000000000..525a54e7d897c3cee749cbc091307d4af4e272e7
--- /dev/null
+++ b/net/http2/hpack/decoder/hpack_decoder_tables.h
@@ -0,0 +1,152 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_
+#define NET_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_
+
+// Static and dynamic tables for the HPACK decoder. See:
+// http://httpwg.org/specs/rfc7541.html#indexing.tables
+
+// Note that the Lookup methods return nullptr if the requested index was not
+// found. This should be treated as a COMPRESSION error according to the HTTP/2
+// spec, which is a connection level protocol error (i.e. the connection must
+// be terminated). See these sections in the two RFCs:
+// http://httpwg.org/specs/rfc7541.html#indexed.header.representation
+// http://httpwg.org/specs/rfc7541.html#index.address.space
+// http://httpwg.org/specs/rfc7540.html#HeaderBlock
+
+#include <stddef.h>
+
+#include <deque>
+#include <functional>
+#include <vector>
+
+#include "base/macros.h"
+#include "net/base/net_export.h"
+#include "net/http2/hpack/hpack_string.h"
+#include "net/http2/http2_constants.h"
+
+namespace net {
+namespace test {
+class HpackDecoderTablesPeer;
+} // namespace test
+
+const size_t kFirstDynamicTableIndex = 62;
+
+// 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 NET_EXPORT_PRIVATE 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:
+// http://httpwg.org/specs/rfc7541.html#dynamic.table
+// http://httpwg.org/specs/rfc7541.html#dynamic.table.management
+class NET_EXPORT_PRIVATE HpackDecoderDynamicTable {
+ public:
+ HpackDecoderDynamicTable();
+ ~HpackDecoderDynamicTable();
+
+ // Sets a new size limit, received from the peer; performs evictions if
+ // necessary to ensure that the current size does not exceed the new limit.
+ // The caller needs to have validated that size_limit does not
+ // exceed the acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
+ void DynamicTableSizeUpdate(size_t size_limit);
+
+ // Returns true if inserted, false if too large (at which point the
+ // dynamic table will be empty.)
+ bool Insert(const HpackString& name, const HpackString& value);
+
+ // If index is valid, returns a pointer to the entry, otherwise returns
+ // nullptr.
+ const HpackStringPair* Lookup(size_t index) const;
+
+ size_t size_limit() const { return size_limit_; }
+ size_t current_size() const { return current_size_; }
+
+ private:
+ friend class test::HpackDecoderTablesPeer;
+
+ // Drop older entries to ensure the size is not greater than limit.
+ void EnsureSizeNoMoreThan(size_t limit);
+
+ // Removes the oldest dynamic table entry.
+ void RemoveLastEntry();
+
+ // The last received DynamicTableSizeUpdate value, initialized to
+ // SETTINGS_HEADER_TABLE_SIZE.
+ size_t size_limit_ = Http2SettingsInfo::DefaultHeaderTableSize();
+
+ size_t current_size_ = 0;
+
+ std::deque<HpackStringPair> table_;
+
+ DISALLOW_COPY_AND_ASSIGN(HpackDecoderDynamicTable);
+};
+
+class NET_EXPORT_PRIVATE HpackDecoderTables {
+ public:
+ HpackDecoderTables();
+ ~HpackDecoderTables();
+
+ // Sets a new size limit, received from the peer; performs evictions if
+ // necessary to ensure that the current size does not exceed the new limit.
+ // The caller needs to have validated that size_limit does not
+ // exceed the acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
+ void DynamicTableSizeUpdate(size_t size_limit) {
+ dynamic_table_.DynamicTableSizeUpdate(size_limit);
+ }
+
+ // Returns true if inserted, false if too large (at which point the
+ // dynamic table will be empty.)
+ // TODO(jamessynge): Add methods for moving the string(s) into the table,
+ // or for otherwise avoiding unnecessary copies.
+ bool Insert(const HpackString& name, const HpackString& value) {
+ return dynamic_table_.Insert(name, value);
+ }
+
+ // If index is valid, returns a pointer to the entry, otherwise returns
+ // nullptr.
+ const HpackStringPair* Lookup(size_t index) const {
+ if (index < kFirstDynamicTableIndex) {
+ return static_table_.Lookup(index);
+ } else {
+ return dynamic_table_.Lookup(index - kFirstDynamicTableIndex);
+ }
+ }
+
+ // 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.
+ size_t header_table_size_limit() const { return dynamic_table_.size_limit(); }
+
+ // Sum of the sizes of the dynamic table entries.
+ size_t current_header_table_size() const {
+ return dynamic_table_.current_size();
+ }
+
+ private:
+ friend class test::HpackDecoderTablesPeer;
+ HpackDecoderStaticTable static_table_;
+ HpackDecoderDynamicTable dynamic_table_;
+
+ DISALLOW_COPY_AND_ASSIGN(HpackDecoderTables);
+};
+
+} // namespace net
+
+#endif // NET_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_
« no previous file with comments | « no previous file | net/http2/hpack/decoder/hpack_decoder_tables.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698