blob: 95e7f2e90f3b1cc243900cbb11904d9eae666f3f [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
danakj1fd259a02016-04-16 03:17:0910#include <memory>
11
xunjieli11834f02015-12-22 04:27:0812#include "base/compiler_specific.h"
13#include "base/macros.h"
xunjielibe07785e2016-04-14 21:15:2914#include "base/memory/ref_counted.h"
xunjieli5749218c2016-03-22 16:43:0615#include "net/http/bidirectional_stream_impl.h"
xunjieli11834f02015-12-22 04:27:0816#include "net/http/http_stream_factory.h"
17#include "net/log/net_log.h"
Nico Weber13d106e2015-12-22 21:41:5618
xunjieli11834f02015-12-22 04:27:0819class GURL;
20
21namespace net {
22
23class HttpAuthController;
24class HttpNetworkSession;
25class HttpStream;
26class HttpStreamRequest;
27class IOBuffer;
28class ProxyInfo;
29class SpdyHeaderBlock;
30struct BidirectionalStreamRequestInfo;
31struct SSLConfig;
32
33// A class to do HTTP/2 bidirectional streaming. Note that at most one each of
xunjieli07a42ce2016-04-26 20:05:3134// ReadData or SendData/SendvData should be in flight until the operation
35// completes. The BidirectionalStream must be torn down before the
36// HttpNetworkSession.
xunjieli11834f02015-12-22 04:27:0837class NET_EXPORT BidirectionalStream
xunjieli5749218c2016-03-22 16:43:0638 : public NON_EXPORTED_BASE(BidirectionalStreamImpl::Delegate),
xunjieli11834f02015-12-22 04:27:0839 public NON_EXPORTED_BASE(HttpStreamRequest::Delegate) {
40 public:
41 // Delegate interface to get notified of success of failure. Callbacks will be
42 // invoked asynchronously.
43 class NET_EXPORT Delegate {
44 public:
45 Delegate();
46
xunjieli07a42ce2016-04-26 20:05:3147 // Called when the stream is ready for writing and reading. This is called
48 // at most once for the lifetime of a stream.
xunjieli11834f02015-12-22 04:27:0849 // The delegate may call BidirectionalStream::ReadData to start reading,
50 // or call BidirectionalStream::SendData to send data.
51 // The delegate should not call BidirectionalStream::Cancel
52 // during this callback.
xunjielibcb0f86e2016-06-03 00:49:2953 // |request_headers_sent| if true, request headers have been sent. If false,
54 // SendRequestHeaders() needs to be explicitly called.
55 virtual void OnStreamReady(bool request_headers_sent) = 0;
xunjieli11834f02015-12-22 04:27:0856
57 // Called when headers are received. This is called at most once for the
58 // lifetime of a stream.
59 // The delegate may call BidirectionalStream::ReadData to start reading,
60 // call BidirectionalStream::SendData to send data,
61 // or call BidirectionalStream::Cancel to cancel the stream.
62 virtual void OnHeadersReceived(const SpdyHeaderBlock& response_headers) = 0;
63
64 // Called when a pending read is completed asynchronously.
65 // |bytes_read| specifies how much data is read.
66 // The delegate may call BidirectionalStream::ReadData to continue
67 // reading, call BidirectionalStream::SendData to send data,
68 // or call BidirectionalStream::Cancel to cancel the stream.
69 virtual void OnDataRead(int bytes_read) = 0;
70
71 // Called when the entire buffer passed through SendData is sent.
72 // The delegate may call BidirectionalStream::ReadData to continue
73 // reading, call BidirectionalStream::SendData to send data,
74 // The delegate should not call BidirectionalStream::Cancel
75 // during this callback.
76 virtual void OnDataSent() = 0;
77
78 // Called when trailers are received. This is called as soon as trailers
79 // are received, which can happen before a read completes.
80 // The delegate is able to continue reading if there is no pending read and
81 // EOF has not been received, or to send data if there is no pending send.
82 virtual void OnTrailersReceived(const SpdyHeaderBlock& trailers) = 0;
83
xunjieli707f8952016-06-06 15:22:0684 // Called when an error occurred. Do not call into the stream after this
85 // point. No other delegate functions will be called after this.
xunjieli11834f02015-12-22 04:27:0886 virtual void OnFailed(int error) = 0;
87
88 protected:
89 virtual ~Delegate();
90
91 private:
92 DISALLOW_COPY_AND_ASSIGN(Delegate);
93 };
94
95 // Constructs a BidirectionalStream. |request_info| contains information about
96 // the request, and must be non-NULL. |session| is the http network session
97 // with which this request will be made. |delegate| must be non-NULL.
98 // |session| and |delegate| must outlive |this|.
xunjielibcb0f86e2016-06-03 00:49:2999 // |send_request_headers_automatically| if true, request headers will be sent
100 // automatically when stream is negotiated. If false, request headers will be
101 // sent only when SendRequestHeaders() is invoked or with
102 // next SendData/SendvData.
danakj1fd259a02016-04-16 03:17:09103 BidirectionalStream(
104 std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
105 HttpNetworkSession* session,
xunjielibcb0f86e2016-06-03 00:49:29106 bool send_request_headers_automatically,
danakj1fd259a02016-04-16 03:17:09107 Delegate* delegate);
xunjieli11834f02015-12-22 04:27:08108
109 // Constructor that accepts a Timer, which can be used in tests to control
110 // the buffering of received data.
danakj1fd259a02016-04-16 03:17:09111 BidirectionalStream(
112 std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
113 HttpNetworkSession* session,
xunjielibcb0f86e2016-06-03 00:49:29114 bool send_request_headers_automatically,
danakj1fd259a02016-04-16 03:17:09115 Delegate* delegate,
116 std::unique_ptr<base::Timer> timer);
xunjieli11834f02015-12-22 04:27:08117
xunjieli5749218c2016-03-22 16:43:06118 // Cancels |stream_request_| or |stream_impl_| if applicable.
xunjieli11834f02015-12-22 04:27:08119 // |this| should not be destroyed during Delegate::OnHeadersSent or
120 // Delegate::OnDataSent.
121 ~BidirectionalStream() override;
122
xunjielibcb0f86e2016-06-03 00:49:29123 // Sends request headers to server.
124 // When |send_request_headers_automatically_| is
125 // false and OnStreamReady() is invoked with request_headers_sent = false,
126 // headers will be combined with next SendData/SendvData unless this
127 // method is called first, in which case headers will be sent separately
128 // without delay.
129 // (This method cannot be called when |send_request_headers_automatically_| is
130 // true nor when OnStreamReady() is invoked with request_headers_sent = true,
131 // since headers have been sent by the stream when stream is negotiated
132 // successfully.)
133 void SendRequestHeaders();
134
xunjieli11834f02015-12-22 04:27:08135 // Reads at most |buf_len| bytes into |buf|. Returns the number of bytes read,
136 // or ERR_IO_PENDING if the read is to be completed asynchronously, or an
137 // error code if any error occurred. If returns 0, there is no more data to
138 // read. This should not be called before Delegate::OnHeadersReceived is
139 // invoked, and should not be called again unless it returns with number
140 // greater than 0 or until Delegate::OnDataRead is invoked.
141 int ReadData(IOBuffer* buf, int buf_len);
142
143 // Sends data. This should not be called before Delegate::OnHeadersSent is
144 // invoked, and should not be called again until Delegate::OnDataSent is
145 // invoked. If |end_stream| is true, the DATA frame will have an END_STREAM
146 // flag.
xunjieli2328a2682016-05-16 19:38:25147 void SendData(const scoped_refptr<IOBuffer>& data,
148 int length,
149 bool end_stream);
xunjieli11834f02015-12-22 04:27:08150
xunjieli07a42ce2016-04-26 20:05:31151 // Same as SendData except this takes in a vector of IOBuffers.
xunjieli2328a2682016-05-16 19:38:25152 void SendvData(const std::vector<scoped_refptr<IOBuffer>>& buffers,
xunjieli07a42ce2016-04-26 20:05:31153 const std::vector<int>& lengths,
154 bool end_stream);
155
xunjieli5749218c2016-03-22 16:43:06156 // If |stream_request_| is non-NULL, cancel it. If |stream_impl_| is
xunjieli11834f02015-12-22 04:27:08157 // established, cancel it. No delegate method will be called after Cancel().
158 // Any pending operations may or may not succeed.
159 void Cancel();
160
161 // Returns the protocol used by this stream. If stream has not been
162 // established, return kProtoUnknown.
163 NextProto GetProtocol() const;
164
165 // Total number of bytes received over the network of SPDY data, headers, and
166 // push_promise frames associated with this stream, including the size of
167 // frame headers, after SSL decryption and not including proxy overhead.
168 // If stream has not been established, return 0.
169 int64_t GetTotalReceivedBytes() const;
170
171 // Total number of bytes sent over the network of SPDY frames associated with
172 // this stream, including the size of frame headers, before SSL encryption and
173 // not including proxy overhead. Note that some SPDY frames such as pings are
174 // not associated with any stream, and are not included in this value.
175 int64_t GetTotalSentBytes() const;
176
177 // TODO(xunjieli): Implement a method to do flow control and a method to ping
178 // remote end point.
179
180 private:
xunjieli5749218c2016-03-22 16:43:06181 // BidirectionalStreamImpl::Delegate implementation:
xunjielibcb0f86e2016-06-03 00:49:29182 void OnStreamReady(bool request_headers_sent) override;
xunjieli11834f02015-12-22 04:27:08183 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override;
184 void OnDataRead(int bytes_read) override;
185 void OnDataSent() override;
186 void OnTrailersReceived(const SpdyHeaderBlock& trailers) override;
187 void OnFailed(int error) override;
188
189 // HttpStreamRequest::Delegate implementation:
190 void OnStreamReady(const SSLConfig& used_ssl_config,
191 const ProxyInfo& used_proxy_info,
192 HttpStream* stream) override;
xunjieli5749218c2016-03-22 16:43:06193 void OnBidirectionalStreamImplReady(
194 const SSLConfig& used_ssl_config,
195 const ProxyInfo& used_proxy_info,
196 BidirectionalStreamImpl* stream_impl) override;
xunjieli11834f02015-12-22 04:27:08197 void OnWebSocketHandshakeStreamReady(
198 const SSLConfig& used_ssl_config,
199 const ProxyInfo& used_proxy_info,
200 WebSocketHandshakeStreamBase* stream) override;
201 void OnStreamFailed(int status,
202 const SSLConfig& used_ssl_config,
203 SSLFailureState ssl_failure_state) override;
204 void OnCertificateError(int status,
205 const SSLConfig& used_ssl_config,
206 const SSLInfo& ssl_info) override;
207 void OnNeedsProxyAuth(const HttpResponseInfo& response_info,
208 const SSLConfig& used_ssl_config,
209 const ProxyInfo& used_proxy_info,
210 HttpAuthController* auth_controller) override;
211 void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
212 SSLCertRequestInfo* cert_info) override;
213 void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info,
214 const SSLConfig& used_ssl_config,
215 const ProxyInfo& used_proxy_info,
216 HttpStream* stream) override;
217 void OnQuicBroken() override;
218
219 // BidirectionalStreamRequestInfo used when requesting the stream.
danakj1fd259a02016-04-16 03:17:09220 std::unique_ptr<BidirectionalStreamRequestInfo> request_info_;
xunjieli11834f02015-12-22 04:27:08221 const BoundNetLog net_log_;
222
xunjielib3a648e2016-03-22 03:39:51223 HttpNetworkSession* session_;
224
xunjielibcb0f86e2016-06-03 00:49:29225 bool send_request_headers_automatically_;
226 // Whether request headers have been sent, as indicated in OnStreamReady()
227 // callback.
228 bool request_headers_sent_;
229
xunjieli11834f02015-12-22 04:27:08230 Delegate* const delegate_;
231
232 // Timer used to buffer data received in short time-spans and send a single
233 // read completion notification.
danakj1fd259a02016-04-16 03:17:09234 std::unique_ptr<base::Timer> timer_;
xunjieli5749218c2016-03-22 16:43:06235 // HttpStreamRequest used to request a BidirectionalStreamImpl. This is NULL
236 // if the request has been canceled or completed.
danakj1fd259a02016-04-16 03:17:09237 std::unique_ptr<HttpStreamRequest> stream_request_;
xunjieli5749218c2016-03-22 16:43:06238 // The underlying BidirectioanlStreamImpl used for this stream. It is
239 // non-NULL, if the |stream_request_| successfully finishes.
danakj1fd259a02016-04-16 03:17:09240 std::unique_ptr<BidirectionalStreamImpl> stream_impl_;
xunjieli11834f02015-12-22 04:27:08241
xunjielibe07785e2016-04-14 21:15:29242 // Buffer used for reading.
243 scoped_refptr<IOBuffer> read_buffer_;
xunjieli07a42ce2016-04-26 20:05:31244 // List of buffers used for writing.
245 std::vector<scoped_refptr<IOBuffer>> write_buffer_list_;
246 // List of buffer length.
247 std::vector<int> write_buffer_len_list_;
xunjielibe07785e2016-04-14 21:15:29248
xunjieli11834f02015-12-22 04:27:08249 DISALLOW_COPY_AND_ASSIGN(BidirectionalStream);
250};
251
252} // namespace net
253
254#endif // NET_HTTP_BIDIRECTIONAL_STREAM_H_