// Copyright (c) 2012 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.

// This file contains some protocol structures for use with SPDY 3 and HTTP 2
// The SPDY 3 spec can be found at:
// http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3

#ifndef QUICHE_SPDY_CORE_SPDY_PROTOCOL_H_
#define QUICHE_SPDY_CORE_SPDY_PROTOCOL_H_

#include <cstddef>
#include <cstdint>
#include <iosfwd>
#include <limits>
#include <map>
#include <memory>
#include <new>
#include <utility>

#include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h"
#include "net/third_party/quiche/src/spdy/core/spdy_bitmasks.h"
#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
#include "net/third_party/quiche/src/spdy/platform/api/spdy_bug_tracker.h"
#include "net/third_party/quiche/src/spdy/platform/api/spdy_export.h"
#include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"
#include "net/third_party/quiche/src/spdy/platform/api/spdy_ptr_util.h"
#include "net/third_party/quiche/src/spdy/platform/api/spdy_string.h"
#include "net/third_party/quiche/src/spdy/platform/api/spdy_string_piece.h"

namespace spdy {

// A stream ID is a 31-bit entity.
using SpdyStreamId = uint32_t;

// A SETTINGS ID is a 16-bit entity.
using SpdySettingsId = uint16_t;

// Specifies the stream ID used to denote the current session (for
// flow control).
const SpdyStreamId kSessionFlowControlStreamId = 0;

// 0 is not a valid stream ID for any other purpose than flow control.
const SpdyStreamId kInvalidStreamId = 0;

// Max stream id.
const SpdyStreamId kMaxStreamId = 0x7fffffff;

// The maximum possible frame payload size allowed by the spec.
const uint32_t kSpdyMaxFrameSizeLimit = (1 << 24) - 1;

// The initial value for the maximum frame payload size as per the spec. This is
// the maximum control frame size we accept.
const uint32_t kHttp2DefaultFramePayloadLimit = 1 << 14;

// The maximum size of the control frames that we send, including the size of
// the header. This limit is arbitrary. We can enforce it here or at the
// application layer. We chose the framing layer, but this can be changed (or
// removed) if necessary later down the line.
const size_t kHttp2MaxControlFrameSendSize = kHttp2DefaultFramePayloadLimit - 1;

// Number of octets in the frame header.
const size_t kFrameHeaderSize = 9;

// The initial value for the maximum frame payload size as per the spec. This is
// the maximum control frame size we accept.
const uint32_t kHttp2DefaultFrameSizeLimit =
    kHttp2DefaultFramePayloadLimit + kFrameHeaderSize;

// The initial value for the maximum size of the header list, "unlimited" (max
// unsigned 32-bit int) as per the spec.
const uint32_t kSpdyInitialHeaderListSizeLimit = 0xFFFFFFFF;

// Maximum window size for a Spdy stream or session.
const int32_t kSpdyMaximumWindowSize = 0x7FFFFFFF;  // Max signed 32bit int

// Maximum padding size in octets for one DATA or HEADERS or PUSH_PROMISE frame.
const int32_t kPaddingSizePerFrame = 256;

// The HTTP/2 connection preface, which must be the first bytes sent by the
// client upon starting an HTTP/2 connection, and which must be followed by a
// SETTINGS frame.  Note that even though |kHttp2ConnectionHeaderPrefix| is
// defined as a string literal with a null terminator, the actual connection
// preface is only the first |kHttp2ConnectionHeaderPrefixSize| bytes, which
// excludes the null terminator.
SPDY_EXPORT_PRIVATE extern const char* const kHttp2ConnectionHeaderPrefix;
const int kHttp2ConnectionHeaderPrefixSize = 24;

// Wire values for HTTP2 frame types.
enum class SpdyFrameType : uint8_t {
  DATA = 0x00,
  HEADERS = 0x01,
  PRIORITY = 0x02,
  RST_STREAM = 0x03,
  SETTINGS = 0x04,
  PUSH_PROMISE = 0x05,
  PING = 0x06,
  GOAWAY = 0x07,
  WINDOW_UPDATE = 0x08,
  CONTINUATION = 0x09,
  // ALTSVC is a public extension.
  ALTSVC = 0x0a,
  MAX_FRAME_TYPE = ALTSVC,
  // The specific value of EXTENSION is meaningless; it is a placeholder used
  // within SpdyFramer's state machine when handling unknown frames via an
  // extension API.
  // TODO(birenroy): Remove the fake EXTENSION value from the SpdyFrameType
  // enum.
  EXTENSION = 0xff
};

// Flags on data packets.
enum SpdyDataFlags {
  DATA_FLAG_NONE = 0x00,
  DATA_FLAG_FIN = 0x01,
  DATA_FLAG_PADDED = 0x08,
};

// Flags on control packets
enum SpdyControlFlags {
  CONTROL_FLAG_NONE = 0x00,
  CONTROL_FLAG_FIN = 0x01,
};

enum SpdyPingFlags {
  PING_FLAG_ACK = 0x01,
};

// Used by HEADERS, PUSH_PROMISE, and CONTINUATION.
enum SpdyHeadersFlags {
  HEADERS_FLAG_END_HEADERS = 0x04,
  HEADERS_FLAG_PADDED = 0x08,
  HEADERS_FLAG_PRIORITY = 0x20,
};

enum SpdyPushPromiseFlags {
  PUSH_PROMISE_FLAG_END_PUSH_PROMISE = 0x04,
  PUSH_PROMISE_FLAG_PADDED = 0x08,
};

enum Http2SettingsControlFlags {
  SETTINGS_FLAG_ACK = 0x01,
};

// Wire values of HTTP/2 setting identifiers.
enum SpdyKnownSettingsId : SpdySettingsId {
  // HPACK header table maximum size.
  SETTINGS_HEADER_TABLE_SIZE = 0x1,
  SETTINGS_MIN = SETTINGS_HEADER_TABLE_SIZE,
  // Whether or not server push (PUSH_PROMISE) is enabled.
  SETTINGS_ENABLE_PUSH = 0x2,
  // The maximum number of simultaneous live streams in each direction.
  SETTINGS_MAX_CONCURRENT_STREAMS = 0x3,
  // Initial window size in bytes
  SETTINGS_INITIAL_WINDOW_SIZE = 0x4,
  // The size of the largest frame payload that a receiver is willing to accept.
  SETTINGS_MAX_FRAME_SIZE = 0x5,
  // The maximum size of header list that the sender is prepared to accept.
  SETTINGS_MAX_HEADER_LIST_SIZE = 0x6,
  // Enable Websockets over HTTP/2, see
  // https://tools.ietf.org/html/draft-ietf-httpbis-h2-websockets-00.
  SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x8,
  SETTINGS_MAX = SETTINGS_ENABLE_CONNECT_PROTOCOL,
  // Experimental setting used to configure an alternative write scheduler.
  SETTINGS_EXPERIMENT_SCHEDULER = 0xFF45,
};

// This explicit operator is needed, otherwise compiler finds
// overloaded operator to be ambiguous.
SPDY_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
                                             SpdyKnownSettingsId id);

