OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef NET_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_ |
| 6 #define NET_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_ |
| 7 |
| 8 // Static and dynamic tables for the HPACK decoder. See: |
| 9 // http://httpwg.org/specs/rfc7541.html#indexing.tables |
| 10 |
| 11 // Note that the Lookup methods return nullptr if the requested index was not |
| 12 // found. This should be treated as a COMPRESSION error according to the HTTP/2 |
| 13 // spec, which is a connection level protocol error (i.e. the connection must |
| 14 // be terminated). See these sections in the two RFCs: |
| 15 // http://httpwg.org/specs/rfc7541.html#indexed.header.representation |
| 16 // http://httpwg.org/specs/rfc7541.html#index.address.space |
| 17 // http://httpwg.org/specs/rfc7540.html#HeaderBlock |
| 18 |
| 19 #include <stddef.h> |
| 20 |
| 21 #include <deque> |
| 22 #include <functional> |
| 23 #include <vector> |
| 24 |
| 25 #include "base/macros.h" |
| 26 #include "net/base/net_export.h" |
| 27 #include "net/http2/hpack/hpack_string.h" |
| 28 #include "net/http2/http2_constants.h" |
| 29 |
| 30 namespace net { |
| 31 namespace test { |
| 32 class HpackDecoderTablesPeer; |
| 33 } // namespace test |
| 34 |
| 35 const size_t kFirstDynamicTableIndex = 62; |
| 36 |
| 37 // See http://httpwg.org/specs/rfc7541.html#static.table.definition for the |
| 38 // contents, and http://httpwg.org/specs/rfc7541.html#index.address.space for |
| 39 // info about accessing the static table. |
| 40 class NET_EXPORT_PRIVATE HpackDecoderStaticTable { |
| 41 public: |
| 42 explicit HpackDecoderStaticTable(const std::vector<HpackStringPair>* table); |
| 43 // Uses a global table shared by all threads. |
| 44 HpackDecoderStaticTable(); |
| 45 |
| 46 // If index is valid, returns a pointer to the entry, otherwise returns |
| 47 // nullptr. |
| 48 const HpackStringPair* Lookup(size_t index) const; |
| 49 |
| 50 private: |
| 51 friend class test::HpackDecoderTablesPeer; |
| 52 const std::vector<HpackStringPair>* const table_; |
| 53 }; |
| 54 |
| 55 // HpackDecoderDynamicTable implements HPACK compression feature "indexed |
| 56 // headers"; previously sent headers may be referenced later by their index |
| 57 // in the dynamic table. See these sections of the RFC: |
| 58 // http://httpwg.org/specs/rfc7541.html#dynamic.table |
| 59 // http://httpwg.org/specs/rfc7541.html#dynamic.table.management |
| 60 class NET_EXPORT_PRIVATE HpackDecoderDynamicTable { |
| 61 public: |
| 62 HpackDecoderDynamicTable(); |
| 63 ~HpackDecoderDynamicTable(); |
| 64 |
| 65 // Sets a new size limit, received from the peer; performs evictions if |
| 66 // necessary to ensure that the current size does not exceed the new limit. |
| 67 // The caller needs to have validated that size_limit does not |
| 68 // exceed the acknowledged value of SETTINGS_HEADER_TABLE_SIZE. |
| 69 void DynamicTableSizeUpdate(size_t size_limit); |
| 70 |
| 71 // Returns true if inserted, false if too large (at which point the |
| 72 // dynamic table will be empty.) |
| 73 bool Insert(const HpackString& name, const HpackString& value); |
| 74 |
| 75 // If index is valid, returns a pointer to the entry, otherwise returns |
| 76 // nullptr. |
| 77 const HpackStringPair* Lookup(size_t index) const; |
| 78 |
| 79 size_t size_limit() const { return size_limit_; } |
| 80 size_t current_size() const { return current_size_; } |
| 81 |
| 82 private: |
| 83 friend class test::HpackDecoderTablesPeer; |
| 84 |
| 85 // Drop older entries to ensure the size is not greater than limit. |
| 86 void EnsureSizeNoMoreThan(size_t limit); |
| 87 |
| 88 // Removes the oldest dynamic table entry. |
| 89 void RemoveLastEntry(); |
| 90 |
| 91 // The last received DynamicTableSizeUpdate value, initialized to |
| 92 // SETTINGS_HEADER_TABLE_SIZE. |
| 93 size_t size_limit_ = Http2SettingsInfo::DefaultHeaderTableSize(); |
| 94 |
| 95 size_t current_size_ = 0; |
| 96 |
| 97 std::deque<HpackStringPair> table_; |
| 98 |
| 99 DISALLOW_COPY_AND_ASSIGN(HpackDecoderDynamicTable); |
| 100 }; |
| 101 |
| 102 class NET_EXPORT_PRIVATE HpackDecoderTables { |
| 103 public: |
| 104 HpackDecoderTables(); |
| 105 ~HpackDecoderTables(); |
| 106 |
| 107 // Sets a new size limit, received from the peer; performs evictions if |
| 108 // necessary to ensure that the current size does not exceed the new limit. |
| 109 // The caller needs to have validated that size_limit does not |
| 110 // exceed the acknowledged value of SETTINGS_HEADER_TABLE_SIZE. |
| 111 void DynamicTableSizeUpdate(size_t size_limit) { |
| 112 dynamic_table_.DynamicTableSizeUpdate(size_limit); |
| 113 } |
| 114 |
| 115 // Returns true if inserted, false if too large (at which point the |
| 116 // dynamic table will be empty.) |
| 117 // TODO(jamessynge): Add methods for moving the string(s) into the table, |
| 118 // or for otherwise avoiding unnecessary copies. |
| 119 bool Insert(const HpackString& name, const HpackString& value) { |
| 120 return dynamic_table_.Insert(name, value); |
| 121 } |
| 122 |
| 123 // If index is valid, returns a pointer to the entry, otherwise returns |
| 124 // nullptr. |
| 125 const HpackStringPair* Lookup(size_t index) const { |
| 126 if (index < kFirstDynamicTableIndex) { |
| 127 return static_table_.Lookup(index); |
| 128 } else { |
| 129 return dynamic_table_.Lookup(index - kFirstDynamicTableIndex); |
| 130 } |
| 131 } |
| 132 |
| 133 // The size limit that the peer (the HPACK encoder) has told the decoder it is |
| 134 // currently operating with. Defaults to SETTINGS_HEADER_TABLE_SIZE, 4096. |
| 135 size_t header_table_size_limit() const { return dynamic_table_.size_limit(); } |
| 136 |
| 137 // Sum of the sizes of the dynamic table entries. |
| 138 size_t current_header_table_size() const { |
| 139 return dynamic_table_.current_size(); |
| 140 } |
| 141 |
| 142 private: |
| 143 friend class test::HpackDecoderTablesPeer; |
| 144 HpackDecoderStaticTable static_table_; |
| 145 HpackDecoderDynamicTable dynamic_table_; |
| 146 |
| 147 DISALLOW_COPY_AND_ASSIGN(HpackDecoderTables); |
| 148 }; |
| 149 |
| 150 } // namespace net |
| 151 |
| 152 #endif // NET_HTTP2_HPACK_DECODER_HPACK_DECODER_TABLES_H_ |
OLD | NEW |