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

#ifndef NET_SPDY_SPDY_STREAM_H_
#define NET_SPDY_SPDY_STREAM_H_

#include <memory>
#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "net/base/io_buffer.h"
#include "net/base/net_export.h"
#include "net/base/request_priority.h"
#include "net/log/net_log_source.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/next_proto.h"
#include "net/socket/ssl_client_socket.h"
#include "net/spdy/spdy_buffer.h"
#include "net/ssl/ssl_client_cert_type.h"
#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "starboard/types.h"
#include "url/gurl.h"

namespace net {

class IPEndPoint;
struct LoadTimingInfo;
class SSLInfo;
class SpdySession;

enum SpdyStreamType {
  // The most general type of stream; there are no restrictions on
  // when data can be sent and received.
  SPDY_BIDIRECTIONAL_STREAM,
  // A stream where the client sends a request with possibly a body,
  // and the server then sends a response with a body.
  SPDY_REQUEST_RESPONSE_STREAM,
  // A server-initiated stream where the server just sends a response
  // with a body and the client does not send anything.
  SPDY_PUSH_STREAM
};

// Passed to some SpdyStream functions to indicate whether there's
// more data to send.
enum SpdySendStatus {
  MORE_DATA_TO_SEND,
  NO_MORE_DATA_TO_SEND
};

// SpdyStream is owned by SpdySession and is used to represent each stream known
// on the SpdySession.  This class provides interfaces for SpdySession to use.
// Streams can be created either by the client or by the server.  When they
// are initiated by the client, both the SpdySession and client object (such as
// a SpdyNetworkTransaction) will maintain a reference to the stream.  When
// initiated by the server, only the SpdySession will maintain any reference,
// until such a time as a client object requests a stream for the path.
class NET_EXPORT_PRIVATE SpdyStream {
 public:
  // Delegate handles protocol specific behavior of spdy stream.
  class NET_EXPORT_PRIVATE Delegate {
   public:
    Delegate() {}

    // Called when the request headers have been sent. Never called
    // for push streams. Must not cause the stream to be closed.
    virtual void OnHeadersSent() = 0;

    // OnHeadersReceived(), OnDataReceived(), OnTrailers(), and OnClose()
    // are guaranteed to be called in the following order:
    //   - OnHeadersReceived() exactly once;
    //   - OnDataReceived() zero or more times;
    //   - OnTrailers() zero or one times;
    //   - OnClose() exactly once.

    // Called when response headers have been received.  In case of a pushed
    // stream, the pushed request headers are also passed.
    virtual void OnHeadersReceived(
        const spdy::SpdyHeaderBlock& response_headers,
        const spdy::SpdyHeaderBlock* pushed_request_headers) = 0;

    // Called when data is received.  |buffer| may be NULL, which signals EOF.
    // May cause the stream to be closed.
    virtual void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) = 0;

    // Called when data is sent.  Must not cause the stream to be closed.
    virtual void OnDataSent() = 0;

    // Called when trailers are received.
    virtual void OnTrailers(const spdy::SpdyHeaderBlock& trailers) = 0;

    // Called when SpdyStream is closed. No other delegate functions
    // will be called after this is called, and the delegate must not
    // access the stream after this is called. Must not cause the
    // stream to be (re-)closed.
    //
    // TODO(akalin): Allow this function to re-close the stream and
    // handle it gracefully.
    virtual void OnClose(int status) = 0;

    virtual NetLogSource source_dependency() const = 0;

   protected:
    virtual ~Delegate() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(Delegate);
  };

  // SpdyStream constructor
  SpdyStream(SpdyStreamType type,
             const base::WeakPtr<SpdySession>& session,
             const GURL& url,
             RequestPriority priority,
             int32_t initial_send_window_size,
             int32_t max_recv_window_size,
             const NetLogWithSource& net_log,
             const NetworkTrafficAnnotationTag& traffic_annotation);

  ~SpdyStream();

