// Copyright 2016 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_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_
#define QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_

#include <stddef.h>

#include <cstdint>
#include <memory>
#include <string>

#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "http2/decoder/http2_frame_decoder.h"
#include "common/platform/api/quiche_export.h"
#include "spdy/core/hpack/hpack_decoder_adapter.h"
#include "spdy/core/hpack/hpack_header_table.h"
#include "spdy/core/spdy_alt_svc_wire_format.h"
#include "spdy/core/spdy_headers_handler_interface.h"
#include "spdy/core/spdy_protocol.h"

namespace spdy {

class SpdyFramerVisitorInterface;
class ExtensionVisitorInterface;

}  // namespace spdy

// TODO(dahollings): Perform various renames/moves suggested in cl/164660364.

namespace http2 {

// Adapts SpdyFramer interface to use Http2FrameDecoder.
class QUICHE_EXPORT_PRIVATE Http2DecoderAdapter
    : public http2::Http2FrameDecoderListener {
 public:
  // HTTP2 states.
  enum SpdyState {
    SPDY_ERROR,
    SPDY_READY_FOR_FRAME,  // Framer is ready for reading the next frame.
    SPDY_FRAME_COMPLETE,  // Framer has finished reading a frame, need to reset.
    SPDY_READING_COMMON_HEADER,
    SPDY_CONTROL_FRAME_PAYLOAD,
    SPDY_READ_DATA_FRAME_PADDING_LENGTH,
    SPDY_CONSUME_PADDING,
    SPDY_IGNORE_REMAINING_PAYLOAD,
    SPDY_FORWARD_STREAM_FRAME,
    SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK,
    SPDY_CONTROL_FRAME_HEADER_BLOCK,
    SPDY_GOAWAY_FRAME_PAYLOAD,
    SPDY_SETTINGS_FRAME_HEADER,
    SPDY_SETTINGS_FRAME_PAYLOAD,
    SPDY_ALTSVC_FRAME_PAYLOAD,
    SPDY_EXTENSION_FRAME_PAYLOAD,
  };

  // Framer error codes.
  enum SpdyFramerError {
    SPDY_NO_ERROR,
    SPDY_INVALID_STREAM_ID,            // Stream ID is invalid
    SPDY_INVALID_CONTROL_FRAME,        // Control frame is mal-formatted.
    SPDY_CONTROL_PAYLOAD_TOO_LARGE,    // Control frame payload was too large.
    SPDY_ZLIB_INIT_FAILURE,            // The Zlib library could not initialize.
    SPDY_UNSUPPORTED_VERSION,          // Control frame has unsupported version.
    SPDY_DECOMPRESS_FAILURE,           // There was an error decompressing.
    SPDY_COMPRESS_FAILURE,             // There was an error compressing.
    SPDY_GOAWAY_FRAME_CORRUPT,         // GOAWAY frame could not be parsed.
    SPDY_RST_STREAM_FRAME_CORRUPT,     // RST_STREAM frame could not be parsed.
    SPDY_INVALID_PADDING,              // HEADERS or DATA frame padding invalid
    SPDY_INVALID_DATA_FRAME_FLAGS,     // Data frame has invalid flags.
    SPDY_INVALID_CONTROL_FRAME_FLAGS,  // Control frame has invalid flags.
    SPDY_UNEXPECTED_FRAME,             // Frame received out of order.
    SPDY_INTERNAL_FRAMER_ERROR,        // SpdyFramer was used incorrectly.
    SPDY_INVALID_CONTROL_FRAME_SIZE,   // Control frame not sized to spec
    SPDY_OVERSIZED_PAYLOAD,            // Payload size was too large

    // HttpDecoder or HttpDecoderAdapter error.
    // See HpackDecodingError for description of each error code.
    SPDY_HPACK_INDEX_VARINT_ERROR,
    SPDY_HPACK_NAME_LENGTH_VARINT_ERROR,
    SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR,
    SPDY_HPACK_NAME_TOO_LONG,
    SPDY_HPACK_VALUE_TOO_LONG,
    SPDY_HPACK_NAME_HUFFMAN_ERROR,
    SPDY_HPACK_VALUE_HUFFMAN_ERROR,
    SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE,
    SPDY_HPACK_INVALID_INDEX,
    SPDY_HPACK_INVALID_NAME_INDEX,
    SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED,
    SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK,
    SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING,
    SPDY_HPACK_TRUNCATED_BLOCK,
    SPDY_HPACK_FRAGMENT_TOO_LONG,
    SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT,

    LAST_ERROR,  // Must be the last entry in the enum.
  };

  // For debugging.
  static const char* StateToString(int state);
  static const char* SpdyFramerErrorToString(SpdyFramerError spdy_framer_error);

  Http2DecoderAdapter();
  ~Http2DecoderAdapter() override;

  // Set callbacks to be called from the framer.  A visitor must be set, or
  // else the framer will likely crash.  It is acceptable for the visitor
  // to do nothing.  If this is called multiple times, only the last visitor
  // will be used.
  void set_visitor(spdy::SpdyFramerVisitorInterface* visitor);
  spdy::SpdyFramerVisitorInterface* visitor() const { return visitor_; }

  // Set extension callbacks to be called from the framer or decoder. Optional.
  // If called multiple times, only the last visitor will be used.
  void set_extension_visitor(spdy::ExtensionVisitorInterface* visitor);
  spdy::ExtensionVisitorInterface* extension_visitor() const {
    return extension_;
  }

  // Set debug callbacks to be called from the framer. The debug visitor is
  // completely optional and need not be set in order for normal operation.
  // If this is called multiple times, only the last visitor will be used.
  void set_debug_visitor(spdy::SpdyFramerDebugVisitorInterface* debug_visitor);
  spdy::SpdyFramerDebugVisitorInterface* debug_visitor() const {
    return debug_visitor_;
  }

  // Decode the |len| bytes of encoded HTTP/2 starting at |*data|. Returns
  // the number of bytes consumed. It is safe to pass more bytes in than
  // may be consumed. Should process (or otherwise buffer) as much as
  // available.
  //
  // If the input contains the entirety of a DATA frame payload, GOAWAY frame
  // Additional Debug Data field, or unknown frame payload, then the
  // corresponding SpdyFramerVisitorInterface::OnStreamFrameData(),
  // OnGoAwayFrameData(), or ExtensionVisitorInterface::OnFramePayload() method
  // is guaranteed to be called exactly once, with the entire payload or field.
  size_t ProcessInput(const char* data, size_t len);

  // Reset the decoder (used just for tests at this time).
  void Reset();

  // Current state of the decoder.
  SpdyState state() const;

  // Current error code (NO_ERROR if state != ERROR).
  SpdyFramerError spdy_framer_error() const;

  // Has any frame header looked like the start of an HTTP/1.1 (or earlier)
  // response? Used to detect if a backend/server that we sent a request to
  // has responded with an HTTP/1.1 (or earlier) response.
  bool probable_http_response() const;

  spdy::HpackDecoderAdapter* GetHpackDecoder();

  bool HasError() const;

 private:
  bool OnFrameHeader(const Http2FrameHeader& header) override;
  void OnDataStart(const Http2FrameHeader& header) override;
  void OnDataPayload(const char* data, size_t len) override;
  void OnDataEnd() override;
  void OnHeadersStart(const Http2FrameHeader& header) override;
  void OnHeadersPriority(const Http2PriorityFields& priority) override;
  void OnHpackFragment(const char* data, size_t len) override;
  void OnHeadersEnd() override;
  void OnPriorityFrame(const Http2FrameHeader& header,
                       const Http2PriorityFields& priority) override;
  void OnContinuationStart(const Http2FrameHeader& header) override;
  void OnContinuationEnd() override;
  void OnPadLength(size_t trailing_length) override;
  void OnPadding(const char* padding, size_t skipped_length) override;
  void OnRstStream(const Http2FrameHeader& header,
                   Http2ErrorCode http2_error_code) override;
  void OnSettingsStart(const Http2FrameHeader& header) override;
  void OnSetting(const Http2SettingFields& setting_fields) override;
  void OnSettingsEnd() override;
  void OnSettingsAck(const Http2FrameHeader& header) override;
  void OnPushPromiseStart(const Http2FrameHeader& header,
                          const Http2PushPromiseFields& promise,
                          size_t total_padding_length) override;
  void OnPushPromiseEnd() override;
  void OnPing(const Http2FrameHeader& header,
              const Http2PingFields& ping) override;
  void OnPingAck(const Http2FrameHeader& header,
                 const Http2PingFields& ping) override;
  void OnGoAwayStart(const Http2FrameHeader& header,
                     const Http2GoAwayFields& goaway) override;
  void OnGoAwayOpaqueData(const char* data, size_t len) override;
  void OnGoAwayEnd() override;
  void OnWindowUpdate(const Http2FrameHeader& header,
                      uint32_t increment) override;
  void OnAltSvcStart(const Http2FrameHeader& header,
                     size_t origin_length,
                     size_t value_length) override;
  void OnAltSvcOriginData(const char* data, size_t len) override;
  void OnAltSvcValueData(const char* data, size_t len) override;
  void OnAltSvcEnd() override;
  void OnPriorityUpdateStart(
      const Http2FrameHeader& header,
      const Http2PriorityUpdateFields& priority_update) override;
  void OnPriorityUpdatePayload(const char* data, size_t len) override;
  void OnPriorityUpdateEnd() override;
  void OnUnknownStart(const Http2FrameHeader& header) override;
  void OnUnknownPayload(const char* data, size_t len) override;
  void OnUnknownEnd() override;
  void OnPaddingTooLong(const Http2FrameHeader& header,
                        size_t missing_length) override;
  void OnFrameSizeError(const Http2FrameHeader& header) override;

  size_t ProcessInputFrame(const char* data, size_t len);

  void DetermineSpdyState(DecodeStatus status);
  void ResetBetweenFrames();

  // ResetInternal is called from the constructor, and during tests, but not
  // otherwise (i.e. not between every frame).
  void ResetInternal();

  void set_spdy_state(SpdyState v);

  void SetSpdyErrorAndNotify(SpdyFramerError error, std::string detailed_error);

  const Http2FrameHeader& frame_header() const;

  uint32_t stream_id() const;
  Http2FrameType frame_type() const;

  size_t remaining_total_payload() const;

  bool IsReadingPaddingLength();
  bool IsSkippingPadding();
  bool IsDiscardingPayload();
  // Called from OnXyz or OnXyzStart methods to decide whether it is OK to
  // handle the callback.
  bool IsOkToStartFrame(const Http2FrameHeader& header);
  bool HasRequiredStreamId(uint32_t stream_id);

  bool HasRequiredStreamId(const Http2FrameHeader& header);

  bool HasRequiredStreamIdZero(uint32_t stream_id);

  bool HasRequiredStreamIdZero(const Http2FrameHeader& header);

  void ReportReceiveCompressedFrame(const Http2FrameHeader& header);

  void CommonStartHpackBlock();

  // SpdyFramer calls HandleControlFrameHeadersData even if there are zero
  // fragment bytes in the first frame, so do the same.
  void MaybeAnnounceEmptyFirstHpackFragment();
  void CommonHpackFragmentEnd();

  // The most recently decoded frame header; invalid after we reached the end
  // of that frame.
  Http2FrameHeader frame_header_;

  // If decoding an HPACK block that is split across multiple frames, this holds
  // the frame header of the HEADERS or PUSH_PROMISE that started the block.
  Http2FrameHeader hpack_first_frame_header_;

  // Amount of trailing padding. Currently used just as an indicator of whether
  // OnPadLength has been called.
  absl::optional<size_t> opt_pad_length_;

  // Temporary buffers for the AltSvc fields.
  std::string alt_svc_origin_;
  std::string alt_svc_value_;

  // Temporary buffers for PRIORITY_UPDATE fields.
  uint32_t prioritized_stream_id_ = 0;
  std::string priority_field_value_;

  // Listener used if we transition to an error state; the listener ignores all
  // the callbacks.
  Http2FrameDecoderNoOpListener no_op_listener_;

  spdy::SpdyFramerVisitorInterface* visitor_ = nullptr;
  spdy::SpdyFramerDebugVisitorInterface* debug_visitor_ = nullptr;

  // If non-null, unknown frames and settings are passed to the extension.
  spdy::ExtensionVisitorInterface* extension_ = nullptr;

  // The HPACK decoder to be used for this adapter. User is responsible for
  // clearing if the adapter is to be used for another connection.
  std::unique_ptr<spdy::HpackDecoderAdapter> hpack_decoder_ = nullptr;

  // The HTTP/2 frame decoder. Accessed via a unique_ptr to allow replacement
  // (e.g. in tests) when Reset() is called.
  std::unique_ptr<Http2FrameDecoder> frame_decoder_;

  // Next frame type expected. Currently only used for CONTINUATION frames,
  // but could be used for detecting whether the first frame is a SETTINGS
  // frame.
  // TODO(jamessyng): Provide means to indicate that decoder should require
  // SETTINGS frame as the first frame.
  Http2FrameType expected_frame_type_;

  // Attempt to duplicate the SpdyState and SpdyFramerError values that
  // SpdyFramer sets. Values determined by getting tests to pass.
  SpdyState spdy_state_;
  SpdyFramerError spdy_framer_error_;

  // The limit on the size of received HTTP/2 payloads as specified in the
  // SETTINGS_MAX_FRAME_SIZE advertised to peer.
  size_t recv_frame_size_limit_ = spdy::kHttp2DefaultFramePayloadLimit;

  // Has OnFrameHeader been called?
  bool decoded_frame_header_ = false;

  // Have we recorded an Http2FrameHeader for the current frame?
  // We only do so if the decoder will make multiple callbacks for
  // the frame; for example, for PING frames we don't make record
  // the frame header, but for ALTSVC we do.
  bool has_frame_header_ = false;

  // Have we recorded an Http2FrameHeader for the current HPACK block?
  // True only for multi-frame HPACK blocks.
  bool has_hpack_first_frame_header_ = false;

  // Has OnHeaders() already been called for current HEADERS block? Only
  // meaningful between OnHeadersStart and OnHeadersPriority.
  bool on_headers_called_;

  // Has OnHpackFragment() already been called for current HPACK block?
  // SpdyFramer will pass an empty buffer to the HPACK decoder if a HEADERS
  // or PUSH_PROMISE has no HPACK data in it (e.g. a HEADERS frame with only
  // padding). Detect that condition and replicate the behavior using this
  // field.
  bool on_hpack_fragment_called_;

  // Have we seen a frame header that appears to be an HTTP/1 response?
  bool latched_probable_http_response_ = false;

  // Is expected_frame_type_ set?
  bool has_expected_frame_type_ = false;

  // Is the current frame payload destined for |extension_|?
  bool handling_extension_payload_ = false;
};

}  // namespace http2

