blob: 14063fb0e47758ff6441e161caeb5855dd86a6d0 [file] [log] [blame]
xunjieli11834f02015-12-22 04:27:081// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_HTTP_BIDIRECTIONAL_STREAM_H_
6#define NET_HTTP_BIDIRECTIONAL_STREAM_H_
7
8#include <stdint.h>
9
10#include "base/compiler_specific.h"
11#include "base/macros.h"
12#include "base/memory/scoped_ptr.h"
13#include "net/http/bidirectional_stream_job.h"
14#include "net/http/http_stream_factory.h"
15#include "net/log/net_log.h"
16
Nico Weber13d106e2015-12-22 21:41:5617#if !defined(ENABLE_BIDIRECTIONAL_STREAM)
18#error Only include this if ENABLE_BIDIRECTIONAL_STREAM is defined
19#endif
20
xunjieli11834f02015-12-22 04:27:0821class GURL;
22
23namespace net {
24
25class HttpAuthController;
26class HttpNetworkSession;
27class HttpStream;
28class HttpStreamRequest;
29class IOBuffer;
30class ProxyInfo;
31class SpdyHeaderBlock;
32struct BidirectionalStreamRequestInfo;
33struct SSLConfig;
34
35// A class to do HTTP/2 bidirectional streaming. Note that at most one each of
36// ReadData or SendData should be in flight until the operation completes.
37// The BidirectionalStream must be torn down before the HttpNetworkSession.
38class NET_EXPORT BidirectionalStream
39 : public NON_EXPORTED_BASE(BidirectionalStreamJob::Delegate),
40 public NON_EXPORTED_BASE(HttpStreamRequest::Delegate) {
41 public:
42 // Delegate interface to get notified of success of failure. Callbacks will be
43 // invoked asynchronously.
44 class NET_EXPORT Delegate {
45 public:
46 Delegate();
47
48 // Called when headers have been sent. This is called at most once for
49 // the lifetime of a stream.
50 // The delegate may call BidirectionalStream::ReadData to start reading,
51 // or call BidirectionalStream::SendData to send data.
52 // The delegate should not call BidirectionalStream::Cancel
53 // during this callback.
54 virtual void OnHeadersSent() = 0;
55
56 // Called when headers are received. This is called at most once for the
57 // lifetime of a stream.
58 // The delegate may call BidirectionalStream::ReadData to start reading,
59 // call BidirectionalStream::SendData to send data,
60 // or call BidirectionalStream::Cancel to cancel the stream.
61 virtual void OnHeadersReceived(const SpdyHeaderBlock& response_headers) = 0;
62
63 // Called when a pending read is completed asynchronously.
64 // |bytes_read| specifies how much data is read.
65 // The delegate may call BidirectionalStream::ReadData to continue
66 // reading, call BidirectionalStream::SendData to send data,
67 // or call BidirectionalStream::Cancel to cancel the stream.
68 virtual void OnDataRead(int bytes_read) = 0;
69
70 // Called when the entire buffer passed through SendData is sent.
71 // The delegate may call BidirectionalStream::ReadData to continue
72 // reading, call BidirectionalStream::SendData to send data,
73 // The delegate should not call BidirectionalStream::Cancel
74 // during this callback.
75 virtual void OnDataSent() = 0;
76
77 // Called when trailers are received. This is called as soon as trailers
78 // are received, which can happen before a read completes.
79 // The delegate is able to continue reading if there is no pending read and
80 // EOF has not been received, or to send data if there is no pending send.
81 virtual void OnTrailersReceived(const SpdyHeaderBlock& trailers) = 0;
82
83 // Called when the stream is closed or an error occurred.
84 // No other delegate functions will be called after this.
85 virtual void OnFailed(int error) = 0;
86
87 protected:
88 virtual ~Delegate();
89
90 private:
91 DISALLOW_COPY_AND_ASSIGN(Delegate);
92 };
93
94 // Constructs a BidirectionalStream. |request_info| contains information about
95 // the request, and must be non-NULL. |session| is the http network session
96 // with which this request will be made. |delegate| must be non-NULL.
97 // |session| and |delegate| must outlive |this|.
98 BidirectionalStream(scoped_ptr<BidirectionalStreamRequestInfo> request_info,
99 HttpNetworkSession* session,
100 Delegate* delegate);
101
102 // Constructor that accepts a Timer, which can be used in tests to control
103 // the buffering of received data.
104 BidirectionalStream(scoped_ptr<BidirectionalStreamRequestInfo> request_info,
105 HttpNetworkSession* session,
106 Delegate* delegate,
107 scoped_ptr<base::Timer> timer);
108
109 // Cancels |stream_request_| or |stream_job_| if applicable.
110 // |this| should not be destroyed during Delegate::OnHeadersSent or
111 // Delegate::OnDataSent.
112 ~BidirectionalStream() override;
113
114 // Reads at most |buf_len| bytes into |buf|. Returns the number of bytes read,
115 // or ERR_IO_PENDING if the read is to be completed asynchronously, or an
116 // error code if any error occurred. If returns 0, there is no more data to
117 // read. This should not be called before Delegate::OnHeadersReceived is
118 // invoked, and should not be called again unless it returns with number
119 // greater than 0 or until Delegate::OnDataRead is invoked.
120 int ReadData(IOBuffer* buf, int buf_len);
121
122 // Sends data. This should not be called before Delegate::OnHeadersSent is
123 // invoked, and should not be called again until Delegate::OnDataSent is
124 // invoked. If |end_stream| is true, the DATA frame will have an END_STREAM
125 // flag.
126 void SendData(IOBuffer* data, int length, bool end_stream);
127
128 // If |stream_request_| is non-NULL, cancel it. If |stream_job_| is
129 // established, cancel it. No delegate method will be called after Cancel().
130 // Any pending operations may or may not succeed.
131 void Cancel();
132
133 // Returns the protocol used by this stream. If stream has not been
134 // established, return kProtoUnknown.
135 NextProto GetProtocol() const;
136
137 // Total number of bytes received over the network of SPDY data, headers, and
138 // push_promise frames associated with this stream, including the size of
139 // frame headers, after SSL decryption and not including proxy overhead.
140 // If stream has not been established, return 0.
141 int64_t GetTotalReceivedBytes() const;
142
143 // Total number of bytes sent over the network of SPDY frames associated with
144 // this stream, including the size of frame headers, before SSL encryption and
145 // not including proxy overhead. Note that some SPDY frames such as pings are
146 // not associated with any stream, and are not included in this value.
147 int64_t GetTotalSentBytes() const;
148
149 // TODO(xunjieli): Implement a method to do flow control and a method to ping
150 // remote end point.
151
152 private:
153 // BidirectionalStreamJob::Delegate implementation:
154 void OnHeadersSent() override;
155 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override;
156 void OnDataRead(int bytes_read) override;
157 void OnDataSent() override;
158 void OnTrailersReceived(const SpdyHeaderBlock& trailers) override;
159 void OnFailed(int error) override;
160
161 // HttpStreamRequest::Delegate implementation:
162 void OnStreamReady(const SSLConfig& used_ssl_config,
163 const ProxyInfo& used_proxy_info,
164 HttpStream* stream) override;
165 void OnBidirectionalStreamJobReady(const SSLConfig& used_ssl_config,
166 const ProxyInfo& used_proxy_info,
167 BidirectionalStreamJob* stream) override;
168 void OnWebSocketHandshakeStreamReady(
169 const SSLConfig& used_ssl_config,
170 const ProxyInfo& used_proxy_info,
171 WebSocketHandshakeStreamBase* stream) override;
172 void OnStreamFailed(int status,
173 const SSLConfig& used_ssl_config,
174 SSLFailureState ssl_failure_state) override;
175 void OnCertificateError(int status,
176 const SSLConfig& used_ssl_config,
177 const SSLInfo& ssl_info) override;
178 void OnNeedsProxyAuth(const HttpResponseInfo& response_info,
179 const SSLConfig& used_ssl_config,
180 const ProxyInfo& used_proxy_info,
181 HttpAuthController* auth_controller) override;
182 void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
183 SSLCertRequestInfo* cert_info) override;
184 void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
185 const SSLConfig& used_ssl_config,
186 const ProxyInfo& used_proxy_info,
187 HttpStream* stream) override;
188 void OnQuicBroken() override;
189
190 // BidirectionalStreamRequestInfo used when requesting the stream.
191 scoped_ptr<BidirectionalStreamRequestInfo> request_info_;
192 const BoundNetLog net_log_;
193
194 Delegate* const delegate_;
195
196 // Timer used to buffer data received in short time-spans and send a single
197 // read completion notification.
198 scoped_ptr<base::Timer> timer_;
199 // HttpStreamRequest used to request a BidirectionalStreamJob. This is NULL if
200 // the request has been canceled or completed.
201 scoped_ptr<HttpStreamRequest> stream_request_;
202 // The underlying BidirectioanlStreamJob used for this stream. It is non-NULL,
203 // if the |stream_request_| successfully finishes.
204 scoped_ptr<BidirectionalStreamJob> stream_job_;
205
206 DISALLOW_COPY_AND_ASSIGN(BidirectionalStream);
207};
208
209} // namespace net
210
211#endif // NET_HTTP_BIDIRECTIONAL_STREAM_H_