// This operator is needed, because SpdyFrameType is an enum class,
// therefore implicit conversion to underlying integer type is not allowed.
SPDY_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
                                             SpdyFrameType frame_type);

using SettingsMap = std::map<SpdySettingsId, uint32_t>;

// HTTP/2 error codes, RFC 7540 Section 7.
enum SpdyErrorCode : uint32_t {
  ERROR_CODE_NO_ERROR = 0x0,
  ERROR_CODE_PROTOCOL_ERROR = 0x1,
  ERROR_CODE_INTERNAL_ERROR = 0x2,
  ERROR_CODE_FLOW_CONTROL_ERROR = 0x3,
  ERROR_CODE_SETTINGS_TIMEOUT = 0x4,
  ERROR_CODE_STREAM_CLOSED = 0x5,
  ERROR_CODE_FRAME_SIZE_ERROR = 0x6,
  ERROR_CODE_REFUSED_STREAM = 0x7,
  ERROR_CODE_CANCEL = 0x8,
  ERROR_CODE_COMPRESSION_ERROR = 0x9,
  ERROR_CODE_CONNECT_ERROR = 0xa,
  ERROR_CODE_ENHANCE_YOUR_CALM = 0xb,
  ERROR_CODE_INADEQUATE_SECURITY = 0xc,
  ERROR_CODE_HTTP_1_1_REQUIRED = 0xd,
  ERROR_CODE_MAX = ERROR_CODE_HTTP_1_1_REQUIRED
};

// A SPDY priority is a number between 0 and 7 (inclusive).
typedef uint8_t SpdyPriority;

// Lowest and Highest here refer to SPDY priorities as described in
// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority
const SpdyPriority kV3HighestPriority = 0;
const SpdyPriority kV3LowestPriority = 7;

// Returns SPDY 3.x priority value clamped to the valid range of [0, 7].
SPDY_EXPORT_PRIVATE SpdyPriority ClampSpdy3Priority(SpdyPriority priority);

// HTTP/2 stream weights are integers in range [1, 256], as specified in RFC
// 7540 section 5.3.2. Default stream weight is defined in section 5.3.5.
const int kHttp2MinStreamWeight = 1;
const int kHttp2MaxStreamWeight = 256;
const int kHttp2DefaultStreamWeight = 16;

// Returns HTTP/2 weight clamped to the valid range of [1, 256].
SPDY_EXPORT_PRIVATE int ClampHttp2Weight(int weight);

// Maps SPDY 3.x priority value in range [0, 7] to HTTP/2 weight value in range
// [1, 256], where priority 0 (i.e. highest precedence) corresponds to maximum
// weight 256 and priority 7 (lowest precedence) corresponds to minimum weight
// 1.
SPDY_EXPORT_PRIVATE int Spdy3PriorityToHttp2Weight(SpdyPriority priority);

// Maps HTTP/2 weight value in range [1, 256] to SPDY 3.x priority value in
// range [0, 7], where minimum weight 1 corresponds to priority 7 (lowest
// precedence) and maximum weight 256 corresponds to priority 0 (highest
// precedence).
SPDY_EXPORT_PRIVATE SpdyPriority Http2WeightToSpdy3Priority(int weight);

// Reserved ID for root stream of HTTP/2 stream dependency tree, as specified
// in RFC 7540 section 5.3.1.
const unsigned int kHttp2RootStreamId = 0;

typedef uint64_t SpdyPingId;