namespace spdy {

// Http2DecoderAdapter will use the given visitor implementing this
// interface to deliver event callbacks as frames are decoded.
//
// Control frames that contain HTTP2 header blocks (HEADER, and PUSH_PROMISE)
// are processed in fashion that allows the decompressed header block to be
// delivered in chunks to the visitor.
// The following steps are followed:
//   1. OnHeaders, or OnPushPromise is called.
//   2. OnHeaderFrameStart is called; visitor is expected to return an instance
//      of SpdyHeadersHandlerInterface that will receive the header key-value
//      pairs.
//   3. OnHeaderFrameEnd is called, indicating that the full header block has
//      been delivered for the control frame.
// During step 2, if the visitor is not interested in accepting the header data,
// it should return a no-op implementation of SpdyHeadersHandlerInterface.
class QUICHE_EXPORT_PRIVATE SpdyFramerVisitorInterface {
 public:
  virtual ~SpdyFramerVisitorInterface() {}

  // Called if an error is detected in the SpdyFrame protocol.
  virtual void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
                       std::string detailed_error) = 0;

  // Called when the common header for a frame is received. Validating the
  // common header occurs in later processing.
  virtual void OnCommonHeader(SpdyStreamId /*stream_id*/,
                              size_t /*length*/,
                              uint8_t /*type*/,
                              uint8_t /*flags*/) {}

