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