• 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) : 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(&current_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(&current_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(&current_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(&current_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(&current_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