// 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 <deque>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "net/base/bandwidth_metrics.h"
#include "net/base/io_buffer.h"
#include "net/base/net_export.h"
#include "net/base/net_log.h"
#include "net/base/request_priority.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/server_bound_cert_service.h"
#include "net/ssl/ssl_client_cert_type.h"
#include "url/gurl.h"

namespace net {

class AddressList;
class IPEndPoint;
struct LoadTimingInfo;
class SSLCertRequestInfo;
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.
enum SpdyResponseHeadersStatus {
  RESPONSE_HEADERS_ARE_INCOMPLETE,
  RESPONSE_HEADERS_ARE_COMPLETE
};

// 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(akalin): Treat headers received after data has been
    // received as a protocol error for non-bidirectional streams.
    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 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 initial_send_window_size,
             int32 initial_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 send_window_size() const { return send_window_size_; }

  int32 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 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 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 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 delta_window_size);

  // Called by OnDataReceived (which is in turn called by the session)
  // to decrease 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 go negative.
  //
  // If stream flow control is turned off or the stream is not active,
  // this must not be called.
  void DecreaseRecvWindowSize(int32 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. This is the
  // entry point for a push stream. 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 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 a frame has been successfully and
  // completely written. |frame_size| is the total size of the frame
  // in bytes, including framing overhead.
  void OnFrameWriteComplete(SpdyFrameType frame_type, 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);

  // Fills SSL Certificate Request info |cert_request_info| and returns
  // true when SSL is in use.
  bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);

  // 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 or not this stream has finished sending its
  // request headers and is ready to send/receive more data.
  bool IsIdle() const;

  // Returns the protocol used by this stream. Always between
  // kProtoSPDY2 and kProtoSPDYMaximumVersion.
  //
  // TODO(akalin): Change the lower bound to kProtoSPDYMinimumVersion
  // once we stop supporting SPDY/1.
  NextProto GetProtocol() const;

  int response_status() const { return response_status_; }

  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;

  int GetProtocolVersion() const;

 private:
  class SynStreamBufferProducer;
  class HeaderBufferProducer;

  enum State {
    STATE_NONE,
    STATE_GET_DOMAIN_BOUND_CERT,
    STATE_GET_DOMAIN_BOUND_CERT_COMPLETE,
    STATE_SEND_DOMAIN_BOUND_CERT,
    STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE,
    STATE_SEND_REQUEST_HEADERS,
    STATE_SEND_REQUEST_HEADERS_COMPLETE,
    STATE_IDLE,
    STATE_CLOSED
  };

  void OnGetDomainBoundCertComplete(int result);

  // Try to make progress sending/receiving the request/response.
  int DoLoop(int result);

  // The implementations of each state of the state machine.
  int DoGetDomainBoundCert();
  int DoGetDomainBoundCertComplete(int result);
  int DoSendDomainBoundCert();
  int DoSendDomainBoundCertComplete(int result);
  int DoSendRequestHeaders();
  int DoSendRequestHeadersComplete();
  int DoReadHeaders();
  int DoReadHeadersComplete(int result);
  int DoOpen();

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

  // When a server-pushed stream is first created, this function is
  // posted on the current MessageLoop to replay the data that the
  // server has already sent.
  void PushedStreamReplayData();

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

  const SpdyStreamType type_;

  base::WeakPtrFactory<SpdyStream> weak_ptr_factory_;

  // Sentinel variable used to make sure we don't get destroyed by a
  // function called from DoLoop().
  bool in_do_loop_;

  // There is a small period of time between when a server pushed stream is
  // first created, and the pushed data is replayed. Any data received during
  // this time should continue to be buffered.
  bool continue_buffering_data_;

  SpdyStreamId stream_id_;
  const GURL url_;
  const RequestPriority priority_;
  size_t slot_;

  // Flow control variables.
  bool send_stalled_by_flow_control_;
  int32 send_window_size_;
  int32 recv_window_size_;
  int32 unacked_recv_window_bytes_;

  ScopedBandwidthMetrics metrics_;

  const base::WeakPtr<SpdySession> session_;

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

  // Whether or not we have more data to send on this stream.
  SpdySendStatus send_status_;

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

  // The data waiting to be sent.
  scoped_refptr<DrainableIOBuffer> pending_send_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 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_;

  // Data received before delegate is attached.
  ScopedVector<SpdyBuffer> pending_buffers_;

  std::string domain_bound_private_key_;
  std::string domain_bound_cert_;
  ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_;

  // When OnFrameWriteComplete() is called, these variables are set.
  SpdyFrameType just_completed_frame_type_;
  size_t just_completed_frame_size_;

  DISALLOW_COPY_AND_ASSIGN(SpdyStream);
};

}  // namespace net

#endif  // NET_SPDY_SPDY_STREAM_H_
