OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_SPDY_SPDY_STREAM_H_ | 5 #ifndef NET_SPDY_SPDY_STREAM_H_ |
6 #define NET_SPDY_SPDY_STREAM_H_ | 6 #define NET_SPDY_SPDY_STREAM_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
15 #include "base/memory/scoped_vector.h" | 15 #include "base/memory/scoped_vector.h" |
16 #include "base/memory/weak_ptr.h" | 16 #include "base/memory/weak_ptr.h" |
17 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
18 #include "net/base/bandwidth_metrics.h" | 18 #include "net/base/bandwidth_metrics.h" |
19 #include "net/base/io_buffer.h" | 19 #include "net/base/io_buffer.h" |
20 #include "net/base/net_export.h" | 20 #include "net/base/net_export.h" |
21 #include "net/base/net_log.h" | 21 #include "net/base/net_log.h" |
22 #include "net/base/request_priority.h" | 22 #include "net/base/request_priority.h" |
23 #include "net/socket/ssl_client_socket.h" | 23 #include "net/socket/ssl_client_socket.h" |
24 #include "net/spdy/spdy_buffer.h" | |
24 #include "net/spdy/spdy_framer.h" | 25 #include "net/spdy/spdy_framer.h" |
25 #include "net/spdy/spdy_header_block.h" | 26 #include "net/spdy/spdy_header_block.h" |
26 #include "net/spdy/spdy_protocol.h" | 27 #include "net/spdy/spdy_protocol.h" |
27 #include "net/spdy/spdy_session.h" | |
28 #include "net/ssl/server_bound_cert_service.h" | 28 #include "net/ssl/server_bound_cert_service.h" |
29 #include "net/ssl/ssl_client_cert_type.h" | 29 #include "net/ssl/ssl_client_cert_type.h" |
30 | 30 |
31 namespace net { | 31 namespace net { |
32 | 32 |
33 class AddressList; | 33 class AddressList; |
34 class IPEndPoint; | 34 class IPEndPoint; |
35 class SSLCertRequestInfo; | 35 class SSLCertRequestInfo; |
36 class SSLInfo; | 36 class SSLInfo; |
37 class SpdySession; | |
38 | |
39 enum SpdyStreamType { | |
40 // The most general type of stream; there are no restrictions on | |
41 // when data can be sent and received. | |
42 SPDY_BIDIRECTIONAL_STREAM, | |
43 // A stream where the client sends a request with possibly a body, | |
44 // and the server then sends a response with a body. | |
45 SPDY_REQUEST_RESPONSE_STREAM, | |
46 // A server-initiated stream where the server just sends a response | |
47 // with a body and the client does not send anything. | |
48 SPDY_PUSH_STREAM | |
49 }; | |
37 | 50 |
38 // Returned by some SpdyStream::Delegate functions to indicate whether | 51 // Returned by some SpdyStream::Delegate functions to indicate whether |
39 // there's more data to send. | 52 // there's more data to send. |
40 enum SpdySendStatus { | 53 enum SpdySendStatus { |
41 MORE_DATA_TO_SEND, | 54 MORE_DATA_TO_SEND, |
42 NO_MORE_DATA_TO_SEND | 55 NO_MORE_DATA_TO_SEND |
43 }; | 56 }; |
44 | 57 |
45 // The SpdyStream is used by the SpdySession to represent each stream known | 58 // The SpdyStream is used by the SpdySession to represent each stream known |
46 // on the SpdySession. This class provides interfaces for SpdySession to use. | 59 // 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 | 60 // 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 | 61 // are initiated by the client, both the SpdySession and client object (such as |
49 // a SpdyNetworkTransaction) will maintain a reference to the stream. When | 62 // a SpdyNetworkTransaction) will maintain a reference to the stream. When |
50 // initiated by the server, only the SpdySession will maintain any reference, | 63 // 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. | 64 // until such a time as a client object requests a stream for the path. |
52 class NET_EXPORT_PRIVATE SpdyStream { | 65 class NET_EXPORT_PRIVATE SpdyStream { |
53 public: | 66 public: |
54 // Delegate handles protocol specific behavior of spdy stream. | 67 // Delegate handles protocol specific behavior of spdy stream. |
55 class NET_EXPORT_PRIVATE Delegate { | 68 class NET_EXPORT_PRIVATE Delegate { |
56 public: | 69 public: |
57 Delegate() {} | 70 Delegate() {} |
58 | 71 |
59 // Called when the request headers have been sent. Must return | 72 // Called when the request headers have been sent. Never called |
60 // whether there's body data to send. | 73 // for push streams. |
61 // | 74 virtual void OnSendRequestHeadersComplete() = 0; |
62 // There's some redundancy in SendRequestHeaders() taking a | |
63 // SpdySendStatus and this function returning one, but it's | |
64 // necessary. Bidirectional streams always pass in | |
65 // MORE_DATA_TO_SEND to SendRequestHeaders() but must return | |
66 // NO_MORE_DATA_TO_SEND from OnSendRequestHeadersComplete(), while | |
67 // request/response streams always return the same value from | |
68 // OnSendRequestHeadersComplete() as the one they pass into | |
69 // SendRequestHeaders(). | |
70 // | |
71 // TODO(akalin): Have a less subtle way of differentiating | |
72 // request/response streams from bidirectional ones. | |
73 virtual SpdySendStatus OnSendRequestHeadersComplete() = 0; | |
74 | 75 |
75 // Called when the stream is ready to send body data. The | 76 // Called when the stream is ready to send body data. The |
76 // delegate must call SendStreamData() on the stream, either | 77 // delegate must call SendStreamData() on the stream, either |
77 // immediately or asynchronously (e.g., if the data to be send has | 78 // immediately or asynchronously (e.g., if the data to be send has |
78 // to be read asynchronously). | 79 // to be read asynchronously). |
79 // | 80 // |
80 // Called only when OnSendRequestHeadersComplete() or | 81 // Called only for request/response streams when |
81 // OnSendBodyComplete() returns MORE_DATA_TO_SEND. | 82 // SendRequestHeaders() is called with MORE_DATA_TO_SEND. |
83 // | |
84 // TODO(akalin): Unify this with OnSendRequestHeadersComplete(). | |
82 virtual void OnSendBody() = 0; | 85 virtual void OnSendBody() = 0; |
83 | 86 |
84 // Called when body data has been sent. | 87 // Called when body data has been sent. |
88 // | |
89 // TODO(akalin): Unify this with OnDataSent(). | |
85 virtual void OnSendBodyComplete() = 0; | 90 virtual void OnSendBodyComplete() = 0; |
86 | 91 |
87 // Called when the SYN_STREAM, SYN_REPLY, or HEADERS frames are received. | 92 // Called when the SYN_STREAM, SYN_REPLY, or HEADERS frames are received. |
88 // Normal streams will receive a SYN_REPLY and optional HEADERS frames. | 93 // Normal streams will receive a SYN_REPLY and optional HEADERS frames. |
89 // Pushed streams will receive a SYN_STREAM and optional HEADERS frames. | 94 // Pushed streams will receive a SYN_STREAM and optional HEADERS frames. |
90 // Because a stream may have a SYN_* frame and multiple HEADERS frames, | 95 // Because a stream may have a SYN_* frame and multiple HEADERS frames, |
91 // this callback may be called multiple times. | 96 // this callback may be called multiple times. |
92 // |status| indicates network error. Returns network error code. | 97 // |status| indicates network error. Returns network error code. |
93 virtual int OnResponseReceived(const SpdyHeaderBlock& response, | 98 virtual int OnResponseReceived(const SpdyHeaderBlock& response, |
94 base::Time response_time, | 99 base::Time response_time, |
(...skipping 13 matching lines...) Expand all Loading... | |
108 virtual void OnClose(int status) = 0; | 113 virtual void OnClose(int status) = 0; |
109 | 114 |
110 protected: | 115 protected: |
111 virtual ~Delegate() {} | 116 virtual ~Delegate() {} |
112 | 117 |
113 private: | 118 private: |
114 DISALLOW_COPY_AND_ASSIGN(Delegate); | 119 DISALLOW_COPY_AND_ASSIGN(Delegate); |
115 }; | 120 }; |
116 | 121 |
117 // SpdyStream constructor | 122 // SpdyStream constructor |
118 SpdyStream(SpdySession* session, | 123 SpdyStream(SpdyStreamType type, |
124 SpdySession* session, | |
119 const std::string& path, | 125 const std::string& path, |
120 RequestPriority priority, | 126 RequestPriority priority, |
121 int32 initial_send_window_size, | 127 int32 initial_send_window_size, |
122 int32 initial_recv_window_size, | 128 int32 initial_recv_window_size, |
123 bool pushed, | |
124 const BoundNetLog& net_log); | 129 const BoundNetLog& net_log); |
125 | 130 |
126 ~SpdyStream(); | 131 ~SpdyStream(); |
127 | 132 |
128 // Set new |delegate|. |delegate| must not be NULL. | 133 // Set new |delegate|. |delegate| must not be NULL. |
129 // If it already received SYN_REPLY or data, OnResponseReceived() or | 134 // If it already received SYN_REPLY or data, OnResponseReceived() or |
130 // OnDataReceived() will be called. | 135 // OnDataReceived() will be called. |
131 void SetDelegate(Delegate* delegate); | 136 void SetDelegate(Delegate* delegate); |
132 Delegate* GetDelegate() { return delegate_; } | 137 Delegate* GetDelegate() { return delegate_; } |
133 | 138 |
134 // Detach the delegate from the stream, which must not yet be | 139 // Detach the delegate from the stream, which must not yet be |
135 // closed, and cancel it. | 140 // closed, and cancel it. |
136 void DetachDelegate(); | 141 void DetachDelegate(); |
137 | 142 |
138 // Is this stream a pushed stream from the server. | 143 SpdyStreamType type() const { return type_; } |
139 bool pushed() const { return pushed_; } | |
140 | 144 |
141 SpdyStreamId stream_id() const { return stream_id_; } | 145 SpdyStreamId stream_id() const { return stream_id_; } |
142 void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; } | 146 void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; } |
143 | 147 |
144 bool response_received() const { return response_received_; } | 148 bool response_received() const { return response_received_; } |
145 void set_response_received() { response_received_ = true; } | 149 void set_response_received() { response_received_ = true; } |
146 | 150 |
147 // For pushed streams, we track a path to identify them. | |
148 const std::string& path() const { return path_; } | 151 const std::string& path() const { return path_; } |
149 | 152 |
150 RequestPriority priority() const { return priority_; } | 153 RequestPriority priority() const { return priority_; } |
151 | 154 |
152 int32 send_window_size() const { return send_window_size_; } | 155 int32 send_window_size() const { return send_window_size_; } |
153 | 156 |
154 int32 recv_window_size() const { return recv_window_size_; } | 157 int32 recv_window_size() const { return recv_window_size_; } |
155 | 158 |
156 bool send_stalled_by_flow_control() const { | 159 bool send_stalled_by_flow_control() const { |
157 return send_stalled_by_flow_control_; | 160 return send_stalled_by_flow_control_; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
234 | 237 |
235 // Returns true if the underlying transport socket ever had any reads or | 238 // Returns true if the underlying transport socket ever had any reads or |
236 // writes. | 239 // writes. |
237 bool WasEverUsed() const; | 240 bool WasEverUsed() const; |
238 | 241 |
239 const BoundNetLog& net_log() const { return net_log_; } | 242 const BoundNetLog& net_log() const { return net_log_; } |
240 | 243 |
241 base::Time GetRequestTime() const; | 244 base::Time GetRequestTime() const; |
242 void SetRequestTime(base::Time t); | 245 void SetRequestTime(base::Time t); |
243 | 246 |
244 // Called by the SpdySession when a response (e.g. a SYN_STREAM or SYN_REPLY) | 247 // Called by the SpdySession when a response (e.g. a SYN_STREAM or |
245 // has been received for this stream. Returns a status code. | 248 // SYN_REPLY) has been received for this stream. This is the entry |
249 // point for a push stream. Returns a status code. | |
246 int OnResponseReceived(const SpdyHeaderBlock& response); | 250 int OnResponseReceived(const SpdyHeaderBlock& response); |
247 | 251 |
248 // Called by the SpdySession when late-bound headers are received for a | 252 // Called by the SpdySession when late-bound headers are received for a |
249 // stream. Returns a status code. | 253 // stream. Returns a status code. |
250 int OnHeaders(const SpdyHeaderBlock& headers); | 254 int OnHeaders(const SpdyHeaderBlock& headers); |
251 | 255 |
252 // Called by the SpdySession when response data has been received for this | 256 // Called by the SpdySession when response data has been received for this |
253 // stream. This callback may be called multiple times as data arrives | 257 // stream. This callback may be called multiple times as data arrives |
254 // from the network, and will never be called prior to OnResponseReceived. | 258 // from the network, and will never be called prior to OnResponseReceived. |
255 // | 259 // |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 // Returns whether or not this stream is closed. Note that the only | 291 // Returns whether or not this stream is closed. Note that the only |
288 // time a stream is closed and not deleted is in its delegate's | 292 // time a stream is closed and not deleted is in its delegate's |
289 // OnClose() method. | 293 // OnClose() method. |
290 bool closed() const { return io_state_ == STATE_DONE; } | 294 bool closed() const { return io_state_ == STATE_DONE; } |
291 | 295 |
292 // TODO(satorux): This is only for testing. We should be able to remove | 296 // TODO(satorux): This is only for testing. We should be able to remove |
293 // this once crbug.com/113107 is addressed. | 297 // this once crbug.com/113107 is addressed. |
294 bool body_sent() const { return io_state_ > STATE_SEND_BODY_COMPLETE; } | 298 bool body_sent() const { return io_state_ > STATE_SEND_BODY_COMPLETE; } |
295 | 299 |
296 // Interface for the delegate to use. | 300 // Interface for the delegate to use. |
297 // | |
298 // TODO(akalin): Mandate that only one send can be in flight at one | |
299 // time. | |
300 | 301 |
301 // Sends the request headers. | 302 // Only one send can be in flight at a time, except for push |
302 // For non push stream, it will send SYN_STREAM frame. | 303 // streams, which must not send anything. |
304 | |
305 // Sends the request headers. The delegate is called back via | |
306 // OnSendRequestHeadersComplete() when the request headers have | |
307 // completed sending. |send_status| must be MORE_DATA_TO_SEND for | |
308 // bidirectional streams; for request/response streams, it must be | |
309 // MORE_DATA_TO_SEND if the request has data to upload, or | |
310 // NO_MORE_DATA_TO_SEND if not. | |
303 int SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> headers, | 311 int SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> headers, |
304 SpdySendStatus send_status); | 312 SpdySendStatus send_status); |
305 | 313 |
306 // Sends a DATA frame. The delegate will be notified via | 314 // Sends a DATA frame. The delegate will be notified via |
307 // OnSendBodyComplete() (if the response hasn't been received yet) | 315 // OnSendBodyComplete() (if the response hasn't been received yet) |
308 // or OnDataSent() (if the response has been received) when the send | 316 // or OnDataSent() (if the response has been received) when the send |
309 // is complete. Only one data send can be in flight at one time. | 317 // is complete. |send_status| must be MORE_DATA_TO_SEND for |
318 // bidirectional streams; for request/response streams, it must be | |
Ryan Hamilton
2013/05/26 15:33:49
What if a bidirectional stream knew (because of so
akalin
2013/05/27 08:13:35
Yeah, I think we eventually want to allow that. Fo
| |
319 // MORE_DATA_TO_SEND if there is more data to upload, or | |
320 // NO_MORE_DATA_TO_SEND if not. | |
310 void SendStreamData(IOBuffer* data, int length, SpdySendStatus send_status); | 321 void SendStreamData(IOBuffer* data, int length, SpdySendStatus send_status); |
311 | 322 |
312 // Fills SSL info in |ssl_info| and returns true when SSL is in use. | 323 // Fills SSL info in |ssl_info| and returns true when SSL is in use. |
313 bool GetSSLInfo(SSLInfo* ssl_info, | 324 bool GetSSLInfo(SSLInfo* ssl_info, |
314 bool* was_npn_negotiated, | 325 bool* was_npn_negotiated, |
315 NextProto* protocol_negotiated); | 326 NextProto* protocol_negotiated); |
316 | 327 |
317 // Fills SSL Certificate Request info |cert_request_info| and returns | 328 // Fills SSL Certificate Request info |cert_request_info| and returns |
318 // true when SSL is in use. | 329 // true when SSL is in use. |
319 bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); | 330 bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 // Produce the initial HEADER frame for the stream with the given | 413 // Produce the initial HEADER frame for the stream with the given |
403 // block. The stream must already be activated. | 414 // block. The stream must already be activated. |
404 scoped_ptr<SpdyFrame> ProduceHeaderFrame( | 415 scoped_ptr<SpdyFrame> ProduceHeaderFrame( |
405 scoped_ptr<SpdyHeaderBlock> header_block); | 416 scoped_ptr<SpdyHeaderBlock> header_block); |
406 | 417 |
407 // Queues the send for next frame of the remaining data in | 418 // Queues the send for next frame of the remaining data in |
408 // |pending_send_data_|. Must be called only when | 419 // |pending_send_data_|. Must be called only when |
409 // |pending_send_data_| and |pending_send_flags_| are set. | 420 // |pending_send_data_| and |pending_send_flags_| are set. |
410 void QueueNextDataFrame(); | 421 void QueueNextDataFrame(); |
411 | 422 |
423 const SpdyStreamType type_; | |
424 | |
412 base::WeakPtrFactory<SpdyStream> weak_ptr_factory_; | 425 base::WeakPtrFactory<SpdyStream> weak_ptr_factory_; |
413 | 426 |
414 // Sentinel variable used to make sure we don't get destroyed by a | 427 // Sentinel variable used to make sure we don't get destroyed by a |
415 // function called from DoLoop(). | 428 // function called from DoLoop(). |
416 bool in_do_loop_; | 429 bool in_do_loop_; |
417 | 430 |
418 // There is a small period of time between when a server pushed stream is | 431 // There is a small period of time between when a server pushed stream is |
419 // first created, and the pushed data is replayed. Any data received during | 432 // first created, and the pushed data is replayed. Any data received during |
420 // this time should continue to be buffered. | 433 // this time should continue to be buffered. |
421 bool continue_buffering_data_; | 434 bool continue_buffering_data_; |
422 | 435 |
423 SpdyStreamId stream_id_; | 436 SpdyStreamId stream_id_; |
424 const std::string path_; | 437 const std::string path_; |
425 const RequestPriority priority_; | 438 const RequestPriority priority_; |
426 size_t slot_; | 439 size_t slot_; |
427 | 440 |
428 // Flow control variables. | 441 // Flow control variables. |
429 bool send_stalled_by_flow_control_; | 442 bool send_stalled_by_flow_control_; |
430 int32 send_window_size_; | 443 int32 send_window_size_; |
431 int32 recv_window_size_; | 444 int32 recv_window_size_; |
432 int32 unacked_recv_window_bytes_; | 445 int32 unacked_recv_window_bytes_; |
433 | 446 |
434 const bool pushed_; | |
435 ScopedBandwidthMetrics metrics_; | 447 ScopedBandwidthMetrics metrics_; |
436 bool response_received_; | 448 bool response_received_; |
437 | 449 |
438 scoped_refptr<SpdySession> session_; | 450 scoped_refptr<SpdySession> session_; |
439 | 451 |
440 // The transaction should own the delegate. | 452 // The transaction should own the delegate. |
441 SpdyStream::Delegate* delegate_; | 453 SpdyStream::Delegate* delegate_; |
442 | 454 |
443 // Whether or not we have more data to send on this stream. | 455 // Whether or not we have more data to send on this stream. |
444 SpdySendStatus send_status_; | 456 SpdySendStatus send_status_; |
445 | 457 |
446 // The headers for the request to send. | 458 // The headers for the request to send. |
459 // | |
460 // TODO(akalin): Hang onto this only until we send it. This | |
461 // necessitates stashing the URL separately. | |
447 scoped_ptr<SpdyHeaderBlock> request_; | 462 scoped_ptr<SpdyHeaderBlock> request_; |
448 | 463 |
449 // The data waiting to be sent. | 464 // The data waiting to be sent. |
450 scoped_refptr<DrainableIOBuffer> pending_send_data_; | 465 scoped_refptr<DrainableIOBuffer> pending_send_data_; |
451 | 466 |
452 // The time at which the request was made that resulted in this response. | 467 // The time at which the request was made that resulted in this response. |
453 // For cached responses, this time could be "far" in the past. | 468 // For cached responses, this time could be "far" in the past. |
454 base::Time request_time_; | 469 base::Time request_time_; |
455 | 470 |
456 scoped_ptr<SpdyHeaderBlock> response_; | 471 scoped_ptr<SpdyHeaderBlock> response_; |
(...skipping 27 matching lines...) Expand all Loading... | |
484 // When OnFrameWriteComplete() is called, these variables are set. | 499 // When OnFrameWriteComplete() is called, these variables are set. |
485 SpdyFrameType just_completed_frame_type_; | 500 SpdyFrameType just_completed_frame_type_; |
486 size_t just_completed_frame_size_; | 501 size_t just_completed_frame_size_; |
487 | 502 |
488 DISALLOW_COPY_AND_ASSIGN(SpdyStream); | 503 DISALLOW_COPY_AND_ASSIGN(SpdyStream); |
489 }; | 504 }; |
490 | 505 |
491 } // namespace net | 506 } // namespace net |
492 | 507 |
493 #endif // NET_SPDY_SPDY_STREAM_H_ | 508 #endif // NET_SPDY_SPDY_STREAM_H_ |
OLD | NEW |