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