15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_SPDY_SPDY_STREAM_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_SPDY_SPDY_STREAM_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <deque> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_vector.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/bandwidth_metrics.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/request_priority.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h" 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/spdy/spdy_buffer.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_framer.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_header_block.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_protocol.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_client_cert_type.h" 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AddressList; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IPEndPoint; 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct LoadTimingInfo; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SSLCertRequestInfo; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SSLInfo; 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class SpdySession; 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)enum SpdyStreamType { 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The most general type of stream; there are no restrictions on 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // when data can be sent and received. 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_BIDIRECTIONAL_STREAM, 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // A stream where the client sends a request with possibly a body, 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // and the server then sends a response with a body. 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_REQUEST_RESPONSE_STREAM, 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // A server-initiated stream where the server just sends a response 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // with a body and the client does not send anything. 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SPDY_PUSH_STREAM 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Passed to some SpdyStream functions to indicate whether there's 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// more data to send. 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum SpdySendStatus { 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MORE_DATA_TO_SEND, 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NO_MORE_DATA_TO_SEND 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Returned by SpdyStream::OnResponseHeadersUpdated() to indicate 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// whether the current response headers are complete or not. 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochenum SpdyResponseHeadersStatus { 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RESPONSE_HEADERS_ARE_INCOMPLETE, 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RESPONSE_HEADERS_ARE_COMPLETE 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The SpdyStream is used by the SpdySession to represent each stream known 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on the SpdySession. This class provides interfaces for SpdySession to use. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Streams can be created either by the client or by the server. When they 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are initiated by the client, both the SpdySession and client object (such as 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a SpdyNetworkTransaction) will maintain a reference to the stream. When 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initiated by the server, only the SpdySession will maintain any reference, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// until such a time as a client object requests a stream for the path. 72a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)class NET_EXPORT_PRIVATE SpdyStream { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delegate handles protocol specific behavior of spdy stream. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class NET_EXPORT_PRIVATE Delegate { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate() {} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Called when the request headers have been sent. Never called 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // for push streams. Must not cause the stream to be closed. 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void OnRequestHeadersSent() = 0; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // WARNING: This function is complicated! Be sure to read the 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // whole comment below if you're working with code that implements 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // or calls this function. 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Called when the response headers are updated from the 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // server. |response_headers| contains the set of all headers 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // received up to this point; delegates can assume that any 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // headers previously received remain unchanged. 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This is called at least once before any data is received. If 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this will be 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // called again when more headers are received until 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // RESPONSE_HEADERS_ARE_COMPLETE is returned, and any data 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // received before then will be treated as a protocol error. 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If RESPONSE_HEADERS_ARE_INCOMPLETE is returned, the delegate 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // must not have closed the stream. Otherwise, if 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // RESPONSE_HEADERS_ARE_COMPLETE is returned, the delegate has 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // processed the headers successfully. However, it still may have 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // closed the stream, e.g. if the headers indicated an error 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // condition. 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Some type-specific behavior: 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // - For bidirectional streams, this may be called even after 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // data is received, but it is expected that 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // RESPONSE_HEADERS_ARE_COMPLETE is always returned. If 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this is 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // treated as a protocol error. 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // - For request/response streams, this function is called 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // exactly once before data is received, and it is expected 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // that RESPONSE_HEADERS_ARE_COMPLETE is returned. If 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // RESPONSE_HEADERS_ARE_INCOMPLETE is returned, this is 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // treated as a protocol error. 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // - For push streams, it is expected that this function will be 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // called until RESPONSE_HEADERS_ARE_COMPLETE is returned 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // before any data is received; any deviation from this is 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // treated as a protocol error. 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(akalin): Treat headers received after data has been 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // received as a protocol error for non-bidirectional streams. 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(jgraettinger): This should be at the semantic (HTTP) rather 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // than stream layer. Streams shouldn't have a notion of header 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // completeness. Move to SpdyHttpStream/SpdyWebsocketStream. 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual SpdyResponseHeadersStatus OnResponseHeadersUpdated( 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SpdyHeaderBlock& response_headers) = 0; 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Called when data is received after all required response 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // headers have been received. |buffer| may be NULL, which signals 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // EOF. Must return OK if the data was received successfully, or 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // a network error code otherwise. 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // May cause the stream to be closed. 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) = 0; 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Called when data is sent. Must not cause the stream to be 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // closed. 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void OnDataSent() = 0; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Called when SpdyStream is closed. No other delegate functions 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will be called after this is called, and the delegate must not 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // access the stream after this is called. Must not cause the 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // stream to be be (re-)closed. 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(akalin): Allow this function to re-close the stream and 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // handle it gracefully. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnClose(int status) = 0; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Delegate() {} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Delegate); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SpdyStream constructor 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdyStream(SpdyStreamType type, 162ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::WeakPtr<SpdySession>& session, 163ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GURL& url, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestPriority priority, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 initial_send_window_size, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 initial_recv_window_size, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 169a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ~SpdyStream(); 170a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Set the delegate, which must not be NULL. Must not be called more 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // than once. For push streams, calling this may cause buffered data 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // to be sent to the delegate (from a posted task). 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetDelegate(Delegate* delegate); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 176a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Detach the delegate from the stream, which must not yet be 177a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // closed, and cancel it. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DetachDelegate(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The time at which the first bytes of the response were received 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // from the server, or null if the response hasn't been received 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // yet. 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Time response_time() const { return response_time_; } 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdyStreamType type() const { return type_; } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyStreamId stream_id() const { return stream_id_; } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_stream_id(SpdyStreamId stream_id) { stream_id_ = stream_id; } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GURL& url() const { return url_; } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestPriority priority() const { return priority_; } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 send_window_size() const { return send_window_size_; } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 recv_window_size() const { return recv_window_size_; } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 198a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) bool send_stalled_by_flow_control() const { 199a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return send_stalled_by_flow_control_; 200a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_send_stalled_by_flow_control(bool stalled) { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) send_stalled_by_flow_control_ = stalled; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called by the session to adjust this stream's send window size by 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |delta_window_size|, which is the difference between the 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // SETTINGS_INITIAL_WINDOW_SIZE in the most recent SETTINGS frame 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // and the previous initial send window size, possibly unstalling 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // this stream. Although |delta_window_size| may cause this stream's 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // send window size to go negative, it must not cause it to wrap 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // around in either direction. Does nothing if the stream is already 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // closed. 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If stream flow control is turned off, this must not be called. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AdjustSendWindowSize(int32 delta_window_size); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when bytes are consumed from a SpdyBuffer for a DATA frame 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // that is to be written or is being written. Increases the send 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // window size accordingly if some or all of the SpdyBuffer is being 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // discarded. 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If stream flow control is turned off, this must not be called. 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnWriteBufferConsumed(size_t frame_payload_size, 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t consume_size, 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyBuffer::ConsumeSource consume_source); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called by the session to increase this stream's send window size 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // by |delta_window_size| (which must be at least 1) from a received 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // WINDOW_UPDATE frame or from a dropped DATA frame that was 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // intended to be sent, possibly unstalling this stream. If 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |delta_window_size| would cause this stream's send window size to 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // overflow, calls into the session to reset this stream. Does 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // nothing if the stream is already closed. 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If stream flow control is turned off, this must not be called. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void IncreaseSendWindowSize(int32 delta_window_size); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If stream flow control is turned on, called by the session to 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // decrease this stream's send window size by |delta_window_size|, 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which must be at least 0 and at most kMaxSpdyFrameChunkSize. 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |delta_window_size| must not cause this stream's send window size 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to go negative. Does nothing if the stream is already closed. 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If stream flow control is turned off, this must not be called. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecreaseSendWindowSize(int32 delta_window_size); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when bytes are consumed by the delegate from a SpdyBuffer 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // containing received data. Increases the receive window size 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // accordingly. 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If stream flow control is turned off, this must not be called. 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnReadBufferConsumed(size_t consume_size, 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyBuffer::ConsumeSource consume_source); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called by OnReadBufferConsume to increase this stream's receive 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // window size by |delta_window_size|, which must be at least 1 and 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // must not cause this stream's receive window size to overflow, 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // possibly also sending a WINDOW_UPDATE frame. Does nothing if the 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // stream is not active. 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If stream flow control is turned off, this must not be called. 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void IncreaseRecvWindowSize(int32 delta_window_size); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called by OnDataReceived (which is in turn called by the session) 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to decrease this stream's receive window size by 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |delta_window_size|, which must be at least 1 and must not cause 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // this stream's receive window size to go negative. 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If stream flow control is turned off or the stream is not active, 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // this must not be called. 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void DecreaseRecvWindowSize(int32 delta_window_size); 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetPeerAddress(IPEndPoint* address) const; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetLocalAddress(IPEndPoint* address) const; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the underlying transport socket ever had any reads or 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // writes. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WasEverUsed() const; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log() const { return net_log_; } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time GetRequestTime() const; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetRequestTime(base::Time t); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Called at most once by the SpdySession when the initial response 287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // headers have been received for this stream, i.e., a SYN_REPLY (or 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // SYN_STREAM for push streams) frame has been received. Returns a status 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // code; if it is an error, the stream was closed by this function. 290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int OnInitialResponseHeadersReceived(const SpdyHeaderBlock& response_headers, 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Time response_time, 292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::TimeTicks recv_first_byte_time); 293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Called by the SpdySession (only after 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // OnInitialResponseHeadersReceived() has been called) when 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // late-bound headers are received for a stream. Returns a status 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // code; if it is an error, the stream was closed by this function. 298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int OnAdditionalResponseHeadersReceived( 299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const SpdyHeaderBlock& additional_response_headers); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Called by the SpdySession when a frame carrying request headers opening a 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // push stream is received. Stream transits to STATE_RESERVED_REMOTE state. 3036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) void OnPushPromiseHeadersReceived(const SpdyHeaderBlock& headers); 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Called by the SpdySession when response data has been received 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // for this stream. This callback may be called multiple times as 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // data arrives from the network, and will never be called prior to 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // OnResponseHeadersReceived. 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |buffer| contains the data received, or NULL if the stream is 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // being closed. The stream must copy any data from this 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // buffer before returning from this callback. 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |length| is the number of bytes received (at most 2^24 - 1) or 0 if 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the stream is being closed. 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnDataReceived(scoped_ptr<SpdyBuffer> buffer); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called by the SpdySession when a frame has been successfully and 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // completely written. |frame_size| is the total size of the frame 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // in bytes, including framing overhead. 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnFrameWriteComplete(SpdyFrameType frame_type, size_t frame_size); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SYN_STREAM-specific write handler invoked by OnFrameWriteComplete(). 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int OnRequestHeadersSent(); 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // DATA-specific write handler invoked by OnFrameWriteComplete(). 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If more data is already available to be written, the next write is 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // queued and ERR_IO_PENDING is returned. Returns OK otherwise. 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int OnDataSent(size_t frame_size); 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by the SpdySession when the request is finished. This callback 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will always be called at the end of the request and signals to the 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stream that the stream has no more network events. No further callbacks 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the stream will be made after this call. 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |status| is an error code or OK. 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnClose(int status); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by the SpdySession to log stream related errors. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void LogStreamError(int status, const std::string& description); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 341a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // If this stream is active, reset it, and close it otherwise. In 342a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // either case the stream is deleted. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Cancel(); 344a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 345a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Close this stream without sending a RST_STREAM and delete 346a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // it. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Close(); 348a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 349ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Must be used only by |session_|. 350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::WeakPtr<SpdyStream> GetWeakPtr(); 351a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Interface for the delegate to use. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Only one send can be in flight at a time, except for push 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // streams, which must not send anything. 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Sends the request headers. The delegate is called back via 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // OnRequestHeadersSent() when the request headers have completed 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // sending. |send_status| must be MORE_DATA_TO_SEND for 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // bidirectional streams; for request/response streams, it must be 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // MORE_DATA_TO_SEND if the request has data to upload, or 36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NO_MORE_DATA_TO_SEND if not. 363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers, 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySendStatus send_status); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Sends a DATA frame. The delegate will be notified via 36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // OnDataSent() when the send is complete. |send_status| must be 36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // MORE_DATA_TO_SEND for bidirectional streams; for request/response 36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // streams, it must be MORE_DATA_TO_SEND if there is more data to 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // upload, or NO_MORE_DATA_TO_SEND if not. 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void SendData(IOBuffer* data, int length, SpdySendStatus send_status); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fills SSL info in |ssl_info| and returns true when SSL is in use. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetSSLInfo(SSLInfo* ssl_info, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* was_npn_negotiated, 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NextProto* protocol_negotiated); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fills SSL Certificate Request info |cert_request_info| and returns 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // true when SSL is in use. 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the stream is stalled on sending data, but the session is not 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // stalled on sending data and |send_window_size_| is positive, then 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // set |send_stalled_by_flow_control_| to false and unstall the data 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // sending. Called by the session or by the stream itself. Must be 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // called only when the stream is still open. 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void PossiblyResumeIfSendStalled(); 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns whether or not this stream is closed. Note that the only 390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // time a stream is closed and not deleted is in its delegate's 391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // OnClose() method. 392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool IsClosed() const; 393a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns whether the streams local endpoint is closed. 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The remote endpoint may still be active. 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool IsLocallyClosed() const; 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns whether this stream is IDLE: request and response headers 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // have neither been sent nor receieved. 400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool IsIdle() const; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns whether or not this stream is fully open: that request and 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // response headers are complete, and it is not in a half-closed state. 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool IsOpen() const; 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Returns whether the stream is reserved by remote endpoint: server has sent 4076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // intended request headers for a pushed stream, but haven't started response 4086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // yet. 4096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool IsReservedRemote() const; 4106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 411558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Returns the protocol used by this stream. Always between 4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // kProtoSPDYMinimumVersion and kProtoSPDYMaximumVersion. 413558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch NextProto GetProtocol() const; 414558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_status() const { return response_status_; } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void IncrementRawReceivedBytes(size_t received_bytes) { 418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) raw_received_bytes_ += received_bytes; 419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int64 raw_received_bytes() const { return raw_received_bytes_; } 422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Get the URL from the appropriate stream headers, or the empty 426ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // GURL() if it is unknown. 427ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // 428ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // TODO(akalin): Figure out if we really need this function, 429ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // i.e. can we just use the URL this stream was created with and/or 430ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // one we receive headers validate that the URL from them is the 431ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // same. 432ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GURL GetUrlFromHeaders() const; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns whether the URL for this stream is known. 435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // 436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(akalin): Remove this, as it's only used in tests. 437ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool HasUrlFromHeaders() const; 438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SpdyMajorVersion GetProtocolVersion() const; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) class SynStreamBufferProducer; 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) class HeaderBufferProducer; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SpdyStream states and transitions are modeled 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // on the HTTP/2 stream state machine. All states and transitions 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // are modeled, with the exceptions of RESERVED_LOCAL (the client 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // cannot initate push streams), and the transition to OPEN due to 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a remote SYN_STREAM (the client can only initate streams). 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum State { 451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch STATE_IDLE, 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STATE_OPEN, 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STATE_HALF_CLOSED_LOCAL_UNCLAIMED, 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STATE_HALF_CLOSED_LOCAL, 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STATE_HALF_CLOSED_REMOTE, 456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) STATE_RESERVED_REMOTE, 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STATE_CLOSED, 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the histograms. Can safely be called repeatedly, but should only 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be called after the stream has completed. 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdateHistograms(); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // When a server-push stream is claimed by SetDelegate(), this function is 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // posted on the current MessageLoop to replay everything the server has sent. 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // From the perspective of SpdyStream's state machine, headers, data, and 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // FIN states received prior to the delegate being attached have not yet been 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // read. While buffered by |pending_recv_data_| it's not until 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // PushedStreamReplay() is invoked that reads are considered 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to have occurred, driving the state machine forward. 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void PushedStreamReplay(); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Produces the SYN_STREAM frame for the stream. The stream must 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // already be activated. 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> ProduceSynStreamFrame(); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Produce the initial HEADER frame for the stream with the given 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // block. The stream must already be activated. 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyFrame> ProduceHeaderFrame( 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<SpdyHeaderBlock> header_block); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Queues the send for next frame of the remaining data in 48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // |pending_send_data_|. Must be called only when 48490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // |pending_send_data_| is set. 48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void QueueNextDataFrame(); 48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Merge the given headers into |response_headers_| and calls 488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // OnResponseHeadersUpdated() on the delegate (if attached). 489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns a status code; if it is an error, the stream was closed 490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // by this function. 491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int MergeWithResponseHeaders(const SpdyHeaderBlock& new_response_headers); 492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static std::string DescribeState(State state); 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SpdyStreamType type_; 49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyStreamId stream_id_; 498ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GURL url_; 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const RequestPriority priority_; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flow control variables. 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool send_stalled_by_flow_control_; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 send_window_size_; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 recv_window_size_; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 unacked_recv_window_bytes_; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedBandwidthMetrics metrics_; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 509ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::WeakPtr<SpdySession> session_; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The transaction should own the delegate. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyStream::Delegate* delegate_; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The headers for the request to send. 51590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 51690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(akalin): Hang onto this only until we send it. This 51790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // necessitates stashing the URL separately. 518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<SpdyHeaderBlock> request_headers_; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Data waiting to be sent, and the close state of the local endpoint 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // after the data is fully written. 52290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<DrainableIOBuffer> pending_send_data_; 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdySendStatus pending_send_status_; 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Data waiting to be received, and the close state of the remote endpoint 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // after the data is fully read. Specifically, data received before the 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // delegate is attached must be buffered and later replayed. A remote FIN 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // is represented by a final, zero-length buffer. 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedVector<SpdyBuffer> pending_recv_data_; 53090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The time at which the request was made that resulted in this response. 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For cached responses, this time could be "far" in the past. 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time request_time_; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyHeaderBlock response_headers_; 536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdyResponseHeadersStatus response_headers_status_; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time response_time_; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State io_state_; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we buffer the response, we also buffer the response status. 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not valid until the stream is closed. 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_status_; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog net_log_; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks send_time_; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks recv_first_byte_time_; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks recv_last_byte_time_; 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Number of bytes that have been received on this stream, including frame 552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // overhead and headers. 553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int64 raw_received_bytes_; 554a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Number of data bytes that have been sent/received on this stream, not 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // including frame overhead. Note that this does not count headers. 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int send_bytes_; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int recv_bytes_; 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 560effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Guards calls of delegate write handlers ensuring |this| is not destroyed. 561effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(jgraettinger): Consider removing after crbug.com/35511 is tracked 562effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // down. 563effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool write_handler_guard_; 564effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtrFactory<SpdyStream> weak_ptr_factory_; 566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SpdyStream); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_SPDY_SPDY_STREAM_H_ 573