// Returns true if a given on-the-wire enumeration of a frame type is defined
// in a standardized HTTP/2 specification, false otherwise.
SPDY_EXPORT_PRIVATE bool IsDefinedFrameType(uint8_t frame_type_field);

// Parses a frame type from an on-the-wire enumeration.
// Behavior is undefined for invalid frame type fields; consumers should first
// use IsValidFrameType() to verify validity of frame type fields.
SPDY_EXPORT_PRIVATE SpdyFrameType ParseFrameType(uint8_t frame_type_field);

// Serializes a frame type to the on-the-wire value.
SPDY_EXPORT_PRIVATE uint8_t SerializeFrameType(SpdyFrameType frame_type);

// (HTTP/2) All standard frame types except WINDOW_UPDATE are
// (stream-specific xor connection-level). Returns false iff we know
// the given frame type does not align with the given streamID.
SPDY_EXPORT_PRIVATE bool IsValidHTTP2FrameStreamId(
    SpdyStreamId current_frame_stream_id,
    SpdyFrameType frame_type_field);

// Serialize |frame_type| to string for logging/debugging.
const char* FrameTypeToString(SpdyFrameType frame_type);

// If |wire_setting_id| is the on-the-wire representation of a defined SETTINGS
// parameter, parse it to |*setting_id| and return true.
SPDY_EXPORT_PRIVATE bool ParseSettingsId(SpdySettingsId wire_setting_id,
                                         SpdyKnownSettingsId* setting_id);

// Returns a string representation of the |id| for logging/debugging. Returns
// the |id| prefixed with "SETTINGS_UNKNOWN_" for unknown SETTINGS IDs. To parse
// the |id| into a SpdyKnownSettingsId (if applicable), use ParseSettingsId().
SPDY_EXPORT_PRIVATE SpdyString SettingsIdToString(SpdySettingsId id);

// Parse |wire_error_code| to a SpdyErrorCode.
// Treat unrecognized error codes as INTERNAL_ERROR
// as recommended by the HTTP/2 specification.
SPDY_EXPORT_PRIVATE SpdyErrorCode ParseErrorCode(uint32_t wire_error_code);

// Serialize RST_STREAM or GOAWAY frame error code to string
// for logging/debugging.
const char* ErrorCodeToString(SpdyErrorCode error_code);

// Minimum size of a frame, in octets.
const size_t kFrameMinimumSize = kFrameHeaderSize;

// Minimum frame size for variable size frame types (includes mandatory fields),
// frame size for fixed size frames, in octets.

const size_t kDataFrameMinimumSize = kFrameHeaderSize;
const size_t kHeadersFrameMinimumSize = kFrameHeaderSize;
// PRIORITY frame has stream_dependency (4 octets) and weight (1 octet) fields.
const size_t kPriorityFrameSize = kFrameHeaderSize + 5;
// RST_STREAM frame has error_code (4 octets) field.
const size_t kRstStreamFrameSize = kFrameHeaderSize + 4;
const size_t kSettingsFrameMinimumSize = kFrameHeaderSize;
const size_t kSettingsOneSettingSize =
    sizeof(uint32_t) + sizeof(SpdySettingsId);
// PUSH_PROMISE frame has promised_stream_id (4 octet) field.
const size_t kPushPromiseFrameMinimumSize = kFrameHeaderSize + 4;
// PING frame has opaque_bytes (8 octet) field.
const size_t kPingFrameSize = kFrameHeaderSize + 8;
// GOAWAY frame has last_stream_id (4 octet) and error_code (4 octet) fields.
const size_t kGoawayFrameMinimumSize = kFrameHeaderSize + 8;
// WINDOW_UPDATE frame has window_size_increment (4 octet) field.
const size_t kWindowUpdateFrameSize = kFrameHeaderSize + 4;
const size_t kContinuationFrameMinimumSize = kFrameHeaderSize;
// ALTSVC frame has origin_len (2 octets) field.
const size_t kGetAltSvcFrameMinimumSize = kFrameHeaderSize + 2;

// Maximum possible configurable size of a frame in octets.
const size_t kMaxFrameSizeLimit = kSpdyMaxFrameSizeLimit + kFrameHeaderSize;
// Size of a header block size field.
const size_t kSizeOfSizeField = sizeof(uint32_t);
// Per-header overhead for block size accounting in bytes.
const size_t kPerHeaderOverhead = 32;
// Initial window size for a stream in bytes.
const int32_t kInitialStreamWindowSize = 64 * 1024 - 1;
// Initial window size for a session in bytes.
const int32_t kInitialSessionWindowSize = 64 * 1024 - 1;
// The NPN string for HTTP2, "h2".
extern const char* const kHttp2Npn;
// An estimate size of the HPACK overhead for each header field. 1 bytes for
// indexed literal, 1 bytes for key literal and length encoding, and 2 bytes for
// value literal and length encoding.
const size_t kPerHeaderHpackOverhead = 4;

// Names of pseudo-headers defined for HTTP/2 requests.
SPDY_EXPORT_PRIVATE extern const char* const kHttp2AuthorityHeader;
SPDY_EXPORT_PRIVATE extern const char* const kHttp2MethodHeader;
SPDY_EXPORT_PRIVATE extern const char* const kHttp2PathHeader;
SPDY_EXPORT_PRIVATE extern const char* const kHttp2SchemeHeader;
SPDY_EXPORT_PRIVATE extern const char* const kHttp2ProtocolHeader;