  // Set the delegate, which must not be NULL. Must not be called more
  // than once. For push streams, calling this may cause buffered data
  // to be sent to the delegate (from a posted task).
  void SetDelegate(Delegate* delegate);

  // Detach the delegate from the stream, which must not yet be
  // closed, and cancel it.
  void DetachDelegate();

  // The time at which the first bytes of the response were received
  // from the server, or null if the response hasn't been received
  // yet.
  base::Time response_time() const { return response_time_; }

  SpdyStreamType type() const { return type_; }

  spdy::SpdyStreamId stream_id() const { return stream_id_; }
  void set_stream_id(spdy::SpdyStreamId stream_id) { stream_id_ = stream_id; }

  const GURL& url() const { return url_; }

  RequestPriority priority() const { return priority_; }

  // Update priority and send PRIORITY frames on the wire if necessary.
  void SetPriority(RequestPriority priority);

  int32_t send_window_size() const { return send_window_size_; }

  int32_t recv_window_size() const { return recv_window_size_; }

  bool send_stalled_by_flow_control() const {
    return send_stalled_by_flow_control_;
  }

  void set_send_stalled_by_flow_control(bool stalled) {
    send_stalled_by_flow_control_ = stalled;
  }

  // Called by the session to adjust this stream's send window size by
  // |delta_window_size|, which is the difference between the
  // spdy::SETTINGS_INITIAL_WINDOW_SIZE in the most recent SETTINGS frame
  // and the previous initial send window size, possibly unstalling
  // this stream. Although |delta_window_size| may cause this stream's
  // send window size to go negative, it must not cause it to wrap
  // around in either direction. Does nothing if the stream is already
  // closed.
  // Returns true if successful.  Returns false if |send_window_size_|
  // would exceed 2^31-1 after the update, see RFC7540 Section 6.9.2.
  // Note that |send_window_size_| should not possibly underflow.
  bool AdjustSendWindowSize(int32_t delta_window_size) WARN_UNUSED_RESULT;

  // Called when bytes are consumed from a SpdyBuffer for a DATA frame
  // that is to be written or is being written. Increases the send
  // window size accordingly if some or all of the SpdyBuffer is being
  // discarded.
  //
  // If stream flow control is turned off, this must not be called.
  void OnWriteBufferConsumed(size_t frame_payload_size,
                             size_t consume_size,
                             SpdyBuffer::ConsumeSource consume_source);

  // Called by the session to increase this stream's send window size
  // by |delta_window_size| (which must be at least 1) from a received
  // WINDOW_UPDATE frame or from a dropped DATA frame that was
  // intended to be sent, possibly unstalling this stream. If
  // |delta_window_size| would cause this stream's send window size to
  // overflow, calls into the session to reset this stream. Does
  // nothing if the stream is already closed.
  //
  // If stream flow control is turned off, this must not be called.
  void IncreaseSendWindowSize(int32_t delta_window_size);

  // If stream flow control is turned on, called by the session to
  // decrease this stream's send window size by |delta_window_size|,
  // which must be at least 0 and at most kMaxSpdyFrameChunkSize.
  // |delta_window_size| must not cause this stream's send window size
  // to go negative. Does nothing if the stream is already closed.
  //
  // If stream flow control is turned off, this must not be called.
  void DecreaseSendWindowSize(int32_t delta_window_size);

  // Called when bytes are consumed by the delegate from a SpdyBuffer
  // containing received data. Increases the receive window size
  // accordingly.
  //
  // If stream flow control is turned off, this must not be called.
  void OnReadBufferConsumed(size_t consume_size,
                            SpdyBuffer::ConsumeSource consume_source);

  // Called by OnReadBufferConsume to increase this stream's receive
  // window size by |delta_window_size|, which must be at least 1 and
  // must not cause this stream's receive window size to overflow,
  // possibly also sending a WINDOW_UPDATE frame. Does nothing if the
  // stream is not active.
  //
  // If stream flow control is turned off, this must not be called.
  void IncreaseRecvWindowSize(int32_t delta_window_size);

