// Copyright 2013 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.

// The base class for streams which deliver data to/from an application.
// In each direction, the data on such a stream first contains compressed
// headers then body data.

#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_

#include <sys/types.h>

#include <cstddef>
#include <list>
#include <memory>
#include <optional>
#include <string>

#include "absl/base/attributes.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/quic/core/http/http_decoder.h"
#include "quiche/quic/core/http/http_encoder.h"
#include "quiche/quic/core/http/metadata_decoder.h"
#include "quiche/quic/core/http/quic_header_list.h"
#include "quiche/quic/core/http/quic_spdy_stream_body_manager.h"
#include "quiche/quic/core/http/web_transport_stream_adapter.h"
#include "quiche/quic/core/qpack/qpack_decoded_headers_accumulator.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_session.h"
#include "quiche/quic/core/quic_stream.h"
#include "quiche/quic/core/quic_stream_priority.h"
#include "quiche/quic/core/quic_stream_sequencer.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/web_transport_interface.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/common/capsule.h"
#include "quiche/common/http/http_header_block.h"
#include "quiche/common/platform/api/quiche_mem_slice.h"
#include "quiche/spdy/core/spdy_framer.h"

namespace quic {

namespace test {
class QuicSpdyStreamPeer;
class QuicStreamPeer;
}  // namespace test

class QuicSpdySession;
class WebTransportHttp3;

// A QUIC stream that can send and receive HTTP2 (SPDY) headers.
class QUICHE_EXPORT QuicSpdyStream
    : public QuicStream,
      public quiche::CapsuleParser::Visitor,
      public QpackDecodedHeadersAccumulator::Visitor {
 public:
  // Visitor receives callbacks from the stream.
  class QUICHE_EXPORT Visitor {
   public:
    Visitor() {}
    Visitor(const Visitor&) = delete;
    Visitor& operator=(const Visitor&) = delete;

    // Called when the stream is closed.
    virtual void OnClose(QuicSpdyStream* stream) = 0;

   protected:
    virtual ~Visitor() {}
  };

  // Class which receives HTTP/3 METADATA.
  class QUICHE_EXPORT MetadataVisitor {
   public:
    virtual ~MetadataVisitor() = default;

    // Called when HTTP/3 METADATA has been received and parsed.
    virtual void OnMetadataComplete(size_t frame_len,
                                    const QuicHeaderList& header_list) = 0;
  };

  class QUICHE_EXPORT Http3DatagramVisitor {
   public:
    virtual ~Http3DatagramVisitor() {}

    // Called when an HTTP/3 datagram is received. |payload| does not contain
    // the stream ID.
    virtual void OnHttp3Datagram(QuicStreamId stream_id,
                                 absl::string_view payload) = 0;

    // Called when a Capsule with an unknown type is received.
    virtual void OnUnknownCapsule(QuicStreamId stream_id,
                                  const quiche::UnknownCapsule& capsule) = 0;
  };

  class QUICHE_EXPORT ConnectIpVisitor {
   public:
    virtual ~ConnectIpVisitor() {}

    virtual bool OnAddressAssignCapsule(
        const quiche::AddressAssignCapsule& capsule) = 0;
    virtual bool OnAddressRequestCapsule(
        const quiche::AddressRequestCapsule& capsule) = 0;
    virtual bool OnRouteAdvertisementCapsule(
        const quiche::RouteAdvertisementCapsule& capsule) = 0;
    virtual void OnHeadersWritten() = 0;
  };

  QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session,
                 StreamType type);
  QuicSpdyStream(PendingStream* pending, QuicSpdySession* spdy_session);
  QuicSpdyStream(const QuicSpdyStream&) = delete;
  QuicSpdyStream& operator=(const QuicSpdyStream&) = delete;
  ~QuicSpdyStream() override;

  // QuicStream implementation
  void OnClose() override;
  void StopReading() override;

  // Override to maybe close the write side after writing.
  void OnCanWrite() override;

  // Called by the session when headers with a priority have been received
  // for this stream.  This method will only be called for server streams.
  virtual void OnStreamHeadersPriority(
      const spdy::SpdyStreamPrecedence& precedence);

  // Called by the session when decompressed headers have been completely
  // delivered to this stream.  If |fin| is true, then this stream
  // should be closed; no more data will be sent by the peer.
  virtual void OnStreamHeaderList(bool fin, size_t frame_len,
                                  const QuicHeaderList& header_list);