  // Called when a data frame header is received. The frame's data
  // payload will be provided via subsequent calls to
  // OnStreamFrameData().
  virtual void OnDataFrameHeader(SpdyStreamId stream_id,
                                 size_t length,
                                 bool fin) = 0;

  // Called when data is received.
  // |stream_id| The stream receiving data.
  // |data| A buffer containing the data received.
  // |len| The length of the data buffer.
  virtual void OnStreamFrameData(SpdyStreamId stream_id,
                                 const char* data,
                                 size_t len) = 0;

  // Called when the other side has finished sending data on this stream.
  // |stream_id| The stream that was receiving data.
  virtual void OnStreamEnd(SpdyStreamId stream_id) = 0;

  // Called when padding length field is received on a DATA frame.
  // |stream_id| The stream receiving data.
  // |value| The value of the padding length field.
  virtual void OnStreamPadLength(SpdyStreamId /*stream_id*/, size_t /*value*/) {
  }

  // Called when padding is received (the trailing octets, not pad_len field) on
  // a DATA frame.
  // |stream_id| The stream receiving data.
  // |len| The number of padding octets.
  virtual void OnStreamPadding(SpdyStreamId stream_id, size_t len) = 0;

  // Called just before processing the payload of a frame containing header
  // data. Should return an implementation of SpdyHeadersHandlerInterface that
  // will receive headers for stream |stream_id|. The caller will not take
  // ownership of the headers handler. The same instance should remain live
  // and be returned for all header frames comprising a logical header block
  // (i.e. until OnHeaderFrameEnd() is called).
  virtual SpdyHeadersHandlerInterface* OnHeaderFrameStart(
      SpdyStreamId stream_id) = 0;