// Name of pseudo-header defined for HTTP/2 responses.
SPDY_EXPORT_PRIVATE extern const char* const kHttp2StatusHeader;

SPDY_EXPORT_PRIVATE size_t GetNumberRequiredContinuationFrames(size_t size);

// Variant type (i.e. tagged union) that is either a SPDY 3.x priority value,
// or else an HTTP/2 stream dependency tuple {parent stream ID, weight,
// exclusive bit}. Templated to allow for use by QUIC code; SPDY and HTTP/2
// code should use the concrete type instantiation SpdyStreamPrecedence.
template <typename StreamIdType>
class StreamPrecedence {
 public:
  // Constructs instance that is a SPDY 3.x priority. Clamps priority value to
  // the valid range [0, 7].
  explicit StreamPrecedence(SpdyPriority priority)
      : is_spdy3_priority_(true),
        spdy3_priority_(ClampSpdy3Priority(priority)) {}

  // Constructs instance that is an HTTP/2 stream weight, parent stream ID, and
  // exclusive bit. Clamps stream weight to the valid range [1, 256].
  StreamPrecedence(StreamIdType parent_id, int weight, bool is_exclusive)
      : is_spdy3_priority_(false),
        http2_stream_dependency_{parent_id, ClampHttp2Weight(weight),
                                 is_exclusive} {}

  // Intentionally copyable, to support pass by value.
  StreamPrecedence(const StreamPrecedence& other) = default;
  StreamPrecedence& operator=(const StreamPrecedence& other) = default;

  // Returns true if this instance is a SPDY 3.x priority, or false if this
  // instance is an HTTP/2 stream dependency.
  bool is_spdy3_priority() const { return is_spdy3_priority_; }

  // Returns SPDY 3.x priority value. If |is_spdy3_priority()| is true, this is
  // the value provided at construction, clamped to the legal priority
  // range. Otherwise, it is the HTTP/2 stream weight mapped to a SPDY 3.x
  // priority value, where minimum weight 1 corresponds to priority 7 (lowest
  // precedence) and maximum weight 256 corresponds to priority 0 (highest
  // precedence).
  SpdyPriority spdy3_priority() const {
    return is_spdy3_priority_
               ? spdy3_priority_
               : Http2WeightToSpdy3Priority(http2_stream_dependency_.weight);
  }

  // Returns HTTP/2 parent stream ID. If |is_spdy3_priority()| is false, this is
  // the value provided at construction, otherwise it is |kHttp2RootStreamId|.
  StreamIdType parent_id() const {
    return is_spdy3_priority_ ? kHttp2RootStreamId
                              : http2_stream_dependency_.parent_id;
  }

  // Returns HTTP/2 stream weight. If |is_spdy3_priority()| is false, this is
  // the value provided at construction, clamped to the legal weight
  // range. Otherwise, it is the SPDY 3.x priority value mapped to an HTTP/2
  // stream weight, where priority 0 (i.e. highest precedence) corresponds to
  // maximum weight 256 and priority 7 (lowest precedence) corresponds to
  // minimum weight 1.
  int weight() const {
    return is_spdy3_priority_ ? Spdy3PriorityToHttp2Weight(spdy3_priority_)
                              : http2_stream_dependency_.weight;
  }

  // Returns HTTP/2 parent stream exclusivity. If |is_spdy3_priority()| is
  // false, this is the value provided at construction, otherwise it is false.
  bool is_exclusive() const {
    return !is_spdy3_priority_ && http2_stream_dependency_.is_exclusive;
  }

  // Facilitates test assertions.
  bool operator==(const StreamPrecedence& other) const {
    if (is_spdy3_priority()) {
      return other.is_spdy3_priority() &&
             (spdy3_priority() == other.spdy3_priority());
    } else {
      return !other.is_spdy3_priority() && (parent_id() == other.parent_id()) &&
             (weight() == other.weight()) &&
             (is_exclusive() == other.is_exclusive());
    }
  }

  bool operator!=(const StreamPrecedence& other) const {
    return !(*this == other);
  }

 private:
  struct Http2StreamDependency {
    StreamIdType parent_id;
    int weight;
    bool is_exclusive;
  };

  bool is_spdy3_priority_;
  union {
    SpdyPriority spdy3_priority_;
    Http2StreamDependency http2_stream_dependency_;
  };
};

typedef StreamPrecedence<SpdyStreamId> SpdyStreamPrecedence;

class SpdyFrameVisitor;

// Intermediate representation for HTTP2 frames.
class SPDY_EXPORT_PRIVATE SpdyFrameIR {
 public:
  virtual ~SpdyFrameIR() {}

  virtual void Visit(SpdyFrameVisitor* visitor) const = 0;
  virtual SpdyFrameType frame_type() const = 0;
  SpdyStreamId stream_id() const { return stream_id_; }
  virtual bool fin() const;
  // Returns an estimate of the size of the serialized frame, without applying
  // compression. May not be exact.
  virtual size_t size() const = 0;

  // Returns the number of bytes of flow control window that would be consumed
  // by this frame if written to the wire.
  virtual int flow_control_window_consumed() const;

 protected:
  SpdyFrameIR() : stream_id_(0) {}
  explicit SpdyFrameIR(SpdyStreamId stream_id) : stream_id_(stream_id) {}
  SpdyFrameIR(const SpdyFrameIR&) = delete;
  SpdyFrameIR& operator=(const SpdyFrameIR&) = delete;