  // Called by the session when a PRIORITY frame has been been received for this
  // stream. This method will only be called for server streams.
  void OnPriorityFrame(const spdy::SpdyStreamPrecedence& precedence);

  // Override the base class to not discard response when receiving
  // QUIC_STREAM_NO_ERROR.
  void OnStreamReset(const QuicRstStreamFrame& frame) override;
  void ResetWithError(QuicResetStreamError error) override;
  bool OnStopSending(QuicResetStreamError error) override;

  // Called by the sequencer when new data is available. Decodes the data and
  // calls OnBodyAvailable() to pass to the upper layer.
  void OnDataAvailable() override;

  // Called in OnDataAvailable() after it finishes the decoding job.
  virtual void OnBodyAvailable() = 0;

  // Writes the headers contained in |header_block| on the dedicated headers
  // stream or on this stream, depending on VersionUsesHttp3().  Returns the
  // number of bytes sent, including data sent on the encoder stream when using
  // QPACK.
  virtual size_t WriteHeaders(
      quiche::HttpHeaderBlock header_block, bool fin,
      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
          ack_listener);

  // Sends |data| to the peer, or buffers if it can't be sent immediately.
  virtual void WriteOrBufferBody(absl::string_view data, bool fin);

  // Writes the trailers contained in |trailer_block| on the dedicated headers
  // stream or on this stream, depending on VersionUsesHttp3().  Trailers will
  // always have the FIN flag set.  Returns the number of bytes sent, including
  // data sent on the encoder stream when using QPACK.
  virtual size_t WriteTrailers(
      quiche::HttpHeaderBlock trailer_block,
      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
          ack_listener);

  // Override to report newly acked bytes via ack_listener_.
  bool OnStreamFrameAcked(QuicStreamOffset offset, QuicByteCount data_length,
                          bool fin_acked, QuicTime::Delta ack_delay_time,
                          QuicTime receive_timestamp,
                          QuicByteCount* newly_acked_length) override;

  // Override to report bytes retransmitted via ack_listener_.
  void OnStreamFrameRetransmitted(QuicStreamOffset offset,
                                  QuicByteCount data_length,
                                  bool fin_retransmitted) override;

  // Does the same thing as WriteOrBufferBody except this method takes iovec
  // as the data input. Right now it only calls WritevData.
  QuicConsumedData WritevBody(const struct iovec* iov, int count, bool fin);

  // Does the same thing as WriteOrBufferBody except this method takes
  // memslicespan as the data input. Right now it only calls WriteMemSlices.
  QuicConsumedData WriteBodySlices(absl::Span<quiche::QuicheMemSlice> slices,
                                   bool fin);

  // Marks the trailers as consumed. This applies to the case where this object
  // receives headers and trailers as QuicHeaderLists via calls to
  // OnStreamHeaderList(). Trailer data will be consumed from the sequencer only
  // once all body data has been consumed.
  void MarkTrailersConsumed();

  // Clears |header_list_|.
  void ConsumeHeaderList();

  // This block of functions wraps the sequencer's functions of the same
  // name.  These methods return uncompressed data until that has
  // been fully processed.  Then they simply delegate to the sequencer.
  virtual size_t Readv(const struct iovec* iov, size_t iov_len);
  virtual int GetReadableRegions(iovec* iov, size_t iov_len) const;
  void MarkConsumed(size_t num_bytes);

  // Returns true if header contains a valid 3-digit status and parse the status
  // code to |status_code|.
  static bool ParseHeaderStatusCode(const quiche::HttpHeaderBlock& header,
                                    int* status_code);
  // Returns true if status_value (associated with :status) contains a valid
  // 3-digit status and parse the status code to |status_code|.
  static bool ParseHeaderStatusCode(absl::string_view status_value,
                                    int* status_code);

  // Returns true when headers, data and trailers all are read.
  bool IsDoneReading() const;
  // For IETF QUIC, bytes-to-read/readable-bytes only concern body (not headers
  // or trailers). For gQUIC, they refer to all the bytes in the sequencer.
  bool HasBytesToRead() const;
  QuicByteCount ReadableBytes() const;

  void set_visitor(Visitor* visitor) { visitor_ = visitor; }

  bool headers_decompressed() const { return headers_decompressed_; }

  // Returns total amount of body bytes that have been read.
  uint64_t total_body_bytes_read() const;

  const QuicHeaderList& header_list() const { return header_list_; }

  bool trailers_decompressed() const { return trailers_decompressed_; }

