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