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

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

Issue 863253002: Update from https://crrev.com/312600 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 11 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
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 {
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698