  // Returns whatever trailers have been received for this stream.
  const quiche::HttpHeaderBlock& received_trailers() const {
    return received_trailers_;
  }

  // Returns true if headers have been fully read and consumed.
  bool FinishedReadingHeaders() const;

  // Returns true if FIN has been received and either trailers have been fully
  // read and consumed or there are no trailers.
  bool FinishedReadingTrailers() const;

  // Returns true if the sequencer has delivered the FIN, and no more body bytes
  // will be available.
  bool IsSequencerClosed() { return sequencer()->IsClosed(); }

  // QpackDecodedHeadersAccumulator::Visitor implementation.
  void OnHeadersDecoded(QuicHeaderList headers,
                        bool header_list_size_limit_exceeded) override;
  void OnHeaderDecodingError(QuicErrorCode error_code,
                             absl::string_view error_message) override;

  QuicSpdySession* spdy_session() const { return spdy_session_; }

  // Send PRIORITY_UPDATE frame and update |last_sent_priority_| if
  // |last_sent_priority_| is different from current priority.
  void MaybeSendPriorityUpdateFrame() override;

  // Returns the WebTransport session owned by this stream, if one exists.
  WebTransportHttp3* web_transport() { return web_transport_.get(); }

  // Returns the WebTransport data stream associated with this QUIC stream, or
  // null if this is not a WebTransport data stream.
  WebTransportStream* web_transport_stream() {
    if (web_transport_data_ == nullptr) {
      return nullptr;
    }
    return &web_transport_data_->adapter;
  }

  // Sends a WEBTRANSPORT_STREAM frame and sets up the appropriate metadata.
  void ConvertToWebTransportDataStream(WebTransportSessionId session_id);

  void OnCanWriteNewData() override;

  // If this stream is a WebTransport data stream, closes the connection with an
  // error, and returns false.
  bool AssertNotWebTransportDataStream(absl::string_view operation);

  // Indicates whether a call to WriteBodySlices will be successful and not
  // rejected due to buffer being full.  |write_size| must be non-zero.
  bool CanWriteNewBodyData(QuicByteCount write_size) const;

  // From CapsuleParser::Visitor.
  bool OnCapsule(const quiche::Capsule& capsule) override;
  void OnCapsuleParseFailure(absl::string_view error_message) override;

  // Sends an HTTP/3 datagram. The stream ID is not part of |payload|. Virtual
  // to allow mocking in tests.
  virtual MessageStatus SendHttp3Datagram(absl::string_view payload);

  // Registers |visitor| to receive HTTP/3 datagrams and enables Capsule
  // Protocol by registering a CapsuleParser. |visitor| must be valid until a
  // corresponding call to UnregisterHttp3DatagramVisitor.
  void RegisterHttp3DatagramVisitor(Http3DatagramVisitor* visitor);

  // Unregisters an HTTP/3 datagram visitor. Must only be called after a call to
  // RegisterHttp3DatagramVisitor.
  void UnregisterHttp3DatagramVisitor();

  // Replaces the current HTTP/3 datagram visitor with a different visitor.
  // Mainly meant to be used by the visitors' move operators.
  void ReplaceHttp3DatagramVisitor(Http3DatagramVisitor* visitor);

  // Registers |visitor| to receive CONNECT-IP capsules. |visitor| must be
  // valid until a corresponding call to UnregisterConnectIpVisitor.
  void RegisterConnectIpVisitor(ConnectIpVisitor* visitor);

  // Unregisters a CONNECT-IP visitor. Must only be called after a call to
  // RegisterConnectIpVisitor.
  void UnregisterConnectIpVisitor();

  // Replaces the current CONNECT-IP visitor with a different visitor.
  // Mainly meant to be used by the visitors' move operators.
  void ReplaceConnectIpVisitor(ConnectIpVisitor* visitor);

  // Sets max datagram time in queue.
  void SetMaxDatagramTimeInQueue(QuicTime::Delta max_time_in_queue);

  void OnDatagramReceived(QuicDataReader* reader);

  QuicByteCount GetMaxDatagramSize() const;

  // Writes |capsule| onto the DATA stream.
  void WriteCapsule(const quiche::Capsule& capsule, bool fin = false);

  void WriteGreaseCapsule();

  const std::string& invalid_request_details() const {
    return invalid_request_details_;
  }

