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_SPDY_HEADERS_BLOCK_PARSER_H_
      6 #define NET_SPDY_SPDY_HEADERS_BLOCK_PARSER_H_
      7 
      8 #include "base/logging.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/strings/string_piece.h"
     11 #include "net/base/net_export.h"
     12 #include "net/spdy/spdy_prefixed_buffer_reader.h"
     13 #include "net/spdy/spdy_protocol.h"
     14 
     15 namespace net {
     16 
     17 // A handler class for SPDY headers.
     18 class SpdyHeadersHandlerInterface {
     19  public:
     20   virtual ~SpdyHeadersHandlerInterface() {}
     21 
     22   // A callback method which notifies when the parser starts handling a new
     23   // SPDY headers block, this method also notifies on the number of headers in
     24   // the block.
     25   virtual void OnHeaderBlock(SpdyStreamId stream_id,
     26                              uint32_t num_of_headers) = 0;
     27 
     28   // A callback method which notifies on a SPDY header key value pair.
     29   virtual void OnHeader(SpdyStreamId stream_id,
     30                         base::StringPiece key,
     31                         base::StringPiece value) = 0;
     32 
     33   // A callback method which notifies when the parser finishes handling a SPDY
     34   // headers block. Also notifies on the total number of bytes in this block.
     35   virtual void OnHeaderBlockEnd(SpdyStreamId stream_id,
     36                                 size_t header_bytes_parsed) = 0;
     37 };
     38 
     39 namespace test {
     40 
     41 class SpdyHeadersBlockParserPeer;
     42 
     43 }  // namespace test
     44 
     45 // This class handles SPDY headers block bytes and parses out key-value pairs
     46 // as they arrive. This class is not thread-safe, and assumes that all headers
     47 // block bytes are processed in a single thread.
     48 class NET_EXPORT_PRIVATE SpdyHeadersBlockParser {
     49  public:
     50   // Bound on acceptable header name or value length.
     51   static const size_t kMaximumFieldLength;  // = 16 * 1024
     52 
     53   // Constructor. The handler's OnHeader will be called for every key
     54   // value pair that we parsed from the headers block.
     55   SpdyHeadersBlockParser(SpdyMajorVersion spdy_version,
     56                          SpdyHeadersHandlerInterface* handler);
     57 
     58   virtual ~SpdyHeadersBlockParser();
     59 
     60   // Handles headers block data as it arrives. Returns false if an error has
     61   // been set, which can include the recoverable error NEED_MORE_DATA. Returns
     62   // true if the invocation completes the parse of the entire headers block,
     63   // in which case the parser is ready for a new headers block.
     64   bool HandleControlFrameHeadersData(SpdyStreamId stream_id,
     65                                      const char* headers_data,
     66                                      size_t len);
     67   enum ParserError {
     68     OK,
     69     // Set when parsing failed due to insufficient data.
     70     // This error is recoverable, by passing in new data.
     71     NEED_MORE_DATA,
     72     // Set when a complete block has been read, but unprocessed data remains.
     73     TOO_MUCH_DATA,
     74     // Set when a block exceeds |MaxNumberOfHeadersForVersion| headers.
     75     HEADER_BLOCK_TOO_LARGE,
     76     // Set when a header key or value exceeds |kMaximumFieldLength|.
     77     HEADER_FIELD_TOO_LARGE,
     78   };
     79   ParserError get_error() const { return error_; }
     80 
     81   // Resets the state of the parser to prepare it for a headers block of a
     82   // new frame.
     83   void Reset();
     84 
     85   // Returns the size in bytes of a length field in a SPDY header.
     86   static size_t LengthFieldSizeForVersion(SpdyMajorVersion spdy_version);
     87 
     88   // Returns the maximal number of headers in a SPDY headers block.
     89   static size_t MaxNumberOfHeadersForVersion(SpdyMajorVersion spdy_version);
     90 
     91  private:
     92   typedef SpdyPrefixedBufferReader Reader;
     93 
     94   // Parses and sanity-checks header block length.
     95   void ParseBlockLength(Reader* reader);
     96 
     97   // Parses and sanity-checks header field length.
     98   void ParseFieldLength(Reader* reader);
     99 
    100   // Parses and decodes network-order lengths into |parsed_length|.
    101   void ParseLength(Reader* reader, uint32_t* parsed_length);
    102 
    103   // The state of the parser.
    104   enum ParserState {
    105     READING_HEADER_BLOCK_LEN,
    106     READING_KEY_LEN,
    107     READING_KEY,
    108     READING_VALUE_LEN,
    109     READING_VALUE,
    110     FINISHED_HEADER
    111   };
    112   ParserState state_;
    113 
    114   // Size in bytes of a length field in the spdy header.
    115   const size_t length_field_size_;
    116 
    117   // The maximal number of headers in a SPDY headers block.
    118   const size_t max_headers_in_block_;
    119 
    120   // A running total of the bytes parsed since the last call to Reset().
    121   size_t total_bytes_received_;
    122 
    123   // Number of key-value pairs until we complete handling the current
    124   // headers block.
    125   uint32_t remaining_key_value_pairs_for_frame_;
    126 
    127   // The length of the next header field to be read (either key or value).
    128   uint32_t next_field_length_;
    129 
    130   // Handles key-value pairs as we parse them.
    131   SpdyHeadersHandlerInterface* handler_;
    132 
    133   // Holds unprocessed buffer remainders between calls to
    134   // |HandleControlFrameHeadersData|.
    135   SpdyPinnableBufferPiece headers_block_prefix_;
    136 
    137   // Holds the key of a partially processed header between calls to
    138   // |HandleControlFrameHeadersData|.
    139   SpdyPinnableBufferPiece key_;
    140 
    141   // The current header block stream identifier.
    142   SpdyStreamId stream_id_;
    143 
    144   ParserError error_;
    145 };
    146 
    147 }  // namespace net
    148 
    149 #endif  // NET_SPDY_SPDY_HEADERS_BLOCK_PARSER_H_
    150