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-07 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 // TODO(jgraettinger): This method will eventually emit to the 81 // SpdyHeadersHandlerInterface visitor. 82 void HandleHeaderRepresentation(base::StringPiece name, 83 base::StringPiece value); 84 85 const uint32 max_string_literal_size_; 86 HpackHeaderTable header_table_; 87 88 // Incrementally reconstructed cookie value. 89 std::string cookie_value_; 90 91 // TODO(jgraettinger): Buffer for headers data, and storage for the last- 92 // processed headers block. Both will be removed with the switch to 93 // SpdyHeadersHandlerInterface. 94 std::string headers_block_buffer_; 95 std::map<std::string, std::string> decoded_block_; 96 97 // Huffman table to be applied to decoded Huffman literals, 98 // and scratch space for storing those decoded literals. 99 const HpackHuffmanTable& huffman_table_; 100 std::string key_buffer_, value_buffer_; 101 102 // Handlers for decoding HPACK opcodes and header representations 103 // (or parts thereof). These methods return true on success and 104 // false on error. 105 bool DecodeNextOpcode(HpackInputStream* input_stream); 106 bool DecodeNextContextUpdate(HpackInputStream* input_stream); 107 bool DecodeNextIndexedHeader(HpackInputStream* input_stream); 108 bool DecodeNextLiteralHeader(HpackInputStream* input_stream, 109 bool should_index); 110 bool DecodeNextName(HpackInputStream* input_stream, 111 base::StringPiece* next_name); 112 bool DecodeNextStringLiteral(HpackInputStream* input_stream, 113 bool is_header_key, // As distinct from a value. 114 base::StringPiece* output); 115 116 DISALLOW_COPY_AND_ASSIGN(HpackDecoder); 117 }; 118 119 } // namespace net 120 121 #endif // NET_SPDY_HPACK_DECODER_H_ 122