  // Registers |visitor| to receive HTTP/3 METADATA. |visitor| must be valid
  // until a corresponding call to UnregisterRegisterMetadataVisitor.
  void RegisterMetadataVisitor(MetadataVisitor* visitor);
  void UnregisterMetadataVisitor();

  // Returns how long header decoding was delayed due to waiting for data to
  // arrive on the QPACK encoder stream.
  // Returns zero if header block could be decoded as soon as it was received.
  // Returns `nullopt` if header block is not decoded yet.
  std::optional<QuicTime::Delta> header_decoding_delay() const {
    return header_decoding_delay_;
  }

  const std::vector<uint64_t>& decoded_frame_types() const {
    return decoder_.decoded_frame_types();
  }

 protected:
  // Called when the received headers are too large. By default this will
  // reset the stream.
  virtual void OnHeadersTooLarge();

  virtual void OnInitialHeadersComplete(bool fin, size_t frame_len,
                                        const QuicHeaderList& header_list);
  virtual void OnTrailingHeadersComplete(bool fin, size_t frame_len,
                                         const QuicHeaderList& header_list);
  virtual size_t WriteHeadersImpl(
      quiche::HttpHeaderBlock header_block, bool fin,
      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
          ack_listener);

  virtual bool CopyAndValidateTrailers(const QuicHeaderList& header_list,
                                       bool expect_final_byte_offset,
                                       size_t* final_byte_offset,
                                       quiche::HttpHeaderBlock* trailers);

  Visitor* visitor() { return visitor_; }

  void set_headers_decompressed(bool val) { headers_decompressed_ = val; }

  virtual bool uses_capsules() const { return capsule_parser_ != nullptr; }

  void set_ack_listener(
      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
          ack_listener) {
    ack_listener_ = std::move(ack_listener);
  }

  void OnWriteSideInDataRecvdState() override;

  virtual bool ValidateReceivedHeaders(const QuicHeaderList& header_list);
  // TODO(b/202433856) Merge AreHeaderFieldValueValid into
  // ValidateReceivedHeaders once all flags guarding the behavior of
  // ValidateReceivedHeaders has been rolled out.
  virtual bool AreHeaderFieldValuesValid(
      const QuicHeaderList& header_list) const;

  // Reset stream upon invalid request headers.
  virtual void OnInvalidHeaders();

  void set_invalid_request_details(std::string invalid_request_details);

  // Called by HttpDecoderVisitor.
  virtual bool OnDataFrameStart(QuicByteCount header_length,
                                QuicByteCount payload_length);

  void CloseReadSide() override;

 private:
  friend class test::QuicSpdyStreamPeer;
  friend class test::QuicStreamPeer;
  friend class QuicStreamUtils;
  class HttpDecoderVisitor;

  struct QUICHE_EXPORT WebTransportDataStream {
    WebTransportDataStream(QuicSpdyStream* stream,
                           WebTransportSessionId session_id);

    WebTransportSessionId session_id;
    WebTransportStreamAdapter adapter;
  };

  // Called by HttpDecoderVisitor.
  bool OnDataFramePayload(absl::string_view payload);
  bool OnDataFrameEnd();
  bool OnHeadersFrameStart(QuicByteCount header_length,
                           QuicByteCount payload_length);
  bool OnHeadersFramePayload(absl::string_view payload);
  bool OnHeadersFrameEnd();
  void OnWebTransportStreamFrameType(QuicByteCount header_length,
                                     WebTransportSessionId session_id);
  bool OnMetadataFrameStart(QuicByteCount header_length,
                            QuicByteCount payload_length);
  bool OnMetadataFramePayload(absl::string_view payload);
  bool OnMetadataFrameEnd();
  bool OnUnknownFrameStart(uint64_t frame_type, QuicByteCount header_length,
                           QuicByteCount payload_length);
  bool OnUnknownFramePayload(absl::string_view payload);
  bool OnUnknownFrameEnd();

  // Given the interval marked by [|offset|, |offset| + |data_length|), return
  // the number of frame header bytes contained in it.
  QuicByteCount GetNumFrameHeadersInInterval(QuicStreamOffset offset,
                                             QuicByteCount data_length) const;

  void MaybeProcessSentWebTransportHeaders(quiche::HttpHeaderBlock& headers);
  void MaybeProcessReceivedWebTransportHeaders();

  // Writes HTTP/3 DATA frame header. If |force_write| is true, use
  // WriteOrBufferData if send buffer cannot accomodate the header + data.
  ABSL_MUST_USE_RESULT bool WriteDataFrameHeader(QuicByteCount data_length,
                                                 bool force_write);

