• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~SpdyHeadersHandlerInterface()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   };
get_error()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