// Copyright (c) 2015 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_QUIC_SPDY_SESSION_H_
#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_

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

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "quiche/quic/core/http/http_frames.h"
#include "quiche/quic/core/http/quic_header_list.h"
#include "quiche/quic/core/http/quic_headers_stream.h"
#include "quiche/quic/core/http/quic_receive_control_stream.h"
#include "quiche/quic/core/http/quic_send_control_stream.h"
#include "quiche/quic/core/http/quic_spdy_stream.h"
#include "quiche/quic/core/qpack/qpack_decoder.h"
#include "quiche/quic/core/qpack/qpack_encoder.h"
#include "quiche/quic/core/qpack/qpack_receive_stream.h"
#include "quiche/quic/core/qpack/qpack_send_stream.h"
#include "quiche/quic/core/quic_session.h"
#include "quiche/quic/core/quic_stream_priority.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/spdy/core/http2_frame_decoder_adapter.h"
#include "quiche/spdy/core/http2_header_block.h"

namespace quic {

namespace test {
class QuicSpdySessionPeer;
}  // namespace test

class WebTransportHttp3UnidirectionalStream;

QUIC_EXPORT_PRIVATE extern const size_t kMaxUnassociatedWebTransportStreams;

class QUIC_EXPORT_PRIVATE Http3DebugVisitor {
 public:
  Http3DebugVisitor();
  Http3DebugVisitor(const Http3DebugVisitor&) = delete;
  Http3DebugVisitor& operator=(const Http3DebugVisitor&) = delete;

  virtual ~Http3DebugVisitor();

  // TODO(https://crbug.com/1062700): Remove default implementation of all
  // methods after Chrome's QuicHttp3Logger has overrides.  This is to make sure
  // QUICHE merge is not blocked on having to add those overrides, they can
  // happen asynchronously.

  // Creation of unidirectional streams.

  // Called when locally-initiated control stream is created.
  virtual void OnControlStreamCreated(QuicStreamId /*stream_id*/) = 0;
  // Called when locally-initiated QPACK encoder stream is created.
  virtual void OnQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
  // Called when locally-initiated QPACK decoder stream is created.
  virtual void OnQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
  // Called when peer's control stream type is received.
  virtual void OnPeerControlStreamCreated(QuicStreamId /*stream_id*/) = 0;
  // Called when peer's QPACK encoder stream type is received.
  virtual void OnPeerQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) = 0;
  // Called when peer's QPACK decoder stream type is received.
  virtual void OnPeerQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) = 0;

  // Incoming HTTP/3 frames in ALPS TLS extension.
  virtual void OnSettingsFrameReceivedViaAlps(const SettingsFrame& /*frame*/) {}
  virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/) {}

  // Incoming HTTP/3 frames on the control stream.
  virtual void OnSettingsFrameReceived(const SettingsFrame& /*frame*/) = 0;
  virtual void OnGoAwayFrameReceived(const GoAwayFrame& /*frame*/) = 0;
  virtual void OnPriorityUpdateFrameReceived(
      const PriorityUpdateFrame& /*frame*/) = 0;
  virtual void OnAcceptChFrameReceived(const AcceptChFrame& /*frame*/) {}

  // Incoming HTTP/3 frames on request or push streams.
  virtual void OnDataFrameReceived(QuicStreamId /*stream_id*/,
                                   QuicByteCount /*payload_length*/) = 0;
  virtual void OnHeadersFrameReceived(
      QuicStreamId /*stream_id*/,
      QuicByteCount /*compressed_headers_length*/) = 0;
  virtual void OnHeadersDecoded(QuicStreamId /*stream_id*/,
                                QuicHeaderList /*headers*/) = 0;

  // Incoming HTTP/3 frames of unknown type on any stream.
  virtual void OnUnknownFrameReceived(QuicStreamId /*stream_id*/,
                                      uint64_t /*frame_type*/,
                                      QuicByteCount /*payload_length*/) = 0;

  // Outgoing HTTP/3 frames on the control stream.
  virtual void OnSettingsFrameSent(const SettingsFrame& /*frame*/) = 0;
  virtual void OnGoAwayFrameSent(QuicStreamId /*stream_id*/) = 0;
  virtual void OnPriorityUpdateFrameSent(
      const PriorityUpdateFrame& /*frame*/) = 0;

  // Outgoing HTTP/3 frames on request or push streams.
  virtual void OnDataFrameSent(QuicStreamId /*stream_id*/,
                               QuicByteCount /*payload_length*/) = 0;
  virtual void OnHeadersFrameSent(
      QuicStreamId /*stream_id*/,
      const spdy::Http2HeaderBlock& /*header_block*/) = 0;

  // 0-RTT related events.
  virtual void OnSettingsFrameResumed(const SettingsFrame& /*frame*/) = 0;
};

