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