Home | History | Annotate | Download | only in spdy
      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