// Whether HTTP Datagrams are supported on this session and if so which version
// is currently in use.
enum class HttpDatagramSupport : uint8_t {
  kNone,  // HTTP Datagrams are not supported for this session.
  kDraft04,
  kRfc,
  kRfcAndDraft04,  // Only used locally for sending, we only negotiate one
                   // version.
};

QUIC_EXPORT_PRIVATE std::string HttpDatagramSupportToString(
    HttpDatagramSupport http_datagram_support);
QUIC_EXPORT_PRIVATE std::ostream& operator<<(
    std::ostream& os, const HttpDatagramSupport& http_datagram_support);

// A QUIC session for HTTP.
class QUIC_EXPORT_PRIVATE QuicSpdySession
    : public QuicSession,
      public QpackEncoder::DecoderStreamErrorDelegate,
      public QpackDecoder::EncoderStreamErrorDelegate {
 public:
  // Does not take ownership of |connection| or |visitor|.
  QuicSpdySession(QuicConnection* connection, QuicSession::Visitor* visitor,
                  const QuicConfig& config,
                  const ParsedQuicVersionVector& supported_versions);
  QuicSpdySession(const QuicSpdySession&) = delete;
  QuicSpdySession& operator=(const QuicSpdySession&) = delete;

  ~QuicSpdySession() override;

  void Initialize() override;

  // QpackEncoder::DecoderStreamErrorDelegate implementation.
  void OnDecoderStreamError(QuicErrorCode error_code,
                            absl::string_view error_message) override;

  // QpackDecoder::EncoderStreamErrorDelegate implementation.
  void OnEncoderStreamError(QuicErrorCode error_code,
                            absl::string_view error_message) override;

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

  // Called by |headers_stream_| when headers have been completely received
  // for a stream.  |fin| will be true if the fin flag was set in the headers
  // frame.
  virtual void OnStreamHeaderList(QuicStreamId stream_id, bool fin,
                                  size_t frame_len,
                                  const QuicHeaderList& header_list);

  // Called by |headers_stream_| when push promise headers have been
  // completely received.  |fin| will be true if the fin flag was set
  // in the headers.
  virtual void OnPromiseHeaderList(QuicStreamId stream_id,
                                   QuicStreamId promised_stream_id,
                                   size_t frame_len,
                                   const QuicHeaderList& header_list);

  // Called by |headers_stream_| when a PRIORITY frame has been received for a
  // stream. This method will only be called for server streams.
  virtual void OnPriorityFrame(QuicStreamId stream_id,
                               const spdy::SpdyStreamPrecedence& precedence);

  // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a request
  // stream.  Returns false and closes connection if |stream_id| is invalid.
  bool OnPriorityUpdateForRequestStream(QuicStreamId stream_id,
                                        QuicStreamPriority priority);

  // Called when an HTTP/3 ACCEPT_CH frame has been received.
  // This method will only be called for client sessions.
  virtual void OnAcceptChFrame(const AcceptChFrame& /*frame*/) {}

  // Called when an HTTP/3 frame of unknown type has been received.
  virtual void OnUnknownFrameStart(QuicStreamId /*stream_id*/,
                                   uint64_t /*frame_type*/,
                                   QuicByteCount /*header_length*/,
                                   QuicByteCount /*payload_length*/) {}
  virtual void OnUnknownFramePayload(QuicStreamId /*stream_id*/,
                                     absl::string_view /*payload*/) {}

  // Sends contents of |iov| to h2_deframer_, returns number of bytes processed.
  size_t ProcessHeaderData(const struct iovec& iov);

  // Writes |headers| for the stream |id| to the dedicated headers stream.
  // If |fin| is true, then no more data will be sent for the stream |id|.
  // If provided, |ack_notifier_delegate| will be registered to be notified when
  // we have seen ACKs for all packets resulting from this call.
  virtual size_t WriteHeadersOnHeadersStream(
      QuicStreamId id, spdy::Http2HeaderBlock headers, bool fin,
      const spdy::SpdyStreamPrecedence& precedence,
      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
          ack_listener);

  // Writes an HTTP/2 PRIORITY frame the to peer. Returns the size in bytes of
  // the resulting PRIORITY frame.
  size_t WritePriority(QuicStreamId stream_id, QuicStreamId parent_stream_id,
                       int weight, bool exclusive);

  // Writes an HTTP/3 PRIORITY_UPDATE frame to the peer.
  void WriteHttp3PriorityUpdate(QuicStreamId stream_id,
                                QuicStreamPriority priority);

  // Process received HTTP/3 GOAWAY frame.  When sent from server to client,
  // |id| is a stream ID.  When sent from client to server, |id| is a push ID.
  virtual void OnHttp3GoAway(uint64_t id);

  // Send GOAWAY if the peer is blocked on the implementation max.
  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override;

  // Write GOAWAY frame with maximum stream ID on the control stream.  Called to
  // initite graceful connection shutdown.  Do not use smaller stream ID, in
  // case client does not implement retry on GOAWAY.  Do not send GOAWAY if one
  // has already been sent. Send connection close with |error_code| and |reason|
  // before encryption gets established.
  void SendHttp3GoAway(QuicErrorCode error_code, const std::string& reason);

  // Write |headers| for |promised_stream_id| on |original_stream_id| in a
  // PUSH_PROMISE frame to peer.
  virtual void WritePushPromise(QuicStreamId original_stream_id,
                                QuicStreamId promised_stream_id,
                                spdy::Http2HeaderBlock headers);

  QpackEncoder* qpack_encoder();
  QpackDecoder* qpack_decoder();
  QuicHeadersStream* headers_stream() { return headers_stream_; }

  const QuicHeadersStream* headers_stream() const { return headers_stream_; }

  // Called when the control stream receives HTTP/3 SETTINGS.
  // Returns false in case of 0-RTT if received settings are incompatible with
  // cached values, true otherwise.
  virtual bool OnSettingsFrame(const SettingsFrame& frame);

  // Called when an HTTP/3 SETTINGS frame is received via ALPS.
  // Returns an error message if an error has occurred, or nullopt otherwise.
  // May or may not close the connection on error.
  absl::optional<std::string> OnSettingsFrameViaAlps(
      const SettingsFrame& frame);

  // Called when a setting is parsed from a SETTINGS frame received on the
  // control stream or from cached application state.
  // Returns true on success.
  // Returns false if received setting is incompatible with cached value (in
  // case of 0-RTT) or with previously received value (in case of ALPS).
  // Also closes the connection on error.
  bool OnSetting(uint64_t id, uint64_t value);

  // Return true if this session wants to release headers stream's buffer
  // aggressively.
  virtual bool ShouldReleaseHeadersStreamSequencerBuffer();

  void CloseConnectionWithDetails(QuicErrorCode error,
                                  const std::string& details);

  // Must not be called after Initialize().
  // TODO(bnc): Move to constructor argument.
  void set_qpack_maximum_dynamic_table_capacity(
      uint64_t qpack_maximum_dynamic_table_capacity) {
    qpack_maximum_dynamic_table_capacity_ =
        qpack_maximum_dynamic_table_capacity;
  }

  // Must not be called after Initialize().
  // TODO(bnc): Move to constructor argument.
  void set_qpack_maximum_blocked_streams(
      uint64_t qpack_maximum_blocked_streams) {
    qpack_maximum_blocked_streams_ = qpack_maximum_blocked_streams;
  }

  // Should only be used by IETF QUIC server side.
  // Must not be called after Initialize().
  // TODO(bnc): Move to constructor argument.
  void set_max_inbound_header_list_size(size_t max_inbound_header_list_size) {
    max_inbound_header_list_size_ = max_inbound_header_list_size;
  }

  // Must not be called after Initialize().
  void set_allow_extended_connect(bool allow_extended_connect);

  size_t max_outbound_header_list_size() const {
    return max_outbound_header_list_size_;
  }

  size_t max_inbound_header_list_size() const {
    return max_inbound_header_list_size_;
  }

  bool allow_extended_connect() const { return allow_extended_connect_; }

  // Returns true if the session has active request streams.
  bool HasActiveRequestStreams() const;

  // Called when the size of the compressed frame payload is available.
  void OnCompressedFrameSize(size_t frame_len);

  // Called when a PUSH_PROMISE frame has been received.
  // TODO(b/171463363): Remove.
  void OnPushPromise(spdy::SpdyStreamId stream_id,
                     spdy::SpdyStreamId promised_stream_id);

  // Called when the complete list of headers is available.
  void OnHeaderList(const QuicHeaderList& header_list);

  QuicStreamId promised_stream_id() const { return promised_stream_id_; }

  // Initialze HTTP/3 unidirectional streams if |unidirectional| is true and
  // those streams are not initialized yet.
  void OnCanCreateNewOutgoingStream(bool unidirectional) override;

  int32_t destruction_indicator() const { return destruction_indicator_; }

  void set_debug_visitor(Http3DebugVisitor* debug_visitor) {
    debug_visitor_ = debug_visitor;
  }

  Http3DebugVisitor* debug_visitor() { return debug_visitor_; }

  // When using Google QUIC, return whether a transport layer GOAWAY frame has
  // been received or sent.
  // When using IETF QUIC, return whether an HTTP/3 GOAWAY frame has been
  // received or sent.
  bool goaway_received() const;
  bool goaway_sent() const;

  // Log header compression ratio histogram.
  // |using_qpack| is true for QPACK, false for HPACK.
  // |is_sent| is true for sent headers, false for received ones.
  // Ratio is recorded as percentage.  Smaller value means more efficient
  // compression.  Compressed size might be larger than uncompressed size, but
  // recorded ratio is trunckated at 200%.
  // Uncompressed size can be zero for an empty header list, and compressed size
  // can be zero for an empty header list when using HPACK.  (QPACK always emits
  // a header block prefix of at least two bytes.)  This method records nothing
  // if either |compressed| or |uncompressed| is not positive.
  // In order for measurements for different protocol to be comparable, the
  // caller must ensure that uncompressed size is the total length of header
  // names and values without any overhead.
  static void LogHeaderCompressionRatioHistogram(bool using_qpack, bool is_sent,
                                                 QuicByteCount compressed,
                                                 QuicByteCount uncompressed);

  // True if any dynamic table entries have been referenced from either a sent
  // or received header block.  Used for stats.
  bool dynamic_table_entry_referenced() const {
    return (qpack_encoder_ &&
            qpack_encoder_->dynamic_table_entry_referenced()) ||
           (qpack_decoder_ && qpack_decoder_->dynamic_table_entry_referenced());
  }

  void OnStreamCreated(QuicSpdyStream* stream);

  // Decode SETTINGS from |cached_state| and apply it to the session.
  bool ResumeApplicationState(ApplicationState* cached_state) override;

  absl::optional<std::string> OnAlpsData(const uint8_t* alps_data,
                                         size_t alps_length) override;

  // Called when ACCEPT_CH frame is parsed out of data received in TLS ALPS
  // extension.
  virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/);

  // Whether HTTP datagrams are supported on this session and which draft is in
  // use, based on received SETTINGS.
  HttpDatagramSupport http_datagram_support() const {
    return http_datagram_support_;
  }

  // This must not be used except by QuicSpdyStream::SendHttp3Datagram.
  MessageStatus SendHttp3Datagram(QuicStreamId stream_id,
                                  absl::string_view payload);
  // This must not be used except by QuicSpdyStream::SetMaxDatagramTimeInQueue.
  void SetMaxDatagramTimeInQueueForStreamId(QuicStreamId stream_id,
                                            QuicTime::Delta max_time_in_queue);

  // Override from QuicSession to support HTTP/3 datagrams.
  void OnMessageReceived(absl::string_view message) override;

  // Indicates whether the HTTP/3 session supports WebTransport.
  bool SupportsWebTransport();

  // Indicates whether both the peer and us support HTTP/3 Datagrams.
  bool SupportsH3Datagram() const;

  // Indicates whether the HTTP/3 session will indicate WebTransport support to
  // the peer.
  bool WillNegotiateWebTransport();

  // Returns a WebTransport session by its session ID.  Returns nullptr if no
  // session is associated with the given ID.
  WebTransportHttp3* GetWebTransportSession(WebTransportSessionId id);

  // If true, no data on bidirectional streams will be processed by the server
  // until the SETTINGS are received.  Only works for HTTP/3.
  bool ShouldBufferRequestsUntilSettings() {
    return version().UsesHttp3() && perspective() == Perspective::IS_SERVER &&
           LocalHttpDatagramSupport() != HttpDatagramSupport::kNone;
  }

  // Returns if the incoming bidirectional streams should process data.  This is
  // usually true, but in certain cases we would want to wait until the settings
  // are received.
  bool ShouldProcessIncomingRequests();

  void OnStreamWaitingForClientSettings(QuicStreamId id);

  // Links the specified stream with a WebTransport session.  If the session is
  // not present, it is buffered until a corresponding stream is found.
  void AssociateIncomingWebTransportStreamWithSession(
      WebTransportSessionId session_id, QuicStreamId stream_id);

  void ProcessBufferedWebTransportStreamsForSession(WebTransportHttp3* session);

  bool CanOpenOutgoingUnidirectionalWebTransportStream(
      WebTransportSessionId /*id*/) {
    return CanOpenNextOutgoingUnidirectionalStream();
  }
  bool CanOpenOutgoingBidirectionalWebTransportStream(
      WebTransportSessionId /*id*/) {
    return CanOpenNextOutgoingBidirectionalStream();
  }

  // Creates an outgoing unidirectional WebTransport stream.  Returns nullptr if
  // the stream cannot be created due to flow control or some other reason.
  WebTransportHttp3UnidirectionalStream*
  CreateOutgoingUnidirectionalWebTransportStream(WebTransportHttp3* session);

  // Creates an outgoing bidirectional WebTransport stream.  Returns nullptr if
  // the stream cannot be created due to flow control or some other reason.
  QuicSpdyStream* CreateOutgoingBidirectionalWebTransportStream(
      WebTransportHttp3* session);

  QuicSpdyStream* GetOrCreateSpdyDataStream(const QuicStreamId stream_id);

  // Indicates whether the client should check that the
  // `Sec-Webtransport-Http3-Draft` header is valid.
  // TODO(vasilvv): remove this once this is enabled in Chromium.
  virtual bool ShouldValidateWebTransportVersion() const;

 protected:
  // Override CreateIncomingStream(), CreateOutgoingBidirectionalStream() and
  // CreateOutgoingUnidirectionalStream() with QuicSpdyStream return type to
  // make sure that all data streams are QuicSpdyStreams.
  QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override = 0;
  QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override = 0;
  virtual QuicSpdyStream* CreateOutgoingBidirectionalStream() = 0;
  virtual QuicSpdyStream* CreateOutgoingUnidirectionalStream() = 0;

  // If an incoming stream can be created, return true.
  virtual bool ShouldCreateIncomingStream(QuicStreamId id) = 0;

  // If an outgoing bidirectional/unidirectional stream can be created, return
  // true.
  virtual bool ShouldCreateOutgoingBidirectionalStream() = 0;
  virtual bool ShouldCreateOutgoingUnidirectionalStream() = 0;

  // Indicates whether the underlying backend can accept and process
  // WebTransport sessions over HTTP/3.
  virtual bool ShouldNegotiateWebTransport();

  // Returns true if there are open HTTP requests.
  bool ShouldKeepConnectionAlive() const override;

  // Overridden to buffer incoming unidirectional streams for version 99.
  bool UsesPendingStreamForFrame(QuicFrameType type,
                                 QuicStreamId stream_id) const override;

  // Processes incoming unidirectional streams; parses the stream type, and
  // creates a new stream of the corresponding type.  Returns the pointer to the
  // newly created stream, or nullptr if the stream type is not yet available.
  QuicStream* ProcessPendingStream(PendingStream* pending) override;

  size_t WriteHeadersOnHeadersStreamImpl(
      QuicStreamId id, spdy::Http2HeaderBlock headers, bool fin,
      QuicStreamId parent_stream_id, int weight, bool exclusive,
      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
          ack_listener);

  void OnNewEncryptionKeyAvailable(
      EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) override;

  // Sets the maximum size of the header compression table spdy_framer_ is
  // willing to use to encode header blocks.
  void UpdateHeaderEncoderTableSize(uint32_t value);

  bool IsConnected() { return connection()->connected(); }

  const QuicReceiveControlStream* receive_control_stream() const {
    return receive_control_stream_;
  }

  const SettingsFrame& settings() const { return settings_; }

  // Initializes HTTP/3 unidirectional streams if not yet initialzed.
  virtual void MaybeInitializeHttp3UnidirectionalStreams();

  // QuicConnectionVisitorInterface method.
  void BeforeConnectionCloseSent() override;

  // Called whenever a datagram is dequeued or dropped from datagram_queue().
  virtual void OnDatagramProcessed(absl::optional<MessageStatus> status);

  // Returns which version of the HTTP/3 datagram extension we should advertise
  // in settings and accept remote settings for.
  virtual HttpDatagramSupport LocalHttpDatagramSupport();

  // Sends any data which should be sent at the start of a connection, including
  // the initial SETTINGS frame.  When using 0-RTT, this method is called twice:
  // once when encryption is established, and again when 1-RTT keys are
  // available.
  void SendInitialData();

 private:
  friend class test::QuicSpdySessionPeer;

  class SpdyFramerVisitor;

  // Proxies OnDatagramProcessed() calls to the session.
  class QUIC_EXPORT_PRIVATE DatagramObserver
      : public QuicDatagramQueue::Observer {
   public:
    explicit DatagramObserver(QuicSpdySession* session) : session_(session) {}
    void OnDatagramProcessed(absl::optional<MessageStatus> status) override;

   private:
    QuicSpdySession* session_;  // not owned
  };

  struct QUIC_EXPORT_PRIVATE BufferedWebTransportStream {
    WebTransportSessionId session_id;
    QuicStreamId stream_id;
  };

  // The following methods are called by the SimpleVisitor.

  // Called when a HEADERS frame has been received.
  void OnHeaders(spdy::SpdyStreamId stream_id, bool has_priority,
                 const spdy::SpdyStreamPrecedence& precedence, bool fin);

  // Called when a PRIORITY frame has been received.
  void OnPriority(spdy::SpdyStreamId stream_id,
                  const spdy::SpdyStreamPrecedence& precedence);

  void CloseConnectionOnDuplicateHttp3UnidirectionalStreams(
      absl::string_view type);

  void FillSettingsFrame();

  bool VerifySettingIsZeroOrOne(uint64_t id, uint64_t value);

  std::unique_ptr<QpackEncoder> qpack_encoder_;
  std::unique_ptr<QpackDecoder> qpack_decoder_;

  // Pointer to the header stream in stream_map_.
  QuicHeadersStream* headers_stream_;

  // HTTP/3 control streams. They are owned by QuicSession inside
  // stream map, and can be accessed by those unowned pointers below.
  QuicSendControlStream* send_control_stream_;
  QuicReceiveControlStream* receive_control_stream_;

  // Pointers to HTTP/3 QPACK streams in stream map.
  QpackReceiveStream* qpack_encoder_receive_stream_;
  QpackReceiveStream* qpack_decoder_receive_stream_;
  QpackSendStream* qpack_encoder_send_stream_;
  QpackSendStream* qpack_decoder_send_stream_;

  SettingsFrame settings_;

  // Maximum dynamic table capacity as defined at
  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#maximum-dynamic-table-capacity
  // for the decoding context.  Value will be sent via
  // SETTINGS_QPACK_MAX_TABLE_CAPACITY.
  // |qpack_maximum_dynamic_table_capacity_| also serves as an upper bound for
  // the dynamic table capacity of the encoding context, to limit memory usage
  // if a larger SETTINGS_QPACK_MAX_TABLE_CAPACITY value is received.
  uint64_t qpack_maximum_dynamic_table_capacity_;

  // Maximum number of blocked streams as defined at
  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams
  // for the decoding context.  Value will be sent via
  // SETTINGS_QPACK_BLOCKED_STREAMS.
  uint64_t qpack_maximum_blocked_streams_;

  // The maximum size of a header block that will be accepted from the peer,
  // defined per spec as key + value + overhead per field (uncompressed).
  // Value will be sent via SETTINGS_MAX_HEADER_LIST_SIZE.
  size_t max_inbound_header_list_size_;

  // The maximum size of a header block that can be sent to the peer. This field
  // is informed and set by the peer via SETTINGS frame.
  // TODO(b/148616439): Honor this field when sending headers.
  size_t max_outbound_header_list_size_;

  // Data about the stream whose headers are being processed.
  QuicStreamId stream_id_;
  QuicStreamId promised_stream_id_;
  size_t frame_len_;
  bool fin_;

  spdy::SpdyFramer spdy_framer_;
  http2::Http2DecoderAdapter h2_deframer_;
  std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_;

  // Not owned by the session.
  Http3DebugVisitor* debug_visitor_;

  // Priority values received in PRIORITY_UPDATE frames for streams that are not
  // open yet.
  absl::flat_hash_map<QuicStreamId, QuicStreamPriority>
      buffered_stream_priorities_;

  // An integer used for live check. The indicator is assigned a value in
  // constructor. As long as it is not the assigned value, that would indicate
  // an use-after-free.
  int32_t destruction_indicator_;

  // The identifier in the most recently received GOAWAY frame.  Unset if no
  // GOAWAY frame has been received yet.
  absl::optional<uint64_t> last_received_http3_goaway_id_;
  // The identifier in the most recently sent GOAWAY frame.  Unset if no GOAWAY
  // frame has been sent yet.
  absl::optional<uint64_t> last_sent_http3_goaway_id_;

  // Whether both this endpoint and our peer support HTTP datagrams and which
  // draft is in use for this session.
  HttpDatagramSupport http_datagram_support_ = HttpDatagramSupport::kNone;

  // Whether the peer has indicated WebTransport support.
  bool peer_supports_webtransport_ = false;

  // Whether any settings have been received, either from the peer or from a
  // session ticket.
  bool any_settings_received_ = false;

  // If ShouldBufferRequestsUntilSettings() is true, all streams that are
  // blocked by that are tracked here.
  absl::flat_hash_set<QuicStreamId> streams_waiting_for_settings_;

  // WebTransport streams that do not have a session associated with them.
  // Limited to kMaxUnassociatedWebTransportStreams; when the list is full,
  // oldest streams are evicated first.
  std::list<BufferedWebTransportStream> buffered_streams_;

  // On the server side, if true, advertise and accept extended CONNECT method.
  // On the client side, true if the peer advertised extended CONNECT.
  bool allow_extended_connect_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_
