xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/http/http_decoder.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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(&current_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(&current_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(&current_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(&current_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(&current_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