OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/spdy/spdy_headers_block_parser.h" | 5 #include "net/spdy/spdy_headers_block_parser.h" |
6 | 6 |
7 #include "base/sys_byteorder.h" | 7 #include "base/sys_byteorder.h" |
8 | 8 |
9 namespace net { | 9 namespace net { |
10 | 10 |
11 const size_t SpdyHeadersBlockParser::kMaximumFieldLength = 16 * 1024; | 11 const size_t SpdyHeadersBlockParser::kMaximumFieldLength = 16 * 1024; |
12 | 12 |
13 SpdyHeadersBlockParser::SpdyHeadersBlockParser( | 13 SpdyHeadersBlockParser::SpdyHeadersBlockParser( |
14 SpdyMajorVersion spdy_version, | 14 SpdyMajorVersion spdy_version, |
15 SpdyHeadersHandlerInterface* handler) : | 15 SpdyHeadersHandlerInterface* handler) : |
16 state_(READING_HEADER_BLOCK_LEN), | 16 state_(READING_HEADER_BLOCK_LEN), |
17 length_field_size_(LengthFieldSizeForVersion(spdy_version)), | 17 length_field_size_(LengthFieldSizeForVersion(spdy_version)), |
18 max_headers_in_block_(MaxNumberOfHeadersForVersion(spdy_version)), | 18 max_headers_in_block_(MaxNumberOfHeadersForVersion(spdy_version)), |
| 19 total_bytes_received_(0), |
19 remaining_key_value_pairs_for_frame_(0), | 20 remaining_key_value_pairs_for_frame_(0), |
20 handler_(handler), | 21 handler_(handler), |
21 error_(OK) { | 22 error_(OK) { |
22 // The handler that we set must not be NULL. | 23 // The handler that we set must not be NULL. |
23 DCHECK(handler_ != NULL); | 24 DCHECK(handler_ != NULL); |
24 } | 25 } |
25 | 26 |
26 SpdyHeadersBlockParser::~SpdyHeadersBlockParser() {} | 27 SpdyHeadersBlockParser::~SpdyHeadersBlockParser() {} |
27 | 28 |
28 bool SpdyHeadersBlockParser::HandleControlFrameHeadersData( | 29 bool SpdyHeadersBlockParser::HandleControlFrameHeadersData( |
29 SpdyStreamId stream_id, | 30 SpdyStreamId stream_id, |
30 const char* headers_data, | 31 const char* headers_data, |
31 size_t headers_data_length) { | 32 size_t headers_data_length) { |
32 if (error_ == NEED_MORE_DATA) { | 33 if (error_ == NEED_MORE_DATA) { |
33 error_ = OK; | 34 error_ = OK; |
34 } | 35 } |
35 CHECK_EQ(error_, OK); | 36 CHECK_EQ(error_, OK); |
36 | 37 |
37 // If this is the first call with the current header block, | 38 // If this is the first call with the current header block, |
38 // save its stream id. | 39 // save its stream id. |
39 if (state_ == READING_HEADER_BLOCK_LEN) { | 40 if (state_ == READING_HEADER_BLOCK_LEN) { |
40 stream_id_ = stream_id; | 41 stream_id_ = stream_id; |
41 } | 42 } |
42 CHECK_EQ(stream_id_, stream_id); | 43 CHECK_EQ(stream_id_, stream_id); |
43 | 44 |
| 45 total_bytes_received_ += headers_data_length; |
| 46 |
44 SpdyPinnableBufferPiece prefix, key, value; | 47 SpdyPinnableBufferPiece prefix, key, value; |
45 // Simultaneously tie lifetimes to the stack, and clear member variables. | 48 // Simultaneously tie lifetimes to the stack, and clear member variables. |
46 prefix.Swap(&headers_block_prefix_); | 49 prefix.Swap(&headers_block_prefix_); |
47 key.Swap(&key_); | 50 key.Swap(&key_); |
48 | 51 |
49 // Apply the parsing state machine to the remaining prefix | 52 // Apply the parsing state machine to the remaining prefix |
50 // from last invocation, plus newly-available headers data. | 53 // from last invocation, plus newly-available headers data. |
51 Reader reader(prefix.buffer(), prefix.length(), | 54 Reader reader(prefix.buffer(), prefix.length(), |
52 headers_data, headers_data_length); | 55 headers_data, headers_data_length); |
53 while (error_ == OK) { | 56 while (error_ == OK) { |
(...skipping 25 matching lines...) Expand all Loading... |
79 } else { | 82 } else { |
80 handler_->OnHeader(stream_id, key, value); | 83 handler_->OnHeader(stream_id, key, value); |
81 } | 84 } |
82 break; | 85 break; |
83 case FINISHED_HEADER: | 86 case FINISHED_HEADER: |
84 // Prepare for next header or block. | 87 // Prepare for next header or block. |
85 if (--remaining_key_value_pairs_for_frame_ > 0) { | 88 if (--remaining_key_value_pairs_for_frame_ > 0) { |
86 next_state = READING_KEY_LEN; | 89 next_state = READING_KEY_LEN; |
87 } else { | 90 } else { |
88 next_state = READING_HEADER_BLOCK_LEN; | 91 next_state = READING_HEADER_BLOCK_LEN; |
89 handler_->OnHeaderBlockEnd(stream_id); | 92 handler_->OnHeaderBlockEnd(stream_id, total_bytes_received_); |
90 // Expect to have consumed all buffer. | 93 // Expect to have consumed all buffer. |
91 if (reader.Available() != 0) { | 94 if (reader.Available() != 0) { |
92 error_ = TOO_MUCH_DATA; | 95 error_ = TOO_MUCH_DATA; |
93 } | 96 } |
94 } | 97 } |
95 break; | 98 break; |
96 default: | 99 default: |
97 CHECK(false) << "Not reached."; | 100 CHECK(false) << "Not reached."; |
98 } | 101 } |
99 | 102 |
100 if (error_ == OK) { | 103 if (error_ == OK) { |
101 state_ = next_state; | 104 state_ = next_state; |
102 | 105 |
103 if (next_state == READING_HEADER_BLOCK_LEN) { | 106 if (next_state == READING_HEADER_BLOCK_LEN) { |
104 // We completed reading a full header block. Return to caller. | 107 // We completed reading a full header block. Return to caller. |
| 108 total_bytes_received_ = 0; |
105 break; | 109 break; |
106 } | 110 } |
107 } else if (error_ == NEED_MORE_DATA) { | 111 } else if (error_ == NEED_MORE_DATA) { |
108 // We can't continue parsing until more data is available. Make copies of | 112 // We can't continue parsing until more data is available. Make copies of |
109 // the key and buffer remainder, in preperation for the next invocation. | 113 // the key and buffer remainder, in preperation for the next invocation. |
110 if (state_ > READING_KEY) { | 114 if (state_ > READING_KEY) { |
111 key_.Swap(&key); | 115 key_.Swap(&key); |
112 key_.Pin(); | 116 key_.Pin(); |
113 } | 117 } |
114 reader.ReadN(reader.Available(), &headers_block_prefix_); | 118 reader.ReadN(reader.Available(), &headers_block_prefix_); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 SpdyPinnableBufferPiece empty; | 161 SpdyPinnableBufferPiece empty; |
158 headers_block_prefix_.Swap(&empty); | 162 headers_block_prefix_.Swap(&empty); |
159 } | 163 } |
160 { | 164 { |
161 SpdyPinnableBufferPiece empty; | 165 SpdyPinnableBufferPiece empty; |
162 key_.Swap(&empty); | 166 key_.Swap(&empty); |
163 } | 167 } |
164 error_ = OK; | 168 error_ = OK; |
165 state_ = READING_HEADER_BLOCK_LEN; | 169 state_ = READING_HEADER_BLOCK_LEN; |
166 stream_id_ = 0; | 170 stream_id_ = 0; |
| 171 total_bytes_received_ = 0; |
167 } | 172 } |
168 | 173 |
169 size_t SpdyHeadersBlockParser::LengthFieldSizeForVersion( | 174 size_t SpdyHeadersBlockParser::LengthFieldSizeForVersion( |
170 SpdyMajorVersion spdy_version) { | 175 SpdyMajorVersion spdy_version) { |
171 if (spdy_version < SPDY3) { | 176 if (spdy_version < SPDY3) { |
172 return sizeof(uint16_t); | 177 return sizeof(uint16_t); |
173 } | 178 } |
174 return sizeof(uint32_t); | 179 return sizeof(uint32_t); |
175 } | 180 } |
176 | 181 |
177 size_t SpdyHeadersBlockParser::MaxNumberOfHeadersForVersion( | 182 size_t SpdyHeadersBlockParser::MaxNumberOfHeadersForVersion( |
178 SpdyMajorVersion spdy_version) { | 183 SpdyMajorVersion spdy_version) { |
179 // Account for the length of the header block field. | 184 // Account for the length of the header block field. |
180 size_t max_bytes_for_headers = | 185 size_t max_bytes_for_headers = |
181 kMaximumFieldLength - LengthFieldSizeForVersion(spdy_version); | 186 kMaximumFieldLength - LengthFieldSizeForVersion(spdy_version); |
182 | 187 |
183 // A minimal size header is twice the length field size (and has a | 188 // A minimal size header is twice the length field size (and has a |
184 // zero-lengthed key and a zero-lengthed value). | 189 // zero-lengthed key and a zero-lengthed value). |
185 return max_bytes_for_headers / (2 * LengthFieldSizeForVersion(spdy_version)); | 190 return max_bytes_for_headers / (2 * LengthFieldSizeForVersion(spdy_version)); |
186 } | 191 } |
187 | 192 |
188 } // namespace net | 193 } // namespace net |
OLD | NEW |