 private:
  SpdyStreamId stream_id_;
};

// Abstract class intended to be inherited by IRs that have the option of a FIN
// flag.
class SPDY_EXPORT_PRIVATE SpdyFrameWithFinIR : public SpdyFrameIR {
 public:
  ~SpdyFrameWithFinIR() override {}
  bool fin() const override;
  void set_fin(bool fin) { fin_ = fin; }

 protected:
  explicit SpdyFrameWithFinIR(SpdyStreamId stream_id)
      : SpdyFrameIR(stream_id), fin_(false) {}
  SpdyFrameWithFinIR(const SpdyFrameWithFinIR&) = delete;
  SpdyFrameWithFinIR& operator=(const SpdyFrameWithFinIR&) = delete;

 private:
  bool fin_;
};

// Abstract class intended to be inherited by IRs that contain a header
// block. Implies SpdyFrameWithFinIR.
class SPDY_EXPORT_PRIVATE SpdyFrameWithHeaderBlockIR
    : public SpdyFrameWithFinIR {
 public:
  ~SpdyFrameWithHeaderBlockIR() override;

  const SpdyHeaderBlock& header_block() const { return header_block_; }
  void set_header_block(SpdyHeaderBlock header_block) {
    // Deep copy.
    header_block_ = std::move(header_block);
  }
  void SetHeader(SpdyStringPiece name, SpdyStringPiece value) {
    header_block_[name] = value;
  }

 protected:
  SpdyFrameWithHeaderBlockIR(SpdyStreamId stream_id,
                             SpdyHeaderBlock header_block);
  SpdyFrameWithHeaderBlockIR(const SpdyFrameWithHeaderBlockIR&) = delete;
  SpdyFrameWithHeaderBlockIR& operator=(const SpdyFrameWithHeaderBlockIR&) =
      delete;

 private:
  SpdyHeaderBlock header_block_;
};

class SPDY_EXPORT_PRIVATE SpdyDataIR : public SpdyFrameWithFinIR {
 public:
  // Performs a deep copy on data.
  SpdyDataIR(SpdyStreamId stream_id, SpdyStringPiece data);

  // Performs a deep copy on data.
  SpdyDataIR(SpdyStreamId stream_id, const char* data);

  // Moves data into data_store_. Makes a copy if passed a non-movable string.
  SpdyDataIR(SpdyStreamId stream_id, SpdyString data);

  // Use in conjunction with SetDataShallow() for shallow-copy on data.
  explicit SpdyDataIR(SpdyStreamId stream_id);
  SpdyDataIR(const SpdyDataIR&) = delete;
  SpdyDataIR& operator=(const SpdyDataIR&) = delete;

  ~SpdyDataIR() override;

  const char* data() const { return data_; }
  size_t data_len() const { return data_len_; }

  bool padded() const { return padded_; }

  int padding_payload_len() const { return padding_payload_len_; }

  void set_padding_len(int padding_len) {
    DCHECK_GT(padding_len, 0);
    DCHECK_LE(padding_len, kPaddingSizePerFrame);
    padded_ = true;
    // The pad field takes one octet on the wire.
    padding_payload_len_ = padding_len - 1;
  }

  // Deep-copy of data (keep private copy).
  void SetDataDeep(SpdyStringPiece data) {
    data_store_ = SpdyMakeUnique<SpdyString>(data.data(), data.size());
    data_ = data_store_->data();
    data_len_ = data.size();
  }

  // Shallow-copy of data (do not keep private copy).
  void SetDataShallow(SpdyStringPiece data) {
    data_store_.reset();
    data_ = data.data();
    data_len_ = data.size();
  }

  // Use this method if we don't have a contiguous buffer and only
  // need a length.
  void SetDataShallow(size_t len) {
    data_store_.reset();
    data_ = nullptr;
    data_len_ = len;
  }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  int flow_control_window_consumed() const override;

  size_t size() const override;

 private:
  // Used to store data that this SpdyDataIR should own.
  std::unique_ptr<SpdyString> data_store_;
  const char* data_;
  size_t data_len_;

  bool padded_;
  // padding_payload_len_ = desired padding length - len(padding length field).
  int padding_payload_len_;
};

class SPDY_EXPORT_PRIVATE SpdyRstStreamIR : public SpdyFrameIR {
 public:
  SpdyRstStreamIR(SpdyStreamId stream_id, SpdyErrorCode error_code);
  SpdyRstStreamIR(const SpdyRstStreamIR&) = delete;
  SpdyRstStreamIR& operator=(const SpdyRstStreamIR&) = delete;

  ~SpdyRstStreamIR() override;

  SpdyErrorCode error_code() const { return error_code_; }
  void set_error_code(SpdyErrorCode error_code) { error_code_ = error_code; }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  size_t size() const override;

 private:
  SpdyErrorCode error_code_;
};

class SPDY_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
 public:
  SpdySettingsIR();
  SpdySettingsIR(const SpdySettingsIR&) = delete;
  SpdySettingsIR& operator=(const SpdySettingsIR&) = delete;
  ~SpdySettingsIR() override;

  // Overwrites as appropriate.
  const SettingsMap& values() const { return values_; }
  void AddSetting(SpdySettingsId id, int32_t value) { values_[id] = value; }

  bool is_ack() const { return is_ack_; }
  void set_is_ack(bool is_ack) { is_ack_ = is_ack; }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  size_t size() const override;

 private:
  SettingsMap values_;
  bool is_ack_;
};

