| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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_SPDY_HPACK_HPACK_ENCODER_H_ | |
| 6 #define NET_SPDY_HPACK_HPACK_ENCODER_H_ | |
| 7 | |
| 8 #include <stddef.h> | |
| 9 | |
| 10 #include <functional> | |
| 11 #include <map> | |
| 12 #include <memory> | |
| 13 #include <utility> | |
| 14 #include <vector> | |
| 15 | |
| 16 #include "base/macros.h" | |
| 17 #include "net/base/net_export.h" | |
| 18 #include "net/spdy/hpack/hpack_header_table.h" | |
| 19 #include "net/spdy/hpack/hpack_output_stream.h" | |
| 20 #include "net/spdy/platform/api/spdy_string.h" | |
| 21 #include "net/spdy/platform/api/spdy_string_piece.h" | |
| 22 #include "net/spdy/spdy_protocol.h" | |
| 23 | |
| 24 // An HpackEncoder encodes header sets as outlined in | |
| 25 // http://tools.ietf.org/html/rfc7541. | |
| 26 | |
| 27 namespace net { | |
| 28 | |
| 29 class HpackHuffmanTable; | |
| 30 | |
| 31 namespace test { | |
| 32 class HpackEncoderPeer; | |
| 33 } // namespace test | |
| 34 | |
| 35 class NET_EXPORT_PRIVATE HpackEncoder { | |
| 36 public: | |
| 37 using Representation = std::pair<SpdyStringPiece, SpdyStringPiece>; | |
| 38 using Representations = std::vector<Representation>; | |
| 39 | |
| 40 // Callers may provide a HeaderListener to be informed of header name-value | |
| 41 // pairs processed by this encoder. | |
| 42 typedef std::function<void(SpdyStringPiece, SpdyStringPiece)> HeaderListener; | |
| 43 | |
| 44 // An indexing policy should return true if the provided header name-value | |
| 45 // pair should be inserted into the HPACK dynamic table. | |
| 46 using IndexingPolicy = std::function<bool(SpdyStringPiece, SpdyStringPiece)>; | |
| 47 | |
| 48 // |table| is an initialized HPACK Huffman table, having an | |
| 49 // externally-managed lifetime which spans beyond HpackEncoder. | |
| 50 explicit HpackEncoder(const HpackHuffmanTable& table); | |
| 51 ~HpackEncoder(); | |
| 52 | |
| 53 // Encodes a sequence of Representations into the given string. | |
| 54 void EncodeHeaderSet(const Representations& representations, | |
| 55 SpdyString* output); | |
| 56 | |
| 57 // Encodes the given header set into the given string. Returns | |
| 58 // whether or not the encoding was successful. | |
| 59 bool EncodeHeaderSet(const SpdyHeaderBlock& header_set, SpdyString* output); | |
| 60 | |
| 61 class NET_EXPORT_PRIVATE ProgressiveEncoder { | |
| 62 public: | |
| 63 virtual ~ProgressiveEncoder() {} | |
| 64 | |
| 65 // Returns true iff more remains to encode. | |
| 66 virtual bool HasNext() const = 0; | |
| 67 | |
| 68 // Encodes up to max_encoded_bytes of the current header block into the | |
| 69 // given output string. | |
| 70 virtual void Next(size_t max_encoded_bytes, SpdyString* output) = 0; | |
| 71 }; | |
| 72 | |
| 73 // Returns a ProgressiveEncoder which must be outlived by both the given | |
| 74 // SpdyHeaderBlock and this object. | |
| 75 std::unique_ptr<ProgressiveEncoder> EncodeHeaderSet( | |
| 76 const SpdyHeaderBlock& header_set); | |
| 77 | |
| 78 // Called upon a change to SETTINGS_HEADER_TABLE_SIZE. Specifically, this | |
| 79 // is to be called after receiving (and sending an acknowledgement for) a | |
| 80 // SETTINGS_HEADER_TABLE_SIZE update from the remote decoding endpoint. | |
| 81 void ApplyHeaderTableSizeSetting(size_t size_setting); | |
| 82 | |
| 83 size_t CurrentHeaderTableSizeSetting() const { | |
| 84 return header_table_.settings_size_bound(); | |
| 85 } | |
| 86 | |
| 87 // This HpackEncoder will use |policy| to determine whether to insert header | |
| 88 // name-value pairs into the dynamic table. | |
| 89 void SetIndexingPolicy(IndexingPolicy policy) { should_index_ = policy; } | |
| 90 | |
| 91 // |listener| will be invoked for each header name-value pair processed by | |
| 92 // this encoder. | |
| 93 void SetHeaderListener(HeaderListener listener) { listener_ = listener; } | |
| 94 | |
| 95 void SetHeaderTableDebugVisitor( | |
| 96 std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { | |
| 97 header_table_.set_debug_visitor(std::move(visitor)); | |
| 98 } | |
| 99 | |
| 100 void DisableCompression() { enable_compression_ = false; } | |
| 101 | |
| 102 // Returns the estimate of dynamically allocated memory in bytes. | |
| 103 size_t EstimateMemoryUsage() const; | |
| 104 | |
| 105 private: | |
| 106 friend class test::HpackEncoderPeer; | |
| 107 | |
| 108 class RepresentationIterator; | |
| 109 class Encoderator; | |
| 110 | |
| 111 // Encodes a sequence of header name-value pairs as a single header block. | |
| 112 void EncodeRepresentations(RepresentationIterator* iter, SpdyString* output); | |
| 113 | |
| 114 // Emits a static/dynamic indexed representation (Section 7.1). | |
| 115 void EmitIndex(const HpackEntry* entry); | |
| 116 | |
| 117 // Emits a literal representation (Section 7.2). | |
| 118 void EmitIndexedLiteral(const Representation& representation); | |
| 119 void EmitNonIndexedLiteral(const Representation& representation); | |
| 120 void EmitLiteral(const Representation& representation); | |
| 121 | |
| 122 // Emits a Huffman or identity string (whichever is smaller). | |
| 123 void EmitString(SpdyStringPiece str); | |
| 124 | |
| 125 // Emits the current dynamic table size if the table size was recently | |
| 126 // updated and we have not yet emitted it (Section 6.3). | |
| 127 void MaybeEmitTableSize(); | |
| 128 | |
| 129 // Crumbles a cookie header into ";" delimited crumbs. | |
| 130 static void CookieToCrumbs(const Representation& cookie, | |
| 131 Representations* crumbs_out); | |
| 132 | |
| 133 // Crumbles other header field values at \0 delimiters. | |
| 134 static void DecomposeRepresentation(const Representation& header_field, | |
| 135 Representations* out); | |
| 136 | |
| 137 // Gathers headers without crumbling. Used when compression is not enabled. | |
| 138 static void GatherRepresentation(const Representation& header_field, | |
| 139 Representations* out); | |
| 140 | |
| 141 HpackHeaderTable header_table_; | |
| 142 HpackOutputStream output_stream_; | |
| 143 | |
| 144 const HpackHuffmanTable& huffman_table_; | |
| 145 size_t min_table_size_setting_received_; | |
| 146 HeaderListener listener_; | |
| 147 IndexingPolicy should_index_; | |
| 148 bool enable_compression_; | |
| 149 bool should_emit_table_size_; | |
| 150 | |
| 151 DISALLOW_COPY_AND_ASSIGN(HpackEncoder); | |
| 152 }; | |
| 153 | |
| 154 } // namespace net | |
| 155 | |
| 156 #endif // NET_SPDY_HPACK_HPACK_ENCODER_H_ | |
| OLD | NEW |