  // Called by OnDataReceived or OnPaddingConsumed (which are in turn called by
  // the session) to decrease this stream's receive window size by
  // |delta_window_size|, which must be at least 1.  May close the stream on
  // flow control error.
  //
  // If stream flow control is turned off or the stream is not active,
  // this must not be called.
  void DecreaseRecvWindowSize(int32_t delta_window_size);

  int GetPeerAddress(IPEndPoint* address) const;
  int GetLocalAddress(IPEndPoint* address) const;

  // Returns true if the underlying transport socket ever had any reads or
  // writes.
  bool WasEverUsed() const;

  const NetLogWithSource& net_log() const { return net_log_; }

  base::Time GetRequestTime() const;
  void SetRequestTime(base::Time t);

  // Called by SpdySession when headers are received for this stream.  May close
  // the stream.
  void OnHeadersReceived(const spdy::SpdyHeaderBlock& response_headers,
                         base::Time response_time,
                         base::TimeTicks recv_first_byte_time);

  // Called by the SpdySession when a frame carrying request headers opening a
  // push stream is received. Stream transits to STATE_RESERVED_REMOTE state.
  void OnPushPromiseHeadersReceived(spdy::SpdyHeaderBlock headers, GURL url);

  // Called by the SpdySession when response data has been received
  // for this stream.  This callback may be called multiple times as
  // data arrives from the network, and will never be called prior to
  // OnResponseHeadersReceived.
  //
  // |buffer| contains the data received, or NULL if the stream is
  //          being closed.  The stream must copy any data from this
  //          buffer before returning from this callback.
  //
  // |length| is the number of bytes received (at most 2^24 - 1) or 0 if
  //          the stream is being closed.
  void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer);

  // Called by the SpdySession when padding is consumed to allow for the stream
  // receiving window to be updated.
  void OnPaddingConsumed(size_t len);

  // Called by the SpdySession when a frame has been successfully and completely
  // written. |frame_size| is the total size of the logical frame in bytes,
  // including framing overhead.  For fragmented headers, this is the total size
  // of the HEADERS or PUSH_PROMISE frame and subsequent CONTINUATION frames.
  void OnFrameWriteComplete(spdy::SpdyFrameType frame_type, size_t frame_size);

  // HEADERS-specific write handler invoked by OnFrameWriteComplete().
  int OnHeadersSent();

  // DATA-specific write handler invoked by OnFrameWriteComplete().
  // If more data is already available to be written, the next write is
  // queued and ERR_IO_PENDING is returned. Returns OK otherwise.
  int OnDataSent(size_t frame_size);

  // Called by the SpdySession when the request is finished.  This callback
  // will always be called at the end of the request and signals to the
  // stream that the stream has no more network events.  No further callbacks
  // to the stream will be made after this call.  Must be called before
  // SpdyStream is destroyed.
  // |status| is an error code or OK.
  void OnClose(int status);

  // Called by the SpdySession to log stream related errors.
  void LogStreamError(int error, const std::string& description);

  // If this stream is active, reset it, and close it otherwise. In
  // either case the stream is deleted.
  void Cancel(int error);

  // Close this stream without sending a RST_STREAM and delete
  // it.
  void Close();

  // Must be used only by |session_|.
  base::WeakPtr<SpdyStream> GetWeakPtr();

  // Interface for the delegate to use.

  // Only one send can be in flight at a time, except for push
  // streams, which must not send anything.

  // Sends the request headers. The delegate is called back via OnHeadersSent()
  // when the request headers have completed sending. |send_status| must be
  // MORE_DATA_TO_SEND for bidirectional streams; for request/response streams,
  // it must be MORE_DATA_TO_SEND if the request has data to upload, or
  // NO_MORE_DATA_TO_SEND if not.
  int SendRequestHeaders(spdy::SpdyHeaderBlock request_headers,
                         SpdySendStatus send_status);

  // Sends a DATA frame. The delegate will be notified via
  // OnDataSent() when the send is complete. |send_status| must be
  // MORE_DATA_TO_SEND for bidirectional streams; for request/response
  // streams, it must be MORE_DATA_TO_SEND if there is more data to
  // upload, or NO_MORE_DATA_TO_SEND if not.
  // Must not be called until Delegate::OnHeadersSent() is called.
  void SendData(IOBuffer* data, int length, SpdySendStatus send_status);

  // Fills SSL info in |ssl_info| and returns true when SSL is in use.
  bool GetSSLInfo(SSLInfo* ssl_info) const;

  // Returns true if ALPN was negotiated for the underlying socket.
  bool WasAlpnNegotiated() const;

  // Returns the protocol negotiated via ALPN for the underlying socket.
  NextProto GetNegotiatedProtocol() const;

  // If the stream is stalled on sending data, but the session is not
  // stalled on sending data and |send_window_size_| is positive, then
  // set |send_stalled_by_flow_control_| to false and unstall the data
  // sending. Called by the session or by the stream itself. Must be
  // called only when the stream is still open.
  enum ShouldRequeueStream { Requeue, DoNotRequeue };
  ShouldRequeueStream PossiblyResumeIfSendStalled();

  // Returns whether or not this stream is closed. Note that the only
  // time a stream is closed and not deleted is in its delegate's
  // OnClose() method.
  bool IsClosed() const;

  // Returns whether the streams local endpoint is closed.
  // The remote endpoint may still be active.
  bool IsLocallyClosed() const;

  // Returns whether this stream is IDLE: request and response headers
  // have neither been sent nor receieved.
  bool IsIdle() const;

  // Returns whether or not this stream is fully open: that request and
  // response headers are complete, and it is not in a half-closed state.
  bool IsOpen() const;

  // Returns whether the stream is reserved by remote endpoint: server has sent
  // intended request headers for a pushed stream, but haven't started response
  // yet.
  bool IsReservedRemote() const;

  int response_status() const { return response_status_; }

  void AddRawReceivedBytes(size_t received_bytes);
  void AddRawSentBytes(size_t sent_bytes);

  int64_t raw_received_bytes() const { return raw_received_bytes_; }
  int64_t raw_sent_bytes() const { return raw_sent_bytes_; }
  int recv_bytes() const { return recv_bytes_; }
  bool ShouldRetryRSTPushStream() const;

  bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;

  const spdy::SpdyHeaderBlock& request_headers() const {
    return request_headers_;
  }
  const spdy::SpdyHeaderBlock& response_headers() const {
    return response_headers_;
  }

  // Returns the estimate of dynamically allocated memory in bytes.
  size_t EstimateMemoryUsage() const;

  const NetworkTrafficAnnotationTag traffic_annotation() const {
    return traffic_annotation_;
  }

 private:
  class HeadersBufferProducer;

  // SpdyStream states and transitions are modeled
  // on the HTTP/2 stream state machine. All states and transitions
  // are modeled, with the exceptions of RESERVED_LOCAL (the client
  // cannot initate push streams), and the transition to OPEN due to
  // a remote HEADERS (the client can only initate streams).
  enum State {
    STATE_IDLE,
    STATE_OPEN,
    STATE_HALF_CLOSED_LOCAL_UNCLAIMED,
    STATE_HALF_CLOSED_LOCAL,
    STATE_HALF_CLOSED_REMOTE,
    STATE_RESERVED_REMOTE,
    STATE_CLOSED,
  };

  // Per RFC 7540 Section 8.1, an HTTP response consists of:
  // * zero or more header blocks with informational (1xx) HTTP status,
  // * one header block,
  // * zero or more DATA frames,
  // * zero or one header block ("trailers").
  // Each header block must have a ":status" header field.  SpdyStream enforces
  // these requirements, and resets the stream if they are not met.
  enum ResponseState {
    READY_FOR_HEADERS,
    READY_FOR_DATA_OR_TRAILERS,
    TRAILERS_RECEIVED
  };

  // Update the histograms.  Can safely be called repeatedly, but should only
  // be called after the stream has completed.
  void UpdateHistograms();

  // When a server-push stream is claimed by SetDelegate(), this function is
  // posted on the current MessageLoop to replay everything the server has sent.
  // From the perspective of SpdyStream's state machine, headers, data, and
  // FIN states received prior to the delegate being attached have not yet been
  // read. While buffered by |pending_recv_data_| it's not until
  // PushedStreamReplay() is invoked that reads are considered
  // to have occurred, driving the state machine forward.
  void PushedStreamReplay();

  // Produces the HEADERS frame for the stream. The stream must
  // already be activated.
  std::unique_ptr<spdy::SpdySerializedFrame> ProduceHeadersFrame();

  // Queues the send for next frame of the remaining data in
  // |pending_send_data_|. Must be called only when
  // |pending_send_data_| is set.
  void QueueNextDataFrame();

  // Saves the given headers into |response_headers_| and calls
  // OnHeadersReceived() on the delegate if attached.
  void SaveResponseHeaders(const spdy::SpdyHeaderBlock& response_headers);

  static std::string DescribeState(State state);

  const SpdyStreamType type_;

  spdy::SpdyStreamId stream_id_;
  const GURL url_;
  RequestPriority priority_;

  bool send_stalled_by_flow_control_;

  // Current send window size.
  int32_t send_window_size_;

  // Maximum receive window size.  Each time a WINDOW_UPDATE is sent, it
  // restores the receive window size to this value.
  int32_t max_recv_window_size_;

  // Sum of |session_unacked_recv_window_bytes_| and current receive window
  // size.
  // TODO(bnc): Rename or change semantics so that |window_size_| is actual
  // window size.
  int32_t recv_window_size_;

  // When bytes are consumed, SpdyIOBuffer destructor calls back to SpdySession,
  // and this member keeps count of them until the corresponding WINDOW_UPDATEs
  // are sent.
  int32_t unacked_recv_window_bytes_;

  const base::WeakPtr<SpdySession> session_;

  // The transaction should own the delegate.
  SpdyStream::Delegate* delegate_;

  // The headers for the request to send.
  bool request_headers_valid_;
  spdy::SpdyHeaderBlock request_headers_;

  // Data waiting to be sent, and the close state of the local endpoint
  // after the data is fully written.
  scoped_refptr<DrainableIOBuffer> pending_send_data_;
  SpdySendStatus pending_send_status_;

  // Data waiting to be received, and the close state of the remote endpoint
  // after the data is fully read. Specifically, data received before the
  // delegate is attached must be buffered and later replayed. A remote FIN
  // is represented by a final, zero-length buffer.
  std::vector<std::unique_ptr<SpdyBuffer>> pending_recv_data_;

  // The time at which the request was made that resulted in this response.
  // For cached responses, this time could be "far" in the past.
  base::Time request_time_;

  spdy::SpdyHeaderBlock response_headers_;
  ResponseState response_state_;
  base::Time response_time_;

  State io_state_;

  // Since we buffer the response, we also buffer the response status.
  // Not valid until the stream is closed.
  int response_status_;

  NetLogWithSource net_log_;

  base::TimeTicks send_time_;
  base::TimeTicks recv_first_byte_time_;
  base::TimeTicks recv_last_byte_time_;

  // Number of bytes that have been received on this stream, including frame
  // overhead and headers.
  int64_t raw_received_bytes_;
  // Number of bytes that have been sent on this stream, including frame
  // overhead and headers.
  int64_t raw_sent_bytes_;

  // Number of data bytes that have been sent/received on this stream, not
  // including frame overhead. Note that this does not count headers.
  int send_bytes_;
  int recv_bytes_;

  // Guards calls of delegate write handlers ensuring |this| is not destroyed.
  // TODO(jgraettinger): Consider removing after crbug.com/35511 is tracked
  // down.
  bool write_handler_guard_;

  const NetworkTrafficAnnotationTag traffic_annotation_;

  base::WeakPtrFactory<SpdyStream> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(SpdyStream);
};

}  // namespace net

#endif  // NET_SPDY_SPDY_STREAM_H_
