| 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 |