| 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 |
| 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 |