Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: net/spdy/spdy_headers_block_parser.cc

Issue 885443002: Roll Chrome into Mojo. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Rebase to ToT mojo Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/spdy/spdy_headers_block_parser.h ('k') | net/spdy/spdy_headers_block_parser_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 { 10 namespace {
11 11
12 // 0 is invalid according to both the SPDY 3.1 and HTTP/2 specifications. 12 // 0 is invalid according to both the SPDY 3.1 and HTTP/2 specifications.
13 const SpdyStreamId kInvalidStreamId = 0; 13 const SpdyStreamId kInvalidStreamId = 0;
14 14
15 } // anonymous namespace 15 } // anonymous namespace
16 16
17 const size_t SpdyHeadersBlockParser::kMaximumFieldLength = 16 * 1024; 17 const size_t SpdyHeadersBlockParser::kMaximumFieldLength = 16 * 1024;
18 18
19 SpdyHeadersBlockParser::SpdyHeadersBlockParser( 19 SpdyHeadersBlockParser::SpdyHeadersBlockParser(
20 SpdyMajorVersion spdy_version, 20 SpdyMajorVersion spdy_version,
21 SpdyHeadersHandlerInterface* handler) 21 SpdyHeadersHandlerInterface* handler)
22 : state_(READING_HEADER_BLOCK_LEN), 22 : state_(READING_HEADER_BLOCK_LEN),
23 length_field_size_(LengthFieldSizeForVersion(spdy_version)), 23 length_field_size_(LengthFieldSizeForVersion(spdy_version)),
24 max_headers_in_block_(MaxNumberOfHeadersForVersion(spdy_version)), 24 max_headers_in_block_(MaxNumberOfHeadersForVersion(spdy_version)),
25 total_bytes_received_(0), 25 total_bytes_received_(0),
26 remaining_key_value_pairs_for_frame_(0), 26 remaining_key_value_pairs_for_frame_(0),
27 handler_(handler), 27 handler_(handler),
28 stream_id_(kInvalidStreamId), 28 stream_id_(kInvalidStreamId),
29 error_(OK), 29 error_(NO_PARSER_ERROR),
30 spdy_version_(spdy_version) { 30 spdy_version_(spdy_version) {
31 // The handler that we set must not be NULL. 31 // The handler that we set must not be NULL.
32 DCHECK(handler_ != NULL); 32 DCHECK(handler_ != NULL);
33 } 33 }
34 34
35 SpdyHeadersBlockParser::~SpdyHeadersBlockParser() {} 35 SpdyHeadersBlockParser::~SpdyHeadersBlockParser() {}
36 36
37 bool SpdyHeadersBlockParser::HandleControlFrameHeadersData( 37 bool SpdyHeadersBlockParser::HandleControlFrameHeadersData(
38 SpdyStreamId stream_id, 38 SpdyStreamId stream_id,
39 const char* headers_data, 39 const char* headers_data,
40 size_t headers_data_length) { 40 size_t headers_data_length) {
41 if (error_ == NEED_MORE_DATA) { 41 if (error_ == NEED_MORE_DATA) {
42 error_ = OK; 42 error_ = NO_PARSER_ERROR;
43 } 43 }
44 if (error_ != OK) { 44 if (error_ != NO_PARSER_ERROR) {
45 LOG(DFATAL) << "Unexpected error: " << error_; 45 LOG(DFATAL) << "Unexpected error: " << error_;
46 return false; 46 return false;
47 } 47 }
48 48
49 // If this is the first call with the current header block, 49 // If this is the first call with the current header block,
50 // save its stream id. 50 // save its stream id.
51 if (state_ == READING_HEADER_BLOCK_LEN && stream_id_ == kInvalidStreamId) { 51 if (state_ == READING_HEADER_BLOCK_LEN && stream_id_ == kInvalidStreamId) {
52 stream_id_ = stream_id; 52 stream_id_ = stream_id;
53 } 53 }
54 if (stream_id != stream_id_) { 54 if (stream_id != stream_id_) {
(...skipping 11 matching lines...) Expand all
66 66
67 SpdyPinnableBufferPiece prefix, key, value; 67 SpdyPinnableBufferPiece prefix, key, value;
68 // Simultaneously tie lifetimes to the stack, and clear member variables. 68 // Simultaneously tie lifetimes to the stack, and clear member variables.
69 prefix.Swap(&headers_block_prefix_); 69 prefix.Swap(&headers_block_prefix_);
70 key.Swap(&key_); 70 key.Swap(&key_);
71 71
72 // Apply the parsing state machine to the remaining prefix 72 // Apply the parsing state machine to the remaining prefix
73 // from last invocation, plus newly-available headers data. 73 // from last invocation, plus newly-available headers data.
74 Reader reader(prefix.buffer(), prefix.length(), 74 Reader reader(prefix.buffer(), prefix.length(),
75 headers_data, headers_data_length); 75 headers_data, headers_data_length);
76 while (error_ == OK) { 76 while (error_ == NO_PARSER_ERROR) {
77 ParserState next_state(FINISHED_HEADER); 77 ParserState next_state(FINISHED_HEADER);
78 78
79 switch (state_) { 79 switch (state_) {
80 case READING_HEADER_BLOCK_LEN: 80 case READING_HEADER_BLOCK_LEN:
81 next_state = READING_KEY_LEN; 81 next_state = READING_KEY_LEN;
82 ParseBlockLength(&reader); 82 ParseBlockLength(&reader);
83 break; 83 break;
84 case READING_KEY_LEN: 84 case READING_KEY_LEN:
85 next_state = READING_KEY; 85 next_state = READING_KEY;
86 ParseFieldLength(&reader); 86 ParseFieldLength(&reader);
(...skipping 25 matching lines...) Expand all
112 handler_->OnHeaderBlockEnd(total_bytes_received_); 112 handler_->OnHeaderBlockEnd(total_bytes_received_);
113 stream_id_ = kInvalidStreamId; 113 stream_id_ = kInvalidStreamId;
114 // Expect to have consumed all buffer. 114 // Expect to have consumed all buffer.
115 if (reader.Available() != 0) { 115 if (reader.Available() != 0) {
116 error_ = TOO_MUCH_DATA; 116 error_ = TOO_MUCH_DATA;
117 } 117 }
118 } 118 }
119 break; 119 break;
120 } 120 }
121 121
122 if (error_ == OK) { 122 if (error_ == NO_PARSER_ERROR) {
123 state_ = next_state; 123 state_ = next_state;
124 124
125 if (next_state == READING_HEADER_BLOCK_LEN) { 125 if (next_state == READING_HEADER_BLOCK_LEN) {
126 // We completed reading a full header block. Return to caller. 126 // We completed reading a full header block. Return to caller.
127 total_bytes_received_ = 0; 127 total_bytes_received_ = 0;
128 break; 128 break;
129 } 129 }
130 } else if (error_ == NEED_MORE_DATA) { 130 } else if (error_ == NEED_MORE_DATA) {
131 // We can't continue parsing until more data is available. Make copies of 131 // We can't continue parsing until more data is available. Make copies of
132 // the key and buffer remainder, in preperation for the next invocation. 132 // the key and buffer remainder, in preperation for the next invocation.
133 if (state_ > READING_KEY) { 133 if (state_ > READING_KEY) {
134 key_.Swap(&key); 134 key_.Swap(&key);
135 key_.Pin(); 135 key_.Pin();
136 } 136 }
137 reader.ReadN(reader.Available(), &headers_block_prefix_); 137 reader.ReadN(reader.Available(), &headers_block_prefix_);
138 headers_block_prefix_.Pin(); 138 headers_block_prefix_.Pin();
139 } 139 }
140 } 140 }
141 return error_ == OK; 141 return error_ == NO_PARSER_ERROR;
142 } 142 }
143 143
144 void SpdyHeadersBlockParser::ParseBlockLength(Reader* reader) { 144 void SpdyHeadersBlockParser::ParseBlockLength(Reader* reader) {
145 ParseLength(reader, &remaining_key_value_pairs_for_frame_); 145 ParseLength(reader, &remaining_key_value_pairs_for_frame_);
146 if (error_ == OK && 146 if (error_ == NO_PARSER_ERROR &&
147 remaining_key_value_pairs_for_frame_ > max_headers_in_block_) { 147 remaining_key_value_pairs_for_frame_ > max_headers_in_block_) {
148 error_ = HEADER_BLOCK_TOO_LARGE; 148 error_ = HEADER_BLOCK_TOO_LARGE;
149 } 149 }
150 if (error_ == OK) { 150 if (error_ == NO_PARSER_ERROR) {
151 handler_->OnHeaderBlock(remaining_key_value_pairs_for_frame_); 151 handler_->OnHeaderBlock(remaining_key_value_pairs_for_frame_);
152 } 152 }
153 } 153 }
154 154
155 void SpdyHeadersBlockParser::ParseFieldLength(Reader* reader) { 155 void SpdyHeadersBlockParser::ParseFieldLength(Reader* reader) {
156 ParseLength(reader, &next_field_length_); 156 ParseLength(reader, &next_field_length_);
157 if (error_ == OK && 157 if (error_ == NO_PARSER_ERROR && next_field_length_ > kMaximumFieldLength) {
158 next_field_length_ > kMaximumFieldLength) {
159 error_ = HEADER_FIELD_TOO_LARGE; 158 error_ = HEADER_FIELD_TOO_LARGE;
160 } 159 }
161 } 160 }
162 161
163 void SpdyHeadersBlockParser::ParseLength(Reader* reader, 162 void SpdyHeadersBlockParser::ParseLength(Reader* reader,
164 uint32_t* parsed_length) { 163 uint32_t* parsed_length) {
165 char buffer[] = {0, 0, 0, 0}; 164 char buffer[] = {0, 0, 0, 0};
166 if (!reader->ReadN(length_field_size_, buffer)) { 165 if (!reader->ReadN(length_field_size_, buffer)) {
167 error_ = NEED_MORE_DATA; 166 error_ = NEED_MORE_DATA;
168 return; 167 return;
(...skipping 19 matching lines...) Expand all
188 // Account for the length of the header block field. 187 // Account for the length of the header block field.
189 size_t max_bytes_for_headers = 188 size_t max_bytes_for_headers =
190 kMaximumFieldLength - LengthFieldSizeForVersion(spdy_version); 189 kMaximumFieldLength - LengthFieldSizeForVersion(spdy_version);
191 190
192 // A minimal size header is twice the length field size (and has a 191 // A minimal size header is twice the length field size (and has a
193 // zero-lengthed key and a zero-lengthed value). 192 // zero-lengthed key and a zero-lengthed value).
194 return max_bytes_for_headers / (2 * LengthFieldSizeForVersion(spdy_version)); 193 return max_bytes_for_headers / (2 * LengthFieldSizeForVersion(spdy_version));
195 } 194 }
196 195
197 } // namespace net 196 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_headers_block_parser.h ('k') | net/spdy/spdy_headers_block_parser_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698