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 |