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