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 namespace { |
| 11 |
| 12 // 0 is invalid according to both the SPDY 3.1 and HTTP/2 specifications. |
| 13 const SpdyStreamId kInvalidStreamId = 0; |
| 14 |
| 15 } // anonymous namespace |
10 | 16 |
11 const size_t SpdyHeadersBlockParser::kMaximumFieldLength = 16 * 1024; | 17 const size_t SpdyHeadersBlockParser::kMaximumFieldLength = 16 * 1024; |
12 | 18 |
13 SpdyHeadersBlockParser::SpdyHeadersBlockParser( | 19 SpdyHeadersBlockParser::SpdyHeadersBlockParser( |
14 SpdyMajorVersion spdy_version, | 20 SpdyMajorVersion spdy_version, |
15 SpdyHeadersHandlerInterface* handler) | 21 SpdyHeadersHandlerInterface* handler) |
16 : state_(READING_HEADER_BLOCK_LEN), | 22 : state_(READING_HEADER_BLOCK_LEN), |
17 length_field_size_(LengthFieldSizeForVersion(spdy_version)), | 23 length_field_size_(LengthFieldSizeForVersion(spdy_version)), |
18 max_headers_in_block_(MaxNumberOfHeadersForVersion(spdy_version)), | 24 max_headers_in_block_(MaxNumberOfHeadersForVersion(spdy_version)), |
19 total_bytes_received_(0), | 25 total_bytes_received_(0), |
20 remaining_key_value_pairs_for_frame_(0), | 26 remaining_key_value_pairs_for_frame_(0), |
21 handler_(handler), | 27 handler_(handler), |
| 28 stream_id_(kInvalidStreamId), |
22 error_(OK), | 29 error_(OK), |
23 spdy_version_(spdy_version) { | 30 spdy_version_(spdy_version) { |
24 // The handler that we set must not be NULL. | 31 // The handler that we set must not be NULL. |
25 DCHECK(handler_ != NULL); | 32 DCHECK(handler_ != NULL); |
26 } | 33 } |
27 | 34 |
28 SpdyHeadersBlockParser::~SpdyHeadersBlockParser() {} | 35 SpdyHeadersBlockParser::~SpdyHeadersBlockParser() {} |
29 | 36 |
30 bool SpdyHeadersBlockParser::HandleControlFrameHeadersData( | 37 bool SpdyHeadersBlockParser::HandleControlFrameHeadersData( |
31 SpdyStreamId stream_id, | 38 SpdyStreamId stream_id, |
32 const char* headers_data, | 39 const char* headers_data, |
33 size_t headers_data_length) { | 40 size_t headers_data_length) { |
34 if (error_ == NEED_MORE_DATA) { | 41 if (error_ == NEED_MORE_DATA) { |
35 error_ = OK; | 42 error_ = OK; |
36 } | 43 } |
37 CHECK_EQ(error_, OK); | 44 if (error_ != OK) { |
| 45 LOG(DFATAL) << "Unexpected error: " << error_; |
| 46 return false; |
| 47 } |
38 | 48 |
39 // If this is the first call with the current header block, | 49 // If this is the first call with the current header block, |
40 // save its stream id. | 50 // save its stream id. |
41 if (state_ == READING_HEADER_BLOCK_LEN) { | 51 if (state_ == READING_HEADER_BLOCK_LEN && stream_id_ == kInvalidStreamId) { |
42 stream_id_ = stream_id; | 52 stream_id_ = stream_id; |
43 } | 53 } |
44 CHECK_EQ(stream_id_, stream_id); | 54 if (stream_id != stream_id_) { |
45 | 55 LOG(DFATAL) << "Unexpected stream id: " << stream_id << " (expected " |
| 56 << stream_id_ << ")"; |
| 57 error_ = UNEXPECTED_STREAM_ID; |
| 58 return false; |
| 59 } |
| 60 if (stream_id_ == kInvalidStreamId) { |
| 61 LOG(DFATAL) << "Expected nonzero stream id, saw: " << stream_id_; |
| 62 error_ = UNEXPECTED_STREAM_ID; |
| 63 return false; |
| 64 } |
46 total_bytes_received_ += headers_data_length; | 65 total_bytes_received_ += headers_data_length; |
47 | 66 |
48 SpdyPinnableBufferPiece prefix, key, value; | 67 SpdyPinnableBufferPiece prefix, key, value; |
49 // Simultaneously tie lifetimes to the stack, and clear member variables. | 68 // Simultaneously tie lifetimes to the stack, and clear member variables. |
50 prefix.Swap(&headers_block_prefix_); | 69 prefix.Swap(&headers_block_prefix_); |
51 key.Swap(&key_); | 70 key.Swap(&key_); |
52 | 71 |
53 // Apply the parsing state machine to the remaining prefix | 72 // Apply the parsing state machine to the remaining prefix |
54 // from last invocation, plus newly-available headers data. | 73 // from last invocation, plus newly-available headers data. |
55 Reader reader(prefix.buffer(), prefix.length(), | 74 Reader reader(prefix.buffer(), prefix.length(), |
(...skipping 18 matching lines...) Expand all Loading... |
74 break; | 93 break; |
75 case READING_VALUE_LEN: | 94 case READING_VALUE_LEN: |
76 next_state = READING_VALUE; | 95 next_state = READING_VALUE; |
77 ParseFieldLength(&reader); | 96 ParseFieldLength(&reader); |
78 break; | 97 break; |
79 case READING_VALUE: | 98 case READING_VALUE: |
80 next_state = FINISHED_HEADER; | 99 next_state = FINISHED_HEADER; |
81 if (!reader.ReadN(next_field_length_, &value)) { | 100 if (!reader.ReadN(next_field_length_, &value)) { |
82 error_ = NEED_MORE_DATA; | 101 error_ = NEED_MORE_DATA; |
83 } else { | 102 } else { |
84 handler_->OnHeader(stream_id, key, value); | 103 handler_->OnHeader(key, value); |
85 } | 104 } |
86 break; | 105 break; |
87 case FINISHED_HEADER: | 106 case FINISHED_HEADER: |
88 // Prepare for next header or block. | 107 // Prepare for next header or block. |
89 if (--remaining_key_value_pairs_for_frame_ > 0) { | 108 if (--remaining_key_value_pairs_for_frame_ > 0) { |
90 next_state = READING_KEY_LEN; | 109 next_state = READING_KEY_LEN; |
91 } else { | 110 } else { |
92 next_state = READING_HEADER_BLOCK_LEN; | 111 next_state = READING_HEADER_BLOCK_LEN; |
93 handler_->OnHeaderBlockEnd(stream_id, total_bytes_received_); | 112 handler_->OnHeaderBlockEnd(total_bytes_received_); |
| 113 stream_id_ = kInvalidStreamId; |
94 // Expect to have consumed all buffer. | 114 // Expect to have consumed all buffer. |
95 if (reader.Available() != 0) { | 115 if (reader.Available() != 0) { |
96 error_ = TOO_MUCH_DATA; | 116 error_ = TOO_MUCH_DATA; |
97 } | 117 } |
98 } | 118 } |
99 break; | 119 break; |
100 default: | |
101 CHECK(false) << "Not reached."; | |
102 } | 120 } |
103 | 121 |
104 if (error_ == OK) { | 122 if (error_ == OK) { |
105 state_ = next_state; | 123 state_ = next_state; |
106 | 124 |
107 if (next_state == READING_HEADER_BLOCK_LEN) { | 125 if (next_state == READING_HEADER_BLOCK_LEN) { |
108 // We completed reading a full header block. Return to caller. | 126 // We completed reading a full header block. Return to caller. |
109 total_bytes_received_ = 0; | 127 total_bytes_received_ = 0; |
110 break; | 128 break; |
111 } | 129 } |
(...skipping 11 matching lines...) Expand all Loading... |
123 return error_ == OK; | 141 return error_ == OK; |
124 } | 142 } |
125 | 143 |
126 void SpdyHeadersBlockParser::ParseBlockLength(Reader* reader) { | 144 void SpdyHeadersBlockParser::ParseBlockLength(Reader* reader) { |
127 ParseLength(reader, &remaining_key_value_pairs_for_frame_); | 145 ParseLength(reader, &remaining_key_value_pairs_for_frame_); |
128 if (error_ == OK && | 146 if (error_ == OK && |
129 remaining_key_value_pairs_for_frame_ > max_headers_in_block_) { | 147 remaining_key_value_pairs_for_frame_ > max_headers_in_block_) { |
130 error_ = HEADER_BLOCK_TOO_LARGE; | 148 error_ = HEADER_BLOCK_TOO_LARGE; |
131 } | 149 } |
132 if (error_ == OK) { | 150 if (error_ == OK) { |
133 handler_->OnHeaderBlock(stream_id_, remaining_key_value_pairs_for_frame_); | 151 handler_->OnHeaderBlock(remaining_key_value_pairs_for_frame_); |
134 } | 152 } |
135 } | 153 } |
136 | 154 |
137 void SpdyHeadersBlockParser::ParseFieldLength(Reader* reader) { | 155 void SpdyHeadersBlockParser::ParseFieldLength(Reader* reader) { |
138 ParseLength(reader, &next_field_length_); | 156 ParseLength(reader, &next_field_length_); |
139 if (error_ == OK && | 157 if (error_ == OK && |
140 next_field_length_ > kMaximumFieldLength) { | 158 next_field_length_ > kMaximumFieldLength) { |
141 error_ = HEADER_FIELD_TOO_LARGE; | 159 error_ = HEADER_FIELD_TOO_LARGE; |
142 } | 160 } |
143 } | 161 } |
(...skipping 26 matching lines...) Expand all Loading... |
170 // Account for the length of the header block field. | 188 // Account for the length of the header block field. |
171 size_t max_bytes_for_headers = | 189 size_t max_bytes_for_headers = |
172 kMaximumFieldLength - LengthFieldSizeForVersion(spdy_version); | 190 kMaximumFieldLength - LengthFieldSizeForVersion(spdy_version); |
173 | 191 |
174 // A minimal size header is twice the length field size (and has a | 192 // A minimal size header is twice the length field size (and has a |
175 // zero-lengthed key and a zero-lengthed value). | 193 // zero-lengthed key and a zero-lengthed value). |
176 return max_bytes_for_headers / (2 * LengthFieldSizeForVersion(spdy_version)); | 194 return max_bytes_for_headers / (2 * LengthFieldSizeForVersion(spdy_version)); |
177 } | 195 } |
178 | 196 |
179 } // namespace net | 197 } // namespace net |
OLD | NEW |