• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&current_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(&current_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(&current_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(&current_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(&current_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