  // Simply calls OnBodyAvailable() unless capsules are in use, in which case
  // pass the capsule fragments to the capsule manager.
  void HandleBodyAvailable();

  // Called when a datagram frame or capsule is received.
  void HandleReceivedDatagram(absl::string_view payload);

  // Whether the next received header is trailer or not.
  virtual bool NextHeaderIsTrailer() const { return headers_decompressed_; }

  QuicSpdySession* spdy_session_;

  bool on_body_available_called_because_sequencer_is_closed_;

  Visitor* visitor_;

  // True if read side processing is blocked while waiting for callback from
  // QPACK decoder.
  bool blocked_on_decoding_headers_;
  // True if the headers have been completely decompressed.
  bool headers_decompressed_;
  // True if uncompressed headers or trailers exceed maximum allowed size
  // advertised to peer via SETTINGS_MAX_HEADER_LIST_SIZE.
  bool header_list_size_limit_exceeded_;
  // Contains a copy of the decompressed header (name, value) pairs until they
  // are consumed via Readv.
  QuicHeaderList header_list_;
  // Length of most recently received HEADERS frame payload.
  QuicByteCount headers_payload_length_;

  // True if the trailers have been completely decompressed.
  bool trailers_decompressed_;
  // True if the trailers have been consumed.
  bool trailers_consumed_;

  // The parsed trailers received from the peer.
  quiche::HttpHeaderBlock received_trailers_;

  // Headers accumulator for decoding HEADERS frame payload.
  std::unique_ptr<QpackDecodedHeadersAccumulator>
      qpack_decoded_headers_accumulator_;
  // Visitor of the HttpDecoder.
  std::unique_ptr<HttpDecoderVisitor> http_decoder_visitor_;
  // HttpDecoder for processing raw incoming stream frames.
  HttpDecoder decoder_;
  // Object that manages references to DATA frame payload fragments buffered by
  // the sequencer and calculates how much data should be marked consumed with
  // the sequencer each time new stream data is processed.
  QuicSpdyStreamBodyManager body_manager_;

  std::unique_ptr<quiche::CapsuleParser> capsule_parser_;

  // Sequencer offset keeping track of how much data HttpDecoder has processed.
  // Initial value is zero for fresh streams, or sequencer()->NumBytesConsumed()
  // at time of construction if a PendingStream is converted to account for the
  // length of the unidirectional stream type at the beginning of the stream.
  QuicStreamOffset sequencer_offset_;

  // True when inside an HttpDecoder::ProcessInput() call.
  // Used for detecting reentrancy.
  bool is_decoder_processing_input_;

  // Ack listener of this stream, and it is notified when any of written bytes
  // are acked or retransmitted.
  quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface> ack_listener_;

  // Offset of unacked frame headers.
  QuicIntervalSet<QuicStreamOffset> unacked_frame_headers_offsets_;

  // Priority parameters sent in the last PRIORITY_UPDATE frame, or default
  // values defined by RFC9218 if no PRIORITY_UPDATE frame has been sent.
  QuicStreamPriority last_sent_priority_;

  // If this stream is a WebTransport extended CONNECT stream, contains the
  // WebTransport session associated with this stream.
  std::unique_ptr<WebTransportHttp3> web_transport_;

  // If this stream is a WebTransport data stream, |web_transport_data_|
  // contains all of the associated metadata.
  std::unique_ptr<WebTransportDataStream> web_transport_data_;

  // HTTP/3 Datagram support.
  Http3DatagramVisitor* datagram_visitor_ = nullptr;
  // CONNECT-IP support.
  ConnectIpVisitor* connect_ip_visitor_ = nullptr;

  // Present if HTTP/3 METADATA frames should be parsed.
  MetadataVisitor* metadata_visitor_ = nullptr;

  // Present if an HTTP/3 METADATA is currently being parsed.
  std::unique_ptr<MetadataDecoder> metadata_decoder_;

  // Empty if the headers are valid.
  std::string invalid_request_details_;

  // Time when entire header block was received.
  // Only set if decoding was blocked.
  QuicTime header_block_received_time_ = QuicTime::Zero();

  // Header decoding delay due to waiting for data on the QPACK encoder stream.
  // Zero if header block could be decoded as soon as it was received.
  // `nullopt` if header block is not decoded yet.
  std::optional<QuicTime::Delta> header_decoding_delay_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_H_