class SPDY_EXPORT_PRIVATE SpdyPingIR : public SpdyFrameIR {
 public:
  explicit SpdyPingIR(SpdyPingId id) : id_(id), is_ack_(false) {}
  SpdyPingIR(const SpdyPingIR&) = delete;
  SpdyPingIR& operator=(const SpdyPingIR&) = delete;
  SpdyPingId id() const { return id_; }

  bool is_ack() const { return is_ack_; }
  void set_is_ack(bool is_ack) { is_ack_ = is_ack; }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  size_t size() const override;

 private:
  SpdyPingId id_;
  bool is_ack_;
};

class SPDY_EXPORT_PRIVATE SpdyGoAwayIR : public SpdyFrameIR {
 public:
  // References description, doesn't copy it, so description must outlast
  // this SpdyGoAwayIR.
  SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
               SpdyErrorCode error_code,
               SpdyStringPiece description);

  // References description, doesn't copy it, so description must outlast
  // this SpdyGoAwayIR.
  SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
               SpdyErrorCode error_code,
               const char* description);

  // Moves description into description_store_, so caller doesn't need to
  // keep description live after constructing this SpdyGoAwayIR.
  SpdyGoAwayIR(SpdyStreamId last_good_stream_id,
               SpdyErrorCode error_code,
               SpdyString description);
  SpdyGoAwayIR(const SpdyGoAwayIR&) = delete;
  SpdyGoAwayIR& operator=(const SpdyGoAwayIR&) = delete;

  ~SpdyGoAwayIR() override;

  SpdyStreamId last_good_stream_id() const { return last_good_stream_id_; }
  void set_last_good_stream_id(SpdyStreamId last_good_stream_id) {
    DCHECK_EQ(0u, last_good_stream_id & ~kStreamIdMask);
    last_good_stream_id_ = last_good_stream_id;
  }
  SpdyErrorCode error_code() const { return error_code_; }
  void set_error_code(SpdyErrorCode error_code) {
    // TODO(hkhalil): Check valid ranges of error_code?
    error_code_ = error_code;
  }

  const SpdyStringPiece& description() const { return description_; }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  size_t size() const override;

 private:
  SpdyStreamId last_good_stream_id_;
  SpdyErrorCode error_code_;
  const SpdyString description_store_;
  const SpdyStringPiece description_;
};

class SPDY_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithHeaderBlockIR {
 public:
  explicit SpdyHeadersIR(SpdyStreamId stream_id)
      : SpdyHeadersIR(stream_id, SpdyHeaderBlock()) {}
  SpdyHeadersIR(SpdyStreamId stream_id, SpdyHeaderBlock header_block)
      : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)) {}
  SpdyHeadersIR(const SpdyHeadersIR&) = delete;
  SpdyHeadersIR& operator=(const SpdyHeadersIR&) = delete;

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  size_t size() const override;

  bool has_priority() const { return has_priority_; }
  void set_has_priority(bool has_priority) { has_priority_ = has_priority; }
  int weight() const { return weight_; }
  void set_weight(int weight) { weight_ = weight; }
  SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
  void set_parent_stream_id(SpdyStreamId id) { parent_stream_id_ = id; }
  bool exclusive() const { return exclusive_; }
  void set_exclusive(bool exclusive) { exclusive_ = exclusive; }
  bool padded() const { return padded_; }
  int padding_payload_len() const { return padding_payload_len_; }
  void set_padding_len(int padding_len) {
    DCHECK_GT(padding_len, 0);
    DCHECK_LE(padding_len, kPaddingSizePerFrame);
    padded_ = true;
    // The pad field takes one octet on the wire.
    padding_payload_len_ = padding_len - 1;
  }

 private:
  bool has_priority_ = false;
  int weight_ = kHttp2DefaultStreamWeight;
  SpdyStreamId parent_stream_id_ = 0;
  bool exclusive_ = false;
  bool padded_ = false;
  int padding_payload_len_ = 0;
};

class SPDY_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameIR {
 public:
  SpdyWindowUpdateIR(SpdyStreamId stream_id, int32_t delta)
      : SpdyFrameIR(stream_id) {
    set_delta(delta);
  }
  SpdyWindowUpdateIR(const SpdyWindowUpdateIR&) = delete;
  SpdyWindowUpdateIR& operator=(const SpdyWindowUpdateIR&) = delete;

  int32_t delta() const { return delta_; }
  void set_delta(int32_t delta) {
    DCHECK_LE(0, delta);
    DCHECK_LE(delta, kSpdyMaximumWindowSize);
    delta_ = delta;
  }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  size_t size() const override;

 private:
  int32_t delta_;
};