  // Called after processing the payload of a frame containing header data.
  virtual void OnHeaderFrameEnd(SpdyStreamId stream_id) = 0;

  // Called when a RST_STREAM frame has been parsed.
  virtual void OnRstStream(SpdyStreamId stream_id,
                           SpdyErrorCode error_code) = 0;

  // Called when a SETTINGS frame is received.
  virtual void OnSettings() {}

  // Called when a complete setting within a SETTINGS frame has been parsed.
  // Note that |id| may or may not be a SETTINGS ID defined in the HTTP/2 spec.
  virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;

  // Called when a SETTINGS frame is received with the ACK flag set.
  virtual void OnSettingsAck() {}

  // Called before and after parsing SETTINGS id and value tuples.
  virtual void OnSettingsEnd() = 0;

  // Called when a PING frame has been parsed.
  virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0;

  // Called when a GOAWAY frame has been parsed.
  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
                        SpdyErrorCode error_code) = 0;

  // Called when a HEADERS frame is received.
  // Note that header block data is not included. See OnHeaderFrameStart().
  // |stream_id| The stream receiving the header.
  // |has_priority| Whether or not the headers frame included a priority value,
  //     and stream dependency info.
  // |weight| If |has_priority| is true, then weight (in the range [1, 256])
  //     for the receiving stream, otherwise 0.
  // |parent_stream_id| If |has_priority| is true the parent stream of the
  //     receiving stream, else 0.
  // |exclusive| If |has_priority| is true the exclusivity of dependence on the
  //     parent stream, else false.
  // |fin| Whether FIN flag is set in frame headers.
  // |end| False if HEADERs frame is to be followed by a CONTINUATION frame,
  //     or true if not.
  virtual void OnHeaders(SpdyStreamId stream_id,
                         bool has_priority,
                         int weight,
                         SpdyStreamId parent_stream_id,
                         bool exclusive,
                         bool fin,
                         bool end) = 0;

  // Called when a WINDOW_UPDATE frame has been parsed.
  virtual void OnWindowUpdate(SpdyStreamId stream_id,
                              int delta_window_size) = 0;

  // Called when a goaway frame opaque data is available.
  // |goaway_data| A buffer containing the opaque GOAWAY data chunk received.
  // |len| The length of the header data buffer. A length of zero indicates
  //       that the header data block has been completely sent.
  // When this function returns true the visitor indicates that it accepted
  // all of the data. Returning false indicates that that an error has
  // occurred while processing the data. Default implementation returns true.
  virtual bool OnGoAwayFrameData(const char* goaway_data, size_t len);

  // Called when a PUSH_PROMISE frame is received.
  // Note that header block data is not included. See OnHeaderFrameStart().
  virtual void OnPushPromise(SpdyStreamId stream_id,
                             SpdyStreamId promised_stream_id,
                             bool end) = 0;

  // Called when a CONTINUATION frame is received.
  // Note that header block data is not included. See OnHeaderFrameStart().
  virtual void OnContinuation(SpdyStreamId stream_id, bool end) = 0;

  // Called when an ALTSVC frame has been parsed.
  virtual void OnAltSvc(
      SpdyStreamId /*stream_id*/,
      absl::string_view /*origin*/,
      const SpdyAltSvcWireFormat::AlternativeServiceVector& /*altsvc_vector*/) {
  }

  // Called when a PRIORITY frame is received.
  // |stream_id| The stream to update the priority of.
  // |parent_stream_id| The parent stream of |stream_id|.
  // |weight| Stream weight, in the range [1, 256].
  // |exclusive| Whether |stream_id| should be an only child of
  //     |parent_stream_id|.
  virtual void OnPriority(SpdyStreamId stream_id,
                          SpdyStreamId parent_stream_id,
                          int weight,
                          bool exclusive) = 0;

  // Called when a PRIORITY_UPDATE frame is received on stream 0.
  // |prioritized_stream_id| is the Prioritized Stream ID and
  // |priority_field_value| is the Priority Field Value
  // parsed from the frame payload.
  virtual void OnPriorityUpdate(SpdyStreamId prioritized_stream_id,
                                absl::string_view priority_field_value) = 0;

  // Called when a frame type we don't recognize is received.
  // Return true if this appears to be a valid extension frame, false otherwise.
  // We distinguish between extension frames and nonsense by checking
  // whether the stream id is valid.
  virtual bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) = 0;
};

class QUICHE_EXPORT_PRIVATE ExtensionVisitorInterface {
 public:
  virtual ~ExtensionVisitorInterface() {}

  // Called when SETTINGS are received, including non-standard SETTINGS.
  virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;

  // Called when non-standard frames are received.
  virtual bool OnFrameHeader(SpdyStreamId stream_id,
                             size_t length,
                             uint8_t type,
                             uint8_t flags) = 0;

  // The payload for a single frame may be delivered as multiple calls to
  // OnFramePayload. Since the length field is passed in OnFrameHeader, there is
  // no explicit indication of the end of the frame payload.
  virtual void OnFramePayload(const char* data, size_t len) = 0;
};

}  // namespace spdy

#endif  // QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_
