1 // 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"
6
7 #include <cstdint>
8
9 #include "net/third_party/quiche/src/quic/core/http/http_frames.h"
10 #include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
11 #include "net/third_party/quiche/src/quic/core/quic_types.h"
12 #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"
14 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
15
16 namespace quic {
17
HttpDecoder(Visitor * visitor)18 HttpDecoder::HttpDecoder(Visitor* visitor)
19 : visitor_(visitor),
20 state_(STATE_READING_FRAME_TYPE),
21 current_frame_type_(0),
22 current_length_field_length_(0),
23 remaining_length_field_length_(0),
24 current_frame_length_(0),
25 remaining_frame_length_(0),
26 current_type_field_length_(0),
27 remaining_type_field_length_(0),
28 current_push_id_length_(0),
29 remaining_push_id_length_(0),
30 error_(QUIC_NO_ERROR),
31 error_detail_("") {
32 DCHECK(visitor_);
33 }
34
~HttpDecoder()35 HttpDecoder::~HttpDecoder() {}
36
ProcessInput(const char * data,QuicByteCount len)37 QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
38 DCHECK_EQ(QUIC_NO_ERROR, error_);
39 DCHECK_NE(STATE_ERROR, state_);
40
41 QuicDataReader reader(data, len);
42 bool continue_processing = true;
43 while (continue_processing &&
44 (reader.BytesRemaining() != 0 || state_ == STATE_FINISH_PARSING)) {
45 // |continue_processing| must have been set to false upon error.
46 DCHECK_EQ(QUIC_NO_ERROR, error_);
47 DCHECK_NE(STATE_ERROR, state_);
48
49 switch (state_) {
50 case STATE_READING_FRAME_TYPE:
51 ReadFrameType(&reader);
52 break;
53 case STATE_READING_FRAME_LENGTH:
54 continue_processing = ReadFrameLength(&reader);
55 break;
56 case STATE_READING_FRAME_PAYLOAD:
57 continue_processing = ReadFramePayload(&reader);
58 break;
59 case STATE_FINISH_PARSING:
60 continue_processing = FinishParsing();
61 break;
62 case STATE_ERROR:
63 break;
64 default:
65 QUIC_BUG << "Invalid state: " << state_;
66 }
67 }
68
69 return len - reader.BytesRemaining();
70 }
71
ReadFrameType(QuicDataReader * reader)72 void HttpDecoder::ReadFrameType(QuicDataReader* reader) {
73 DCHECK_NE(0u, reader->BytesRemaining());
74 if (current_type_field_length_ == 0) {
75 // A new frame is coming.
76 current_type_field_length_ = reader->PeekVarInt62Length();
77 DCHECK_NE(0u, current_type_field_length_);
78 if (current_type_field_length_ > reader->BytesRemaining()) {
79 // Buffer a new type field.
80 remaining_type_field_length_ = current_type_field_length_;
81 BufferFrameType(reader);
82 return;
83 }
84 // The reader has all type data needed, so no need to buffer.
85 bool success = reader->ReadVarInt62(¤t_frame_type_);
86 DCHECK(success);
87 } 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_);
95 bool success = type_reader.ReadVarInt62(¤t_frame_type_);
96 DCHECK(success);
97 }
98
99 state_ = STATE_READING_FRAME_LENGTH;
100 }
101
ReadFrameLength(QuicDataReader * reader)102 bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
103 DCHECK_NE(0u, reader->BytesRemaining());
104 if (current_length_field_length_ == 0) {
105 // A new frame is coming.
106 current_length_field_length_ = reader->PeekVarInt62Length();
107 DCHECK_NE(0u, current_length_field_length_);
108 if (current_length_field_length_ > reader->BytesRemaining()) {
109 // Buffer a new length field.
110 remaining_length_field_length_ = current_length_field_length_;
111 BufferFrameLength(reader);
112 return true;
113 }
114 // The reader has all length data needed, so no need to buffer.
115 bool success = reader->ReadVarInt62(¤t_frame_length_);
116 DCHECK(success);
117 } 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) {
122 return true;
123 }
124 QuicDataReader length_reader(length_buffer_.data(),
125 current_length_field_length_);
126 bool success = length_reader.ReadVarInt62(¤t_frame_length_);
127 DCHECK(success);
128 }
129
130 if (current_frame_length_ > MaxFrameLength(current_frame_type_)) {
131 RaiseError(QUIC_HTTP_FRAME_TOO_LARGE, "Frame is too large.");
132 return false;
133 }
134
135 // Calling the following visitor methods does not require parsing of any
136 // frame payload.
137 bool continue_processing = true;
138 const QuicByteCount header_length =
139 current_length_field_length_ + current_type_field_length_;
140
141 switch (current_frame_type_) {
142 case static_cast<uint64_t>(HttpFrameType::DATA):
143 continue_processing =
144 visitor_->OnDataFrameStart(header_length, current_frame_length_);
145 break;
146 case static_cast<uint64_t>(HttpFrameType::HEADERS):
147 continue_processing =
148 visitor_->OnHeadersFrameStart(header_length, current_frame_length_);
149 break;
150 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
151 break;
152 case static_cast<uint64_t>(HttpFrameType::SETTINGS):
153 continue_processing = visitor_->OnSettingsFrameStart(header_length);
154 break;
155 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
156 // This edge case needs to be handled here, because ReadFramePayload()
157 // does not get called if |current_frame_length_| is zero.
158 if (current_frame_length_ == 0) {
159 RaiseError(QUIC_HTTP_FRAME_ERROR,
160 "PUSH_PROMISE frame with empty payload.");
161 return false;
162 }
163 continue_processing = visitor_->OnPushPromiseFrameStart(header_length);
164 break;
165 case static_cast<uint64_t>(HttpFrameType::GOAWAY):
166 break;
167 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
168 break;
169 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE):
170 continue_processing = visitor_->OnPriorityUpdateFrameStart(header_length);
171 break;
172 default:
173 continue_processing = visitor_->OnUnknownFrameStart(
174 current_frame_type_, header_length, current_frame_length_);
175 break;
176 }
177
178 remaining_frame_length_ = current_frame_length_;
179 state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
180 : STATE_READING_FRAME_PAYLOAD;
181 return continue_processing;
182 }
183
ReadFramePayload(QuicDataReader * reader)184 bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
185 DCHECK_NE(0u, reader->BytesRemaining());
186 DCHECK_NE(0u, remaining_frame_length_);
187
188 bool continue_processing = true;
189
190 switch (current_frame_type_) {
191 case static_cast<uint64_t>(HttpFrameType::DATA): {
192 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
193 remaining_frame_length_, reader->BytesRemaining());
194 quiche::QuicheStringPiece payload;
195 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
196 DCHECK(success);
197 DCHECK(!payload.empty());
198 continue_processing = visitor_->OnDataFramePayload(payload);
199 remaining_frame_length_ -= payload.length();
200 break;
201 }
202 case static_cast<uint64_t>(HttpFrameType::HEADERS): {
203 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
204 remaining_frame_length_, reader->BytesRemaining());
205 quiche::QuicheStringPiece payload;
206 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
207 DCHECK(success);
208 DCHECK(!payload.empty());
209 continue_processing = visitor_->OnHeadersFramePayload(payload);
210 remaining_frame_length_ -= payload.length();
211 break;
212 }
213 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
214 BufferFramePayload(reader);
215 break;
216 }
217 case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
218 BufferFramePayload(reader);
219 break;
220 }
221 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
222 PushId push_id;
223 if (current_frame_length_ == remaining_frame_length_) {
224 // 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_) {
228 RaiseError(QUIC_HTTP_FRAME_ERROR,
229 "Unable to read PUSH_PROMISE push_id.");
230 return false;
231 }
232 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);
237 break;
238 }
239 bool success = reader->ReadVarInt62(&push_id);
240 DCHECK(success);
241 remaining_frame_length_ -= current_push_id_length_;
242 if (!visitor_->OnPushPromiseFramePushId(
243 push_id, current_push_id_length_,
244 current_frame_length_ - current_push_id_length_)) {
245 continue_processing = false;
246 current_push_id_length_ = 0;
247 break;
248 }
249 current_push_id_length_ = 0;
250 } else if (remaining_push_id_length_ > 0) {
251 // Waiting for more bytes on push id.
252 BufferPushId(reader);
253 if (remaining_push_id_length_ != 0) {
254 break;
255 }
256 QuicDataReader push_id_reader(push_id_buffer_.data(),
257 current_push_id_length_);
258
259 bool success = push_id_reader.ReadVarInt62(&push_id);
260 DCHECK(success);
261 if (!visitor_->OnPushPromiseFramePushId(
262 push_id, current_push_id_length_,
263 current_frame_length_ - current_push_id_length_)) {
264 continue_processing = false;
265 current_push_id_length_ = 0;
266 break;
267 }
268 current_push_id_length_ = 0;
269 }
270
271 // Read Push Promise headers.
272 DCHECK_LT(remaining_frame_length_, current_frame_length_);
273 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
274 remaining_frame_length_, reader->BytesRemaining());
275 if (bytes_to_read == 0) {
276 break;
277 }
278 quiche::QuicheStringPiece payload;
279 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
280 DCHECK(success);
281 DCHECK(!payload.empty());
282 continue_processing = visitor_->OnPushPromiseFramePayload(payload);
283 remaining_frame_length_ -= payload.length();
284 break;
285 }
286 case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
287 BufferFramePayload(reader);
288 break;
289 }
290 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
291 BufferFramePayload(reader);
292 break;
293 }
294 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE): {
295 // TODO(bnc): Avoid buffering if the entire frame is present, and
296 // instead parse directly out of |reader|.
297 BufferFramePayload(reader);
298 break;
299 }
300 default: {
301 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
302 remaining_frame_length_, reader->BytesRemaining());
303 quiche::QuicheStringPiece payload;
304 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
305 DCHECK(success);
306 DCHECK(!payload.empty());
307 continue_processing = visitor_->OnUnknownFramePayload(payload);
308 remaining_frame_length_ -= payload.length();
309 break;
310 }
311 }
312
313 if (remaining_frame_length_ == 0) {
314 state_ = STATE_FINISH_PARSING;
315 }
316
317 return continue_processing;
318 }
319
FinishParsing()320 bool HttpDecoder::FinishParsing() {
321 DCHECK_EQ(0u, remaining_frame_length_);
322
323 bool continue_processing = true;
324
325 switch (current_frame_type_) {
326 case static_cast<uint64_t>(HttpFrameType::DATA): {
327 continue_processing = visitor_->OnDataFrameEnd();
328 break;
329 }
330 case static_cast<uint64_t>(HttpFrameType::HEADERS): {
331 continue_processing = visitor_->OnHeadersFrameEnd();
332 break;
333 }
334 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
335 CancelPushFrame frame;
336 QuicDataReader reader(buffer_.data(), current_frame_length_);
337 if (!reader.ReadVarInt62(&frame.push_id)) {
338 RaiseError(QUIC_HTTP_FRAME_ERROR,
339 "Unable to read CANCEL_PUSH push_id.");
340 return false;
341 }
342 if (!reader.IsDoneReading()) {
343 RaiseError(QUIC_HTTP_FRAME_ERROR,
344 "Superfluous data in CANCEL_PUSH frame.");
345 return false;
346 }
347 continue_processing = visitor_->OnCancelPushFrame(frame);
348 break;
349 }
350 case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
351 SettingsFrame frame;
352 QuicDataReader reader(buffer_.data(), current_frame_length_);
353 if (!ParseSettingsFrame(&reader, &frame)) {
354 return false;
355 }
356 continue_processing = visitor_->OnSettingsFrame(frame);
357 break;
358 }
359 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
360 continue_processing = visitor_->OnPushPromiseFrameEnd();
361 break;
362 }
363 case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
364 QuicDataReader reader(buffer_.data(), current_frame_length_);
365 GoAwayFrame frame;
366 static_assert(!std::is_same<decltype(frame.stream_id), uint64_t>::value,
367 "Please remove local |stream_id| variable and pass "
368 "&frame.stream_id directly to ReadVarInt62() when changing "
369 "QuicStreamId from uint32_t to uint64_t.");
370 uint64_t stream_id;
371 if (!reader.ReadVarInt62(&stream_id)) {
372 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read GOAWAY stream_id.");
373 return false;
374 }
375 if (!reader.IsDoneReading()) {
376 RaiseError(QUIC_HTTP_FRAME_ERROR, "Superfluous data in GOAWAY frame.");
377 return false;
378 }
379 frame.stream_id = static_cast<QuicStreamId>(stream_id);
380 continue_processing = visitor_->OnGoAwayFrame(frame);
381 break;
382 }
383 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
384 QuicDataReader reader(buffer_.data(), current_frame_length_);
385 MaxPushIdFrame frame;
386 if (!reader.ReadVarInt62(&frame.push_id)) {
387 RaiseError(QUIC_HTTP_FRAME_ERROR,
388 "Unable to read MAX_PUSH_ID push_id.");
389 return false;
390 }
391 if (!reader.IsDoneReading()) {
392 RaiseError(QUIC_HTTP_FRAME_ERROR,
393 "Superfluous data in MAX_PUSH_ID frame.");
394 return false;
395 }
396 continue_processing = visitor_->OnMaxPushIdFrame(frame);
397 break;
398 }
399 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE): {
400 // TODO(bnc): Avoid buffering if the entire frame is present, and
401 // instead parse directly out of |reader|.
402 PriorityUpdateFrame frame;
403 QuicDataReader reader(buffer_.data(), current_frame_length_);
404 if (!ParsePriorityUpdateFrame(&reader, &frame)) {
405 return false;
406 }
407 continue_processing = visitor_->OnPriorityUpdateFrame(frame);
408 break;
409 }
410 default: {
411 continue_processing = visitor_->OnUnknownFrameEnd();
412 break;
413 }
414 }
415
416 current_length_field_length_ = 0;
417 current_type_field_length_ = 0;
418 state_ = STATE_READING_FRAME_TYPE;
419 return continue_processing;
420 }
421
DiscardFramePayload(QuicDataReader * reader)422 void HttpDecoder::DiscardFramePayload(QuicDataReader* reader) {
423 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
424 remaining_frame_length_, reader->BytesRemaining());
425 quiche::QuicheStringPiece payload;
426 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
427 DCHECK(success);
428 remaining_frame_length_ -= payload.length();
429 if (remaining_frame_length_ == 0) {
430 state_ = STATE_READING_FRAME_TYPE;
431 current_length_field_length_ = 0;
432 current_type_field_length_ = 0;
433 }
434 }
435
BufferFramePayload(QuicDataReader * reader)436 void HttpDecoder::BufferFramePayload(QuicDataReader* reader) {
437 if (current_frame_length_ == remaining_frame_length_) {
438 buffer_.erase(buffer_.size());
439 buffer_.reserve(current_frame_length_);
440 }
441 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
442 remaining_frame_length_, reader->BytesRemaining());
443 bool success = reader->ReadBytes(
444 &(buffer_[0]) + current_frame_length_ - remaining_frame_length_,
445 bytes_to_read);
446 DCHECK(success);
447 remaining_frame_length_ -= bytes_to_read;
448 }
449
BufferFrameLength(QuicDataReader * reader)450 void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
451 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
452 remaining_length_field_length_, reader->BytesRemaining());
453 bool success =
454 reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
455 remaining_length_field_length_,
456 bytes_to_read);
457 DCHECK(success);
458 remaining_length_field_length_ -= bytes_to_read;
459 }
460
BufferFrameType(QuicDataReader * reader)461 void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
462 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
463 remaining_type_field_length_, reader->BytesRemaining());
464 bool success =
465 reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
466 remaining_type_field_length_,
467 bytes_to_read);
468 DCHECK(success);
469 remaining_type_field_length_ -= bytes_to_read;
470 }
471
BufferPushId(QuicDataReader * reader)472 void HttpDecoder::BufferPushId(QuicDataReader* reader) {
473 DCHECK_LE(remaining_push_id_length_, current_frame_length_);
474 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
475 reader->BytesRemaining(), remaining_push_id_length_);
476 bool success =
477 reader->ReadBytes(push_id_buffer_.data() + current_push_id_length_ -
478 remaining_push_id_length_,
479 bytes_to_read);
480 DCHECK(success);
481 remaining_push_id_length_ -= bytes_to_read;
482 remaining_frame_length_ -= bytes_to_read;
483 }
484
RaiseError(QuicErrorCode error,std::string error_detail)485 void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
486 state_ = STATE_ERROR;
487 error_ = error;
488 error_detail_ = std::move(error_detail);
489 visitor_->OnError(this);
490 }
491
ParseSettingsFrame(QuicDataReader * reader,SettingsFrame * frame)492 bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
493 SettingsFrame* frame) {
494 while (!reader->IsDoneReading()) {
495 uint64_t id;
496 if (!reader->ReadVarInt62(&id)) {
497 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting identifier.");
498 return false;
499 }
500 uint64_t content;
501 if (!reader->ReadVarInt62(&content)) {
502 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting value.");
503 return false;
504 }
505 auto result = frame->values.insert({id, content});
506 if (!result.second) {
507 RaiseError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER,
508 "Duplicate setting identifier.");
509 return false;
510 }
511 }
512 return true;
513 }
514
ParsePriorityUpdateFrame(QuicDataReader * reader,PriorityUpdateFrame * frame)515 bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader,
516 PriorityUpdateFrame* frame) {
517 uint8_t prioritized_element_type;
518 if (!reader->ReadUInt8(&prioritized_element_type)) {
519 RaiseError(QUIC_HTTP_FRAME_ERROR,
520 "Unable to read prioritized element type.");
521 return false;
522 }
523
524 if (prioritized_element_type != REQUEST_STREAM &&
525 prioritized_element_type != PUSH_STREAM) {
526 RaiseError(QUIC_HTTP_FRAME_ERROR, "Invalid prioritized element type.");
527 return false;
528 }
529
530 frame->prioritized_element_type =
531 static_cast<PrioritizedElementType>(prioritized_element_type);
532
533 if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
534 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id.");
535 return false;
536 }
537
538 quiche::QuicheStringPiece priority_field_value =
539 reader->ReadRemainingPayload();
540 frame->priority_field_value =
541 std::string(priority_field_value.data(), priority_field_value.size());
542
543 return true;
544 }
545
MaxFrameLength(uint64_t frame_type)546 QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
547 switch (frame_type) {
548 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
549 return sizeof(PushId);
550 case static_cast<uint64_t>(HttpFrameType::SETTINGS):
551 // This limit is arbitrary.
552 return 1024 * 1024;
553 case static_cast<uint64_t>(HttpFrameType::GOAWAY):
554 return VARIABLE_LENGTH_INTEGER_LENGTH_8;
555 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
556 return sizeof(PushId);
557 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE):
558 // This limit is arbitrary.
559 return 1024 * 1024;
560 default:
561 // Other frames require no data buffering, so it's safe to have no limit.
562 return std::numeric_limits<QuicByteCount>::max();
563 }
564 }
565
566 } // namespace quic
567