blob: 4d18e3eff389dc1c7ca09497fe5b7baf0607ad4b [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01008#include <deque>
Torne (Richard Coles)58218062012-11-14 11:43:16 +00009#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"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010015#include "base/memory/scoped_vector.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000016#include "base/memory/weak_ptr.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000017#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"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000022#include "net/socket/ssl_client_socket.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010023#include "net/spdy/spdy_buffer.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000024#include "net/spdy/spdy_framer.h"
25#include "net/spdy/spdy_header_block.h"
26#include "net/spdy/spdy_protocol.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000027#include "net/ssl/server_bound_cert_service.h"
28#include "net/ssl/ssl_client_cert_type.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010029#include "url/gurl.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000030
31namespace net {
32
33class AddressList;
34class IPEndPoint;
Ben Murdocheb525c52013-07-10 11:40:50 +010035struct LoadTimingInfo;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000036class SSLCertRequestInfo;
37class SSLInfo;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010038class SpdySession;
39
40enum 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};
Torne (Richard Coles)58218062012-11-14 11:43:16 +000051
Ben Murdocheb525c52013-07-10 11:40:50 +010052// Passed to some SpdyStream functions to indicate whether there's
53// more data to send.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010054enum SpdySendStatus {
55 MORE_DATA_TO_SEND,
56 NO_MORE_DATA_TO_SEND
57};
58
Ben Murdocheb525c52013-07-10 11:40:50 +010059// Returned by SpdyStream::OnResponseHeadersUpdated() to indicate
60// whether the current response headers are complete or not.
61enum SpdyResponseHeadersStatus {
62 RESPONSE_HEADERS_ARE_INCOMPLETE,
63 RESPONSE_HEADERS_ARE_COMPLETE
64};
65
Torne (Richard Coles)58218062012-11-14 11:43:16 +000066// 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.
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +010073class NET_EXPORT_PRIVATE SpdyStream {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000074 public:
75 // Delegate handles protocol specific behavior of spdy stream.
76 class NET_EXPORT_PRIVATE Delegate {
77 public:
78 Delegate() {}
79
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010080 // Called when the request headers have been sent. Never called
Ben Murdocheb525c52013-07-10 11:40:50 +010081 // for push streams. Must not cause the stream to be closed.
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010082 virtual void OnRequestHeadersSent() = 0;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000083
Ben Murdocheb525c52013-07-10 11:40:50 +010084 // 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;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000129
Ben Murdocheb525c52013-07-10 11:40:50 +0100130 // 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;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000137
Ben Murdocheb525c52013-07-10 11:40:50 +0100138 // Called when data is sent. Must not cause the stream to be
139 // closed.
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100140 virtual void OnDataSent() = 0;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000141
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000142 // Called when SpdyStream is closed. No other delegate functions
143 // will be called after this is called, and the delegate must not
Ben Murdocheb525c52013-07-10 11:40:50 +0100144 // 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.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000149 virtual void OnClose(int status) = 0;
150
151 protected:
152 virtual ~Delegate() {}
153
154 private:
155 DISALLOW_COPY_AND_ASSIGN(Delegate);
156 };
157
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000158 // SpdyStream constructor
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100159 SpdyStream(SpdyStreamType type,
Ben Murdochca12bfa2013-07-23 11:17:05 +0100160 const base::WeakPtr<SpdySession>& session,
161 const GURL& url,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000162 RequestPriority priority,
163 int32 initial_send_window_size,
164 int32 initial_recv_window_size,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000165 const BoundNetLog& net_log);
166
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100167 ~SpdyStream();
168
Ben Murdocheb525c52013-07-10 11:40:50 +0100169 // 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).
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000172 void SetDelegate(Delegate* delegate);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000173
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100174 // Detach the delegate from the stream, which must not yet be
175 // closed, and cancel it.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000176 void DetachDelegate();
177
Ben Murdocheb525c52013-07-10 11:40:50 +0100178 // 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
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100183 SpdyStreamType type() const { return type_; }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000184
185 SpdyStreamId stream_id() const { return stream_id_; }
186 void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; }
187
Ben Murdochca12bfa2013-07-23 11:17:05 +0100188 const GURL& url() const { return url_; }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000189
190 RequestPriority priority() const { return priority_; }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000191
192 int32 send_window_size() const { return send_window_size_; }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000193
194 int32 recv_window_size() const { return recv_window_size_; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000195
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100196 bool send_stalled_by_flow_control() const {
197 return send_stalled_by_flow_control_;
198 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000199
200 void set_send_stalled_by_flow_control(bool stalled) {
201 send_stalled_by_flow_control_ = stalled;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000202 }
203
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100204 // 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.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000212 //
213 // If stream flow control is turned off, this must not be called.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000214 void AdjustSendWindowSize(int32 delta_window_size);
215
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100216 // 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.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000233 //
234 // If stream flow control is turned off, this must not be called.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000235 void IncreaseSendWindowSize(int32 delta_window_size);
236
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000237 // 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.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000244 void DecreaseSendWindowSize(int32 delta_window_size);
245
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100246 // Called when bytes are consumed by the delegate from a SpdyBuffer
247 // containing received data. Increases the receive window size
248 // accordingly.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000249 //
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100250 // 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.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000261 void IncreaseRecvWindowSize(int32 delta_window_size);
262
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100263 // 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
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000272 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
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000279 const BoundNetLog& net_log() const { return net_log_; }
280
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000281 base::Time GetRequestTime() const;
282 void SetRequestTime(base::Time t);
283
Ben Murdocheb525c52013-07-10 11:40:50 +0100284 // 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);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000292
Ben Murdocheb525c52013-07-10 11:40:50 +0100293 // 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);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000299
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100300 // 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.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000304 //
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.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100311 void OnDataReceived(scoped_ptr<SpdyBuffer> buffer);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000312
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100313 // 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);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000317
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
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100328 // If this stream is active, reset it, and close it otherwise. In
329 // either case the stream is deleted.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000330 void Cancel();
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100331
332 // Close this stream without sending a RST_STREAM and delete
333 // it.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000334 void Close();
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100335
Ben Murdochca12bfa2013-07-23 11:17:05 +0100336 // Must be used only by |session_|.
Ben Murdocheb525c52013-07-10 11:40:50 +0100337 base::WeakPtr<SpdyStream> GetWeakPtr();
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100338
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100339 // Interface for the delegate to use.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000340
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100341 // Only one send can be in flight at a time, except for push
342 // streams, which must not send anything.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000343
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100344 // 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.
Ben Murdocheb525c52013-07-10 11:40:50 +0100350 int SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100351 SpdySendStatus send_status);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000352
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100353 // 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);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000359
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
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000369 // 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
Ben Murdocheb525c52013-07-10 11:40:50 +0100376 // 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;
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +0100380
Ben Murdocheb525c52013-07-10 11:40:50 +0100381 // 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;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000384
Ben Murdoch558790d2013-07-30 15:19:42 +0100385 // Returns the protocol used by this stream. Always between
386 // kProtoSPDY2 and kProtoSPDYMaximumVersion.
387 //
388 // TODO(akalin): Change the lower bound to kProtoSPDYMinimumVersion
389 // once we stop supporting SPDY/1.
390 NextProto GetProtocol() const;
391
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000392 int response_status() const { return response_status_; }
393
Ben Murdocheb525c52013-07-10 11:40:50 +0100394 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000395
Ben Murdochca12bfa2013-07-23 11:17:05 +0100396 // Get the URL from the appropriate stream headers, or the empty
397 // GURL() if it is unknown.
398 //
399 // TODO(akalin): Figure out if we really need this function,
400 // i.e. can we just use the URL this stream was created with and/or
401 // one we receive headers validate that the URL from them is the
402 // same.
403 GURL GetUrlFromHeaders() const;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000404
Ben Murdocheb525c52013-07-10 11:40:50 +0100405 // Returns whether the URL for this stream is known.
406 //
407 // TODO(akalin): Remove this, as it's only used in tests.
Ben Murdochca12bfa2013-07-23 11:17:05 +0100408 bool HasUrlFromHeaders() const;
Ben Murdocheb525c52013-07-10 11:40:50 +0100409
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000410 int GetProtocolVersion() const;
411
412 private:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100413 class SynStreamBufferProducer;
414 class HeaderBufferProducer;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000415
416 enum State {
417 STATE_NONE,
418 STATE_GET_DOMAIN_BOUND_CERT,
419 STATE_GET_DOMAIN_BOUND_CERT_COMPLETE,
420 STATE_SEND_DOMAIN_BOUND_CERT,
421 STATE_SEND_DOMAIN_BOUND_CERT_COMPLETE,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100422 STATE_SEND_REQUEST_HEADERS,
423 STATE_SEND_REQUEST_HEADERS_COMPLETE,
Ben Murdocheb525c52013-07-10 11:40:50 +0100424 STATE_IDLE,
425 STATE_CLOSED
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000426 };
427
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000428 void OnGetDomainBoundCertComplete(int result);
429
430 // Try to make progress sending/receiving the request/response.
431 int DoLoop(int result);
432
433 // The implementations of each state of the state machine.
434 int DoGetDomainBoundCert();
435 int DoGetDomainBoundCertComplete(int result);
436 int DoSendDomainBoundCert();
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100437 int DoSendDomainBoundCertComplete(int result);
438 int DoSendRequestHeaders();
439 int DoSendRequestHeadersComplete();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000440 int DoReadHeaders();
441 int DoReadHeadersComplete(int result);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100442 int DoOpen();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000443
444 // Update the histograms. Can safely be called repeatedly, but should only
445 // be called after the stream has completed.
446 void UpdateHistograms();
447
Ben Murdocheb525c52013-07-10 11:40:50 +0100448 // When a server-pushed stream is first created, this function is
449 // posted on the current MessageLoop to replay the data that the
450 // server has already sent.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000451 void PushedStreamReplayData();
452
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100453 // Produces the SYN_STREAM frame for the stream. The stream must
454 // already be activated.
455 scoped_ptr<SpdyFrame> ProduceSynStreamFrame();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000456
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100457 // Produce the initial HEADER frame for the stream with the given
458 // block. The stream must already be activated.
459 scoped_ptr<SpdyFrame> ProduceHeaderFrame(
460 scoped_ptr<SpdyHeaderBlock> header_block);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000461
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100462 // Queues the send for next frame of the remaining data in
463 // |pending_send_data_|. Must be called only when
464 // |pending_send_data_| is set.
465 void QueueNextDataFrame();
466
Ben Murdocheb525c52013-07-10 11:40:50 +0100467 // Merge the given headers into |response_headers_| and calls
468 // OnResponseHeadersUpdated() on the delegate (if attached).
469 // Returns a status code; if it is an error, the stream was closed
470 // by this function.
471 int MergeWithResponseHeaders(const SpdyHeaderBlock& new_response_headers);
472
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100473 const SpdyStreamType type_;
474
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000475 base::WeakPtrFactory<SpdyStream> weak_ptr_factory_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000476
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100477 // Sentinel variable used to make sure we don't get destroyed by a
478 // function called from DoLoop().
479 bool in_do_loop_;
480
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000481 // There is a small period of time between when a server pushed stream is
482 // first created, and the pushed data is replayed. Any data received during
483 // this time should continue to be buffered.
484 bool continue_buffering_data_;
485
486 SpdyStreamId stream_id_;
Ben Murdochca12bfa2013-07-23 11:17:05 +0100487 const GURL url_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000488 const RequestPriority priority_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000489 size_t slot_;
490
491 // Flow control variables.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000492 bool send_stalled_by_flow_control_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000493 int32 send_window_size_;
494 int32 recv_window_size_;
495 int32 unacked_recv_window_bytes_;
496
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000497 ScopedBandwidthMetrics metrics_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000498
Ben Murdochca12bfa2013-07-23 11:17:05 +0100499 const base::WeakPtr<SpdySession> session_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000500
501 // The transaction should own the delegate.
502 SpdyStream::Delegate* delegate_;
503
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100504 // Whether or not we have more data to send on this stream.
505 SpdySendStatus send_status_;
506
507 // The headers for the request to send.
508 //
509 // TODO(akalin): Hang onto this only until we send it. This
510 // necessitates stashing the URL separately.
Ben Murdocheb525c52013-07-10 11:40:50 +0100511 scoped_ptr<SpdyHeaderBlock> request_headers_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000512
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100513 // The data waiting to be sent.
514 scoped_refptr<DrainableIOBuffer> pending_send_data_;
515
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000516 // The time at which the request was made that resulted in this response.
517 // For cached responses, this time could be "far" in the past.
518 base::Time request_time_;
519
Ben Murdocheb525c52013-07-10 11:40:50 +0100520 SpdyHeaderBlock response_headers_;
521 SpdyResponseHeadersStatus response_headers_status_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000522 base::Time response_time_;
523
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000524 State io_state_;
525
526 // Since we buffer the response, we also buffer the response status.
527 // Not valid until the stream is closed.
528 int response_status_;
529
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000530 BoundNetLog net_log_;
531
532 base::TimeTicks send_time_;
533 base::TimeTicks recv_first_byte_time_;
534 base::TimeTicks recv_last_byte_time_;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100535
536 // Number of data bytes that have been sent/received on this stream, not
537 // including frame overhead. Note that this does not count headers.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000538 int send_bytes_;
539 int recv_bytes_;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100540
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000541 // Data received before delegate is attached.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100542 ScopedVector<SpdyBuffer> pending_buffers_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000543
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000544 std::string domain_bound_private_key_;
545 std::string domain_bound_cert_;
546 ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_;
547
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100548 // When OnFrameWriteComplete() is called, these variables are set.
549 SpdyFrameType just_completed_frame_type_;
550 size_t just_completed_frame_size_;
551
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000552 DISALLOW_COPY_AND_ASSIGN(SpdyStream);
553};
554
555} // namespace net
556
557#endif // NET_SPDY_SPDY_STREAM_H_