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