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