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_DECODER_H_ | |
6 #define NET_SPDY_HPACK_DECODER_H_ | |
7 | |
8 #include <map> | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/macros.h" | |
14 #include "base/strings/string_piece.h" | |
15 #include "net/base/net_export.h" | |
16 #include "net/spdy/hpack_header_table.h" | |
17 #include "net/spdy/hpack_input_stream.h" | |
18 #include "net/spdy/spdy_protocol.h" | |
19 | |
20 // An HpackDecoder decodes header sets as outlined in | |
21 // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08 | |
22 | |
23 namespace net { | |
24 | |
25 class HpackHuffmanTable; | |
26 | |
27 namespace test { | |
28 class HpackDecoderPeer; | |
29 } // namespace test | |
30 | |
31 class NET_EXPORT_PRIVATE HpackDecoder { | |
32 public: | |
33 friend class test::HpackDecoderPeer; | |
34 | |
35 // |table| is an initialized HPACK Huffman table, having an | |
36 // externally-managed lifetime which spans beyond HpackDecoder. | |
37 explicit HpackDecoder(const HpackHuffmanTable& table); | |
38 ~HpackDecoder(); | |
39 | |
40 // Called upon acknowledgement of SETTINGS_HEADER_TABLE_SIZE. | |
41 void ApplyHeaderTableSizeSetting(size_t size_setting) { | |
42 header_table_.SetSettingsHeaderTableSize(size_setting); | |
43 } | |
44 | |
45 // Called as headers data arrives. Returns false if an error occurred. | |
46 // TODO(jgraettinger): A future version of this method will incrementally | |
47 // parse and deliver headers via SpdyHeadersHandlerInterface. For now, | |
48 // header data is buffered until HandleControlFrameHeadersComplete(). | |
49 bool HandleControlFrameHeadersData(SpdyStreamId stream_id, | |
50 const char* headers_data, | |
51 size_t headers_data_length); | |
52 | |
53 // Called after a headers block has been completely delivered via | |
54 // HandleControlFrameHeadersData(). Returns false if an error occurred. | |
55 // TODO(jgraettinger): A future version of this method will simply deliver | |
56 // the Cookie header (which has been incrementally reconstructed) and notify | |
57 // the visitor that the block is finished. For now, this method decodes the | |
58 // complete buffered block, and stores results to |decoded_block_|. | |
59 bool HandleControlFrameHeadersComplete(SpdyStreamId stream_id); | |
60 | |
61 // Accessor for the most recently decoded headers block. Valid until the next | |
62 // call to HandleControlFrameHeadersData(). | |
63 // TODO(jgraettinger): This was added to facilitate re-encoding the block in | |
64 // SPDY3 format for delivery to the SpdyFramer visitor, and will be removed | |
65 // with the migration to SpdyHeadersHandlerInterface. | |
66 const std::map<std::string, std::string>& decoded_block() { | |
67 return decoded_block_; | |
68 } | |
69 | |
70 private: | |
71 // Adds the header representation to |decoded_block_|, applying the | |
72 // following rules, as per sections 8.1.3.3 & 8.1.3.4 of the HTTP2 draft | |
73 // specification: | |
74 // - Multiple values of the Cookie header are joined, delmited by '; '. | |
75 // This reconstruction is required to properly handle Cookie crumbling. | |
76 // - Multiple values of other headers are joined and delimited by '\0'. | |
77 // Note that this may be too accomodating, as the sender's HTTP2 layer | |
78 // should have already joined and delimited these values. | |
79 // | |
80 // Returns false if a pseudo-header field follows a regular header one, which | |
81 // MUST be treated as malformed, as per sections 8.1.2.1. of the HTTP2 draft | |
82 // specification. | |
83 // | |
84 // TODO(jgraettinger): This method will eventually emit to the | |
85 // SpdyHeadersHandlerInterface visitor. | |
86 bool HandleHeaderRepresentation(base::StringPiece name, | |
87 base::StringPiece value); | |
88 | |
89 const uint32 max_string_literal_size_; | |
90 HpackHeaderTable header_table_; | |
91 | |
92 // Incrementally reconstructed cookie value. | |
93 std::string cookie_value_; | |
94 | |
95 // TODO(jgraettinger): Buffer for headers data, and storage for the last- | |
96 // processed headers block. Both will be removed with the switch to | |
97 // SpdyHeadersHandlerInterface. | |
98 std::string headers_block_buffer_; | |
99 std::map<std::string, std::string> decoded_block_; | |
100 | |
101 // Flag to keep track of having seen a regular header field. | |
102 bool regular_header_seen_; | |
103 | |
104 // Huffman table to be applied to decoded Huffman literals, | |
105 // and scratch space for storing those decoded literals. | |
106 const HpackHuffmanTable& huffman_table_; | |
107 std::string key_buffer_, value_buffer_; | |
108 | |
109 // Handlers for decoding HPACK opcodes and header representations | |
110 // (or parts thereof). These methods return true on success and | |
111 // false on error. | |
112 bool DecodeNextOpcode(HpackInputStream* input_stream); | |
113 bool DecodeNextHeaderTableSizeUpdate(HpackInputStream* input_stream); | |
114 bool DecodeNextIndexedHeader(HpackInputStream* input_stream); | |
115 bool DecodeNextLiteralHeader(HpackInputStream* input_stream, | |
116 bool should_index); | |
117 bool DecodeNextName(HpackInputStream* input_stream, | |
118 base::StringPiece* next_name); | |
119 bool DecodeNextStringLiteral(HpackInputStream* input_stream, | |
120 bool is_header_key, // As distinct from a value. | |
121 base::StringPiece* output); | |
122 | |
123 DISALLOW_COPY_AND_ASSIGN(HpackDecoder); | |
124 }; | |
125 | |
126 } // namespace net | |
127 | |
128 #endif // NET_SPDY_HPACK_DECODER_H_ | |
OLD | NEW |