Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/http/http_decoder.h b/quic/core/http/http_decoder.h
new file mode 100644
index 0000000..910d189
--- /dev/null
+++ b/quic/core/http/http_decoder.h
@@ -0,0 +1,185 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
+#define QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_
+
+#include <cstddef>
+
+#include "net/third_party/quiche/src/quic/core/http/http_frames.h"
+#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
+#include "net/third_party/quiche/src/quic/core/quic_types.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+
+namespace quic {
+
+class QuicDataReader;
+
+// Struct that stores meta data of a data frame.
+// |header_length| stores number of bytes header occupies.
+// |payload_length| stores number of bytes payload occupies.
+struct QUIC_EXPORT_PRIVATE Http3FrameLengths {
+  Http3FrameLengths(QuicByteCount header, QuicByteCount payload)
+      : header_length(header), payload_length(payload) {}
+
+  bool operator==(const Http3FrameLengths& other) const {
+    return (header_length == other.header_length) &&
+           (payload_length == other.payload_length);
+  }
+
+  QuicByteCount header_length;
+  QuicByteCount payload_length;
+};
+
+// A class for decoding the HTTP frames that are exchanged in an HTTP over QUIC
+// session.
+class QUIC_EXPORT_PRIVATE HttpDecoder {
+ public:
+  class QUIC_EXPORT_PRIVATE Visitor {
+   public:
+    virtual ~Visitor() {}
+
+    // Called if an error is detected.
+    virtual void OnError(HttpDecoder* decoder) = 0;
+
+    // Called when a PRIORITY frame has been successfully parsed.
+    virtual void OnPriorityFrame(const PriorityFrame& frame) = 0;
+
+    // Called when a CANCEL_PUSH frame has been successfully parsed.
+    virtual void OnCancelPushFrame(const CancelPushFrame& frame) = 0;
+
+    // Called when a MAX_PUSH_ID frame has been successfully parsed.
+    virtual void OnMaxPushIdFrame(const MaxPushIdFrame& frame) = 0;
+
+    // Called when a GOAWAY frame has been successfully parsed.
+    virtual void OnGoAwayFrame(const GoAwayFrame& frame) = 0;
+
+    // Called when a SETTINGS frame has been successfully parsed.
+    virtual void OnSettingsFrame(const SettingsFrame& frame) = 0;
+
+    // Called when a DUPLICATE_PUSH frame has been successfully parsed.
+    virtual void OnDuplicatePushFrame(const DuplicatePushFrame& frame) = 0;
+
+    // Called when a DATA frame has been received, |frame_lengths| will be
+    // passed to inform header length and payload length of the frame.
+    virtual void OnDataFrameStart(Http3FrameLengths frame_length) = 0;
+    // Called when the payload of a DATA frame has read. May be called
+    // multiple times for a single frame.
+    virtual void OnDataFramePayload(QuicStringPiece payload) = 0;
+    // Called when a DATA frame has been completely processed.
+    virtual void OnDataFrameEnd() = 0;
+
+    // Called when a HEADERS frame has been recevied.
+    virtual void OnHeadersFrameStart() = 0;
+    // Called when the payload of a HEADERS frame has read. May be called
+    // multiple times for a single frame.
+    virtual void OnHeadersFramePayload(QuicStringPiece payload) = 0;
+    // Called when a HEADERS frame has been completely processed.
+    // |frame_len| is the length of the HEADERS frame payload.
+    virtual void OnHeadersFrameEnd(QuicByteCount frame_len) = 0;
+
+    // Called when a PUSH_PROMISE frame has been recevied for |push_id|.
+    virtual void OnPushPromiseFrameStart(PushId push_id) = 0;
+    // Called when the payload of a PUSH_PROMISE frame has read. May be called
+    // multiple times for a single frame.
+    virtual void OnPushPromiseFramePayload(QuicStringPiece payload) = 0;
+    // Called when a PUSH_PROMISE frame has been completely processed.
+    virtual void OnPushPromiseFrameEnd() = 0;
+
+    // TODO(rch): Consider adding methods like:
+    // OnUnknownFrame{Start,Payload,End}()
+    // to allow callers to handle unknown frames.
+  };
+
+  HttpDecoder();
+
+  ~HttpDecoder();
+
+  // Set callbacks to be called from the decoder.  A visitor must be set, or
+  // else the decoder will crash.  It is acceptable for the visitor to do
+  // nothing.  If this is called multiple times, only the last visitor
+  // will be used.  |visitor| will be owned by the caller.
+  void set_visitor(Visitor* visitor) { visitor_ = visitor; }
+
+  // Processes the input and invokes the visitor for any frames.
+  // Returns the number of bytes consumed, or 0 if there was an error, in which
+  // case error() should be consulted.
+  QuicByteCount ProcessInput(const char* data, QuicByteCount len);
+
+  bool has_payload() { return has_payload_; }
+
+  QuicErrorCode error() const { return error_; }
+  const QuicString& error_detail() const { return error_detail_; }
+
+ private:
+  // Represents the current state of the parsing state machine.
+  enum HttpDecoderState {
+    STATE_READING_FRAME_LENGTH,
+    STATE_READING_FRAME_TYPE,
+    STATE_READING_FRAME_PAYLOAD,
+    STATE_ERROR
+  };
+
+  // Reads the length of a frame from |reader|. Sets error_ and error_detail_
+  // if there are any errors.
+  void ReadFrameLength(QuicDataReader* reader);
+
+  // Reads the type of a frame from |reader|. Sets error_ and error_detail_
+  // if there are any errors.
+  void ReadFrameType(QuicDataReader* reader);
+
+  // Reads the payload of the current frame from |reader| and processes it,
+  // possibly buffering the data or invoking the visitor.
+  void ReadFramePayload(QuicDataReader* reader);
+
+  // Discards any remaining frame payload from |reader|.
+  void DiscardFramePayload(QuicDataReader* reader);
+
+  // Buffers any remaining frame payload from |reader| into |buffer_|.
+  void BufferFramePayload(QuicDataReader* reader);
+
+  // Buffers any remaining frame length field from |reader| into
+  // |length_buffer_|
+  void BufferFrameLength(QuicDataReader* reader);
+
+  // Sets |error_| and |error_detail_| accordingly.
+  void RaiseError(QuicErrorCode error, QuicString error_detail);
+
+  // Parses the payload of a PRIORITY frame from |reader| into |frame|.
+  bool ParsePriorityFrame(QuicDataReader* reader, PriorityFrame* frame);
+
+  // Parses the payload of a SETTINGS frame from |reader| into |frame|.
+  bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
+
+  // Visitor to invoke when messages are parsed.
+  Visitor* visitor_;  // Unowned.
+  // Current state of the parsing.
+  HttpDecoderState state_;
+  // Type of the frame currently being parsed.
+  uint8_t current_frame_type_;
+  // Size of the frame's length field.
+  QuicByteCount current_length_field_size_;
+  // Remaining length that's needed for the frame's length field.
+  QuicByteCount remaining_length_field_length_;
+  // Length of the payload of the frame currently being parsed.
+  QuicByteCount current_frame_length_;
+  // Remaining payload bytes to be parsed.
+  QuicByteCount remaining_frame_length_;
+  // Last error.
+  QuicErrorCode error_;
+  // The issue which caused |error_|
+  QuicString error_detail_;
+  // True if the call to ProcessInput() generates any payload. Flushed every
+  // time ProcessInput() is called.
+  bool has_payload_;
+  // Remaining unparsed data.
+  QuicString buffer_;
+  // Remaining unparsed length field data.
+  QuicString length_buffer_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_HTTP_HTTP_DECODER_H_