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.
5 #ifndef NET_SPDY_SPDY_STREAM_H_
6 #define NET_SPDY_SPDY_STREAM_H_
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 "googleurl/src/gurl.h"
18 #include "net/base/bandwidth_metrics.h"
19 #include "net/base/io_buffer.h"
20 #include "net/base/net_export.h"
21 #include "net/base/net_log.h"
22 #include "net/base/request_priority.h"
23 #include "net/socket/ssl_client_socket.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/spdy/spdy_session.h"
28 #include "net/ssl/server_bound_cert_service.h"
29 #include "net/ssl/ssl_client_cert_type.h"
35 class SSLCertRequestInfo
;
38 // Returned by some SpdyStream::Delegate functions to indicate whether
39 // there's more data to send.
45 // The SpdyStream is used by the SpdySession to represent each stream known
46 // on the SpdySession. This class provides interfaces for SpdySession to use.
47 // Streams can be created either by the client or by the server. When they
48 // are initiated by the client, both the SpdySession and client object (such as
49 // a SpdyNetworkTransaction) will maintain a reference to the stream. When
50 // initiated by the server, only the SpdySession will maintain any reference,
51 // until such a time as a client object requests a stream for the path.
52 class NET_EXPORT_PRIVATE SpdyStream
53 : public base::RefCounted
<SpdyStream
> {
55 // Delegate handles protocol specific behavior of spdy stream.
56 class NET_EXPORT_PRIVATE Delegate
{
60 // Called when SYN frame has been sent.
61 // Returns true if no more data to be sent after SYN frame.
62 virtual SpdySendStatus
OnSendHeadersComplete() = 0;
64 // Called when stream is ready to send data.
65 // Returns network error code. OK when it successfully sent data.
66 // ERR_IO_PENDING when performing operation asynchronously.
67 virtual int OnSendBody() = 0;
69 // Called when body data has been sent. |bytes_sent| is the number
70 // of bytes that has been sent (may be zero). Must return whether
71 // there's more body data to send.
72 virtual SpdySendStatus
OnSendBodyComplete(size_t bytes_sent
) = 0;
74 // Called when the SYN_STREAM, SYN_REPLY, or HEADERS frames are received.
75 // Normal streams will receive a SYN_REPLY and optional HEADERS frames.
76 // Pushed streams will receive a SYN_STREAM and optional HEADERS frames.
77 // Because a stream may have a SYN_* frame and multiple HEADERS frames,
78 // this callback may be called multiple times.
79 // |status| indicates network error. Returns network error code.
80 virtual int OnResponseReceived(const SpdyHeaderBlock
& response
,
81 base::Time response_time
,
84 // Called when a HEADERS frame is sent.
85 virtual void OnHeadersSent() = 0;
87 // Called when data is received. |buffer| may be NULL, which
88 // signals EOF. Must return OK if the data was received
89 // successfully, or a network error code otherwise.
90 virtual int OnDataReceived(scoped_ptr
<SpdyBuffer
> buffer
) = 0;
92 // Called when data is sent.
93 virtual void OnDataSent(size_t bytes_sent
) = 0;
95 // Called when SpdyStream is closed. No other delegate functions
96 // will be called after this is called, and the delegate must not
97 // access the stream after this is called.
98 virtual void OnClose(int status
) = 0;
101 virtual ~Delegate() {}
104 DISALLOW_COPY_AND_ASSIGN(Delegate
);
107 // SpdyStream constructor
108 SpdyStream(SpdySession
* session
,
109 const std::string
& path
,
110 RequestPriority priority
,
111 int32 initial_send_window_size
,
112 int32 initial_recv_window_size
,
114 const BoundNetLog
& net_log
);
116 // Set new |delegate|. |delegate| must not be NULL.
117 // If it already received SYN_REPLY or data, OnResponseReceived() or
118 // OnDataReceived() will be called.
119 void SetDelegate(Delegate
* delegate
);
120 Delegate
* GetDelegate() { return delegate_
; }
122 // Detach delegate from the stream. It will cancel the stream if it was not
123 // cancelled yet. It is safe to call multiple times.
124 void DetachDelegate();
126 // Is this stream a pushed stream from the server.
127 bool pushed() const { return pushed_
; }
129 SpdyStreamId
stream_id() const { return stream_id_
; }
130 void set_stream_id(SpdyStreamId stream_id
) { stream_id_
= stream_id
; }
132 bool response_received() const { return response_received_
; }
133 void set_response_received() { response_received_
= true; }
135 // For pushed streams, we track a path to identify them.
136 const std::string
& path() const { return path_
; }
138 RequestPriority
priority() const { return priority_
; }
140 int32
send_window_size() const { return send_window_size_
; }
142 int32
recv_window_size() const { return recv_window_size_
; }
144 bool send_stalled_by_flow_control() { return send_stalled_by_flow_control_
; }
146 void set_send_stalled_by_flow_control(bool stalled
) {
147 send_stalled_by_flow_control_
= stalled
;
150 // Called by the session to adjust this stream's send window size by
151 // |delta_window_size|, which is the difference between the
152 // SETTINGS_INITIAL_WINDOW_SIZE in the most recent SETTINGS frame
153 // and the previous initial send window size, possibly unstalling
154 // this stream. Although |delta_window_size| may cause this stream's
155 // send window size to go negative, it must not cause it to wrap
156 // around in either direction. Does nothing if the stream is already
159 // If stream flow control is turned off, this must not be called.
160 void AdjustSendWindowSize(int32 delta_window_size
);
162 // Called when bytes are consumed from a SpdyBuffer for a DATA frame
163 // that is to be written or is being written. Increases the send
164 // window size accordingly if some or all of the SpdyBuffer is being
167 // If stream flow control is turned off, this must not be called.
168 void OnWriteBufferConsumed(size_t frame_payload_size
,
170 SpdyBuffer::ConsumeSource consume_source
);
172 // Called by the session to increase this stream's send window size
173 // by |delta_window_size| (which must be at least 1) from a received
174 // WINDOW_UPDATE frame or from a dropped DATA frame that was
175 // intended to be sent, possibly unstalling this stream. If
176 // |delta_window_size| would cause this stream's send window size to
177 // overflow, calls into the session to reset this stream. Does
178 // nothing if the stream is already closed.
180 // If stream flow control is turned off, this must not be called.
181 void IncreaseSendWindowSize(int32 delta_window_size
);
183 // If stream flow control is turned on, called by the session to
184 // decrease this stream's send window size by |delta_window_size|,
185 // which must be at least 0 and at most kMaxSpdyFrameChunkSize.
186 // |delta_window_size| must not cause this stream's send window size
187 // to go negative. Does nothing if the stream is already closed.
189 // If stream flow control is turned off, this must not be called.
190 void DecreaseSendWindowSize(int32 delta_window_size
);
192 // Called when bytes are consumed by the delegate from a SpdyBuffer
193 // containing received data. Increases the receive window size
196 // If stream flow control is turned off, this must not be called.
197 void OnReadBufferConsumed(size_t consume_size
,
198 SpdyBuffer::ConsumeSource consume_source
);
200 // Called by OnReadBufferConsume to increase this stream's receive
201 // window size by |delta_window_size|, which must be at least 1 and
202 // must not cause this stream's receive window size to overflow,
203 // possibly also sending a WINDOW_UPDATE frame. Does nothing if the
204 // stream is not active.
206 // If stream flow control is turned off, this must not be called.
207 void IncreaseRecvWindowSize(int32 delta_window_size
);
209 // Called by OnDataReceived (which is in turn called by the session)
210 // to decrease this stream's receive window size by
211 // |delta_window_size|, which must be at least 1 and must not cause
212 // this stream's receive window size to go negative.
214 // If stream flow control is turned off or the stream is not active,
215 // this must not be called.
216 void DecreaseRecvWindowSize(int32 delta_window_size
);
218 int GetPeerAddress(IPEndPoint
* address
) const;
219 int GetLocalAddress(IPEndPoint
* address
) const;
221 // Returns true if the underlying transport socket ever had any reads or
223 bool WasEverUsed() const;
225 const BoundNetLog
& net_log() const { return net_log_
; }
227 const SpdyHeaderBlock
& spdy_headers() const;
228 void set_spdy_headers(scoped_ptr
<SpdyHeaderBlock
> headers
);
229 base::Time
GetRequestTime() const;
230 void SetRequestTime(base::Time t
);
232 // Called by the SpdySession when a response (e.g. a SYN_STREAM or SYN_REPLY)
233 // has been received for this stream. Returns a status code.
234 int OnResponseReceived(const SpdyHeaderBlock
& response
);
236 // Called by the SpdySession when late-bound headers are received for a
237 // stream. Returns a status code.
238 int OnHeaders(const SpdyHeaderBlock
& headers
);
240 // Called by the SpdySession when response data has been received for this
241 // stream. This callback may be called multiple times as data arrives
242 // from the network, and will never be called prior to OnResponseReceived.
244 // |buffer| contains the data received, or NULL if the stream is
245 // being closed. The stream must copy any data from this
246 // buffer before returning from this callback.
248 // |length| is the number of bytes received (at most 2^24 - 1) or 0 if
249 // the stream is being closed.
250 void OnDataReceived(scoped_ptr
<SpdyBuffer
> buffer
);
252 // Called by the SpdySession when a frame has been successfully and
253 // completely written. |frame_size| is the total size of the frame
254 // in bytes, including framing overhead.
255 void OnFrameWriteComplete(SpdyFrameType frame_type
, size_t frame_size
);
257 // Called by the SpdySession when the request is finished. This callback
258 // will always be called at the end of the request and signals to the
259 // stream that the stream has no more network events. No further callbacks
260 // to the stream will be made after this call.
261 // |status| is an error code or OK.
262 void OnClose(int status
);
264 // Called by the SpdySession to log stream related errors.
265 void LogStreamError(int status
, const std::string
& description
);
269 bool cancelled() const { return cancelled_
; }
270 bool closed() const { return io_state_
== STATE_DONE
; }
271 // TODO(satorux): This is only for testing. We should be able to remove
272 // this once crbug.com/113107 is addressed.
273 bool body_sent() const { return io_state_
> STATE_SEND_BODY_COMPLETE
; }
275 // Interface for Spdy[Http|WebSocket]Stream to use.
277 // Sends the request.
278 // For non push stream, it will send SYN_STREAM frame.
279 int SendRequest(bool has_upload_data
);
281 // Queues a HEADERS frame to be sent.
282 void QueueHeaders(scoped_ptr
<SpdyHeaderBlock
> headers
);
284 // Queues a DATA frame to be sent. May not queue all the data that
285 // is given (or even any of it) depending on flow control.
286 void QueueStreamData(IOBuffer
* data
, int length
,
287 SpdyDataFlags flags
);
289 // Fills SSL info in |ssl_info| and returns true when SSL is in use.
290 bool GetSSLInfo(SSLInfo
* ssl_info
,
291 bool* was_npn_negotiated
,
292 NextProto
* protocol_negotiated
);
294 // Fills SSL Certificate Request info |cert_request_info| and returns
295 // true when SSL is in use.
296 bool GetSSLCertRequestInfo(SSLCertRequestInfo
* cert_request_info
);
298 // If the stream is stalled on sending data, but the session is not
299 // stalled on sending data and |send_window_size_| is positive, then
300 // set |send_stalled_by_flow_control_| to false and unstall the data
301 // sending. Called by the session or by the stream itself. Must be
302 // called only when the stream is still open.
303 void PossiblyResumeIfSendStalled();
305 bool is_idle() const {
306 return io_state_
== STATE_OPEN
|| io_state_
== STATE_DONE
;
309 int response_status() const { return response_status_
; }
311 // Returns true if the URL for this stream is known.
314 // Get the URL associated with this stream. Only valid when has_url() is
318 int GetProtocolVersion() const;
321 class SynStreamBufferProducer
;
322 class HeaderBufferProducer
;
326 STATE_GET_DOMAIN_BOUND_CERT
,
327 STATE_GET_DOMAIN_BOUND_CERT_COMPLETE
,
328 STATE_SEND_DOMAIN_BOUND_CERT
,
329 STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE
,
331 STATE_SEND_HEADERS_COMPLETE
,
333 STATE_SEND_BODY_COMPLETE
,
334 STATE_WAITING_FOR_RESPONSE
,
339 friend class base::RefCounted
<SpdyStream
>;
341 virtual ~SpdyStream();
343 void OnGetDomainBoundCertComplete(int result
);
345 // Try to make progress sending/receiving the request/response.
346 int DoLoop(int result
);
348 // The implementations of each state of the state machine.
349 int DoGetDomainBoundCert();
350 int DoGetDomainBoundCertComplete(int result
);
351 int DoSendDomainBoundCert();
352 int DoSendDomainBoundCertComplete();
354 int DoSendHeadersComplete();
356 int DoSendBodyComplete();
358 int DoReadHeadersComplete(int result
);
361 // Update the histograms. Can safely be called repeatedly, but should only
362 // be called after the stream has completed.
363 void UpdateHistograms();
365 // When a server pushed stream is first created, this function is posted on
366 // the MessageLoop to replay all the data that the server has already sent.
367 void PushedStreamReplayData();
369 // Produces the SYN_STREAM frame for the stream. The stream must
370 // already be activated.
371 scoped_ptr
<SpdyFrame
> ProduceSynStreamFrame();
373 // Produce the initial HEADER frame for the stream with the given
374 // block. The stream must already be activated.
375 scoped_ptr
<SpdyFrame
> ProduceHeaderFrame(
376 scoped_ptr
<SpdyHeaderBlock
> header_block
);
378 base::WeakPtrFactory
<SpdyStream
> weak_ptr_factory_
;
380 // There is a small period of time between when a server pushed stream is
381 // first created, and the pushed data is replayed. Any data received during
382 // this time should continue to be buffered.
383 bool continue_buffering_data_
;
385 SpdyStreamId stream_id_
;
386 const std::string path_
;
387 const RequestPriority priority_
;
390 // Flow control variables.
391 bool send_stalled_by_flow_control_
;
392 int32 send_window_size_
;
393 int32 recv_window_size_
;
394 int32 unacked_recv_window_bytes_
;
397 ScopedBandwidthMetrics metrics_
;
398 bool response_received_
;
400 scoped_refptr
<SpdySession
> session_
;
402 // The transaction should own the delegate.
403 SpdyStream::Delegate
* delegate_
;
405 // The request to send.
406 scoped_ptr
<SpdyHeaderBlock
> request_
;
408 // The time at which the request was made that resulted in this response.
409 // For cached responses, this time could be "far" in the past.
410 base::Time request_time_
;
412 scoped_ptr
<SpdyHeaderBlock
> response_
;
413 base::Time response_time_
;
417 // Since we buffer the response, we also buffer the response status.
418 // Not valid until the stream is closed.
419 int response_status_
;
422 bool has_upload_data_
;
424 BoundNetLog net_log_
;
426 base::TimeTicks send_time_
;
427 base::TimeTicks recv_first_byte_time_
;
428 base::TimeTicks recv_last_byte_time_
;
430 // Number of data bytes that have been sent/received on this stream, not
431 // including frame overhead. Note that this does not count headers.
435 // Data received before delegate is attached.
436 ScopedVector
<SpdyBuffer
> pending_buffers_
;
438 SSLClientCertType domain_bound_cert_type_
;
439 std::string domain_bound_private_key_
;
440 std::string domain_bound_cert_
;
441 ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_
;
443 // When OnFrameWriteComplete() is called, these variables are set.
444 SpdyFrameType just_completed_frame_type_
;
445 size_t just_completed_frame_size_
;
447 DISALLOW_COPY_AND_ASSIGN(SpdyStream
);
452 #endif // NET_SPDY_SPDY_STREAM_H_