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.
5 #ifndef NET_SPDY_HPACK_DECODER_H_
6 #define NET_SPDY_HPACK_DECODER_H_
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/hpack_header_table.h"
17 #include "net/spdy/hpack/hpack_input_stream.h"
18 #include "net/spdy/spdy_protocol.h"
20 // An HpackDecoder decodes header sets as outlined in
21 // http://tools.ietf.org/html/rfc7541.
25 class HpackHuffmanTable
;
28 class HpackDecoderPeer
;
31 class NET_EXPORT_PRIVATE HpackDecoder
{
33 friend class test::HpackDecoderPeer
;
35 // |table| is an initialized HPACK Huffman table, having an
36 // externally-managed lifetime which spans beyond HpackDecoder.
37 explicit HpackDecoder(const HpackHuffmanTable
& table
);
40 // Called upon acknowledgement of SETTINGS_HEADER_TABLE_SIZE.
41 void ApplyHeaderTableSizeSetting(size_t size_setting
) {
42 header_table_
.SetSettingsHeaderTableSize(size_setting
);
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
);
53 // Called after a headers block has been completely delivered via
54 // HandleControlFrameHeadersData(). Returns false if an error
55 // occurred. |compressed_len| if non-null will be set to the size
56 // of the encoded buffered block that was accumulated in
57 // HandleControlFrameHeadersData(), to support subsequent
58 // calculation of compression percentage. TODO(jgraettinger): A
59 // future version of this method will simply deliver the Cookie
60 // header (which has been incrementally reconstructed) and notify
61 // the visitor that the block is finished. For now, this method
62 // decodes the complete buffered block, and stores results to
64 bool HandleControlFrameHeadersComplete(SpdyStreamId stream_id
,
65 size_t* compressed_len
);
67 // Accessor for the most recently decoded headers block. Valid until the next
68 // call to HandleControlFrameHeadersData().
69 // TODO(jgraettinger): This was added to facilitate re-encoding the block in
70 // SPDY3 format for delivery to the SpdyFramer visitor, and will be removed
71 // with the migration to SpdyHeadersHandlerInterface.
72 const SpdyHeaderBlock
& decoded_block() { return decoded_block_
; }
75 // Adds the header representation to |decoded_block_|, applying the
77 // - Multiple values of the Cookie header are joined, delmited by '; '.
78 // This reconstruction is required to properly handle Cookie crumbling
79 // (as per section 8.1.2.5 in RFC 7540).
80 // - Multiple values of other headers are joined and delimited by '\0'.
81 // Note that this may be too accomodating, as the sender's HTTP2 layer
82 // should have already joined and delimited these values.
84 // Returns false if a pseudo-header field follows a regular header one, which
85 // MUST be treated as malformed, as per sections 8.1.2.3. of the HTTP2
86 // specification (RFC 7540).
88 // TODO(jgraettinger): This method will eventually emit to the
89 // SpdyHeadersHandlerInterface visitor.
90 bool HandleHeaderRepresentation(base::StringPiece name
,
91 base::StringPiece value
);
93 const uint32 max_string_literal_size_
;
94 HpackHeaderTable header_table_
;
96 // TODO(jgraettinger): Buffer for headers data, and storage for the last-
97 // processed headers block. Both will be removed with the switch to
98 // SpdyHeadersHandlerInterface.
99 std::string headers_block_buffer_
;
100 SpdyHeaderBlock decoded_block_
;
102 // Flag to keep track of having seen a regular header field.
103 bool regular_header_seen_
;
105 // Huffman table to be applied to decoded Huffman literals,
106 // and scratch space for storing those decoded literals.
107 const HpackHuffmanTable
& huffman_table_
;
108 std::string key_buffer_
, value_buffer_
;
110 // Handlers for decoding HPACK opcodes and header representations
111 // (or parts thereof). These methods return true on success and
113 bool DecodeNextOpcode(HpackInputStream
* input_stream
);
114 bool DecodeNextHeaderTableSizeUpdate(HpackInputStream
* input_stream
);
115 bool DecodeNextIndexedHeader(HpackInputStream
* input_stream
);
116 bool DecodeNextLiteralHeader(HpackInputStream
* input_stream
,
118 bool DecodeNextName(HpackInputStream
* input_stream
,
119 base::StringPiece
* next_name
);
120 bool DecodeNextStringLiteral(HpackInputStream
* input_stream
,
121 bool is_header_key
, // As distinct from a value.
122 base::StringPiece
* output
);
124 DISALLOW_COPY_AND_ASSIGN(HpackDecoder
);
129 #endif // NET_SPDY_HPACK_DECODER_H_