Home | History | Annotate | Download | only in spdy
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef NET_SPDY_SPDY_STREAM_H_
      6 #define NET_SPDY_SPDY_STREAM_H_
      7 
      8 #include <deque>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/scoped_vector.h"
     16 #include "base/memory/weak_ptr.h"
     17 #include "net/base/bandwidth_metrics.h"
     18 #include "net/base/io_buffer.h"
     19 #include "net/base/net_export.h"
     20 #include "net/base/net_log.h"
     21 #include "net/base/request_priority.h"
     22 #include "net/socket/ssl_client_socket.h"
     23 #include "net/spdy/spdy_buffer.h"
     24 #include "net/spdy/spdy_framer.h"
     25 #include "net/spdy/spdy_header_block.h"
     26 #include "net/spdy/spdy_protocol.h"
     27 #include "net/ssl/server_bound_cert_service.h"
     28 #include "net/ssl/ssl_client_cert_type.h"
     29 #include "url/gurl.h"
     30 
     31 namespace net {
     32 
     33 class AddressList;
     34 class IPEndPoint;
     35 struct LoadTimingInfo;
     36 class SSLCertRequestInfo;
     37 class SSLInfo;
     38 class SpdySession;
     39 
     40 enum SpdyStreamType {
     41   // The most general type of stream; there are no restrictions on
     42   // when data can be sent and received.
     43   SPDY_BIDIRECTIONAL_STREAM,
     44   // A stream where the client sends a request with possibly a body,
     45   // and the server then sends a response with a body.
     46   SPDY_REQUEST_RESPONSE_STREAM,
     47   // A server-initiated stream where the server just sends a response
     48   // with a body and the client does not send anything.
     49   SPDY_PUSH_STREAM
     50 };
     51 
     52 // Passed to some SpdyStream functions to indicate whether there's
     53 // more data to send.
     54 enum SpdySendStatus {
     55   MORE_DATA_TO_SEND,
     56   NO_MORE_DATA_TO_SEND
     57 };
     58 
     59 // Returned by SpdyStream::OnResponseHeadersUpdated() to indicate
     60 // whether the current response headers are complete or not.
     61 enum SpdyResponseHeadersStatus {
     62   RESPONSE_HEADERS_ARE_INCOMPLETE,
     63   RESPONSE_HEADERS_ARE_COMPLETE
     64 };
     65 
     66 // The SpdyStream is used by the SpdySession to represent each stream known
     67 // on the SpdySession.  This class provides interfaces for SpdySession to use.
     68 // Streams can be created either by the client or by the server.  When they
     69 // are initiated by the client, both the SpdySession and client object (such as
     70 // a SpdyNetworkTransaction) will maintain a reference to the stream.  When
     71 // initiated by the server, only the SpdySession will maintain any reference,
     72 // until such a time as a client object requests a stream for the path.
     73 class NET_EXPORT_PRIVATE SpdyStream {
     74  public:
     75   // Delegate handles protocol specific behavior of spdy stream.
     76   class NET_EXPORT_PRIVATE Delegate {
     77    public:
     78     Delegate() {}
     79 
     80     // Called when the request headers have been sent. Never called
     81     // for push streams. Must not cause the stream to be closed.
     82     virtual void OnRequestHeadersSent() = 0;
     83 
     84     // WARNING: This function is complicated! Be sure to read the
     85     // whole comment below if you're working with code that implements
     86     // or calls this function.
     87     //
     88     // Called when the response headers are updated from the
     89     // server. |response_headers| contains the set of all headers
     90     // received up to this point; delegates can assume that any
     91     // headers previously received remain unchanged.
     92     //
     93     // This is called at least once before any data is received. If
     94     // RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this will be
     95     // called again when more headers are received until
     96     // RESPONSE_HEADERS_ARE_COMPLETE is returned, and any data
     97     // received before then will be treated as a protocol error.
     98     //
     99     // If RESPONSE_HEADERS_ARE_INCOMPLETE is returned, the delegate
    100     // must not have closed the stream. Otherwise, if
    101     // RESPONSE_HEADERS_ARE_COMPLETE is returned, the delegate has
    102     // processed the headers successfully. However, it still may have
    103     // closed the stream, e.g. if the headers indicated an error
    104     // condition.
    105     //
    106     // Some type-specific behavior:
    107     //
    108     //   - For bidirectional streams, this may be called even after
    109     //     data is received, but it is expected that
    110     //     RESPONSE_HEADERS_ARE_COMPLETE is always returned. If
    111     //     RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this is
    112     //     treated as a protocol error.
    113     //
    114     //   - For request/response streams, this function is called
    115     //     exactly once before data is received, and it is expected
    116     //     that RESPONSE_HEADERS_ARE_COMPLETE is returned. If
    117     //     RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this is
    118     //     treated as a protocol error.
    119     //
    120     //   - For push streams, it is expected that this function will be
    121     //     called until RESPONSE_HEADERS_ARE_COMPLETE is returned
    122     //     before any data is received; any deviation from this is
    123     //     treated as a protocol error.
    124     //
    125     // TODO(akalin): Treat headers received after data has been
    126     // received as a protocol error for non-bidirectional streams.
    127     virtual SpdyResponseHeadersStatus OnResponseHeadersUpdated(
    128         const SpdyHeaderBlock& response_headers) = 0;
    129 
    130     // Called when data is received after all required response
    131     // headers have been received. |buffer| may be NULL, which signals
    132     // EOF.  Must return OK if the data was received successfully, or
    133     // a network error code otherwise.
    134     //
    135     // May cause the stream to be closed.
    136     virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) = 0;
    137 
    138     // Called when data is sent. Must not cause the stream to be
    139     // closed.
    140     virtual void OnDataSent() = 0;
    141 
    142     // Called when SpdyStream is closed. No other delegate functions
    143     // will be called after this is called, and the delegate must not
    144     // access the stream after this is called. Must not cause the
    145     // stream to be be (re-)closed.
    146     //
    147     // TODO(akalin): Allow this function to re-close the stream and
    148     // handle it gracefully.
    149     virtual void OnClose(int status) = 0;
    150 
    151    protected:
    152     virtual ~Delegate() {}
    153 
    154    private:
    155     DISALLOW_COPY_AND_ASSIGN(Delegate);
    156   };
    157 
    158   // SpdyStream constructor
    159   SpdyStream(SpdyStreamType type,
    160              const base::WeakPtr<SpdySession>& session,
    161              const GURL& url,
    162              RequestPriority priority,
    163              int32 initial_send_window_size,
    164              int32 initial_recv_window_size,
    165              const BoundNetLog& net_log);
    166 
    167   ~SpdyStream();
    168 
    169   // Set the delegate, which must not be NULL. Must not be called more
    170   // than once. For push streams, calling this may cause buffered data
    171   // to be sent to the delegate (from a posted task).
    172   void SetDelegate(Delegate* delegate);
    173 
    174   // Detach the delegate from the stream, which must not yet be
    175   // closed, and cancel it.
    176   void DetachDelegate();
    177 
    178   // The time at which the first bytes of the response were received
    179   // from the server, or null if the response hasn't been received
    180   // yet.
    181   base::Time response_time() const { return response_time_; }
    182 
    183   SpdyStreamType type() const { return type_; }
    184 
    185   SpdyStreamId stream_id() const { return stream_id_; }
    186   void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; }
    187 
    188   const GURL& url() const { return url_; }
    189 
    190   RequestPriority priority() const { return priority_; }
    191 
    192   int32 send_window_size() const { return send_window_size_; }
    193 
    194   int32 recv_window_size() const { return recv_window_size_; }
    195 
    196   bool send_stalled_by_flow_control() const {
    197     return send_stalled_by_flow_control_;
    198   }
    199 
    200   void set_send_stalled_by_flow_control(bool stalled) {
    201     send_stalled_by_flow_control_ = stalled;
    202   }
    203 
    204   // Called by the session to adjust this stream's send window size by
    205   // |delta_window_size|, which is the difference between the
    206   // SETTINGS_INITIAL_WINDOW_SIZE in the most recent SETTINGS frame
    207   // and the previous initial send window size, possibly unstalling
    208   // this stream. Although |delta_window_size| may cause this stream's
    209   // send window size to go negative, it must not cause it to wrap
    210   // around in either direction. Does nothing if the stream is already
    211   // closed.
    212   //
    213   // If stream flow control is turned off, this must not be called.
    214   void AdjustSendWindowSize(int32 delta_window_size);
    215 
    216   // Called when bytes are consumed from a SpdyBuffer for a DATA frame
    217   // that is to be written or is being written. Increases the send
    218   // window size accordingly if some or all of the SpdyBuffer is being
    219   // discarded.
    220   //
    221   // If stream flow control is turned off, this must not be called.
    222   void OnWriteBufferConsumed(size_t frame_payload_size,
    223                              size_t consume_size,
    224                              SpdyBuffer::ConsumeSource consume_source);
    225 
    226   // Called by the session to increase this stream's send window size
    227   // by |delta_window_size| (which must be at least 1) from a received
    228   // WINDOW_UPDATE frame or from a dropped DATA frame that was
    229   // intended to be sent, possibly unstalling this stream. If
    230   // |delta_window_size| would cause this stream's send window size to
    231   // overflow, calls into the session to reset this stream. Does
    232   // nothing if the stream is already closed.
    233   //
    234   // If stream flow control is turned off, this must not be called.
    235   void IncreaseSendWindowSize(int32 delta_window_size);
    236 
    237   // If stream flow control is turned on, called by the session to
    238   // decrease this stream's send window size by |delta_window_size|,
    239   // which must be at least 0 and at most kMaxSpdyFrameChunkSize.
    240   // |delta_window_size| must not cause this stream's send window size
    241   // to go negative. Does nothing if the stream is already closed.
    242   //
    243   // If stream flow control is turned off, this must not be called.
    244   void DecreaseSendWindowSize(int32 delta_window_size);
    245 
    246   // Called when bytes are consumed by the delegate from a SpdyBuffer
    247   // containing received data. Increases the receive window size
    248   // accordingly.
    249   //
    250   // If stream flow control is turned off, this must not be called.
    251   void OnReadBufferConsumed(size_t consume_size,
    252                             SpdyBuffer::ConsumeSource consume_source);
    253 
    254   // Called by OnReadBufferConsume to increase this stream's receive
    255   // window size by |delta_window_size|, which must be at least 1 and
    256   // must not cause this stream's receive window size to overflow,
    257   // possibly also sending a WINDOW_UPDATE frame. Does nothing if the
    258   // stream is not active.
    259   //
    260   // If stream flow control is turned off, this must not be called.
    261   void IncreaseRecvWindowSize(int32 delta_window_size);
    262 
    263   // Called by OnDataReceived (which is in turn called by the session)
    264   // to decrease this stream's receive window size by
    265   // |delta_window_size|, which must be at least 1 and must not cause
    266   // this stream's receive window size to go negative.
    267   //
    268   // If stream flow control is turned off or the stream is not active,
    269   // this must not be called.
    270   void DecreaseRecvWindowSize(int32 delta_window_size);
    271 
    272   int GetPeerAddress(IPEndPoint* address) const;
    273   int GetLocalAddress(IPEndPoint* address) const;
    274 
    275   // Returns true if the underlying transport socket ever had any reads or
    276   // writes.
    277   bool WasEverUsed() const;
    278 
    279   const BoundNetLog& net_log() const { return net_log_; }
    280 
    281   base::Time GetRequestTime() const;
    282   void SetRequestTime(base::Time t);
    283 
    284   // Called at most once by the SpdySession when the initial response
    285   // headers have been received for this stream, i.e., a SYN_REPLY (or
    286   // SYN_STREAM for push streams) frame has been received. This is the
    287   // entry point for a push stream. Returns a status code; if it is
    288   // an error, the stream was closed by this function.
    289   int OnInitialResponseHeadersReceived(const SpdyHeaderBlock& response_headers,
    290                                        base::Time response_time,
    291                                        base::TimeTicks recv_first_byte_time);
    292 
    293   // Called by the SpdySession (only after
    294   // OnInitialResponseHeadersReceived() has been called) when
    295   // late-bound headers are received for a stream. Returns a status
    296   // code; if it is an error, the stream was closed by this function.
    297   int OnAdditionalResponseHeadersReceived(
    298       const SpdyHeaderBlock& additional_response_headers);
    299 
    300   // Called by the SpdySession when response data has been received
    301   // for this stream.  This callback may be called multiple times as
    302   // data arrives from the network, and will never be called prior to
    303   // OnResponseHeadersReceived.
    304   //
    305   // |buffer| contains the data received, or NULL if the stream is
    306   //          being closed.  The stream must copy any data from this
    307   //          buffer before returning from this callback.
    308   //
    309   // |length| is the number of bytes received (at most 2^24 - 1) or 0 if
    310   //          the stream is being closed.
    311   void OnDataReceived(scoped_ptr<SpdyBuffer> buffer);
    312 
    313   // Called by the SpdySession when a frame has been successfully and
    314   // completely written. |frame_size| is the total size of the frame
    315   // in bytes, including framing overhead.
    316   void OnFrameWriteComplete(SpdyFrameType frame_type, size_t frame_size);
    317 
    318   // Called by the SpdySession when the request is finished.  This callback
    319   // will always be called at the end of the request and signals to the
    320   // stream that the stream has no more network events.  No further callbacks
    321   // to the stream will be made after this call.
    322   // |status| is an error code or OK.
    323   void OnClose(int status);
    324 
    325   // Called by the SpdySession to log stream related errors.
    326   void LogStreamError(int status, const std::string& description);
    327 
    328   // If this stream is active, reset it, and close it otherwise. In
    329   // either case the stream is deleted.
    330   void Cancel();
    331 
    332   // Close this stream without sending a RST_STREAM and delete
    333   // it.
    334   void Close();
    335 
    336   // Must be used only by |session_|.
    337   base::WeakPtr<SpdyStream> GetWeakPtr();
    338 
    339   // Interface for the delegate to use.
    340 
    341   // Only one send can be in flight at a time, except for push
    342   // streams, which must not send anything.
    343 
    344   // Sends the request headers. The delegate is called back via
    345   // OnRequestHeadersSent() when the request headers have completed
    346   // sending. |send_status| must be MORE_DATA_TO_SEND for
    347   // bidirectional streams; for request/response streams, it must be
    348   // MORE_DATA_TO_SEND if the request has data to upload, or
    349   // NO_MORE_DATA_TO_SEND if not.
    350   int SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers,
    351                          SpdySendStatus send_status);
    352 
    353   // Sends a DATA frame. The delegate will be notified via
    354   // OnDataSent() when the send is complete. |send_status| must be
    355   // MORE_DATA_TO_SEND for bidirectional streams; for request/response
    356   // streams, it must be MORE_DATA_TO_SEND if there is more data to
    357   // upload, or NO_MORE_DATA_TO_SEND if not.
    358   void SendData(IOBuffer* data, int length, SpdySendStatus send_status);
    359 
    360   // Fills SSL info in |ssl_info| and returns true when SSL is in use.
    361   bool GetSSLInfo(SSLInfo* ssl_info,
    362                   bool* was_npn_negotiated,
    363                   NextProto* protocol_negotiated);
    364 
    365   // Fills SSL Certificate Request info |cert_request_info| and returns
    366   // true when SSL is in use.
    367   bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
    368 
    369   // If the stream is stalled on sending data, but the session is not
    370   // stalled on sending data and |send_window_size_| is positive, then
    371   // set |send_stalled_by_flow_control_| to false and unstall the data
    372   // sending. Called by the session or by the stream itself. Must be
    373   // called only when the stream is still open.
    374   void PossiblyResumeIfSendStalled();
    375 
    376   // Returns whether or not this stream is closed. Note that the only
    377   // time a stream is closed and not deleted is in its delegate's
    378   // OnClose() method.
    379   bool IsClosed() const;
    380 
    381   // Returns whether or not this stream has finished sending its
    382   // request headers and is ready to send/receive more data.
    383   bool IsIdle() const;
    384 
    385   // Returns the protocol used by this stream. Always between
    386   // kProtoSPDYMinimumVersion and kProtoSPDYMaximumVersion.
    387   NextProto GetProtocol() const;
    388 
    389   int response_status() const { return response_status_; }
    390 
    391   void IncrementRawReceivedBytes(size_t received_bytes) {
    392     raw_received_bytes_ += received_bytes;
    393   }
    394 
    395   int64 raw_received_bytes() const { return raw_received_bytes_; }
    396 
    397   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
    398 
    399   // Get the URL from the appropriate stream headers, or the empty
    400   // GURL() if it is unknown.
    401   //
    402   // TODO(akalin): Figure out if we really need this function,
    403   // i.e. can we just use the URL this stream was created with and/or
    404   // one we receive headers validate that the URL from them is the
    405   // same.
    406   GURL GetUrlFromHeaders() const;
    407 
    408   // Returns whether the URL for this stream is known.
    409   //
    410   // TODO(akalin): Remove this, as it's only used in tests.
    411   bool HasUrlFromHeaders() const;
    412 
    413   SpdyMajorVersion GetProtocolVersion() const;
    414 
    415  private:
    416   class SynStreamBufferProducer;
    417   class HeaderBufferProducer;
    418 
    419   enum State {
    420     STATE_NONE,
    421     STATE_SEND_REQUEST_HEADERS,
    422     STATE_SEND_REQUEST_HEADERS_COMPLETE,
    423     STATE_IDLE,
    424     STATE_CLOSED
    425   };
    426 
    427   // Try to make progress sending/receiving the request/response.
    428   int DoLoop(int result);
    429 
    430   // The implementations of each state of the state machine.
    431   int DoSendRequestHeaders();
    432   int DoSendRequestHeadersComplete();
    433   int DoReadHeaders();
    434   int DoReadHeadersComplete(int result);
    435   int DoOpen();
    436 
    437   // Update the histograms.  Can safely be called repeatedly, but should only
    438   // be called after the stream has completed.
    439   void UpdateHistograms();
    440 
    441   // When a server-pushed stream is first created, this function is
    442   // posted on the current MessageLoop to replay the data that the
    443   // server has already sent.
    444   void PushedStreamReplayData();
    445 
    446   // Produces the SYN_STREAM frame for the stream. The stream must
    447   // already be activated.
    448   scoped_ptr<SpdyFrame> ProduceSynStreamFrame();
    449 
    450   // Produce the initial HEADER frame for the stream with the given
    451   // block. The stream must already be activated.
    452   scoped_ptr<SpdyFrame> ProduceHeaderFrame(
    453       scoped_ptr<SpdyHeaderBlock> header_block);
    454 
    455   // Queues the send for next frame of the remaining data in
    456   // |pending_send_data_|. Must be called only when
    457   // |pending_send_data_| is set.
    458   void QueueNextDataFrame();
    459 
    460   // Merge the given headers into |response_headers_| and calls
    461   // OnResponseHeadersUpdated() on the delegate (if attached).
    462   // Returns a status code; if it is an error, the stream was closed
    463   // by this function.
    464   int MergeWithResponseHeaders(const SpdyHeaderBlock& new_response_headers);
    465 
    466   const SpdyStreamType type_;
    467 
    468   base::WeakPtrFactory<SpdyStream> weak_ptr_factory_;
    469 
    470   // Sentinel variable used to make sure we don't get destroyed by a
    471   // function called from DoLoop().
    472   bool in_do_loop_;
    473 
    474   // There is a small period of time between when a server pushed stream is
    475   // first created, and the pushed data is replayed. Any data received during
    476   // this time should continue to be buffered.
    477   bool continue_buffering_data_;
    478 
    479   SpdyStreamId stream_id_;
    480   const GURL url_;
    481   const RequestPriority priority_;
    482   size_t slot_;
    483 
    484   // Flow control variables.
    485   bool send_stalled_by_flow_control_;
    486   int32 send_window_size_;
    487   int32 recv_window_size_;
    488   int32 unacked_recv_window_bytes_;
    489 
    490   ScopedBandwidthMetrics metrics_;
    491 
    492   const base::WeakPtr<SpdySession> session_;
    493 
    494   // The transaction should own the delegate.
    495   SpdyStream::Delegate* delegate_;
    496 
    497   // Whether or not we have more data to send on this stream.
    498   SpdySendStatus send_status_;
    499 
    500   // The headers for the request to send.
    501   //
    502   // TODO(akalin): Hang onto this only until we send it. This
    503   // necessitates stashing the URL separately.
    504   scoped_ptr<SpdyHeaderBlock> request_headers_;
    505 
    506   // The data waiting to be sent.
    507   scoped_refptr<DrainableIOBuffer> pending_send_data_;
    508 
    509   // The time at which the request was made that resulted in this response.
    510   // For cached responses, this time could be "far" in the past.
    511   base::Time request_time_;
    512 
    513   SpdyHeaderBlock response_headers_;
    514   SpdyResponseHeadersStatus response_headers_status_;
    515   base::Time response_time_;
    516 
    517   State io_state_;
    518 
    519   // Since we buffer the response, we also buffer the response status.
    520   // Not valid until the stream is closed.
    521   int response_status_;
    522 
    523   BoundNetLog net_log_;
    524 
    525   base::TimeTicks send_time_;
    526   base::TimeTicks recv_first_byte_time_;
    527   base::TimeTicks recv_last_byte_time_;
    528 
    529   // Number of bytes that have been received on this stream, including frame
    530   // overhead and headers.
    531   int64 raw_received_bytes_;
    532 
    533   // Number of data bytes that have been sent/received on this stream, not
    534   // including frame overhead. Note that this does not count headers.
    535   int send_bytes_;
    536   int recv_bytes_;
    537 
    538   // Data received before delegate is attached.
    539   ScopedVector<SpdyBuffer> pending_buffers_;
    540 
    541   std::string domain_bound_private_key_;
    542   std::string domain_bound_cert_;
    543   ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_;
    544 
    545   // When OnFrameWriteComplete() is called, these variables are set.
    546   SpdyFrameType just_completed_frame_type_;
    547   size_t just_completed_frame_size_;
    548 
    549   DISALLOW_COPY_AND_ASSIGN(SpdyStream);
    550 };
    551 
    552 }  // namespace net
    553 
    554 #endif  // NET_SPDY_SPDY_STREAM_H_
    555