blob: c5aa08c06e298868f8916d0150118b126782bfa0 [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_)) {
bncdfabdfb2020-01-17 17:46:40 -0800131 RaiseError(QUIC_HTTP_FRAME_TOO_LARGE, "Frame is too large.");
bncb9d07d92019-06-25 17:43:49 -0700132 return false;
renjietang4ab9d9f2019-04-10 14:30:26 -0700133 }
134
renjietang7d4f9132019-06-20 15:04:34 -0700135 // Calling the following visitor methods does not require parsing of any
bnc70914262019-03-16 12:49:50 -0700136 // frame payload.
bncb9d07d92019-06-25 17:43:49 -0700137 bool continue_processing = true;
bnca2b13be2019-07-31 12:04:20 -0700138 const QuicByteCount header_length =
139 current_length_field_length_ + current_type_field_length_;
bncbf3dbe52019-07-17 05:17:41 -0700140
141 switch (current_frame_type_) {
bnc95fb6b62019-07-21 11:20:47 -0700142 case static_cast<uint64_t>(HttpFrameType::DATA):
bnca2b13be2019-07-31 12:04:20 -0700143 continue_processing = visitor_->OnDataFrameStart(header_length);
bncbf3dbe52019-07-17 05:17:41 -0700144 break;
bnc95fb6b62019-07-21 11:20:47 -0700145 case static_cast<uint64_t>(HttpFrameType::HEADERS):
bnca2b13be2019-07-31 12:04:20 -0700146 continue_processing = visitor_->OnHeadersFrameStart(header_length);
bncbf3dbe52019-07-17 05:17:41 -0700147 break;
bnc95fb6b62019-07-21 11:20:47 -0700148 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
bncbf3dbe52019-07-17 05:17:41 -0700149 break;
bnc95fb6b62019-07-21 11:20:47 -0700150 case static_cast<uint64_t>(HttpFrameType::SETTINGS):
bnca2b13be2019-07-31 12:04:20 -0700151 continue_processing = visitor_->OnSettingsFrameStart(header_length);
bncbf3dbe52019-07-17 05:17:41 -0700152 break;
bnc95fb6b62019-07-21 11:20:47 -0700153 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
bncf0db6542019-09-23 11:18:28 -0700154 // This edge case needs to be handled here, because ReadFramePayload()
155 // does not get called if |current_frame_length_| is zero.
bncfcd42352019-09-20 17:55:47 -0700156 if (current_frame_length_ == 0) {
bncdfabdfb2020-01-17 17:46:40 -0800157 RaiseError(QUIC_HTTP_FRAME_ERROR,
158 "PUSH_PROMISE frame with empty payload.");
bncfcd42352019-09-20 17:55:47 -0700159 return false;
160 }
bncf0db6542019-09-23 11:18:28 -0700161 continue_processing = visitor_->OnPushPromiseFrameStart(header_length);
bncbf3dbe52019-07-17 05:17:41 -0700162 break;
bnc95fb6b62019-07-21 11:20:47 -0700163 case static_cast<uint64_t>(HttpFrameType::GOAWAY):
bncbf3dbe52019-07-17 05:17:41 -0700164 break;
bnc95fb6b62019-07-21 11:20:47 -0700165 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
bncbf3dbe52019-07-17 05:17:41 -0700166 break;
bnc95fb6b62019-07-21 11:20:47 -0700167 case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH):
bncbf3dbe52019-07-17 05:17:41 -0700168 break;
bnc51e89622020-01-10 10:40:32 -0800169 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE):
170 continue_processing = visitor_->OnPriorityUpdateFrameStart(header_length);
171 break;
bncbf3dbe52019-07-17 05:17:41 -0700172 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::CANCEL_PUSH): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500214 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700215 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500216 }
bnc95fb6b62019-07-21 11:20:47 -0700217 case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500218 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700219 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220 }
bnc95fb6b62019-07-21 11:20:47 -0700221 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
renjietang857362b2019-08-09 09:52:35 -0700222 PushId push_id;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500223 if (current_frame_length_ == remaining_frame_length_) {
renjietang857362b2019-08-09 09:52:35 -0700224 // A new Push Promise frame just arrived.
225 DCHECK_EQ(0u, current_push_id_length_);
226 current_push_id_length_ = reader->PeekVarInt62Length();
227 if (current_push_id_length_ > remaining_frame_length_) {
bncdfabdfb2020-01-17 17:46:40 -0800228 RaiseError(QUIC_HTTP_FRAME_ERROR,
229 "Unable to read PUSH_PROMISE push_id.");
bncb9d07d92019-06-25 17:43:49 -0700230 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500231 }
renjietang857362b2019-08-09 09:52:35 -0700232 if (current_push_id_length_ > reader->BytesRemaining()) {
233 // Not all bytes of push id is present yet, buffer push id.
234 DCHECK_EQ(0u, remaining_push_id_length_);
235 remaining_push_id_length_ = current_push_id_length_;
236 BufferPushId(reader);
bncb9d07d92019-06-25 17:43:49 -0700237 break;
renjietang546a6282019-06-03 10:21:21 -0700238 }
renjietang857362b2019-08-09 09:52:35 -0700239 bool success = reader->ReadVarInt62(&push_id);
240 DCHECK(success);
241 remaining_frame_length_ -= current_push_id_length_;
bncf0db6542019-09-23 11:18:28 -0700242 if (!visitor_->OnPushPromiseFramePushId(push_id,
243 current_push_id_length_)) {
renjietang857362b2019-08-09 09:52:35 -0700244 continue_processing = false;
245 current_push_id_length_ = 0;
246 break;
247 }
248 current_push_id_length_ = 0;
249 } else if (remaining_push_id_length_ > 0) {
250 // Waiting for more bytes on push id.
251 BufferPushId(reader);
252 if (remaining_push_id_length_ != 0) {
253 break;
254 }
255 QuicDataReader push_id_reader(push_id_buffer_.data(),
256 current_push_id_length_);
257
258 bool success = push_id_reader.ReadVarInt62(&push_id);
259 DCHECK(success);
bncf0db6542019-09-23 11:18:28 -0700260 if (!visitor_->OnPushPromiseFramePushId(push_id,
261 current_push_id_length_)) {
renjietang857362b2019-08-09 09:52:35 -0700262 continue_processing = false;
263 current_push_id_length_ = 0;
264 break;
265 }
266 current_push_id_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500267 }
renjietang857362b2019-08-09 09:52:35 -0700268
269 // Read Push Promise headers.
bnc70914262019-03-16 12:49:50 -0700270 DCHECK_LT(remaining_frame_length_, current_frame_length_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500271 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
272 remaining_frame_length_, reader->BytesRemaining());
273 if (bytes_to_read == 0) {
bnc70914262019-03-16 12:49:50 -0700274 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500275 }
dmcardleba2fb7e2019-12-13 07:44:34 -0800276 quiche::QuicheStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700277 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
278 DCHECK(success);
bnc70914262019-03-16 12:49:50 -0700279 DCHECK(!payload.empty());
bncb9d07d92019-06-25 17:43:49 -0700280 continue_processing = visitor_->OnPushPromiseFramePayload(payload);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500281 remaining_frame_length_ -= payload.length();
bnc70914262019-03-16 12:49:50 -0700282 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500283 }
bnc95fb6b62019-07-21 11:20:47 -0700284 case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500285 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700286 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500287 }
bnc95fb6b62019-07-21 11:20:47 -0700288 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500289 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700290 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500291 }
bnc95fb6b62019-07-21 11:20:47 -0700292 case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH): {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500293 BufferFramePayload(reader);
bnc70914262019-03-16 12:49:50 -0700294 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500295 }
bnc51e89622020-01-10 10:40:32 -0800296 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE): {
297 // TODO(bnc): Avoid buffering if the entire frame is present, and
298 // instead parse directly out of |reader|.
299 BufferFramePayload(reader);
300 break;
301 }
bncbf3dbe52019-07-17 05:17:41 -0700302 default: {
303 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
304 remaining_frame_length_, reader->BytesRemaining());
dmcardleba2fb7e2019-12-13 07:44:34 -0800305 quiche::QuicheStringPiece payload;
bncbf3dbe52019-07-17 05:17:41 -0700306 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
307 DCHECK(success);
308 DCHECK(!payload.empty());
309 continue_processing = visitor_->OnUnknownFramePayload(payload);
310 remaining_frame_length_ -= payload.length();
311 break;
312 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500313 }
bnc70914262019-03-16 12:49:50 -0700314
315 if (remaining_frame_length_ == 0) {
316 state_ = STATE_FINISH_PARSING;
317 }
bncb9d07d92019-06-25 17:43:49 -0700318
319 return continue_processing;
bnc70914262019-03-16 12:49:50 -0700320}
321
bncb9d07d92019-06-25 17:43:49 -0700322bool HttpDecoder::FinishParsing() {
bnc70914262019-03-16 12:49:50 -0700323 DCHECK_EQ(0u, remaining_frame_length_);
bncb9d07d92019-06-25 17:43:49 -0700324
325 bool continue_processing = true;
326
bnc70914262019-03-16 12:49:50 -0700327 switch (current_frame_type_) {
bnc95fb6b62019-07-21 11:20:47 -0700328 case static_cast<uint64_t>(HttpFrameType::DATA): {
bncb9d07d92019-06-25 17:43:49 -0700329 continue_processing = visitor_->OnDataFrameEnd();
bnc70914262019-03-16 12:49:50 -0700330 break;
331 }
bnc95fb6b62019-07-21 11:20:47 -0700332 case static_cast<uint64_t>(HttpFrameType::HEADERS): {
bncb9d07d92019-06-25 17:43:49 -0700333 continue_processing = visitor_->OnHeadersFrameEnd();
bnc70914262019-03-16 12:49:50 -0700334 break;
335 }
bnc95fb6b62019-07-21 11:20:47 -0700336 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
bnc70914262019-03-16 12:49:50 -0700337 CancelPushFrame frame;
338 QuicDataReader reader(buffer_.data(), current_frame_length_);
339 if (!reader.ReadVarInt62(&frame.push_id)) {
bncdfabdfb2020-01-17 17:46:40 -0800340 RaiseError(QUIC_HTTP_FRAME_ERROR,
341 "Unable to read CANCEL_PUSH push_id.");
bncb9d07d92019-06-25 17:43:49 -0700342 return false;
bnc70914262019-03-16 12:49:50 -0700343 }
bnc01918c02019-08-08 07:08:47 -0700344 if (!reader.IsDoneReading()) {
bncdfabdfb2020-01-17 17:46:40 -0800345 RaiseError(QUIC_HTTP_FRAME_ERROR,
bnc01918c02019-08-08 07:08:47 -0700346 "Superfluous data in CANCEL_PUSH frame.");
347 return false;
348 }
bncb9d07d92019-06-25 17:43:49 -0700349 continue_processing = visitor_->OnCancelPushFrame(frame);
bnc70914262019-03-16 12:49:50 -0700350 break;
351 }
bnc95fb6b62019-07-21 11:20:47 -0700352 case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
bnc70914262019-03-16 12:49:50 -0700353 SettingsFrame frame;
354 QuicDataReader reader(buffer_.data(), current_frame_length_);
355 if (!ParseSettingsFrame(&reader, &frame)) {
bncb9d07d92019-06-25 17:43:49 -0700356 return false;
bnc70914262019-03-16 12:49:50 -0700357 }
bncb9d07d92019-06-25 17:43:49 -0700358 continue_processing = visitor_->OnSettingsFrame(frame);
bnc70914262019-03-16 12:49:50 -0700359 break;
360 }
bnc95fb6b62019-07-21 11:20:47 -0700361 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
bncb9d07d92019-06-25 17:43:49 -0700362 continue_processing = visitor_->OnPushPromiseFrameEnd();
bnc70914262019-03-16 12:49:50 -0700363 break;
364 }
bnc95fb6b62019-07-21 11:20:47 -0700365 case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
bnc70914262019-03-16 12:49:50 -0700366 QuicDataReader reader(buffer_.data(), current_frame_length_);
367 GoAwayFrame frame;
368 static_assert(!std::is_same<decltype(frame.stream_id), uint64_t>::value,
369 "Please remove local |stream_id| variable and pass "
370 "&frame.stream_id directly to ReadVarInt62() when changing "
371 "QuicStreamId from uint32_t to uint64_t.");
372 uint64_t stream_id;
373 if (!reader.ReadVarInt62(&stream_id)) {
bncdfabdfb2020-01-17 17:46:40 -0800374 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read GOAWAY stream_id.");
bncb9d07d92019-06-25 17:43:49 -0700375 return false;
bnc70914262019-03-16 12:49:50 -0700376 }
bnc01918c02019-08-08 07:08:47 -0700377 if (!reader.IsDoneReading()) {
bncdfabdfb2020-01-17 17:46:40 -0800378 RaiseError(QUIC_HTTP_FRAME_ERROR, "Superfluous data in GOAWAY frame.");
bnc01918c02019-08-08 07:08:47 -0700379 return false;
380 }
bnc70914262019-03-16 12:49:50 -0700381 frame.stream_id = static_cast<QuicStreamId>(stream_id);
bncb9d07d92019-06-25 17:43:49 -0700382 continue_processing = visitor_->OnGoAwayFrame(frame);
bnc70914262019-03-16 12:49:50 -0700383 break;
384 }
bnc95fb6b62019-07-21 11:20:47 -0700385 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
bnc70914262019-03-16 12:49:50 -0700386 QuicDataReader reader(buffer_.data(), current_frame_length_);
387 MaxPushIdFrame frame;
388 if (!reader.ReadVarInt62(&frame.push_id)) {
bncdfabdfb2020-01-17 17:46:40 -0800389 RaiseError(QUIC_HTTP_FRAME_ERROR,
390 "Unable to read MAX_PUSH_ID push_id.");
bncb9d07d92019-06-25 17:43:49 -0700391 return false;
bnc70914262019-03-16 12:49:50 -0700392 }
bnc01918c02019-08-08 07:08:47 -0700393 if (!reader.IsDoneReading()) {
bncdfabdfb2020-01-17 17:46:40 -0800394 RaiseError(QUIC_HTTP_FRAME_ERROR,
bnc01918c02019-08-08 07:08:47 -0700395 "Superfluous data in MAX_PUSH_ID frame.");
396 return false;
397 }
bncb9d07d92019-06-25 17:43:49 -0700398 continue_processing = visitor_->OnMaxPushIdFrame(frame);
bnc70914262019-03-16 12:49:50 -0700399 break;
400 }
bnc95fb6b62019-07-21 11:20:47 -0700401 case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH): {
bnc70914262019-03-16 12:49:50 -0700402 QuicDataReader reader(buffer_.data(), current_frame_length_);
403 DuplicatePushFrame frame;
404 if (!reader.ReadVarInt62(&frame.push_id)) {
bncdfabdfb2020-01-17 17:46:40 -0800405 RaiseError(QUIC_HTTP_FRAME_ERROR,
406 "Unable to read DUPLICATE_PUSH push_id.");
bncb9d07d92019-06-25 17:43:49 -0700407 return false;
bnc70914262019-03-16 12:49:50 -0700408 }
bnc01918c02019-08-08 07:08:47 -0700409 if (!reader.IsDoneReading()) {
bncdfabdfb2020-01-17 17:46:40 -0800410 RaiseError(QUIC_HTTP_FRAME_ERROR,
bnc01918c02019-08-08 07:08:47 -0700411 "Superfluous data in DUPLICATE_PUSH frame.");
412 return false;
413 }
bncb9d07d92019-06-25 17:43:49 -0700414 continue_processing = visitor_->OnDuplicatePushFrame(frame);
bnc70914262019-03-16 12:49:50 -0700415 break;
416 }
bnc51e89622020-01-10 10:40:32 -0800417 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE): {
418 // TODO(bnc): Avoid buffering if the entire frame is present, and
419 // instead parse directly out of |reader|.
420 PriorityUpdateFrame frame;
421 QuicDataReader reader(buffer_.data(), current_frame_length_);
422 if (!ParsePriorityUpdateFrame(&reader, &frame)) {
423 return false;
424 }
425 continue_processing = visitor_->OnPriorityUpdateFrame(frame);
426 break;
427 }
bncbf3dbe52019-07-17 05:17:41 -0700428 default: {
429 continue_processing = visitor_->OnUnknownFrameEnd();
430 break;
431 }
bnc70914262019-03-16 12:49:50 -0700432 }
433
renjietangbb98cbc2019-04-23 13:13:56 -0700434 current_length_field_length_ = 0;
renjietang2d475cf2019-04-18 17:03:37 -0700435 current_type_field_length_ = 0;
renjietangfcd91c02019-04-22 10:40:35 -0700436 state_ = STATE_READING_FRAME_TYPE;
bncb9d07d92019-06-25 17:43:49 -0700437 return continue_processing;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500438}
439
440void HttpDecoder::DiscardFramePayload(QuicDataReader* reader) {
441 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
442 remaining_frame_length_, reader->BytesRemaining());
dmcardleba2fb7e2019-12-13 07:44:34 -0800443 quiche::QuicheStringPiece payload;
bnc4368e7f2019-06-24 12:15:48 -0700444 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
445 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446 remaining_frame_length_ -= payload.length();
447 if (remaining_frame_length_ == 0) {
renjietangfcd91c02019-04-22 10:40:35 -0700448 state_ = STATE_READING_FRAME_TYPE;
renjietangbb98cbc2019-04-23 13:13:56 -0700449 current_length_field_length_ = 0;
renjietang2d475cf2019-04-18 17:03:37 -0700450 current_type_field_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500451 }
452}
453
454void HttpDecoder::BufferFramePayload(QuicDataReader* reader) {
455 if (current_frame_length_ == remaining_frame_length_) {
456 buffer_.erase(buffer_.size());
457 buffer_.reserve(current_frame_length_);
458 }
459 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
460 remaining_frame_length_, reader->BytesRemaining());
bnc4368e7f2019-06-24 12:15:48 -0700461 bool success = reader->ReadBytes(
462 &(buffer_[0]) + current_frame_length_ - remaining_frame_length_,
463 bytes_to_read);
464 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500465 remaining_frame_length_ -= bytes_to_read;
466}
467
468void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500469 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
470 remaining_length_field_length_, reader->BytesRemaining());
bnc4368e7f2019-06-24 12:15:48 -0700471 bool success =
472 reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
473 remaining_length_field_length_,
474 bytes_to_read);
475 DCHECK(success);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500476 remaining_length_field_length_ -= bytes_to_read;
477}
478
renjietang2d475cf2019-04-18 17:03:37 -0700479void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
renjietang2d475cf2019-04-18 17:03:37 -0700480 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
481 remaining_type_field_length_, reader->BytesRemaining());
bnc4368e7f2019-06-24 12:15:48 -0700482 bool success =
483 reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
484 remaining_type_field_length_,
485 bytes_to_read);
486 DCHECK(success);
renjietang2d475cf2019-04-18 17:03:37 -0700487 remaining_type_field_length_ -= bytes_to_read;
488}
489
renjietang857362b2019-08-09 09:52:35 -0700490void HttpDecoder::BufferPushId(QuicDataReader* reader) {
491 DCHECK_LE(remaining_push_id_length_, current_frame_length_);
492 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
493 reader->BytesRemaining(), remaining_push_id_length_);
494 bool success =
495 reader->ReadBytes(push_id_buffer_.data() + current_push_id_length_ -
496 remaining_push_id_length_,
497 bytes_to_read);
498 DCHECK(success);
499 remaining_push_id_length_ -= bytes_to_read;
500 remaining_frame_length_ -= bytes_to_read;
501}
502
vasilvvc48c8712019-03-11 13:38:16 -0700503void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500504 state_ = STATE_ERROR;
505 error_ = error;
506 error_detail_ = std::move(error_detail);
bnc8983c0f2019-08-08 06:12:10 -0700507 visitor_->OnError(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500508}
509
QUICHE teama6ef0a62019-03-07 20:34:33 -0500510bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
511 SettingsFrame* frame) {
512 while (!reader->IsDoneReading()) {
renjietang3b3e3b32019-04-22 18:01:20 -0700513 uint64_t id;
514 if (!reader->ReadVarInt62(&id)) {
bncdfabdfb2020-01-17 17:46:40 -0800515 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting identifier.");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500516 return false;
517 }
518 uint64_t content;
519 if (!reader->ReadVarInt62(&content)) {
bncdfabdfb2020-01-17 17:46:40 -0800520 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting value.");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500521 return false;
522 }
bnc93ea18d2019-08-22 09:57:43 -0700523 auto result = frame->values.insert({id, content});
524 if (!result.second) {
bncdfabdfb2020-01-17 17:46:40 -0800525 RaiseError(QUIC_HTTP_FRAME_ERROR, "Duplicate setting identifier.");
bnc93ea18d2019-08-22 09:57:43 -0700526 return false;
527 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500528 }
529 return true;
530}
531
bnc51e89622020-01-10 10:40:32 -0800532bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader,
533 PriorityUpdateFrame* frame) {
534 uint8_t prioritized_element_type;
535 if (!reader->ReadUInt8(&prioritized_element_type)) {
bncdfabdfb2020-01-17 17:46:40 -0800536 RaiseError(QUIC_HTTP_FRAME_ERROR,
bnc51e89622020-01-10 10:40:32 -0800537 "Unable to read prioritized element type.");
538 return false;
539 }
540
541 if (prioritized_element_type != REQUEST_STREAM &&
542 prioritized_element_type != PUSH_STREAM) {
bncdfabdfb2020-01-17 17:46:40 -0800543 RaiseError(QUIC_HTTP_FRAME_ERROR, "Invalid prioritized element type.");
bnc51e89622020-01-10 10:40:32 -0800544 return false;
545 }
546
547 frame->prioritized_element_type =
548 static_cast<PrioritizedElementType>(prioritized_element_type);
549
550 if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
bncdfabdfb2020-01-17 17:46:40 -0800551 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id.");
bnc51e89622020-01-10 10:40:32 -0800552 return false;
553 }
554
555 quiche::QuicheStringPiece priority_field_value =
556 reader->ReadRemainingPayload();
557 frame->priority_field_value =
558 std::string(priority_field_value.data(), priority_field_value.size());
559
560 return true;
561}
562
bnc95fb6b62019-07-21 11:20:47 -0700563QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
renjietang4ab9d9f2019-04-10 14:30:26 -0700564 switch (frame_type) {
bnc95fb6b62019-07-21 11:20:47 -0700565 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
renjietang4ab9d9f2019-04-10 14:30:26 -0700566 return sizeof(PushId);
bnc95fb6b62019-07-21 11:20:47 -0700567 case static_cast<uint64_t>(HttpFrameType::SETTINGS):
renjietang4ab9d9f2019-04-10 14:30:26 -0700568 // This limit is arbitrary.
569 return 1024 * 1024;
bnc95fb6b62019-07-21 11:20:47 -0700570 case static_cast<uint64_t>(HttpFrameType::GOAWAY):
renjietang5843bfd2019-10-10 13:24:57 -0700571 return VARIABLE_LENGTH_INTEGER_LENGTH_8;
bnc95fb6b62019-07-21 11:20:47 -0700572 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
renjietang4ab9d9f2019-04-10 14:30:26 -0700573 return sizeof(PushId);
bnc95fb6b62019-07-21 11:20:47 -0700574 case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH):
renjietang4ab9d9f2019-04-10 14:30:26 -0700575 return sizeof(PushId);
bnc51e89622020-01-10 10:40:32 -0800576 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE):
577 // This limit is arbitrary.
578 return 1024 * 1024;
renjietang4ab9d9f2019-04-10 14:30:26 -0700579 default:
580 // Other frames require no data buffering, so it's safe to have no limit.
581 return std::numeric_limits<QuicByteCount>::max();
582 }
583}
584
QUICHE teama6ef0a62019-03-07 20:34:33 -0500585} // namespace quic