• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors
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 <memory>
11 #include <vector>
12 
13 #include "base/compiler_specific.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/memory/scoped_refptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/time/time.h"
18 #include "net/base/load_timing_info.h"
19 #include "net/base/net_export.h"
20 #include "net/http/bidirectional_stream_impl.h"
21 #include "net/http/http_stream_factory.h"
22 #include "net/http/http_stream_request.h"
23 #include "net/log/net_log_with_source.h"
24 #include "net/third_party/quiche/src/quiche/common/http/http_header_block.h"
25 
26 namespace base {
27 class OneShotTimer;
28 }  // namespace base
29 
30 namespace net {
31 
32 class HttpAuthController;
33 class HttpNetworkSession;
34 class HttpStream;
35 class IOBuffer;
36 class ProxyInfo;
37 struct BidirectionalStreamRequestInfo;
38 struct NetErrorDetails;
39 
40 // A class to do HTTP/2 bidirectional streaming. Note that at most one each of
41 // ReadData or SendData/SendvData should be in flight until the operation
42 // completes. The BidirectionalStream must be torn down before the
43 // HttpNetworkSession.
44 class NET_EXPORT BidirectionalStream : public BidirectionalStreamImpl::Delegate,
45                                        public HttpStreamRequest::Delegate {
46  public:
47   // Delegate interface to get notified of success of failure. Callbacks will be
48   // invoked asynchronously.
49   class NET_EXPORT Delegate {
50    public:
51     Delegate();
52 
53     Delegate(const Delegate&) = delete;
54     Delegate& operator=(const Delegate&) = delete;
55 
56     // Called when the stream is ready for writing and reading. This is called
57     // at most once for the lifetime of a stream.
58     // The delegate may call BidirectionalStream::ReadData to start reading,
59     // or call BidirectionalStream::SendData to send data.
60     // The delegate should not call BidirectionalStream::Cancel
61     // during this callback.
62     // |request_headers_sent| if true, request headers have been sent. If false,
63     // SendRequestHeaders() needs to be explicitly called.
64     virtual void OnStreamReady(bool request_headers_sent) = 0;
65 
66     // Called when headers are received. This is called at most once for the
67     // lifetime of a stream.
68     // The delegate may call BidirectionalStream::ReadData to start reading,
69     // call BidirectionalStream::SendData to send data,
70     // or call BidirectionalStream::Cancel to cancel the stream.
71     virtual void OnHeadersReceived(
72         const quiche::HttpHeaderBlock& response_headers) = 0;
73 
74     // Called when a pending read is completed asynchronously.
75     // |bytes_read| specifies how much data is read.
76     // The delegate may call BidirectionalStream::ReadData to continue
77     // reading, call BidirectionalStream::SendData to send data,
78     // or call BidirectionalStream::Cancel to cancel the stream.
79     virtual void OnDataRead(int bytes_read) = 0;
80 
81     // Called when the entire buffer passed through SendData is sent.
82     // The delegate may call BidirectionalStream::ReadData to continue
83     // reading, call BidirectionalStream::SendData to send data,
84     // The delegate should not call BidirectionalStream::Cancel
85     // during this callback.
86     virtual void OnDataSent() = 0;
87 
88     // Called when trailers are received. This is called as soon as trailers
89     // are received, which can happen before a read completes.
90     // The delegate is able to continue reading if there is no pending read and
91     // EOF has not been received, or to send data if there is no pending send.
92     virtual void OnTrailersReceived(
93         const quiche::HttpHeaderBlock& trailers) = 0;
94 
95     // Called when an error occurred. Do not call into the stream after this
96     // point. No other delegate functions will be called after this.
97     virtual void OnFailed(int error) = 0;
98 
99    protected:
100     virtual ~Delegate();
101   };
102 
103   // Constructs a BidirectionalStream. |request_info| contains information about
104   // the request, and must be non-NULL. |session| is the http network session
105   // with which this request will be made. |delegate| must be non-NULL.
106   // |session| and |delegate| must outlive |this|.
107   // |send_request_headers_automatically| if true, request headers will be sent
108   // automatically when stream is negotiated. If false, request headers will be
109   // sent only when SendRequestHeaders() is invoked or with
110   // next SendData/SendvData.
111   BidirectionalStream(
112       std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
113       HttpNetworkSession* session,
114       bool send_request_headers_automatically,
115       Delegate* delegate);
116 
117   // Constructor that accepts a Timer, which can be used in tests to control
118   // the buffering of received data.
119   BidirectionalStream(
120       std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
121       HttpNetworkSession* session,
122       bool send_request_headers_automatically,
123       Delegate* delegate,
124       std::unique_ptr<base::OneShotTimer> timer);
125 
126   BidirectionalStream(const BidirectionalStream&) = delete;
127   BidirectionalStream& operator=(const BidirectionalStream&) = delete;
128 
129   // Cancels |stream_request_| or |stream_impl_| if applicable.
130   // |this| should not be destroyed during Delegate::OnHeadersSent or
131   // Delegate::OnDataSent.
132   ~BidirectionalStream() override;
133 
134   // Sends request headers to server.
135   // When |send_request_headers_automatically_| is
136   // false and OnStreamReady() is invoked with request_headers_sent = false,
137   // headers will be combined with next SendData/SendvData unless this
138   // method is called first, in which case headers will be sent separately
139   // without delay.
140   // (This method cannot be called when |send_request_headers_automatically_| is
141   // true nor when OnStreamReady() is invoked with request_headers_sent = true,
142   // since headers have been sent by the stream when stream is negotiated
143   // successfully.)
144   void SendRequestHeaders();
145 
146   // Reads at most |buf_len| bytes into |buf|. Returns the number of bytes read,
147   // or ERR_IO_PENDING if the read is to be completed asynchronously, or an
148   // error code if any error occurred. If returns 0, there is no more data to
149   // read. This should not be called before Delegate::OnStreamReady is
150   // invoked, and should not be called again unless it returns with number
151   // greater than 0 or until Delegate::OnDataRead is invoked.
152   int ReadData(IOBuffer* buf, int buf_len);
153 
154   // Sends data. This should not be called before Delegate::OnStreamReady is
155   // invoked, and should not be called again until Delegate::OnDataSent is
156   // invoked. If |end_stream| is true, the DATA frame will have an END_STREAM
157   // flag.
158   void SendvData(const std::vector<scoped_refptr<IOBuffer>>& buffers,
159                  const std::vector<int>& lengths,
160                  bool end_stream);
161 
162   // Returns the protocol used by this stream. If stream has not been
163   // established, return kProtoUnknown.
164   NextProto GetProtocol() const;
165 
166   // Total number of bytes received over the network of SPDY data, headers, and
167   // push_promise frames associated with this stream, including the size of
168   // frame headers, after SSL decryption and not including proxy overhead.
169   // If stream has not been established, return 0.
170   int64_t GetTotalReceivedBytes() const;
171 
172   // Total number of bytes sent over the network of SPDY frames associated with
173   // this stream, including the size of frame headers, before SSL encryption and
174   // not including proxy overhead. Note that some SPDY frames such as pings are
175   // not associated with any stream, and are not included in this value.
176   int64_t GetTotalSentBytes() const;
177 
178   // Gets LoadTimingInfo of this stream.
179   void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const;
180 
181   // Get the network error details this stream is encountering.
182   // Fills in |details| if it is available; leaves |details| unchanged if it
183   // is unavailable.
184   void PopulateNetErrorDetails(NetErrorDetails* details);
185 
186  private:
187   void StartRequest();
188   // BidirectionalStreamImpl::Delegate implementation:
189   void OnStreamReady(bool request_headers_sent) override;
190   void OnHeadersReceived(
191       const quiche::HttpHeaderBlock& response_headers) override;
192   void OnDataRead(int bytes_read) override;
193   void OnDataSent() override;
194   void OnTrailersReceived(const quiche::HttpHeaderBlock& trailers) override;
195   void OnFailed(int error) override;
196 
197   // HttpStreamRequest::Delegate implementation:
198   void OnStreamReady(const ProxyInfo& used_proxy_info,
199                      std::unique_ptr<HttpStream> stream) override;
200   void OnBidirectionalStreamImplReady(
201       const ProxyInfo& used_proxy_info,
202       std::unique_ptr<BidirectionalStreamImpl> stream) override;
203   void OnWebSocketHandshakeStreamReady(
204       const ProxyInfo& used_proxy_info,
205       std::unique_ptr<WebSocketHandshakeStreamBase> stream) override;
206   void OnStreamFailed(int status,
207                       const NetErrorDetails& net_error_details,
208                       const ProxyInfo& used_proxy_info,
209                       ResolveErrorInfo resolve_error_info) override;
210   void OnCertificateError(int status, const SSLInfo& ssl_info) override;
211   void OnNeedsProxyAuth(const HttpResponseInfo& response_info,
212                         const ProxyInfo& used_proxy_info,
213                         HttpAuthController* auth_controller) override;
214   void OnNeedsClientAuth(SSLCertRequestInfo* cert_info) override;
215   void OnQuicBroken() override;
216   void OnSwitchesToHttpStreamPool(
217       HttpStreamPoolRequestInfo request_info) override;
218 
219   // Helper method to notify delegate if there is an error.
220   void NotifyFailed(int error);
221 
222   // BidirectionalStreamRequestInfo used when requesting the stream.
223   std::unique_ptr<BidirectionalStreamRequestInfo> request_info_;
224   const NetLogWithSource net_log_;
225 
226   raw_ptr<HttpNetworkSession> session_;
227 
228   bool send_request_headers_automatically_;
229   // Whether request headers have been sent, as indicated in OnStreamReady()
230   // callback.
231   bool request_headers_sent_ = false;
232 
233   const raw_ptr<Delegate> delegate_;
234 
235   // Timer used to buffer data received in short time-spans and send a single
236   // read completion notification.
237   std::unique_ptr<base::OneShotTimer> timer_;
238   // HttpStreamRequest used to request a BidirectionalStreamImpl. This is NULL
239   // if the request has been canceled or completed.
240   std::unique_ptr<HttpStreamRequest> stream_request_;
241   // The underlying BidirectioanlStreamImpl used for this stream. It is
242   // non-NULL, if the |stream_request_| successfully finishes.
243   std::unique_ptr<BidirectionalStreamImpl> stream_impl_;
244 
245   // Buffer used for reading.
246   scoped_refptr<IOBuffer> read_buffer_;
247   // List of buffers used for writing.
248   std::vector<scoped_refptr<IOBuffer>> write_buffer_list_;
249   // List of buffer length.
250   std::vector<int> write_buffer_len_list_;
251 
252   // TODO(xunjieli): Remove this once LoadTimingInfo has response end.
253   base::TimeTicks read_end_time_;
254 
255   // Load timing info of this stream. |connect_timing| is obtained when headers
256   // are received. Other fields are populated at different stages of the request
257   LoadTimingInfo load_timing_info_;
258 
259   base::WeakPtrFactory<BidirectionalStream> weak_factory_{this};
260 };
261 
262 }  // namespace net
263 
264 #endif  // NET_HTTP_BIDIRECTIONAL_STREAM_H_
265