class SPDY_EXPORT_PRIVATE SpdyPushPromiseIR
    : public SpdyFrameWithHeaderBlockIR {
 public:
  SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id)
      : SpdyPushPromiseIR(stream_id, promised_stream_id, SpdyHeaderBlock()) {}
  SpdyPushPromiseIR(SpdyStreamId stream_id,
                    SpdyStreamId promised_stream_id,
                    SpdyHeaderBlock header_block)
      : SpdyFrameWithHeaderBlockIR(stream_id, std::move(header_block)),
        promised_stream_id_(promised_stream_id),
        padded_(false),
        padding_payload_len_(0) {}
  SpdyPushPromiseIR(const SpdyPushPromiseIR&) = delete;
  SpdyPushPromiseIR& operator=(const SpdyPushPromiseIR&) = delete;
  SpdyStreamId promised_stream_id() const { return promised_stream_id_; }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  size_t size() const override;

  bool padded() const { return padded_; }
  int padding_payload_len() const { return padding_payload_len_; }
  void set_padding_len(int padding_len) {
    DCHECK_GT(padding_len, 0);
    DCHECK_LE(padding_len, kPaddingSizePerFrame);
    padded_ = true;
    // The pad field takes one octet on the wire.
    padding_payload_len_ = padding_len - 1;
  }

 private:
  SpdyStreamId promised_stream_id_;

  bool padded_;
  int padding_payload_len_;
};

class SPDY_EXPORT_PRIVATE SpdyContinuationIR : public SpdyFrameIR {
 public:
  explicit SpdyContinuationIR(SpdyStreamId stream_id);
  SpdyContinuationIR(const SpdyContinuationIR&) = delete;
  SpdyContinuationIR& operator=(const SpdyContinuationIR&) = delete;
  ~SpdyContinuationIR() override;

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  bool end_headers() const { return end_headers_; }
  void set_end_headers(bool end_headers) { end_headers_ = end_headers; }
  const SpdyString& encoding() const { return *encoding_; }
  void take_encoding(std::unique_ptr<SpdyString> encoding) {
    encoding_ = std::move(encoding);
  }
  size_t size() const override;

 private:
  std::unique_ptr<SpdyString> encoding_;
  bool end_headers_;
};

class SPDY_EXPORT_PRIVATE SpdyAltSvcIR : public SpdyFrameIR {
 public:
  explicit SpdyAltSvcIR(SpdyStreamId stream_id);
  SpdyAltSvcIR(const SpdyAltSvcIR&) = delete;
  SpdyAltSvcIR& operator=(const SpdyAltSvcIR&) = delete;
  ~SpdyAltSvcIR() override;

  SpdyString origin() const { return origin_; }
  const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector() const {
    return altsvc_vector_;
  }

  void set_origin(SpdyString origin) { origin_ = std::move(origin); }
  void add_altsvc(const SpdyAltSvcWireFormat::AlternativeService& altsvc) {
    altsvc_vector_.push_back(altsvc);
  }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  size_t size() const override;

 private:
  SpdyString origin_;
  SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector_;
};

class SPDY_EXPORT_PRIVATE SpdyPriorityIR : public SpdyFrameIR {
 public:
  SpdyPriorityIR(SpdyStreamId stream_id,
                 SpdyStreamId parent_stream_id,
                 int weight,
                 bool exclusive)
      : SpdyFrameIR(stream_id),
        parent_stream_id_(parent_stream_id),
        weight_(weight),
        exclusive_(exclusive) {}
  SpdyPriorityIR(const SpdyPriorityIR&) = delete;
  SpdyPriorityIR& operator=(const SpdyPriorityIR&) = delete;
  SpdyStreamId parent_stream_id() const { return parent_stream_id_; }
  int weight() const { return weight_; }
  bool exclusive() const { return exclusive_; }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  size_t size() const override;

 private:
  SpdyStreamId parent_stream_id_;
  int weight_;
  bool exclusive_;
};

// Represents a frame of unrecognized type.
class SPDY_EXPORT_PRIVATE SpdyUnknownIR : public SpdyFrameIR {
 public:
  SpdyUnknownIR(SpdyStreamId stream_id,
                uint8_t type,
                uint8_t flags,
                SpdyString payload)
      : SpdyFrameIR(stream_id),
        type_(type),
        flags_(flags),
        length_(payload.size()),
        payload_(std::move(payload)) {}
  SpdyUnknownIR(const SpdyUnknownIR&) = delete;
  SpdyUnknownIR& operator=(const SpdyUnknownIR&) = delete;
  uint8_t type() const { return type_; }
  uint8_t flags() const { return flags_; }
  size_t length() const { return length_; }
  const SpdyString& payload() const { return payload_; }

  void Visit(SpdyFrameVisitor* visitor) const override;

  SpdyFrameType frame_type() const override;

  int flow_control_window_consumed() const override;

  size_t size() const override;

 protected:
  // Allows subclasses to overwrite the default payload length.
  void set_length(size_t length) { length_ = length; }

 private:
  uint8_t type_;
  uint8_t flags_;
  size_t length_;
  const SpdyString payload_;
};

class SPDY_EXPORT_PRIVATE SpdySerializedFrame {
 public:
  SpdySerializedFrame()
      : frame_(const_cast<char*>("")), size_(0), owns_buffer_(false) {}

  // Create a valid SpdySerializedFrame using a pre-created buffer.
  // If |owns_buffer| is true, this class takes ownership of the buffer and will
  // delete it on cleanup.  The buffer must have been created using new char[].
  // If |owns_buffer| is false, the caller retains ownership of the buffer and
  // is responsible for making sure the buffer outlives this frame.  In other
  // words, this class does NOT create a copy of the buffer.
  SpdySerializedFrame(char* data, size_t size, bool owns_buffer)
      : frame_(data), size_(size), owns_buffer_(owns_buffer) {}

