blob: ffd5c74eaf05c6ce0b28e27694f1704b26075b40 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 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#include "net/third_party/quiche/src/quic/core/http/http_decoder.h"
bnc70914262019-03-16 12:49:50 -07006
QUICHE teama6ef0a62019-03-07 20:34:33 -05007#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
8#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
9#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h"
10
11namespace quic {
12
13namespace {
14
15// Create a mask that sets the last |num_bits| to 1 and the rest to 0.
16inline uint8_t GetMaskFromNumBits(uint8_t num_bits) {
17 return (1u << num_bits) - 1;
18}
19
20// Extract |num_bits| from |flags| offset by |offset|.
21uint8_t ExtractBits(uint8_t flags, uint8_t num_bits, uint8_t offset) {
22 return (flags >> offset) & GetMaskFromNumBits(num_bits);
23}
24
renjietang4ab9d9f2019-04-10 14:30:26 -070025// Length of the weight field of a priority frame.
26static const size_t kPriorityWeightLength = 1;
27// Length of a priority frame's first byte.
28static const size_t kPriorityFirstByteLength = 1;
QUICHE teama6ef0a62019-03-07 20:34:33 -050029
30} // namespace
31
32HttpDecoder::HttpDecoder()
33 : visitor_(nullptr),
renjietangfcd91c02019-04-22 10:40:35 -070034 state_(STATE_READING_FRAME_TYPE),
QUICHE teama6ef0a62019-03-07 20:34:33 -050035 current_frame_type_(0),
renjietangbb98cbc2019-04-23 13:13:56 -070036 current_length_field_length_(0),
QUICHE teama6ef0a62019-03-07 20:34:33 -050037 remaining_length_field_length_(0),
38 current_frame_length_(0),
39 remaining_frame_length_(0),
renjietang2d475cf2019-04-18 17:03:37 -070040 current_type_field_length_(0),
41 remaining_type_field_length_(0),
QUICHE teama6ef0a62019-03-07 20:34:33 -050042 error_(QUIC_NO_ERROR),
bncfa0c90c2019-03-13 14:14:28 -070043 error_detail_("") {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050044
45HttpDecoder::~HttpDecoder() {}
46
47QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
bnc620095a2019-06-26 05:31:05 -070048 DCHECK_EQ(QUIC_NO_ERROR, error_);
49 DCHECK_NE(STATE_ERROR, state_);
50
QUICHE teama6ef0a62019-03-07 20:34:33 -050051 QuicDataReader reader(data, len);
bncb9d07d92019-06-25 17:43:49 -070052 bool continue_processing = true;
bnc620095a2019-06-26 05:31:05 -070053 while (continue_processing &&
bnc70914262019-03-16 12:49:50 -070054 (reader.BytesRemaining() != 0 || state_ == STATE_FINISH_PARSING)) {
bnc620095a2019-06-26 05:31:05 -070055 // |continue_processing| must have been set to false upon error.
56 DCHECK_EQ(QUIC_NO_ERROR, error_);
57 DCHECK_NE(STATE_ERROR, state_);
58
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 switch (state_) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050060 case STATE_READING_FRAME_TYPE:
61 ReadFrameType(&reader);
62 break;
renjietangfcd91c02019-04-22 10:40:35 -070063 case STATE_READING_FRAME_LENGTH:
bncb9d07d92019-06-25 17:43:49 -070064 continue_processing = ReadFrameLength(&reader);
renjietangfcd91c02019-04-22 10:40:35 -070065 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -050066 case STATE_READING_FRAME_PAYLOAD:
bncb9d07d92019-06-25 17:43:49 -070067 continue_processing = ReadFramePayload(&reader);
QUICHE teama6ef0a62019-03-07 20:34:33 -050068 break;
bnc70914262019-03-16 12:49:50 -070069 case STATE_FINISH_PARSING:
bncb9d07d92019-06-25 17:43:49 -070070 continue_processing = FinishParsing();
bnc70914262019-03-16 12:49:50 -070071 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -050072 case STATE_ERROR:
73 break;
74 default:
75 QUIC_BUG << "Invalid state: " << state_;
76 }
77 }
78
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 return len - reader.BytesRemaining();
80}
81
QUICHE teama6ef0a62019-03-07 20:34:33 -050082void HttpDecoder::ReadFrameType(QuicDataReader* reader) {
83 DCHECK_NE(0u, reader->BytesRemaining());
renjietang2d475cf2019-04-18 17:03:37 -070084 if (current_type_field_length_ == 0) {
85 // A new frame is coming.
86 current_type_field_length_ = reader->PeekVarInt62Length();
bnc4368e7f2019-06-24 12:15:48 -070087 DCHECK_NE(0u, current_type_field_length_);
88 if (current_type_field_length_ > reader->BytesRemaining()) {
renjietang2d475cf2019-04-18 17:03:37 -070089 // Buffer a new type field.
90 remaining_type_field_length_ = current_type_field_length_;
91 BufferFrameType(reader);
92 return;
93 }
bnc4368e7f2019-06-24 12:15:48 -070094 // The reader has all type data needed, so no need to buffer.
95 bool success = reader->ReadVarInt62(&current_frame_type_);
96 DCHECK(success);
renjietang2d475cf2019-04-18 17:03:37 -070097 } else {
98 // Buffer the existing type field.
99 BufferFrameType(reader);
100 // The frame is still not buffered completely.
101 if (remaining_type_field_length_ != 0) {
102 return;
103 }
104 QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_);
bnc4368e7f2019-06-24 12:15:48 -0700105 bool success = type_reader.ReadVarInt62(&current_frame_type_);
106 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500107 }
108
renjietangfcd91c02019-04-22 10:40:35 -0700109 state_ = STATE_READING_FRAME_LENGTH;
110}
111
bncb9d07d92019-06-25 17:43:49 -0700112bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
renjietangfcd91c02019-04-22 10:40:35 -0700113 DCHECK_NE(0u, reader->BytesRemaining());
renjietangbb98cbc2019-04-23 13:13:56 -0700114 if (current_length_field_length_ == 0) {
115 // A new frame is coming.
116 current_length_field_length_ = reader->PeekVarInt62Length();
bnc4368e7f2019-06-24 12:15:48 -0700117 DCHECK_NE(0u, current_length_field_length_);
118 if (current_length_field_length_ > reader->BytesRemaining()) {
renjietangbb98cbc2019-04-23 13:13:56 -0700119 // Buffer a new length field.
120 remaining_length_field_length_ = current_length_field_length_;
121 BufferFrameLength(reader);
bncb9d07d92019-06-25 17:43:49 -0700122 return true;
renjietangbb98cbc2019-04-23 13:13:56 -0700123 }
bnc4368e7f2019-06-24 12:15:48 -0700124 // The reader has all length data needed, so no need to buffer.
125 bool success = reader->ReadVarInt62(&current_frame_length_);
126 DCHECK(success);
renjietangbb98cbc2019-04-23 13:13:56 -0700127 } else {
128 // Buffer the existing length field.
129 BufferFrameLength(reader);
130 // The frame is still not buffered completely.
131 if (remaining_length_field_length_ != 0) {
bncb9d07d92019-06-25 17:43:49 -0700132 return true;
renjietangbb98cbc2019-04-23 13:13:56 -0700133 }
134 QuicDataReader length_reader(length_buffer_.data(),
135 current_length_field_length_);
bnc4368e7f2019-06-24 12:15:48 -0700136 bool success = length_reader.ReadVarInt62(&current_frame_length_);
137 DCHECK(success);
renjietangfcd91c02019-04-22 10:40:35 -0700138 }
139
renjietang4ab9d9f2019-04-10 14:30:26 -0700140 if (current_frame_length_ > MaxFrameLength(current_frame_type_)) {
bnc4368e7f2019-06-24 12:15:48 -0700141 // TODO(bnc): Signal HTTP_EXCESSIVE_LOAD or similar to peer.
renjietang4ab9d9f2019-04-10 14:30:26 -0700142 RaiseError(QUIC_INTERNAL_ERROR, "Frame is too large");
143 visitor_->OnError(this);
bncb9d07d92019-06-25 17:43:49 -0700144 return false;
renjietang4ab9d9f2019-04-10 14:30:26 -0700145 }
146
renjietang7d4f9132019-06-20 15:04:34 -0700147 // Calling the following visitor methods does not require parsing of any
bnc70914262019-03-16 12:49:50 -0700148 // frame payload.
bncb9d07d92019-06-25 17:43:49 -0700149 bool continue_processing = true;
renjietang7d4f9132019-06-20 15:04:34 -0700150 auto frame_meta = Http3FrameLengths(
151 current_length_field_length_ + current_type_field_length_,
152 current_frame_length_);
bnc70914262019-03-16 12:49:50 -0700153 if (current_frame_type_ == 0x0) {
bncb9d07d92019-06-25 17:43:49 -0700154 continue_processing = visitor_->OnDataFrameStart(frame_meta);
bnc70914262019-03-16 12:49:50 -0700155 } else if (current_frame_type_ == 0x1) {
bncb9d07d92019-06-25 17:43:49 -0700156 continue_processing = visitor_->OnHeadersFrameStart(frame_meta);
renjietangf41bf642019-04-02 11:45:34 -0700157 } else if (current_frame_type_ == 0x4) {
bncb9d07d92019-06-25 17:43:49 -0700158 continue_processing = visitor_->OnSettingsFrameStart(frame_meta);
renjietang7d4f9132019-06-20 15:04:34 -0700159 } else if (current_frame_type_ == 0x2) {
bncb9d07d92019-06-25 17:43:49 -0700160 continue_processing = visitor_->OnPriorityFrameStart(frame_meta);
bnc70914262019-03-16 12:49:50 -0700161 }
162
renjietangfcd91c02019-04-22 10:40:35 -0700163 remaining_frame_length_ = current_frame_length_;
bnc70914262019-03-16 12:49:50 -0700164 state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
165 : STATE_READING_FRAME_PAYLOAD;
bncb9d07d92019-06-25 17:43:49 -0700166 return continue_processing;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500167}
168
bncb9d07d92019-06-25 17:43:49 -0700169bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500170 DCHECK_NE(0u, reader->BytesRemaining());
bnc70914262019-03-16 12:49:50 -0700171 DCHECK_NE(0u, remaining_frame_length_);
bncb9d07d92019-06-25 17:43:49 -0700172
173 bool continue_processing = true;
174
QUICHE teama6ef0a62019-03-07 20:34:33 -0500175 switch (current_frame_type_) {
176 case 0x0: { // DATA
QUICHE teama6ef0a62019-03-07 20:34:33 -0500177 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
178 remaining_frame_length_, reader->BytesRemaining());
179 QuicStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700180 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
181 DCHECK(success);
bnc70914262019-03-16 12:49:50 -0700182 DCHECK(!payload.empty());
bncb9d07d92019-06-25 17:43:49 -0700183 continue_processing = visitor_->OnDataFramePayload(payload);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500184 remaining_frame_length_ -= payload.length();
bnc70914262019-03-16 12:49:50 -0700185 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500186 }
187 case 0x1: { // HEADERS
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
189 remaining_frame_length_, reader->BytesRemaining());
190 QuicStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700191 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
192 DCHECK(success);
bnc70914262019-03-16 12:49:50 -0700193 DCHECK(!payload.empty());
bncb9d07d92019-06-25 17:43:49 -0700194 continue_processing = visitor_->OnHeadersFramePayload(payload);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500195 remaining_frame_length_ -= payload.length();
bnc70914262019-03-16 12:49:50 -0700196 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500197 }
198 case 0x2: { // PRIORITY
199 // TODO(rch): avoid buffering if the entire frame is present, and
200 // instead parse directly out of |reader|.
201 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700202 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500203 }
204 case 0x3: { // CANCEL_PUSH
QUICHE teama6ef0a62019-03-07 20:34:33 -0500205 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700206 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207 }
208 case 0x4: { // SETTINGS
QUICHE teama6ef0a62019-03-07 20:34:33 -0500209 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700210 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500211 }
212 case 0x5: { // PUSH_PROMISE
213 if (current_frame_length_ == remaining_frame_length_) {
214 QuicByteCount bytes_remaining = reader->BytesRemaining();
215 PushId push_id;
216 // TODO(rch): Handle partial delivery of this field.
217 if (!reader->ReadVarInt62(&push_id)) {
218 RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
bncb9d07d92019-06-25 17:43:49 -0700219 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220 }
221 remaining_frame_length_ -= bytes_remaining - reader->BytesRemaining();
renjietang546a6282019-06-03 10:21:21 -0700222 if (!visitor_->OnPushPromiseFrameStart(push_id)) {
bncb9d07d92019-06-25 17:43:49 -0700223 continue_processing = false;
224 break;
renjietang546a6282019-06-03 10:21:21 -0700225 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500226 }
bnc70914262019-03-16 12:49:50 -0700227 DCHECK_LT(remaining_frame_length_, current_frame_length_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500228 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
229 remaining_frame_length_, reader->BytesRemaining());
230 if (bytes_to_read == 0) {
bnc70914262019-03-16 12:49:50 -0700231 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500232 }
233 QuicStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700234 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
235 DCHECK(success);
bnc70914262019-03-16 12:49:50 -0700236 DCHECK(!payload.empty());
bncb9d07d92019-06-25 17:43:49 -0700237 continue_processing = visitor_->OnPushPromiseFramePayload(payload);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500238 remaining_frame_length_ -= payload.length();
bnc70914262019-03-16 12:49:50 -0700239 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500240 }
241 case 0x7: { // GOAWAY
242 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700243 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500244 }
245
246 case 0xD: { // MAX_PUSH_ID
247 // TODO(rch): Handle partial delivery.
248 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700249 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500250 }
251
252 case 0xE: { // DUPLICATE_PUSH
253 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700254 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500255 }
256 // Reserved frame types.
257 // TODO(rch): Since these are actually the same behavior as the
258 // default, we probably don't need to special case them here?
259 case 0xB:
260 QUIC_FALLTHROUGH_INTENDED;
261 case 0xB + 0x1F:
262 QUIC_FALLTHROUGH_INTENDED;
263 case 0xB + 0x1F * 2:
264 QUIC_FALLTHROUGH_INTENDED;
265 case 0xB + 0x1F * 3:
266 QUIC_FALLTHROUGH_INTENDED;
267 case 0xB + 0x1F * 4:
268 QUIC_FALLTHROUGH_INTENDED;
269 case 0xB + 0x1F * 5:
270 QUIC_FALLTHROUGH_INTENDED;
271 case 0xB + 0x1F * 6:
272 QUIC_FALLTHROUGH_INTENDED;
273 case 0xB + 0x1F * 7:
274 QUIC_FALLTHROUGH_INTENDED;
275 default:
276 DiscardFramePayload(reader);
bncb9d07d92019-06-25 17:43:49 -0700277 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500278 }
bnc70914262019-03-16 12:49:50 -0700279
280 if (remaining_frame_length_ == 0) {
281 state_ = STATE_FINISH_PARSING;
282 }
bncb9d07d92019-06-25 17:43:49 -0700283
284 return continue_processing;
bnc70914262019-03-16 12:49:50 -0700285}
286
bncb9d07d92019-06-25 17:43:49 -0700287bool HttpDecoder::FinishParsing() {
bnc70914262019-03-16 12:49:50 -0700288 DCHECK_EQ(0u, remaining_frame_length_);
bncb9d07d92019-06-25 17:43:49 -0700289
290 bool continue_processing = true;
291
bnc70914262019-03-16 12:49:50 -0700292 switch (current_frame_type_) {
293 case 0x0: { // DATA
bncb9d07d92019-06-25 17:43:49 -0700294 continue_processing = visitor_->OnDataFrameEnd();
bnc70914262019-03-16 12:49:50 -0700295 break;
296 }
297 case 0x1: { // HEADERS
bncb9d07d92019-06-25 17:43:49 -0700298 continue_processing = visitor_->OnHeadersFrameEnd();
bnc70914262019-03-16 12:49:50 -0700299 break;
300 }
301 case 0x2: { // PRIORITY
302 // TODO(rch): avoid buffering if the entire frame is present, and
303 // instead parse directly out of |reader|.
304 PriorityFrame frame;
305 QuicDataReader reader(buffer_.data(), current_frame_length_);
306 if (!ParsePriorityFrame(&reader, &frame)) {
bncb9d07d92019-06-25 17:43:49 -0700307 return false;
bnc70914262019-03-16 12:49:50 -0700308 }
bncb9d07d92019-06-25 17:43:49 -0700309 continue_processing = visitor_->OnPriorityFrame(frame);
bnc70914262019-03-16 12:49:50 -0700310 break;
311 }
312 case 0x3: { // CANCEL_PUSH
313 // TODO(rch): Handle partial delivery.
314 CancelPushFrame frame;
315 QuicDataReader reader(buffer_.data(), current_frame_length_);
316 if (!reader.ReadVarInt62(&frame.push_id)) {
317 RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
bncb9d07d92019-06-25 17:43:49 -0700318 return false;
bnc70914262019-03-16 12:49:50 -0700319 }
bncb9d07d92019-06-25 17:43:49 -0700320 continue_processing = visitor_->OnCancelPushFrame(frame);
bnc70914262019-03-16 12:49:50 -0700321 break;
322 }
323 case 0x4: { // SETTINGS
bnc70914262019-03-16 12:49:50 -0700324 SettingsFrame frame;
325 QuicDataReader reader(buffer_.data(), current_frame_length_);
326 if (!ParseSettingsFrame(&reader, &frame)) {
bncb9d07d92019-06-25 17:43:49 -0700327 return false;
bnc70914262019-03-16 12:49:50 -0700328 }
bncb9d07d92019-06-25 17:43:49 -0700329 continue_processing = visitor_->OnSettingsFrame(frame);
bnc70914262019-03-16 12:49:50 -0700330 break;
331 }
332 case 0x5: { // PUSH_PROMISE
bncb9d07d92019-06-25 17:43:49 -0700333 continue_processing = visitor_->OnPushPromiseFrameEnd();
bnc70914262019-03-16 12:49:50 -0700334 break;
335 }
336 case 0x7: { // GOAWAY
bnc4368e7f2019-06-24 12:15:48 -0700337 // TODO(bnc): Handle partial delivery.
bnc70914262019-03-16 12:49:50 -0700338 QuicDataReader reader(buffer_.data(), current_frame_length_);
339 GoAwayFrame frame;
340 static_assert(!std::is_same<decltype(frame.stream_id), uint64_t>::value,
341 "Please remove local |stream_id| variable and pass "
342 "&frame.stream_id directly to ReadVarInt62() when changing "
343 "QuicStreamId from uint32_t to uint64_t.");
344 uint64_t stream_id;
345 if (!reader.ReadVarInt62(&stream_id)) {
346 RaiseError(QUIC_INTERNAL_ERROR, "Unable to read GOAWAY stream_id");
bncb9d07d92019-06-25 17:43:49 -0700347 return false;
bnc70914262019-03-16 12:49:50 -0700348 }
349 frame.stream_id = static_cast<QuicStreamId>(stream_id);
bncb9d07d92019-06-25 17:43:49 -0700350 continue_processing = visitor_->OnGoAwayFrame(frame);
bnc70914262019-03-16 12:49:50 -0700351 break;
352 }
353
354 case 0xD: { // MAX_PUSH_ID
bnc4368e7f2019-06-24 12:15:48 -0700355 // TODO(bnc): Handle partial delivery.
bnc70914262019-03-16 12:49:50 -0700356 QuicDataReader reader(buffer_.data(), current_frame_length_);
357 MaxPushIdFrame frame;
358 if (!reader.ReadVarInt62(&frame.push_id)) {
359 RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
bncb9d07d92019-06-25 17:43:49 -0700360 return false;
bnc70914262019-03-16 12:49:50 -0700361 }
bncb9d07d92019-06-25 17:43:49 -0700362 continue_processing = visitor_->OnMaxPushIdFrame(frame);
bnc70914262019-03-16 12:49:50 -0700363 break;
364 }
365
366 case 0xE: { // DUPLICATE_PUSH
bnc4368e7f2019-06-24 12:15:48 -0700367 // TODO(bnc): Handle partial delivery.
bnc70914262019-03-16 12:49:50 -0700368 QuicDataReader reader(buffer_.data(), current_frame_length_);
369 DuplicatePushFrame frame;
370 if (!reader.ReadVarInt62(&frame.push_id)) {
371 RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
bncb9d07d92019-06-25 17:43:49 -0700372 return false;
bnc70914262019-03-16 12:49:50 -0700373 }
bncb9d07d92019-06-25 17:43:49 -0700374 continue_processing = visitor_->OnDuplicatePushFrame(frame);
bnc70914262019-03-16 12:49:50 -0700375 break;
376 }
377 }
378
renjietangbb98cbc2019-04-23 13:13:56 -0700379 current_length_field_length_ = 0;
renjietang2d475cf2019-04-18 17:03:37 -0700380 current_type_field_length_ = 0;
renjietangfcd91c02019-04-22 10:40:35 -0700381 state_ = STATE_READING_FRAME_TYPE;
bncb9d07d92019-06-25 17:43:49 -0700382 return continue_processing;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500383}
384
385void HttpDecoder::DiscardFramePayload(QuicDataReader* reader) {
386 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
387 remaining_frame_length_, reader->BytesRemaining());
388 QuicStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700389 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
390 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500391 remaining_frame_length_ -= payload.length();
392 if (remaining_frame_length_ == 0) {
renjietangfcd91c02019-04-22 10:40:35 -0700393 state_ = STATE_READING_FRAME_TYPE;
renjietangbb98cbc2019-04-23 13:13:56 -0700394 current_length_field_length_ = 0;
renjietang2d475cf2019-04-18 17:03:37 -0700395 current_type_field_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500396 }
397}
398
399void HttpDecoder::BufferFramePayload(QuicDataReader* reader) {
400 if (current_frame_length_ == remaining_frame_length_) {
401 buffer_.erase(buffer_.size());
402 buffer_.reserve(current_frame_length_);
403 }
404 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
405 remaining_frame_length_, reader->BytesRemaining());
bnc4368e7f2019-06-24 12:15:48 -0700406 bool success = reader->ReadBytes(
407 &(buffer_[0]) + current_frame_length_ - remaining_frame_length_,
408 bytes_to_read);
409 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500410 remaining_frame_length_ -= bytes_to_read;
411}
412
413void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
renjietangbb98cbc2019-04-23 13:13:56 -0700414 if (current_length_field_length_ == remaining_length_field_length_) {
415 length_buffer_.fill(0);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500416 }
417 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
418 remaining_length_field_length_, reader->BytesRemaining());
bnc4368e7f2019-06-24 12:15:48 -0700419 bool success =
420 reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
421 remaining_length_field_length_,
422 bytes_to_read);
423 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500424 remaining_length_field_length_ -= bytes_to_read;
425}
426
renjietang2d475cf2019-04-18 17:03:37 -0700427void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
428 if (current_type_field_length_ == remaining_type_field_length_) {
429 type_buffer_.fill(0);
430 }
431 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
432 remaining_type_field_length_, reader->BytesRemaining());
bnc4368e7f2019-06-24 12:15:48 -0700433 bool success =
434 reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
435 remaining_type_field_length_,
436 bytes_to_read);
437 DCHECK(success);
renjietang2d475cf2019-04-18 17:03:37 -0700438 remaining_type_field_length_ -= bytes_to_read;
439}
440
vasilvvc48c8712019-03-11 13:38:16 -0700441void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500442 state_ = STATE_ERROR;
443 error_ = error;
444 error_detail_ = std::move(error_detail);
445}
446
447bool HttpDecoder::ParsePriorityFrame(QuicDataReader* reader,
448 PriorityFrame* frame) {
449 uint8_t flags;
bnc4368e7f2019-06-24 12:15:48 -0700450 bool success = reader->ReadUInt8(&flags);
451 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500452
453 frame->prioritized_type =
454 static_cast<PriorityElementType>(ExtractBits(flags, 2, 6));
455 frame->dependency_type =
456 static_cast<PriorityElementType>(ExtractBits(flags, 2, 4));
457 frame->exclusive = flags % 2 == 1;
bnc4368e7f2019-06-24 12:15:48 -0700458 // TODO(bnc): Handle partial delivery.
renjietangec095762019-06-19 14:35:02 -0700459 if (frame->prioritized_type != ROOT_OF_TREE &&
460 !reader->ReadVarInt62(&frame->prioritized_element_id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500461 RaiseError(QUIC_INTERNAL_ERROR, "Unable to read prioritized_element_id");
462 return false;
463 }
renjietangec095762019-06-19 14:35:02 -0700464 if (frame->dependency_type != ROOT_OF_TREE &&
465 !reader->ReadVarInt62(&frame->element_dependency_id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500466 RaiseError(QUIC_INTERNAL_ERROR, "Unable to read element_dependency_id");
467 return false;
468 }
469 if (!reader->ReadUInt8(&frame->weight)) {
470 RaiseError(QUIC_INTERNAL_ERROR, "Unable to read priority frame weight");
471 return false;
472 }
473 return true;
474}
475
476bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
477 SettingsFrame* frame) {
478 while (!reader->IsDoneReading()) {
bnc4368e7f2019-06-24 12:15:48 -0700479 // TODO(bnc): Handle partial delivery of both fields.
renjietang3b3e3b32019-04-22 18:01:20 -0700480 uint64_t id;
481 if (!reader->ReadVarInt62(&id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500482 RaiseError(QUIC_INTERNAL_ERROR,
483 "Unable to read settings frame identifier");
484 return false;
485 }
486 uint64_t content;
487 if (!reader->ReadVarInt62(&content)) {
488 RaiseError(QUIC_INTERNAL_ERROR, "Unable to read settings frame content");
489 return false;
490 }
491 frame->values[id] = content;
492 }
493 return true;
494}
495
renjietang4ab9d9f2019-04-10 14:30:26 -0700496QuicByteCount HttpDecoder::MaxFrameLength(uint8_t frame_type) {
497 switch (frame_type) {
498 case 0x2: // PRIORITY
499 return kPriorityFirstByteLength + VARIABLE_LENGTH_INTEGER_LENGTH_8 * 2 +
500 kPriorityWeightLength;
501 case 0x3: // CANCEL_PUSH
502 return sizeof(PushId);
503 case 0x4: // SETTINGS
504 // This limit is arbitrary.
505 return 1024 * 1024;
506 case 0x7: // GOAWAY
507 return sizeof(QuicStreamId);
508 case 0xD: // MAX_PUSH_ID
509 return sizeof(PushId);
510 case 0xE: // DUPLICATE_PUSH
511 return sizeof(PushId);
512 default:
513 // Other frames require no data buffering, so it's safe to have no limit.
514 return std::numeric_limits<QuicByteCount>::max();
515 }
516}
517
QUICHE teama6ef0a62019-03-07 20:34:33 -0500518} // namespace quic