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