// 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 <stddef.h>
#include <stdint.h>

#include <deque>
#include <string>
#include <vector>

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.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.h"
#include "net/socket/ssl_client_socket.h"
#include "net/spdy/spdy_buffer.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_header_block.h"
#include "net/spdy/spdy_protocol.h"
#include "net/ssl/ssl_client_cert_type.h"
#include "url/gurl.h"

namespace net {

class AddressList;
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
};

// Returned by SpdyStream::OnResponseHeadersUpdated() to indicate
// whether the current response headers are complete or not, or whether
// trailers have been received. TRAILERS_RECEIVED denotes the state where
// headers are received after DATA frames. TRAILERS_RECEIVED is only used for
// SPDY_REQUEST_RESPONSE_STREAM, and this state also implies that the response
// headers are complete.
enum SpdyResponseHeadersStatus {
  RESPONSE_HEADERS_ARE_INCOMPLETE,
  RESPONSE_HEADERS_ARE_COMPLETE,
  TRAILERS_RECEIVED,
};

// The SpdyStream is used by the SpdySession 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 OnRequestHeadersSent() = 0;

    // WARNING: This function is complicated! Be sure to read the
    // whole comment below if you're working with code that implements
    // or calls this function.
    //
    // Called when the response headers are updated from the
    // server. |response_headers| contains the set of all headers
    // received up to this point; delegates can assume that any
    // headers previously received remain unchanged.
    //
    // This is called at least once before any data is received. If
    // RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this will be
    // called again when more headers are received until
    // RESPONSE_HEADERS_ARE_COMPLETE is returned, and any data
    // received before then will be treated as a protocol error.
    //
    // If RESPONSE_HEADERS_ARE_INCOMPLETE is returned, the delegate
    // must not have closed the stream. Otherwise, if
    // RESPONSE_HEADERS_ARE_COMPLETE is returned, the delegate has
    // processed the headers successfully. However, it still may have
    // closed the stream, e.g. if the headers indicated an error
    // condition.
    //
    // Some type-specific behavior:
    //
    //   - For bidirectional streams, this may be called even after
    //     data is received, but it is expected that
    //     RESPONSE_HEADERS_ARE_COMPLETE is always returned. If
    //     RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this is
    //     treated as a protocol error.
    //
    //   - For request/response streams, this function is called
    //     exactly once before data is received, and it is expected
    //     that RESPONSE_HEADERS_ARE_COMPLETE is returned. If
    //     RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this is
    //     treated as a protocol error.
    //
    //   - For push streams, it is expected that this function will be
    //     called until RESPONSE_HEADERS_ARE_COMPLETE is returned
    //     before any data is received; any deviation from this is
    //     treated as a protocol error.
    //
    // TODO(jgraettinger): This should be at the semantic (HTTP) rather
    // than stream layer. Streams shouldn't have a notion of header
    // completeness. Move to SpdyHttpStream/SpdyWebsocketStream.
    virtual SpdyResponseHeadersStatus OnResponseHeadersUpdated(
        const SpdyHeaderBlock& response_headers) = 0;

    // Called when data is received after all required response
    // headers have been received. |buffer| may be NULL, which signals
    // EOF.  Must return OK if the data was received successfully, or
    // a network error code otherwise.
    //
    // May cause the stream to be closed.
    virtual void OnDataReceived(scoped_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. Note that trailers HEADER frame will
    // have END_STREAM flag set according to section 8.1 of the HTTP/2 RFC,
    // so this will be followed by OnClose.
    virtual void OnTrailers(const 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 be (re-)closed.
    //
    // TODO(akalin): Allow this function to re-close the stream and
    // handle it gracefully.
    virtual void OnClose(int status) = 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 BoundNetLog& net_log);

  ~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_; }

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

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

  RequestPriority priority() const { return 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
  // 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.
  //
  // If stream flow control is turned off, this must not be called.
  void AdjustSendWindowSize(int32_t delta_window_size);

  // 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 BoundNetLog& net_log() const { return net_log_; }

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

  // Called at most once by the SpdySession when the initial response
  // headers have been received for this stream, i.e., a SYN_REPLY (or
  // SYN_STREAM for push streams) frame has been received. Returns a status
  // code; if it is an error, the stream was closed by this function.
  int OnInitialResponseHeadersReceived(const SpdyHeaderBlock& response_headers,
                                       base::Time response_time,
                                       base::TimeTicks recv_first_byte_time);

  // Called by the SpdySession (only after
  // OnInitialResponseHeadersReceived() has been called) when
  // late-bound headers are received for a stream. Returns a status
  // code; if it is an error, the stream was closed by this function.
  int OnAdditionalResponseHeadersReceived(
      const SpdyHeaderBlock& additional_response_headers);

  // 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(const SpdyHeaderBlock& headers);

  // 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(scoped_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(SpdyFrameType frame_type, size_t frame_size);

  // SYN_STREAM-specific write handler invoked by OnFrameWriteComplete().
  int OnRequestHeadersSent();

  // 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.
  // |status| is an error code or OK.
  void OnClose(int status);

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

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

  // 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
  // OnRequestHeadersSent() 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(scoped_ptr<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.
  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,
                  bool* was_npn_negotiated,
                  NextProto* protocol_negotiated);

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

  // Returns the protocol used by this stream. Always between
  // kProtoSPDYMinimumVersion and kProtoSPDYMaximumVersion.
  NextProto GetProtocol() 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_; }

  bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;

  // Get the URL from the appropriate stream headers, or the empty
  // GURL() if it is unknown.
  //
  // TODO(akalin): Figure out if we really need this function,
  // i.e. can we just use the URL this stream was created with and/or
  // one we receive headers validate that the URL from them is the
  // same.
  GURL GetUrlFromHeaders() const;

  // Returns whether the URL for this stream is known.
  //
  // TODO(akalin): Remove this, as it's only used in tests.
  bool HasUrlFromHeaders() const;

  SpdyMajorVersion GetProtocolVersion() const;

 private:
  class SynStreamBufferProducer;
  class HeaderBufferProducer;

  // 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 SYN_STREAM (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,
  };

  // 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 SYN_STREAM frame for the stream. The stream must
  // already be activated.
  scoped_ptr<SpdyFrame> ProduceSynStreamFrame();

  // Produce the initial HEADER frame for the stream with the given
  // block. The stream must already be activated.
  scoped_ptr<SpdyFrame> ProduceHeaderFrame(
      scoped_ptr<SpdyHeaderBlock> header_block);

  // 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();

  // Merge the given headers into |response_headers_| and calls
  // OnResponseHeadersUpdated() on the delegate (if attached).
  // Returns a status code; if it is an error, the stream was closed
  // by this function.
  int MergeWithResponseHeaders(const SpdyHeaderBlock& new_response_headers);

  static std::string DescribeState(State state);

  const SpdyStreamType type_;

  SpdyStreamId stream_id_;
  const GURL url_;
  const 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.
  //
  // TODO(akalin): Hang onto this only until we send it. This
  // necessitates stashing the URL separately.
  scoped_ptr<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<scoped_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_;

  SpdyHeaderBlock response_headers_;
  SpdyResponseHeadersStatus response_headers_status_;
  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_;

  BoundNetLog 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_;

  base::WeakPtrFactory<SpdyStream> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(SpdyStream);
};

}  // namespace net

#endif  // NET_SPDY_SPDY_STREAM_H_
