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