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
30namespace net {
31
32class AddressList;
33class IPEndPoint;
34struct LoadTimingInfo;
35class SSLCertRequestInfo;
36class SSLInfo;
37class SpdySession;
38
39enum 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.
53enum 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.
60enum 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.
72class 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