blob: 51c70e051c515bf14799a20a2dc232f3391590ce [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
renjietang3a76c892019-07-17 10:03:53 -07007#include <cstdint>
8
9#include "net/third_party/quiche/src/quic/core/http/http_frames.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
renjietang5843bfd2019-10-10 13:24:57 -070011#include "net/third_party/quiche/src/quic/core/quic_types.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h"
dmcardleba2fb7e2019-12-13 07:44:34 -080014#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015
16namespace quic {
17
bnca9bb4692019-07-09 17:29:48 -070018HttpDecoder::HttpDecoder(Visitor* visitor)
19 : visitor_(visitor),
renjietangfcd91c02019-04-22 10:40:35 -070020 state_(STATE_READING_FRAME_TYPE),
QUICHE teama6ef0a62019-03-07 20:34:33 -050021 current_frame_type_(0),
renjietangbb98cbc2019-04-23 13:13:56 -070022 current_length_field_length_(0),
QUICHE teama6ef0a62019-03-07 20:34:33 -050023 remaining_length_field_length_(0),
24 current_frame_length_(0),
25 remaining_frame_length_(0),
renjietang2d475cf2019-04-18 17:03:37 -070026 current_type_field_length_(0),
27 remaining_type_field_length_(0),
renjietang857362b2019-08-09 09:52:35 -070028 current_push_id_length_(0),
29 remaining_push_id_length_(0),
QUICHE teama6ef0a62019-03-07 20:34:33 -050030 error_(QUIC_NO_ERROR),
bnca9bb4692019-07-09 17:29:48 -070031 error_detail_("") {
32 DCHECK(visitor_);
33}
QUICHE teama6ef0a62019-03-07 20:34:33 -050034
35HttpDecoder::~HttpDecoder() {}
36
37QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
bnc620095a2019-06-26 05:31:05 -070038 DCHECK_EQ(QUIC_NO_ERROR, error_);
39 DCHECK_NE(STATE_ERROR, state_);
40
QUICHE teama6ef0a62019-03-07 20:34:33 -050041 QuicDataReader reader(data, len);
bncb9d07d92019-06-25 17:43:49 -070042 bool continue_processing = true;
bnc620095a2019-06-26 05:31:05 -070043 while (continue_processing &&
bnc70914262019-03-16 12:49:50 -070044 (reader.BytesRemaining() != 0 || state_ == STATE_FINISH_PARSING)) {
bnc620095a2019-06-26 05:31:05 -070045 // |continue_processing| must have been set to false upon error.
46 DCHECK_EQ(QUIC_NO_ERROR, error_);
47 DCHECK_NE(STATE_ERROR, state_);
48
QUICHE teama6ef0a62019-03-07 20:34:33 -050049 switch (state_) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050050 case STATE_READING_FRAME_TYPE:
51 ReadFrameType(&reader);
52 break;
renjietangfcd91c02019-04-22 10:40:35 -070053 case STATE_READING_FRAME_LENGTH:
bncb9d07d92019-06-25 17:43:49 -070054 continue_processing = ReadFrameLength(&reader);
renjietangfcd91c02019-04-22 10:40:35 -070055 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -050056 case STATE_READING_FRAME_PAYLOAD:
bncb9d07d92019-06-25 17:43:49 -070057 continue_processing = ReadFramePayload(&reader);
QUICHE teama6ef0a62019-03-07 20:34:33 -050058 break;
bnc70914262019-03-16 12:49:50 -070059 case STATE_FINISH_PARSING:
bncb9d07d92019-06-25 17:43:49 -070060 continue_processing = FinishParsing();
bnc70914262019-03-16 12:49:50 -070061 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -050062 case STATE_ERROR:
63 break;
64 default:
65 QUIC_BUG << "Invalid state: " << state_;
66 }
67 }
68
QUICHE teama6ef0a62019-03-07 20:34:33 -050069 return len - reader.BytesRemaining();
70}
71
QUICHE teama6ef0a62019-03-07 20:34:33 -050072void HttpDecoder::ReadFrameType(QuicDataReader* reader) {
73 DCHECK_NE(0u, reader->BytesRemaining());
renjietang2d475cf2019-04-18 17:03:37 -070074 if (current_type_field_length_ == 0) {
75 // A new frame is coming.
76 current_type_field_length_ = reader->PeekVarInt62Length();
bnc4368e7f2019-06-24 12:15:48 -070077 DCHECK_NE(0u, current_type_field_length_);
78 if (current_type_field_length_ > reader->BytesRemaining()) {
renjietang2d475cf2019-04-18 17:03:37 -070079 // Buffer a new type field.
80 remaining_type_field_length_ = current_type_field_length_;
81 BufferFrameType(reader);
82 return;
83 }
bnc4368e7f2019-06-24 12:15:48 -070084 // The reader has all type data needed, so no need to buffer.
85 bool success = reader->ReadVarInt62(&current_frame_type_);
86 DCHECK(success);
renjietang2d475cf2019-04-18 17:03:37 -070087 } else {
88 // Buffer the existing type field.
89 BufferFrameType(reader);
90 // The frame is still not buffered completely.
91 if (remaining_type_field_length_ != 0) {
92 return;
93 }
94 QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_);
bnc4368e7f2019-06-24 12:15:48 -070095 bool success = type_reader.ReadVarInt62(&current_frame_type_);
96 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -050097 }
98
renjietangfcd91c02019-04-22 10:40:35 -070099 state_ = STATE_READING_FRAME_LENGTH;
100}
101
bncb9d07d92019-06-25 17:43:49 -0700102bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
renjietangfcd91c02019-04-22 10:40:35 -0700103 DCHECK_NE(0u, reader->BytesRemaining());
renjietangbb98cbc2019-04-23 13:13:56 -0700104 if (current_length_field_length_ == 0) {
105 // A new frame is coming.
106 current_length_field_length_ = reader->PeekVarInt62Length();
bnc4368e7f2019-06-24 12:15:48 -0700107 DCHECK_NE(0u, current_length_field_length_);
108 if (current_length_field_length_ > reader->BytesRemaining()) {
renjietangbb98cbc2019-04-23 13:13:56 -0700109 // Buffer a new length field.
110 remaining_length_field_length_ = current_length_field_length_;
111 BufferFrameLength(reader);
bncb9d07d92019-06-25 17:43:49 -0700112 return true;
renjietangbb98cbc2019-04-23 13:13:56 -0700113 }
bnc4368e7f2019-06-24 12:15:48 -0700114 // The reader has all length data needed, so no need to buffer.
115 bool success = reader->ReadVarInt62(&current_frame_length_);
116 DCHECK(success);
renjietangbb98cbc2019-04-23 13:13:56 -0700117 } else {
118 // Buffer the existing length field.
119 BufferFrameLength(reader);
120 // The frame is still not buffered completely.
121 if (remaining_length_field_length_ != 0) {
bncb9d07d92019-06-25 17:43:49 -0700122 return true;
renjietangbb98cbc2019-04-23 13:13:56 -0700123 }
124 QuicDataReader length_reader(length_buffer_.data(),
125 current_length_field_length_);
bnc4368e7f2019-06-24 12:15:48 -0700126 bool success = length_reader.ReadVarInt62(&current_frame_length_);
127 DCHECK(success);
renjietangfcd91c02019-04-22 10:40:35 -0700128 }
129
renjietang4ab9d9f2019-04-10 14:30:26 -0700130 if (current_frame_length_ > MaxFrameLength(current_frame_type_)) {
bnce7f67962019-08-08 06:34:35 -0700131 // TODO(b/124216424): Use HTTP_EXCESSIVE_LOAD.
132 RaiseError(QUIC_INVALID_FRAME_DATA, "Frame is too large");
bncb9d07d92019-06-25 17:43:49 -0700133 return false;
renjietang4ab9d9f2019-04-10 14:30:26 -0700134 }
135
renjietang7d4f9132019-06-20 15:04:34 -0700136 // Calling the following visitor methods does not require parsing of any
bnc70914262019-03-16 12:49:50 -0700137 // frame payload.
bncb9d07d92019-06-25 17:43:49 -0700138 bool continue_processing = true;
bnca2b13be2019-07-31 12:04:20 -0700139 const QuicByteCount header_length =
140 current_length_field_length_ + current_type_field_length_;
bncbf3dbe52019-07-17 05:17:41 -0700141
142 switch (current_frame_type_) {
bnc95fb6b62019-07-21 11:20:47 -0700143 case static_cast<uint64_t>(HttpFrameType::DATA):
bnca2b13be2019-07-31 12:04:20 -0700144 continue_processing = visitor_->OnDataFrameStart(header_length);
bncbf3dbe52019-07-17 05:17:41 -0700145 break;
bnc95fb6b62019-07-21 11:20:47 -0700146 case static_cast<uint64_t>(HttpFrameType::HEADERS):
bnca2b13be2019-07-31 12:04:20 -0700147 continue_processing = visitor_->OnHeadersFrameStart(header_length);
bncbf3dbe52019-07-17 05:17:41 -0700148 break;
bnc95fb6b62019-07-21 11:20:47 -0700149 case static_cast<uint64_t>(HttpFrameType::PRIORITY):
bnca2b13be2019-07-31 12:04:20 -0700150 continue_processing = visitor_->OnPriorityFrameStart(header_length);
bncbf3dbe52019-07-17 05:17:41 -0700151 break;
bnc95fb6b62019-07-21 11:20:47 -0700152 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
bncbf3dbe52019-07-17 05:17:41 -0700153 break;
bnc95fb6b62019-07-21 11:20:47 -0700154 case static_cast<uint64_t>(HttpFrameType::SETTINGS):
bnca2b13be2019-07-31 12:04:20 -0700155 continue_processing = visitor_->OnSettingsFrameStart(header_length);
bncbf3dbe52019-07-17 05:17:41 -0700156 break;
bnc95fb6b62019-07-21 11:20:47 -0700157 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
bncf0db6542019-09-23 11:18:28 -0700158 // This edge case needs to be handled here, because ReadFramePayload()
159 // does not get called if |current_frame_length_| is zero.
bncfcd42352019-09-20 17:55:47 -0700160 if (current_frame_length_ == 0) {
161 RaiseError(QUIC_INVALID_FRAME_DATA, "Corrupt PUSH_PROMISE frame.");
162 return false;
163 }
bncf0db6542019-09-23 11:18:28 -0700164 continue_processing = visitor_->OnPushPromiseFrameStart(header_length);
bncbf3dbe52019-07-17 05:17:41 -0700165 break;
bnc95fb6b62019-07-21 11:20:47 -0700166 case static_cast<uint64_t>(HttpFrameType::GOAWAY):
bncbf3dbe52019-07-17 05:17:41 -0700167 break;
bnc95fb6b62019-07-21 11:20:47 -0700168 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
bncbf3dbe52019-07-17 05:17:41 -0700169 break;
bnc95fb6b62019-07-21 11:20:47 -0700170 case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH):
bncbf3dbe52019-07-17 05:17:41 -0700171 break;
172 default:
173 continue_processing =
bnca2b13be2019-07-31 12:04:20 -0700174 visitor_->OnUnknownFrameStart(current_frame_type_, header_length);
bncbf3dbe52019-07-17 05:17:41 -0700175 break;
bnc70914262019-03-16 12:49:50 -0700176 }
177
renjietangfcd91c02019-04-22 10:40:35 -0700178 remaining_frame_length_ = current_frame_length_;
bnc70914262019-03-16 12:49:50 -0700179 state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
180 : STATE_READING_FRAME_PAYLOAD;
bncb9d07d92019-06-25 17:43:49 -0700181 return continue_processing;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500182}
183
bncb9d07d92019-06-25 17:43:49 -0700184bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500185 DCHECK_NE(0u, reader->BytesRemaining());
bnc70914262019-03-16 12:49:50 -0700186 DCHECK_NE(0u, remaining_frame_length_);
bncb9d07d92019-06-25 17:43:49 -0700187
188 bool continue_processing = true;
189
QUICHE teama6ef0a62019-03-07 20:34:33 -0500190 switch (current_frame_type_) {
bnc95fb6b62019-07-21 11:20:47 -0700191 case static_cast<uint64_t>(HttpFrameType::DATA): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500192 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
193 remaining_frame_length_, reader->BytesRemaining());
dmcardleba2fb7e2019-12-13 07:44:34 -0800194 quiche::QuicheStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700195 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
196 DCHECK(success);
bnc70914262019-03-16 12:49:50 -0700197 DCHECK(!payload.empty());
bncb9d07d92019-06-25 17:43:49 -0700198 continue_processing = visitor_->OnDataFramePayload(payload);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500199 remaining_frame_length_ -= payload.length();
bnc70914262019-03-16 12:49:50 -0700200 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500201 }
bnc95fb6b62019-07-21 11:20:47 -0700202 case static_cast<uint64_t>(HttpFrameType::HEADERS): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500203 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
204 remaining_frame_length_, reader->BytesRemaining());
dmcardleba2fb7e2019-12-13 07:44:34 -0800205 quiche::QuicheStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700206 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
207 DCHECK(success);
bnc70914262019-03-16 12:49:50 -0700208 DCHECK(!payload.empty());
bncb9d07d92019-06-25 17:43:49 -0700209 continue_processing = visitor_->OnHeadersFramePayload(payload);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500210 remaining_frame_length_ -= payload.length();
bnc70914262019-03-16 12:49:50 -0700211 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500212 }
bnc95fb6b62019-07-21 11:20:47 -0700213 case static_cast<uint64_t>(HttpFrameType::PRIORITY): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500214 // TODO(rch): avoid buffering if the entire frame is present, and
215 // instead parse directly out of |reader|.
216 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700217 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500218 }
bnc95fb6b62019-07-21 11:20:47 -0700219 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700221 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500222 }
bnc95fb6b62019-07-21 11:20:47 -0700223 case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500224 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700225 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500226 }
bnc95fb6b62019-07-21 11:20:47 -0700227 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
renjietang857362b2019-08-09 09:52:35 -0700228 PushId push_id;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500229 if (current_frame_length_ == remaining_frame_length_) {
renjietang857362b2019-08-09 09:52:35 -0700230 // A new Push Promise frame just arrived.
231 DCHECK_EQ(0u, current_push_id_length_);
232 current_push_id_length_ = reader->PeekVarInt62Length();
233 if (current_push_id_length_ > remaining_frame_length_) {
234 RaiseError(QUIC_INVALID_FRAME_DATA, "PUSH_PROMISE frame malformed.");
bncb9d07d92019-06-25 17:43:49 -0700235 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500236 }
renjietang857362b2019-08-09 09:52:35 -0700237 if (current_push_id_length_ > reader->BytesRemaining()) {
238 // Not all bytes of push id is present yet, buffer push id.
239 DCHECK_EQ(0u, remaining_push_id_length_);
240 remaining_push_id_length_ = current_push_id_length_;
241 BufferPushId(reader);
bncb9d07d92019-06-25 17:43:49 -0700242 break;
renjietang546a6282019-06-03 10:21:21 -0700243 }
renjietang857362b2019-08-09 09:52:35 -0700244 bool success = reader->ReadVarInt62(&push_id);
245 DCHECK(success);
246 remaining_frame_length_ -= current_push_id_length_;
bncf0db6542019-09-23 11:18:28 -0700247 if (!visitor_->OnPushPromiseFramePushId(push_id,
248 current_push_id_length_)) {
renjietang857362b2019-08-09 09:52:35 -0700249 continue_processing = false;
250 current_push_id_length_ = 0;
251 break;
252 }
253 current_push_id_length_ = 0;
254 } else if (remaining_push_id_length_ > 0) {
255 // Waiting for more bytes on push id.
256 BufferPushId(reader);
257 if (remaining_push_id_length_ != 0) {
258 break;
259 }
260 QuicDataReader push_id_reader(push_id_buffer_.data(),
261 current_push_id_length_);
262
263 bool success = push_id_reader.ReadVarInt62(&push_id);
264 DCHECK(success);
bncf0db6542019-09-23 11:18:28 -0700265 if (!visitor_->OnPushPromiseFramePushId(push_id,
266 current_push_id_length_)) {
renjietang857362b2019-08-09 09:52:35 -0700267 continue_processing = false;
268 current_push_id_length_ = 0;
269 break;
270 }
271 current_push_id_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500272 }
renjietang857362b2019-08-09 09:52:35 -0700273
274 // Read Push Promise headers.
bnc70914262019-03-16 12:49:50 -0700275 DCHECK_LT(remaining_frame_length_, current_frame_length_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500276 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
277 remaining_frame_length_, reader->BytesRemaining());
278 if (bytes_to_read == 0) {
bnc70914262019-03-16 12:49:50 -0700279 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500280 }
dmcardleba2fb7e2019-12-13 07:44:34 -0800281 quiche::QuicheStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700282 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
283 DCHECK(success);
bnc70914262019-03-16 12:49:50 -0700284 DCHECK(!payload.empty());
bncb9d07d92019-06-25 17:43:49 -0700285 continue_processing = visitor_->OnPushPromiseFramePayload(payload);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500286 remaining_frame_length_ -= payload.length();
bnc70914262019-03-16 12:49:50 -0700287 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500288 }
bnc95fb6b62019-07-21 11:20:47 -0700289 case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500290 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700291 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500292 }
bnc95fb6b62019-07-21 11:20:47 -0700293 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500294 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700295 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500296 }
bnc95fb6b62019-07-21 11:20:47 -0700297 case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500298 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700299 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500300 }
bncbf3dbe52019-07-17 05:17:41 -0700301 default: {
302 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
303 remaining_frame_length_, reader->BytesRemaining());
dmcardleba2fb7e2019-12-13 07:44:34 -0800304 quiche::QuicheStringPiece payload;
bncbf3dbe52019-07-17 05:17:41 -0700305 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
306 DCHECK(success);
307 DCHECK(!payload.empty());
308 continue_processing = visitor_->OnUnknownFramePayload(payload);
309 remaining_frame_length_ -= payload.length();
310 break;
311 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500312 }
bnc70914262019-03-16 12:49:50 -0700313
314 if (remaining_frame_length_ == 0) {
315 state_ = STATE_FINISH_PARSING;
316 }
bncb9d07d92019-06-25 17:43:49 -0700317
318 return continue_processing;
bnc70914262019-03-16 12:49:50 -0700319}
320
bncb9d07d92019-06-25 17:43:49 -0700321bool HttpDecoder::FinishParsing() {
bnc70914262019-03-16 12:49:50 -0700322 DCHECK_EQ(0u, remaining_frame_length_);
bncb9d07d92019-06-25 17:43:49 -0700323
324 bool continue_processing = true;
325
bnc70914262019-03-16 12:49:50 -0700326 switch (current_frame_type_) {
bnc95fb6b62019-07-21 11:20:47 -0700327 case static_cast<uint64_t>(HttpFrameType::DATA): {
bncb9d07d92019-06-25 17:43:49 -0700328 continue_processing = visitor_->OnDataFrameEnd();
bnc70914262019-03-16 12:49:50 -0700329 break;
330 }
bnc95fb6b62019-07-21 11:20:47 -0700331 case static_cast<uint64_t>(HttpFrameType::HEADERS): {
bncb9d07d92019-06-25 17:43:49 -0700332 continue_processing = visitor_->OnHeadersFrameEnd();
bnc70914262019-03-16 12:49:50 -0700333 break;
334 }
bnc95fb6b62019-07-21 11:20:47 -0700335 case static_cast<uint64_t>(HttpFrameType::PRIORITY): {
bnc70914262019-03-16 12:49:50 -0700336 // TODO(rch): avoid buffering if the entire frame is present, and
337 // instead parse directly out of |reader|.
338 PriorityFrame frame;
339 QuicDataReader reader(buffer_.data(), current_frame_length_);
340 if (!ParsePriorityFrame(&reader, &frame)) {
bncb9d07d92019-06-25 17:43:49 -0700341 return false;
bnc70914262019-03-16 12:49:50 -0700342 }
bncb9d07d92019-06-25 17:43:49 -0700343 continue_processing = visitor_->OnPriorityFrame(frame);
bnc70914262019-03-16 12:49:50 -0700344 break;
345 }
bnc95fb6b62019-07-21 11:20:47 -0700346 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
bnc70914262019-03-16 12:49:50 -0700347 CancelPushFrame frame;
348 QuicDataReader reader(buffer_.data(), current_frame_length_);
349 if (!reader.ReadVarInt62(&frame.push_id)) {
bnce7f67962019-08-08 06:34:35 -0700350 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
351 RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read push_id");
bncb9d07d92019-06-25 17:43:49 -0700352 return false;
bnc70914262019-03-16 12:49:50 -0700353 }
bnc01918c02019-08-08 07:08:47 -0700354 if (!reader.IsDoneReading()) {
355 RaiseError(QUIC_INVALID_FRAME_DATA,
356 "Superfluous data in CANCEL_PUSH frame.");
357 return false;
358 }
bncb9d07d92019-06-25 17:43:49 -0700359 continue_processing = visitor_->OnCancelPushFrame(frame);
bnc70914262019-03-16 12:49:50 -0700360 break;
361 }
bnc95fb6b62019-07-21 11:20:47 -0700362 case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
bnc70914262019-03-16 12:49:50 -0700363 SettingsFrame frame;
364 QuicDataReader reader(buffer_.data(), current_frame_length_);
365 if (!ParseSettingsFrame(&reader, &frame)) {
bncb9d07d92019-06-25 17:43:49 -0700366 return false;
bnc70914262019-03-16 12:49:50 -0700367 }
bncb9d07d92019-06-25 17:43:49 -0700368 continue_processing = visitor_->OnSettingsFrame(frame);
bnc70914262019-03-16 12:49:50 -0700369 break;
370 }
bnc95fb6b62019-07-21 11:20:47 -0700371 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
bncb9d07d92019-06-25 17:43:49 -0700372 continue_processing = visitor_->OnPushPromiseFrameEnd();
bnc70914262019-03-16 12:49:50 -0700373 break;
374 }
bnc95fb6b62019-07-21 11:20:47 -0700375 case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
bnc70914262019-03-16 12:49:50 -0700376 QuicDataReader reader(buffer_.data(), current_frame_length_);
377 GoAwayFrame frame;
378 static_assert(!std::is_same<decltype(frame.stream_id), uint64_t>::value,
379 "Please remove local |stream_id| variable and pass "
380 "&frame.stream_id directly to ReadVarInt62() when changing "
381 "QuicStreamId from uint32_t to uint64_t.");
382 uint64_t stream_id;
383 if (!reader.ReadVarInt62(&stream_id)) {
bnce7f67962019-08-08 06:34:35 -0700384 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
385 RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read GOAWAY stream_id");
bncb9d07d92019-06-25 17:43:49 -0700386 return false;
bnc70914262019-03-16 12:49:50 -0700387 }
bnc01918c02019-08-08 07:08:47 -0700388 if (!reader.IsDoneReading()) {
389 RaiseError(QUIC_INVALID_FRAME_DATA,
390 "Superfluous data in GOAWAY frame.");
391 return false;
392 }
bnc70914262019-03-16 12:49:50 -0700393 frame.stream_id = static_cast<QuicStreamId>(stream_id);
bncb9d07d92019-06-25 17:43:49 -0700394 continue_processing = visitor_->OnGoAwayFrame(frame);
bnc70914262019-03-16 12:49:50 -0700395 break;
396 }
bnc95fb6b62019-07-21 11:20:47 -0700397 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
bnc70914262019-03-16 12:49:50 -0700398 QuicDataReader reader(buffer_.data(), current_frame_length_);
399 MaxPushIdFrame frame;
400 if (!reader.ReadVarInt62(&frame.push_id)) {
bnce7f67962019-08-08 06:34:35 -0700401 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
402 RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read push_id");
bncb9d07d92019-06-25 17:43:49 -0700403 return false;
bnc70914262019-03-16 12:49:50 -0700404 }
bnc01918c02019-08-08 07:08:47 -0700405 if (!reader.IsDoneReading()) {
406 RaiseError(QUIC_INVALID_FRAME_DATA,
407 "Superfluous data in MAX_PUSH_ID frame.");
408 return false;
409 }
bncb9d07d92019-06-25 17:43:49 -0700410 continue_processing = visitor_->OnMaxPushIdFrame(frame);
bnc70914262019-03-16 12:49:50 -0700411 break;
412 }
bnc95fb6b62019-07-21 11:20:47 -0700413 case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH): {
bnc70914262019-03-16 12:49:50 -0700414 QuicDataReader reader(buffer_.data(), current_frame_length_);
415 DuplicatePushFrame frame;
416 if (!reader.ReadVarInt62(&frame.push_id)) {
bnce7f67962019-08-08 06:34:35 -0700417 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
418 RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read push_id");
bncb9d07d92019-06-25 17:43:49 -0700419 return false;
bnc70914262019-03-16 12:49:50 -0700420 }
bnc01918c02019-08-08 07:08:47 -0700421 if (!reader.IsDoneReading()) {
422 RaiseError(QUIC_INVALID_FRAME_DATA,
423 "Superfluous data in DUPLICATE_PUSH frame.");
424 return false;
425 }
bncb9d07d92019-06-25 17:43:49 -0700426 continue_processing = visitor_->OnDuplicatePushFrame(frame);
bnc70914262019-03-16 12:49:50 -0700427 break;
428 }
bncbf3dbe52019-07-17 05:17:41 -0700429 default: {
430 continue_processing = visitor_->OnUnknownFrameEnd();
431 break;
432 }
bnc70914262019-03-16 12:49:50 -0700433 }
434
renjietangbb98cbc2019-04-23 13:13:56 -0700435 current_length_field_length_ = 0;
renjietang2d475cf2019-04-18 17:03:37 -0700436 current_type_field_length_ = 0;
renjietangfcd91c02019-04-22 10:40:35 -0700437 state_ = STATE_READING_FRAME_TYPE;
bncb9d07d92019-06-25 17:43:49 -0700438 return continue_processing;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500439}
440
441void HttpDecoder::DiscardFramePayload(QuicDataReader* reader) {
442 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
443 remaining_frame_length_, reader->BytesRemaining());
dmcardleba2fb7e2019-12-13 07:44:34 -0800444 quiche::QuicheStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700445 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
446 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500447 remaining_frame_length_ -= payload.length();
448 if (remaining_frame_length_ == 0) {
renjietangfcd91c02019-04-22 10:40:35 -0700449 state_ = STATE_READING_FRAME_TYPE;
renjietangbb98cbc2019-04-23 13:13:56 -0700450 current_length_field_length_ = 0;
renjietang2d475cf2019-04-18 17:03:37 -0700451 current_type_field_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500452 }
453}
454
455void HttpDecoder::BufferFramePayload(QuicDataReader* reader) {
456 if (current_frame_length_ == remaining_frame_length_) {
457 buffer_.erase(buffer_.size());
458 buffer_.reserve(current_frame_length_);
459 }
460 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
461 remaining_frame_length_, reader->BytesRemaining());
bnc4368e7f2019-06-24 12:15:48 -0700462 bool success = reader->ReadBytes(
463 &(buffer_[0]) + current_frame_length_ - remaining_frame_length_,
464 bytes_to_read);
465 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500466 remaining_frame_length_ -= bytes_to_read;
467}
468
469void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500470 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
471 remaining_length_field_length_, reader->BytesRemaining());
bnc4368e7f2019-06-24 12:15:48 -0700472 bool success =
473 reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
474 remaining_length_field_length_,
475 bytes_to_read);
476 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500477 remaining_length_field_length_ -= bytes_to_read;
478}
479
renjietang2d475cf2019-04-18 17:03:37 -0700480void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
renjietang2d475cf2019-04-18 17:03:37 -0700481 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
482 remaining_type_field_length_, reader->BytesRemaining());
bnc4368e7f2019-06-24 12:15:48 -0700483 bool success =
484 reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
485 remaining_type_field_length_,
486 bytes_to_read);
487 DCHECK(success);
renjietang2d475cf2019-04-18 17:03:37 -0700488 remaining_type_field_length_ -= bytes_to_read;
489}
490
renjietang857362b2019-08-09 09:52:35 -0700491void HttpDecoder::BufferPushId(QuicDataReader* reader) {
492 DCHECK_LE(remaining_push_id_length_, current_frame_length_);
493 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
494 reader->BytesRemaining(), remaining_push_id_length_);
495 bool success =
496 reader->ReadBytes(push_id_buffer_.data() + current_push_id_length_ -
497 remaining_push_id_length_,
498 bytes_to_read);
499 DCHECK(success);
500 remaining_push_id_length_ -= bytes_to_read;
501 remaining_frame_length_ -= bytes_to_read;
502}
503
vasilvvc48c8712019-03-11 13:38:16 -0700504void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500505 state_ = STATE_ERROR;
506 error_ = error;
507 error_detail_ = std::move(error_detail);
bnc8983c0f2019-08-08 06:12:10 -0700508 visitor_->OnError(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500509}
510
511bool HttpDecoder::ParsePriorityFrame(QuicDataReader* reader,
512 PriorityFrame* frame) {
513 uint8_t flags;
bnc8dfeebd2019-07-16 11:41:29 -0700514 if (!reader->ReadUInt8(&flags)) {
515 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
516 RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read PRIORITY frame flags.");
517 return false;
518 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500519
renjietang3a76c892019-07-17 10:03:53 -0700520 // Assign two most significant bits to prioritized_type.
521 frame->prioritized_type = static_cast<PriorityElementType>((flags >> 6) & 3);
522 // Assign the next two most significant bits to dependency type.
523 frame->dependency_type = static_cast<PriorityElementType>((flags >> 4) & 3);
bncefbda662019-07-17 17:01:13 -0700524 frame->exclusive = flags & kPriorityExclusiveBit;
525 // TODO(bnc): Close connection with HTTP_MALFORMED_FRAME
526 // if lowest three bits are not all zero.
527
renjietangec095762019-06-19 14:35:02 -0700528 if (frame->prioritized_type != ROOT_OF_TREE &&
529 !reader->ReadVarInt62(&frame->prioritized_element_id)) {
bnc8dfeebd2019-07-16 11:41:29 -0700530 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
531 RaiseError(QUIC_INVALID_FRAME_DATA,
532 "Unable to read prioritized_element_id.");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500533 return false;
534 }
renjietangec095762019-06-19 14:35:02 -0700535 if (frame->dependency_type != ROOT_OF_TREE &&
536 !reader->ReadVarInt62(&frame->element_dependency_id)) {
bnc8dfeebd2019-07-16 11:41:29 -0700537 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
538 RaiseError(QUIC_INVALID_FRAME_DATA,
539 "Unable to read element_dependency_id.");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500540 return false;
541 }
542 if (!reader->ReadUInt8(&frame->weight)) {
bnc8dfeebd2019-07-16 11:41:29 -0700543 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
544 RaiseError(QUIC_INVALID_FRAME_DATA,
bnc01918c02019-08-08 07:08:47 -0700545 "Unable to read PRIORITY frame weight.");
bnc8dfeebd2019-07-16 11:41:29 -0700546 return false;
547 }
548 if (!reader->IsDoneReading()) {
549 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
bnc01918c02019-08-08 07:08:47 -0700550 RaiseError(QUIC_INVALID_FRAME_DATA, "Superfluous data in PRIORITY frame.");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500551 return false;
552 }
553 return true;
554}
555
556bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
557 SettingsFrame* frame) {
558 while (!reader->IsDoneReading()) {
renjietang3b3e3b32019-04-22 18:01:20 -0700559 uint64_t id;
560 if (!reader->ReadVarInt62(&id)) {
bnce7f67962019-08-08 06:34:35 -0700561 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
562 RaiseError(QUIC_INVALID_FRAME_DATA,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500563 "Unable to read settings frame identifier");
564 return false;
565 }
566 uint64_t content;
567 if (!reader->ReadVarInt62(&content)) {
bnce7f67962019-08-08 06:34:35 -0700568 // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
569 RaiseError(QUIC_INVALID_FRAME_DATA,
570 "Unable to read settings frame content");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500571 return false;
572 }
bnc93ea18d2019-08-22 09:57:43 -0700573 auto result = frame->values.insert({id, content});
574 if (!result.second) {
575 // TODO(b/124216424): Use HTTP_SETTINGS_ERROR.
576 RaiseError(QUIC_INVALID_FRAME_DATA, "Duplicate SETTINGS identifier.");
577 return false;
578 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500579 }
580 return true;
581}
582
bnc95fb6b62019-07-21 11:20:47 -0700583QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
renjietang4ab9d9f2019-04-10 14:30:26 -0700584 switch (frame_type) {
bnc95fb6b62019-07-21 11:20:47 -0700585 case static_cast<uint64_t>(HttpFrameType::PRIORITY):
renjietang4ab9d9f2019-04-10 14:30:26 -0700586 return kPriorityFirstByteLength + VARIABLE_LENGTH_INTEGER_LENGTH_8 * 2 +
587 kPriorityWeightLength;
bnc95fb6b62019-07-21 11:20:47 -0700588 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
renjietang4ab9d9f2019-04-10 14:30:26 -0700589 return sizeof(PushId);
bnc95fb6b62019-07-21 11:20:47 -0700590 case static_cast<uint64_t>(HttpFrameType::SETTINGS):
renjietang4ab9d9f2019-04-10 14:30:26 -0700591 // This limit is arbitrary.
592 return 1024 * 1024;
bnc95fb6b62019-07-21 11:20:47 -0700593 case static_cast<uint64_t>(HttpFrameType::GOAWAY):
renjietang5843bfd2019-10-10 13:24:57 -0700594 return VARIABLE_LENGTH_INTEGER_LENGTH_8;
bnc95fb6b62019-07-21 11:20:47 -0700595 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
renjietang4ab9d9f2019-04-10 14:30:26 -0700596 return sizeof(PushId);
bnc95fb6b62019-07-21 11:20:47 -0700597 case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH):
renjietang4ab9d9f2019-04-10 14:30:26 -0700598 return sizeof(PushId);
599 default:
600 // Other frames require no data buffering, so it's safe to have no limit.
601 return std::numeric_limits<QuicByteCount>::max();
602 }
603}
604
QUICHE teama6ef0a62019-03-07 20:34:33 -0500605} // namespace quic