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 "quiche/quic/core/http/http_decoder.h"
6
7 #include <cstdint>
8
9 #include "absl/base/attributes.h"
10 #include "absl/strings/string_view.h"
11 #include "quiche/http2/http2_constants.h"
12 #include "quiche/quic/core/http/http_frames.h"
13 #include "quiche/quic/core/quic_data_reader.h"
14 #include "quiche/quic/core/quic_error_codes.h"
15 #include "quiche/quic/core/quic_types.h"
16 #include "quiche/quic/platform/api/quic_bug_tracker.h"
17 #include "quiche/quic/platform/api/quic_flag_utils.h"
18 #include "quiche/quic/platform/api/quic_flags.h"
19 #include "quiche/quic/platform/api/quic_logging.h"
20
21 namespace quic {
22
23 namespace {
24
25 // Limit on the payload length for frames that are buffered by HttpDecoder.
26 // If a frame header indicating a payload length exceeding this limit is
27 // received, HttpDecoder closes the connection. Does not apply to frames that
28 // are not buffered here but each payload fragment is immediately passed to
29 // Visitor, like HEADERS, DATA, and unknown frames.
30 constexpr QuicByteCount kPayloadLengthLimit = 1024 * 1024;
31
32 } // anonymous namespace
33
HttpDecoder(Visitor * visitor)34 HttpDecoder::HttpDecoder(Visitor* visitor)
35 : visitor_(visitor),
36 allow_web_transport_stream_(false),
37 state_(STATE_READING_FRAME_TYPE),
38 current_frame_type_(0),
39 current_length_field_length_(0),
40 remaining_length_field_length_(0),
41 current_frame_length_(0),
42 remaining_frame_length_(0),
43 current_type_field_length_(0),
44 remaining_type_field_length_(0),
45 error_(QUIC_NO_ERROR),
46 error_detail_(""),
47 enable_metadata_decoding_(
48 GetQuicReloadableFlag(quic_enable_http3_metadata_decoding)) {
49 QUICHE_DCHECK(visitor_);
50 }
51
~HttpDecoder()52 HttpDecoder::~HttpDecoder() {}
53
54 // static
DecodeSettings(const char * data,QuicByteCount len,SettingsFrame * frame)55 bool HttpDecoder::DecodeSettings(const char* data, QuicByteCount len,
56 SettingsFrame* frame) {
57 QuicDataReader reader(data, len);
58 uint64_t frame_type;
59 if (!reader.ReadVarInt62(&frame_type)) {
60 QUIC_DLOG(ERROR) << "Unable to read frame type.";
61 return false;
62 }
63
64 if (frame_type != static_cast<uint64_t>(HttpFrameType::SETTINGS)) {
65 QUIC_DLOG(ERROR) << "Invalid frame type " << frame_type;
66 return false;
67 }
68
69 absl::string_view frame_contents;
70 if (!reader.ReadStringPieceVarInt62(&frame_contents)) {
71 QUIC_DLOG(ERROR) << "Failed to read SETTINGS frame contents";
72 return false;
73 }
74
75 QuicDataReader frame_reader(frame_contents);
76
77 while (!frame_reader.IsDoneReading()) {
78 uint64_t id;
79 if (!frame_reader.ReadVarInt62(&id)) {
80 QUIC_DLOG(ERROR) << "Unable to read setting identifier.";
81 return false;
82 }
83 uint64_t content;
84 if (!frame_reader.ReadVarInt62(&content)) {
85 QUIC_DLOG(ERROR) << "Unable to read setting value.";
86 return false;
87 }
88 auto result = frame->values.insert({id, content});
89 if (!result.second) {
90 QUIC_DLOG(ERROR) << "Duplicate setting identifier.";
91 return false;
92 }
93 }
94 return true;
95 }
96
ProcessInput(const char * data,QuicByteCount len)97 QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
98 QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
99 QUICHE_DCHECK_NE(STATE_ERROR, state_);
100
101 QuicDataReader reader(data, len);
102 bool continue_processing = true;
103 // BufferOrParsePayload() and FinishParsing() may need to be called even if
104 // there is no more data so that they can finish processing the current frame.
105 while (continue_processing && (reader.BytesRemaining() != 0 ||
106 state_ == STATE_BUFFER_OR_PARSE_PAYLOAD ||
107 state_ == STATE_FINISH_PARSING)) {
108 // |continue_processing| must have been set to false upon error.
109 QUICHE_DCHECK_EQ(QUIC_NO_ERROR, error_);
110 QUICHE_DCHECK_NE(STATE_ERROR, state_);
111
112 switch (state_) {
113 case STATE_READING_FRAME_TYPE:
114 continue_processing = ReadFrameType(&reader);
115 break;
116 case STATE_READING_FRAME_LENGTH:
117 continue_processing = ReadFrameLength(&reader);
118 break;
119 case STATE_BUFFER_OR_PARSE_PAYLOAD:
120 continue_processing = BufferOrParsePayload(&reader);
121 break;
122 case STATE_READING_FRAME_PAYLOAD:
123 continue_processing = ReadFramePayload(&reader);
124 break;
125 case STATE_FINISH_PARSING:
126 continue_processing = FinishParsing();
127 break;
128 case STATE_PARSING_NO_LONGER_POSSIBLE:
129 continue_processing = false;
130 QUIC_BUG(HttpDecoder PARSING_NO_LONGER_POSSIBLE)
131 << "HttpDecoder called after an indefinite-length frame has been "
132 "received";
133 RaiseError(QUIC_INTERNAL_ERROR,
134 "HttpDecoder called after an indefinite-length frame has "
135 "been received");
136 break;
137 case STATE_ERROR:
138 break;
139 default:
140 QUIC_BUG(quic_bug_10411_1) << "Invalid state: " << state_;
141 }
142 }
143
144 return len - reader.BytesRemaining();
145 }
146
ReadFrameType(QuicDataReader * reader)147 bool HttpDecoder::ReadFrameType(QuicDataReader* reader) {
148 QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
149 if (current_type_field_length_ == 0) {
150 // A new frame is coming.
151 current_type_field_length_ = reader->PeekVarInt62Length();
152 QUICHE_DCHECK_NE(0u, current_type_field_length_);
153 if (current_type_field_length_ > reader->BytesRemaining()) {
154 // Buffer a new type field.
155 remaining_type_field_length_ = current_type_field_length_;
156 BufferFrameType(reader);
157 return true;
158 }
159 // The reader has all type data needed, so no need to buffer.
160 bool success = reader->ReadVarInt62(¤t_frame_type_);
161 QUICHE_DCHECK(success);
162 } else {
163 // Buffer the existing type field.
164 BufferFrameType(reader);
165 // The frame is still not buffered completely.
166 if (remaining_type_field_length_ != 0) {
167 return true;
168 }
169 QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_);
170 bool success = type_reader.ReadVarInt62(¤t_frame_type_);
171 QUICHE_DCHECK(success);
172 }
173
174 // https://tools.ietf.org/html/draft-ietf-quic-http-31#section-7.2.8
175 // specifies that the following frames are treated as errors.
176 if (current_frame_type_ ==
177 static_cast<uint64_t>(http2::Http2FrameType::PRIORITY) ||
178 current_frame_type_ ==
179 static_cast<uint64_t>(http2::Http2FrameType::PING) ||
180 current_frame_type_ ==
181 static_cast<uint64_t>(http2::Http2FrameType::WINDOW_UPDATE) ||
182 current_frame_type_ ==
183 static_cast<uint64_t>(http2::Http2FrameType::CONTINUATION)) {
184 RaiseError(QUIC_HTTP_RECEIVE_SPDY_FRAME,
185 absl::StrCat("HTTP/2 frame received in a HTTP/3 connection: ",
186 current_frame_type_));
187 return false;
188 }
189
190 if (current_frame_type_ ==
191 static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH)) {
192 RaiseError(QUIC_HTTP_FRAME_ERROR, "CANCEL_PUSH frame received.");
193 return false;
194 }
195 if (current_frame_type_ ==
196 static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE)) {
197 RaiseError(QUIC_HTTP_FRAME_ERROR, "PUSH_PROMISE frame received.");
198 return false;
199 }
200
201 state_ = STATE_READING_FRAME_LENGTH;
202 return true;
203 }
204
ReadFrameLength(QuicDataReader * reader)205 bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
206 QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
207 if (current_length_field_length_ == 0) {
208 // A new frame is coming.
209 current_length_field_length_ = reader->PeekVarInt62Length();
210 QUICHE_DCHECK_NE(0u, current_length_field_length_);
211 if (current_length_field_length_ > reader->BytesRemaining()) {
212 // Buffer a new length field.
213 remaining_length_field_length_ = current_length_field_length_;
214 BufferFrameLength(reader);
215 return true;
216 }
217 // The reader has all length data needed, so no need to buffer.
218 bool success = reader->ReadVarInt62(¤t_frame_length_);
219 QUICHE_DCHECK(success);
220 } else {
221 // Buffer the existing length field.
222 BufferFrameLength(reader);
223 // The frame is still not buffered completely.
224 if (remaining_length_field_length_ != 0) {
225 return true;
226 }
227 QuicDataReader length_reader(length_buffer_.data(),
228 current_length_field_length_);
229 bool success = length_reader.ReadVarInt62(¤t_frame_length_);
230 QUICHE_DCHECK(success);
231 }
232
233 // WEBTRANSPORT_STREAM frames are indefinitely long, and thus require
234 // special handling; the number after the frame type is actually the
235 // WebTransport session ID, and not the length.
236 if (allow_web_transport_stream_ &&
237 current_frame_type_ ==
238 static_cast<uint64_t>(HttpFrameType::WEBTRANSPORT_STREAM)) {
239 visitor_->OnWebTransportStreamFrameType(
240 current_length_field_length_ + current_type_field_length_,
241 current_frame_length_);
242 state_ = STATE_PARSING_NO_LONGER_POSSIBLE;
243 return false;
244 }
245
246 if (IsFrameBuffered() &&
247 current_frame_length_ > MaxFrameLength(current_frame_type_)) {
248 RaiseError(QUIC_HTTP_FRAME_TOO_LARGE, "Frame is too large.");
249 return false;
250 }
251
252 // Calling the following visitor methods does not require parsing of any
253 // frame payload.
254 bool continue_processing = true;
255 const QuicByteCount header_length =
256 current_length_field_length_ + current_type_field_length_;
257
258 switch (current_frame_type_) {
259 case static_cast<uint64_t>(HttpFrameType::DATA):
260 continue_processing =
261 visitor_->OnDataFrameStart(header_length, current_frame_length_);
262 break;
263 case static_cast<uint64_t>(HttpFrameType::HEADERS):
264 continue_processing =
265 visitor_->OnHeadersFrameStart(header_length, current_frame_length_);
266 break;
267 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
268 QUICHE_NOTREACHED();
269 break;
270 case static_cast<uint64_t>(HttpFrameType::SETTINGS):
271 continue_processing = visitor_->OnSettingsFrameStart(header_length);
272 break;
273 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
274 QUICHE_NOTREACHED();
275 break;
276 case static_cast<uint64_t>(HttpFrameType::GOAWAY):
277 break;
278 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
279 break;
280 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
281 continue_processing = visitor_->OnPriorityUpdateFrameStart(header_length);
282 break;
283 case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
284 continue_processing = visitor_->OnAcceptChFrameStart(header_length);
285 break;
286 default:
287 if (enable_metadata_decoding_ &&
288 current_frame_type_ ==
289 static_cast<uint64_t>(HttpFrameType::METADATA)) {
290 QUIC_RELOADABLE_FLAG_COUNT_N(quic_enable_http3_metadata_decoding, 1, 3);
291 continue_processing = visitor_->OnMetadataFrameStart(
292 header_length, current_frame_length_);
293 break;
294 }
295 continue_processing = visitor_->OnUnknownFrameStart(
296 current_frame_type_, header_length, current_frame_length_);
297 break;
298 }
299
300 remaining_frame_length_ = current_frame_length_;
301
302 if (IsFrameBuffered()) {
303 state_ = STATE_BUFFER_OR_PARSE_PAYLOAD;
304 return continue_processing;
305 }
306
307 state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
308 : STATE_READING_FRAME_PAYLOAD;
309 return continue_processing;
310 }
311
IsFrameBuffered()312 bool HttpDecoder::IsFrameBuffered() {
313 switch (current_frame_type_) {
314 case static_cast<uint64_t>(HttpFrameType::SETTINGS):
315 return true;
316 case static_cast<uint64_t>(HttpFrameType::GOAWAY):
317 return true;
318 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
319 return true;
320 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
321 return true;
322 case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
323 return true;
324 }
325
326 // Other defined frame types as well as unknown frames are not buffered.
327 return false;
328 }
329
ReadFramePayload(QuicDataReader * reader)330 bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
331 QUICHE_DCHECK(!IsFrameBuffered());
332 QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
333 QUICHE_DCHECK_NE(0u, remaining_frame_length_);
334
335 bool continue_processing = true;
336
337 switch (current_frame_type_) {
338 case static_cast<uint64_t>(HttpFrameType::DATA): {
339 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
340 remaining_frame_length_, reader->BytesRemaining());
341 absl::string_view payload;
342 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
343 QUICHE_DCHECK(success);
344 QUICHE_DCHECK(!payload.empty());
345 continue_processing = visitor_->OnDataFramePayload(payload);
346 remaining_frame_length_ -= payload.length();
347 break;
348 }
349 case static_cast<uint64_t>(HttpFrameType::HEADERS): {
350 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
351 remaining_frame_length_, reader->BytesRemaining());
352 absl::string_view payload;
353 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
354 QUICHE_DCHECK(success);
355 QUICHE_DCHECK(!payload.empty());
356 continue_processing = visitor_->OnHeadersFramePayload(payload);
357 remaining_frame_length_ -= payload.length();
358 break;
359 }
360 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
361 QUICHE_NOTREACHED();
362 break;
363 }
364 case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
365 QUICHE_NOTREACHED();
366 break;
367 }
368 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
369 QUICHE_NOTREACHED();
370 break;
371 }
372 case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
373 QUICHE_NOTREACHED();
374 break;
375 }
376 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
377 QUICHE_NOTREACHED();
378 break;
379 }
380 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
381 QUICHE_NOTREACHED();
382 break;
383 }
384 case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
385 QUICHE_NOTREACHED();
386 break;
387 }
388 default: {
389 if (enable_metadata_decoding_ &&
390 current_frame_type_ ==
391 static_cast<uint64_t>(HttpFrameType::METADATA)) {
392 QUIC_RELOADABLE_FLAG_COUNT_N(quic_enable_http3_metadata_decoding, 2, 3);
393 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
394 remaining_frame_length_, reader->BytesRemaining());
395 absl::string_view payload;
396 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
397 QUICHE_DCHECK(success);
398 QUICHE_DCHECK(!payload.empty());
399 continue_processing = visitor_->OnMetadataFramePayload(payload);
400 remaining_frame_length_ -= payload.length();
401 break;
402 }
403 continue_processing = HandleUnknownFramePayload(reader);
404 break;
405 }
406 }
407
408 if (remaining_frame_length_ == 0) {
409 state_ = STATE_FINISH_PARSING;
410 }
411
412 return continue_processing;
413 }
414
FinishParsing()415 bool HttpDecoder::FinishParsing() {
416 QUICHE_DCHECK(!IsFrameBuffered());
417 QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
418
419 bool continue_processing = true;
420
421 switch (current_frame_type_) {
422 case static_cast<uint64_t>(HttpFrameType::DATA): {
423 continue_processing = visitor_->OnDataFrameEnd();
424 break;
425 }
426 case static_cast<uint64_t>(HttpFrameType::HEADERS): {
427 continue_processing = visitor_->OnHeadersFrameEnd();
428 break;
429 }
430 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
431 QUICHE_NOTREACHED();
432 break;
433 }
434 case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
435 QUICHE_NOTREACHED();
436 break;
437 }
438 case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
439 QUICHE_NOTREACHED();
440 break;
441 }
442 case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
443 QUICHE_NOTREACHED();
444 break;
445 }
446 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
447 QUICHE_NOTREACHED();
448 break;
449 }
450 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
451 QUICHE_NOTREACHED();
452 break;
453 }
454 case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
455 QUICHE_NOTREACHED();
456 break;
457 }
458 default:
459 if (enable_metadata_decoding_ &&
460 current_frame_type_ ==
461 static_cast<uint64_t>(HttpFrameType::METADATA)) {
462 QUIC_RELOADABLE_FLAG_COUNT_N(quic_enable_http3_metadata_decoding, 3, 3);
463 continue_processing = visitor_->OnMetadataFrameEnd();
464 break;
465 }
466 continue_processing = visitor_->OnUnknownFrameEnd();
467 }
468
469 ResetForNextFrame();
470 return continue_processing;
471 }
472
ResetForNextFrame()473 void HttpDecoder::ResetForNextFrame() {
474 current_length_field_length_ = 0;
475 current_type_field_length_ = 0;
476 state_ = STATE_READING_FRAME_TYPE;
477 }
478
HandleUnknownFramePayload(QuicDataReader * reader)479 bool HttpDecoder::HandleUnknownFramePayload(QuicDataReader* reader) {
480 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
481 remaining_frame_length_, reader->BytesRemaining());
482 absl::string_view payload;
483 bool success = reader->ReadStringPiece(&payload, bytes_to_read);
484 QUICHE_DCHECK(success);
485 QUICHE_DCHECK(!payload.empty());
486 remaining_frame_length_ -= payload.length();
487 return visitor_->OnUnknownFramePayload(payload);
488 }
489
BufferOrParsePayload(QuicDataReader * reader)490 bool HttpDecoder::BufferOrParsePayload(QuicDataReader* reader) {
491 QUICHE_DCHECK(IsFrameBuffered());
492 QUICHE_DCHECK_EQ(current_frame_length_,
493 buffer_.size() + remaining_frame_length_);
494
495 if (buffer_.empty() && reader->BytesRemaining() >= current_frame_length_) {
496 // |*reader| contains entire payload, which might be empty.
497 remaining_frame_length_ = 0;
498 QuicDataReader current_payload_reader(reader->PeekRemainingPayload().data(),
499 current_frame_length_);
500 bool continue_processing = ParseEntirePayload(¤t_payload_reader);
501
502 reader->Seek(current_frame_length_);
503 ResetForNextFrame();
504 return continue_processing;
505 }
506
507 // Buffer as much of the payload as |*reader| contains.
508 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
509 remaining_frame_length_, reader->BytesRemaining());
510 absl::StrAppend(&buffer_, reader->PeekRemainingPayload().substr(
511 /* pos = */ 0, bytes_to_read));
512 reader->Seek(bytes_to_read);
513 remaining_frame_length_ -= bytes_to_read;
514
515 QUICHE_DCHECK_EQ(current_frame_length_,
516 buffer_.size() + remaining_frame_length_);
517
518 if (remaining_frame_length_ > 0) {
519 QUICHE_DCHECK(reader->IsDoneReading());
520 return false;
521 }
522
523 QuicDataReader buffer_reader(buffer_);
524 bool continue_processing = ParseEntirePayload(&buffer_reader);
525 buffer_.clear();
526
527 ResetForNextFrame();
528 return continue_processing;
529 }
530
ParseEntirePayload(QuicDataReader * reader)531 bool HttpDecoder::ParseEntirePayload(QuicDataReader* reader) {
532 QUICHE_DCHECK(IsFrameBuffered());
533 QUICHE_DCHECK_EQ(current_frame_length_, reader->BytesRemaining());
534 QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
535
536 switch (current_frame_type_) {
537 case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
538 QUICHE_NOTREACHED();
539 return false;
540 }
541 case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
542 SettingsFrame frame;
543 if (!ParseSettingsFrame(reader, &frame)) {
544 return false;
545 }
546 return visitor_->OnSettingsFrame(frame);
547 }
548 case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
549 GoAwayFrame frame;
550 if (!reader->ReadVarInt62(&frame.id)) {
551 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read GOAWAY ID.");
552 return false;
553 }
554 if (!reader->IsDoneReading()) {
555 RaiseError(QUIC_HTTP_FRAME_ERROR, "Superfluous data in GOAWAY frame.");
556 return false;
557 }
558 return visitor_->OnGoAwayFrame(frame);
559 }
560 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
561 uint64_t unused;
562 if (!reader->ReadVarInt62(&unused)) {
563 RaiseError(QUIC_HTTP_FRAME_ERROR,
564 "Unable to read MAX_PUSH_ID push_id.");
565 return false;
566 }
567 if (!reader->IsDoneReading()) {
568 RaiseError(QUIC_HTTP_FRAME_ERROR,
569 "Superfluous data in MAX_PUSH_ID frame.");
570 return false;
571 }
572 return visitor_->OnMaxPushIdFrame();
573 }
574 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
575 PriorityUpdateFrame frame;
576 if (!ParsePriorityUpdateFrame(reader, &frame)) {
577 return false;
578 }
579 return visitor_->OnPriorityUpdateFrame(frame);
580 }
581 case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
582 AcceptChFrame frame;
583 if (!ParseAcceptChFrame(reader, &frame)) {
584 return false;
585 }
586 return visitor_->OnAcceptChFrame(frame);
587 }
588 default:
589 // Only above frame types are parsed by ParseEntirePayload().
590 QUICHE_NOTREACHED();
591 return false;
592 }
593 }
594
BufferFrameLength(QuicDataReader * reader)595 void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
596 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
597 remaining_length_field_length_, reader->BytesRemaining());
598 bool success =
599 reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
600 remaining_length_field_length_,
601 bytes_to_read);
602 QUICHE_DCHECK(success);
603 remaining_length_field_length_ -= bytes_to_read;
604 }
605
BufferFrameType(QuicDataReader * reader)606 void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
607 QuicByteCount bytes_to_read = std::min<QuicByteCount>(
608 remaining_type_field_length_, reader->BytesRemaining());
609 bool success =
610 reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
611 remaining_type_field_length_,
612 bytes_to_read);
613 QUICHE_DCHECK(success);
614 remaining_type_field_length_ -= bytes_to_read;
615 }
616
RaiseError(QuicErrorCode error,std::string error_detail)617 void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
618 state_ = STATE_ERROR;
619 error_ = error;
620 error_detail_ = std::move(error_detail);
621 visitor_->OnError(this);
622 }
623
ParseSettingsFrame(QuicDataReader * reader,SettingsFrame * frame)624 bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
625 SettingsFrame* frame) {
626 while (!reader->IsDoneReading()) {
627 uint64_t id;
628 if (!reader->ReadVarInt62(&id)) {
629 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting identifier.");
630 return false;
631 }
632 uint64_t content;
633 if (!reader->ReadVarInt62(&content)) {
634 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting value.");
635 return false;
636 }
637 auto result = frame->values.insert({id, content});
638 if (!result.second) {
639 RaiseError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER,
640 "Duplicate setting identifier.");
641 return false;
642 }
643 }
644 return true;
645 }
646
ParsePriorityUpdateFrame(QuicDataReader * reader,PriorityUpdateFrame * frame)647 bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader,
648 PriorityUpdateFrame* frame) {
649 if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
650 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id.");
651 return false;
652 }
653
654 absl::string_view priority_field_value = reader->ReadRemainingPayload();
655 frame->priority_field_value =
656 std::string(priority_field_value.data(), priority_field_value.size());
657
658 return true;
659 }
660
ParseAcceptChFrame(QuicDataReader * reader,AcceptChFrame * frame)661 bool HttpDecoder::ParseAcceptChFrame(QuicDataReader* reader,
662 AcceptChFrame* frame) {
663 absl::string_view origin;
664 absl::string_view value;
665 while (!reader->IsDoneReading()) {
666 if (!reader->ReadStringPieceVarInt62(&origin)) {
667 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH origin.");
668 return false;
669 }
670 if (!reader->ReadStringPieceVarInt62(&value)) {
671 RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH value.");
672 return false;
673 }
674 // Copy data.
675 frame->entries.push_back({std::string(origin.data(), origin.size()),
676 std::string(value.data(), value.size())});
677 }
678 return true;
679 }
680
MaxFrameLength(uint64_t frame_type)681 QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
682 QUICHE_DCHECK(IsFrameBuffered());
683
684 switch (frame_type) {
685 case static_cast<uint64_t>(HttpFrameType::SETTINGS):
686 return kPayloadLengthLimit;
687 case static_cast<uint64_t>(HttpFrameType::GOAWAY):
688 return quiche::VARIABLE_LENGTH_INTEGER_LENGTH_8;
689 case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
690 return quiche::VARIABLE_LENGTH_INTEGER_LENGTH_8;
691 case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
692 return kPayloadLengthLimit;
693 case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
694 return kPayloadLengthLimit;
695 default:
696 QUICHE_NOTREACHED();
697 return 0;
698 }
699 }
700
DebugString() const701 std::string HttpDecoder::DebugString() const {
702 return absl::StrCat(
703 "HttpDecoder:", "\n state: ", state_, "\n error: ", error_,
704 "\n current_frame_type: ", current_frame_type_,
705 "\n current_length_field_length: ", current_length_field_length_,
706 "\n remaining_length_field_length: ", remaining_length_field_length_,
707 "\n current_frame_length: ", current_frame_length_,
708 "\n remaining_frame_length: ", remaining_frame_length_,
709 "\n current_type_field_length: ", current_type_field_length_,
710 "\n remaining_type_field_length: ", remaining_type_field_length_);
711 }
712
713 } // namespace quic
714