- add sources.
[platform/framework/web/crosswalk.git] / src / net / spdy / spdy_stream.h
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   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
392
393   // Get the URL from the appropriate stream headers, or the empty
394   // GURL() if it is unknown.
395   //
396   // TODO(akalin): Figure out if we really need this function,
397   // i.e. can we just use the URL this stream was created with and/or
398   // one we receive headers validate that the URL from them is the
399   // same.
400   GURL GetUrlFromHeaders() const;
401
402   // Returns whether the URL for this stream is known.
403   //
404   // TODO(akalin): Remove this, as it's only used in tests.
405   bool HasUrlFromHeaders() const;
406
407   int GetProtocolVersion() const;
408
409  private:
410   class SynStreamBufferProducer;
411   class HeaderBufferProducer;
412
413   enum State {
414     STATE_NONE,
415     STATE_SEND_REQUEST_HEADERS,
416     STATE_SEND_REQUEST_HEADERS_COMPLETE,
417     STATE_IDLE,
418     STATE_CLOSED
419   };
420
421   // Try to make progress sending/receiving the request/response.
422   int DoLoop(int result);
423
424   // The implementations of each state of the state machine.
425   int DoSendRequestHeaders();
426   int DoSendRequestHeadersComplete();
427   int DoReadHeaders();
428   int DoReadHeadersComplete(int result);
429   int DoOpen();
430
431   // Update the histograms.  Can safely be called repeatedly, but should only
432   // be called after the stream has completed.
433   void UpdateHistograms();
434
435   // When a server-pushed stream is first created, this function is
436   // posted on the current MessageLoop to replay the data that the
437   // server has already sent.
438   void PushedStreamReplayData();
439
440   // Produces the SYN_STREAM frame for the stream. The stream must
441   // already be activated.
442   scoped_ptr<SpdyFrame> ProduceSynStreamFrame();
443
444   // Produce the initial HEADER frame for the stream with the given
445   // block. The stream must already be activated.
446   scoped_ptr<SpdyFrame> ProduceHeaderFrame(
447       scoped_ptr<SpdyHeaderBlock> header_block);
448
449   // Queues the send for next frame of the remaining data in
450   // |pending_send_data_|. Must be called only when
451   // |pending_send_data_| is set.
452   void QueueNextDataFrame();
453
454   // Merge the given headers into |response_headers_| and calls
455   // OnResponseHeadersUpdated() on the delegate (if attached).
456   // Returns a status code; if it is an error, the stream was closed
457   // by this function.
458   int MergeWithResponseHeaders(const SpdyHeaderBlock& new_response_headers);
459
460   const SpdyStreamType type_;
461
462   base::WeakPtrFactory<SpdyStream> weak_ptr_factory_;
463
464   // Sentinel variable used to make sure we don't get destroyed by a
465   // function called from DoLoop().
466   bool in_do_loop_;
467
468   // There is a small period of time between when a server pushed stream is
469   // first created, and the pushed data is replayed. Any data received during
470   // this time should continue to be buffered.
471   bool continue_buffering_data_;
472
473   SpdyStreamId stream_id_;
474   const GURL url_;
475   const RequestPriority priority_;
476   size_t slot_;
477
478   // Flow control variables.
479   bool send_stalled_by_flow_control_;
480   int32 send_window_size_;
481   int32 recv_window_size_;
482   int32 unacked_recv_window_bytes_;
483
484   ScopedBandwidthMetrics metrics_;
485
486   const base::WeakPtr<SpdySession> session_;
487
488   // The transaction should own the delegate.
489   SpdyStream::Delegate* delegate_;
490
491   // Whether or not we have more data to send on this stream.
492   SpdySendStatus send_status_;
493
494   // The headers for the request to send.
495   //
496   // TODO(akalin): Hang onto this only until we send it. This
497   // necessitates stashing the URL separately.
498   scoped_ptr<SpdyHeaderBlock> request_headers_;
499
500   // The data waiting to be sent.
501   scoped_refptr<DrainableIOBuffer> pending_send_data_;
502
503   // The time at which the request was made that resulted in this response.
504   // For cached responses, this time could be "far" in the past.
505   base::Time request_time_;
506
507   SpdyHeaderBlock response_headers_;
508   SpdyResponseHeadersStatus response_headers_status_;
509   base::Time response_time_;
510
511   State io_state_;
512
513   // Since we buffer the response, we also buffer the response status.
514   // Not valid until the stream is closed.
515   int response_status_;
516
517   BoundNetLog net_log_;
518
519   base::TimeTicks send_time_;
520   base::TimeTicks recv_first_byte_time_;
521   base::TimeTicks recv_last_byte_time_;
522
523   // Number of data bytes that have been sent/received on this stream, not
524   // including frame overhead. Note that this does not count headers.
525   int send_bytes_;
526   int recv_bytes_;
527
528   // Data received before delegate is attached.
529   ScopedVector<SpdyBuffer> pending_buffers_;
530
531   std::string domain_bound_private_key_;
532   std::string domain_bound_cert_;
533   ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_;
534
535   // When OnFrameWriteComplete() is called, these variables are set.
536   SpdyFrameType just_completed_frame_type_;
537   size_t just_completed_frame_size_;
538
539   DISALLOW_COPY_AND_ASSIGN(SpdyStream);
540 };
541
542 }  // namespace net
543
544 #endif  // NET_SPDY_SPDY_STREAM_H_