  SpdySerializedFrame(SpdySerializedFrame&& other)
      : frame_(other.frame_),
        size_(other.size_),
        owns_buffer_(other.owns_buffer_) {
    // |other| is no longer responsible for the buffer.
    other.owns_buffer_ = false;
  }
  SpdySerializedFrame(const SpdySerializedFrame&) = delete;
  SpdySerializedFrame& operator=(const SpdySerializedFrame&) = delete;

  SpdySerializedFrame& operator=(SpdySerializedFrame&& other) {
    // Free buffer if necessary.
    if (owns_buffer_) {
      delete[] frame_;
    }
    // Take over |other|.
    frame_ = other.frame_;
    size_ = other.size_;
    owns_buffer_ = other.owns_buffer_;
    // |other| is no longer responsible for the buffer.
    other.owns_buffer_ = false;
    return *this;
  }

  ~SpdySerializedFrame() {
    if (owns_buffer_) {
      delete[] frame_;
    }
  }

  // Provides access to the frame bytes, which is a buffer containing the frame
  // packed as expected for sending over the wire.
  char* data() const { return frame_; }

  // Returns the actual size of the underlying buffer.
  size_t size() const { return size_; }

  // Returns a buffer containing the contents of the frame, of which the caller
  // takes ownership, and clears this SpdySerializedFrame.
  char* ReleaseBuffer() {
    char* buffer;
    if (owns_buffer_) {
      // If the buffer is owned, relinquish ownership to the caller.
      buffer = frame_;
      owns_buffer_ = false;
    } else {
      // Otherwise, we need to make a copy to give to the caller.
      buffer = new char[size_];
      memcpy(buffer, frame_, size_);
    }
    *this = SpdySerializedFrame();
    return buffer;
  }

  // Returns the estimate of dynamically allocated memory in bytes.
  size_t EstimateMemoryUsage() const { return owns_buffer_ ? size_ : 0; }

 protected:
  char* frame_;

 private:
  size_t size_;
  bool owns_buffer_;
};

// This interface is for classes that want to process SpdyFrameIRs without
// having to know what type they are.  An instance of this interface can be
// passed to a SpdyFrameIR's Visit method, and the appropriate type-specific
// method of this class will be called.
class SPDY_EXPORT_PRIVATE SpdyFrameVisitor {
 public:
  virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) = 0;
  virtual void VisitSettings(const SpdySettingsIR& settings) = 0;
  virtual void VisitPing(const SpdyPingIR& ping) = 0;
  virtual void VisitGoAway(const SpdyGoAwayIR& goaway) = 0;
  virtual void VisitHeaders(const SpdyHeadersIR& headers) = 0;
  virtual void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) = 0;
  virtual void VisitPushPromise(const SpdyPushPromiseIR& push_promise) = 0;
  virtual void VisitContinuation(const SpdyContinuationIR& continuation) = 0;
  virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) = 0;
  virtual void VisitPriority(const SpdyPriorityIR& priority) = 0;
  virtual void VisitData(const SpdyDataIR& data) = 0;
  virtual void VisitUnknown(const SpdyUnknownIR& /*unknown*/) {
    // TODO(birenroy): make abstract.
  }

 protected:
  SpdyFrameVisitor() {}
  SpdyFrameVisitor(const SpdyFrameVisitor&) = delete;
  SpdyFrameVisitor& operator=(const SpdyFrameVisitor&) = delete;
  virtual ~SpdyFrameVisitor() {}
};

// Optionally, and in addition to SpdyFramerVisitorInterface, a class supporting
// SpdyFramerDebugVisitorInterface may be used in conjunction with SpdyFramer in
// order to extract debug/internal information about the SpdyFramer as it
// operates.
//
// Most HTTP2 implementations need not bother with this interface at all.
class SPDY_EXPORT_PRIVATE SpdyFramerDebugVisitorInterface {
 public:
  virtual ~SpdyFramerDebugVisitorInterface() {}

  // Called after compressing a frame with a payload of
  // a list of name-value pairs.
  // |payload_len| is the uncompressed payload size.
  // |frame_len| is the compressed frame size.
  virtual void OnSendCompressedFrame(SpdyStreamId /*stream_id*/,
                                     SpdyFrameType /*type*/,
                                     size_t /*payload_len*/,
                                     size_t /*frame_len*/) {}

  // Called when a frame containing a compressed payload of
  // name-value pairs is received.
  // |frame_len| is the compressed frame size.
  virtual void OnReceiveCompressedFrame(SpdyStreamId /*stream_id*/,
                                        SpdyFrameType /*type*/,
                                        size_t /*frame_len*/) {}
};

// Calculates the number of bytes required to serialize a SpdyHeadersIR, not
// including the bytes to be used for the encoded header set.
size_t GetHeaderFrameSizeSansBlock(const SpdyHeadersIR& header_ir);

// Calculates the number of bytes required to serialize a SpdyPushPromiseIR,
// not including the bytes to be used for the encoded header set.
size_t GetPushPromiseFrameSizeSansBlock(
    const SpdyPushPromiseIR& push_promise_ir);

}  // namespace spdy

#endif  // QUICHE_SPDY_CORE_SPDY_PROTOCOL_H_
