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/spdy/core/http2_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 spdy::Http2HeaderBlock& 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(const spdy::Http2HeaderBlock& trailers) = 0; 93 94 // Called when an error occurred. Do not call into the stream after this 95 // point. No other delegate functions will be called after this. 96 virtual void OnFailed(int error) = 0; 97 98 protected: 99 virtual ~Delegate(); 100 }; 101 102 // Constructs a BidirectionalStream. |request_info| contains information about 103 // the request, and must be non-NULL. |session| is the http network session 104 // with which this request will be made. |delegate| must be non-NULL. 105 // |session| and |delegate| must outlive |this|. 106 // |send_request_headers_automatically| if true, request headers will be sent 107 // automatically when stream is negotiated. If false, request headers will be 108 // sent only when SendRequestHeaders() is invoked or with 109 // next SendData/SendvData. 110 BidirectionalStream( 111 std::unique_ptr<BidirectionalStreamRequestInfo> request_info, 112 HttpNetworkSession* session, 113 bool send_request_headers_automatically, 114 Delegate* delegate); 115 116 // Constructor that accepts a Timer, which can be used in tests to control 117 // the buffering of received data. 118 BidirectionalStream( 119 std::unique_ptr<BidirectionalStreamRequestInfo> request_info, 120 HttpNetworkSession* session, 121 bool send_request_headers_automatically, 122 Delegate* delegate, 123 std::unique_ptr<base::OneShotTimer> timer); 124 125 BidirectionalStream(const BidirectionalStream&) = delete; 126 BidirectionalStream& operator=(const BidirectionalStream&) = delete; 127 128 // Cancels |stream_request_| or |stream_impl_| if applicable. 129 // |this| should not be destroyed during Delegate::OnHeadersSent or 130 // Delegate::OnDataSent. 131 ~BidirectionalStream() override; 132 133 // Sends request headers to server. 134 // When |send_request_headers_automatically_| is 135 // false and OnStreamReady() is invoked with request_headers_sent = false, 136 // headers will be combined with next SendData/SendvData unless this 137 // method is called first, in which case headers will be sent separately 138 // without delay. 139 // (This method cannot be called when |send_request_headers_automatically_| is 140 // true nor when OnStreamReady() is invoked with request_headers_sent = true, 141 // since headers have been sent by the stream when stream is negotiated 142 // successfully.) 143 void SendRequestHeaders(); 144 145 // Reads at most |buf_len| bytes into |buf|. Returns the number of bytes read, 146 // or ERR_IO_PENDING if the read is to be completed asynchronously, or an 147 // error code if any error occurred. If returns 0, there is no more data to 148 // read. This should not be called before Delegate::OnStreamReady is 149 // invoked, and should not be called again unless it returns with number 150 // greater than 0 or until Delegate::OnDataRead is invoked. 151 int ReadData(IOBuffer* buf, int buf_len); 152 153 // Sends data. This should not be called before Delegate::OnStreamReady is 154 // invoked, and should not be called again until Delegate::OnDataSent is 155 // invoked. If |end_stream| is true, the DATA frame will have an END_STREAM 156 // flag. 157 void SendvData(const std::vector<scoped_refptr<IOBuffer>>& buffers, 158 const std::vector<int>& lengths, 159 bool end_stream); 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 // Gets LoadTimingInfo of this stream. 178 void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const; 179 180 // Get the network error details this stream is encountering. 181 // Fills in |details| if it is available; leaves |details| unchanged if it 182 // is unavailable. 183 void PopulateNetErrorDetails(NetErrorDetails* details); 184 185 private: 186 void StartRequest(); 187 // BidirectionalStreamImpl::Delegate implementation: 188 void OnStreamReady(bool request_headers_sent) override; 189 void OnHeadersReceived( 190 const spdy::Http2HeaderBlock& response_headers) override; 191 void OnDataRead(int bytes_read) override; 192 void OnDataSent() override; 193 void OnTrailersReceived(const spdy::Http2HeaderBlock& trailers) override; 194 void OnFailed(int error) override; 195 196 // HttpStreamRequest::Delegate implementation: 197 void OnStreamReady(const ProxyInfo& used_proxy_info, 198 std::unique_ptr<HttpStream> stream) override; 199 void OnBidirectionalStreamImplReady( 200 const ProxyInfo& used_proxy_info, 201 std::unique_ptr<BidirectionalStreamImpl> stream) override; 202 void OnWebSocketHandshakeStreamReady( 203 const ProxyInfo& used_proxy_info, 204 std::unique_ptr<WebSocketHandshakeStreamBase> stream) override; 205 void OnStreamFailed(int status, 206 const NetErrorDetails& net_error_details, 207 const ProxyInfo& used_proxy_info, 208 ResolveErrorInfo resolve_error_info) override; 209 void OnCertificateError(int status, const SSLInfo& ssl_info) override; 210 void OnNeedsProxyAuth(const HttpResponseInfo& response_info, 211 const ProxyInfo& used_proxy_info, 212 HttpAuthController* auth_controller) override; 213 void OnNeedsClientAuth(SSLCertRequestInfo* cert_info) override; 214 void OnQuicBroken() override; 215 216 // Helper method to notify delegate if there is an error. 217 void NotifyFailed(int error); 218 219 // BidirectionalStreamRequestInfo used when requesting the stream. 220 std::unique_ptr<BidirectionalStreamRequestInfo> request_info_; 221 const NetLogWithSource net_log_; 222 223 raw_ptr<HttpNetworkSession, DanglingUntriaged> session_; 224 225 bool send_request_headers_automatically_; 226 // Whether request headers have been sent, as indicated in OnStreamReady() 227 // callback. 228 bool request_headers_sent_ = false; 229 230 const raw_ptr<Delegate> delegate_; 231 232 // Timer used to buffer data received in short time-spans and send a single 233 // read completion notification. 234 std::unique_ptr<base::OneShotTimer> timer_; 235 // HttpStreamRequest used to request a BidirectionalStreamImpl. This is NULL 236 // if the request has been canceled or completed. 237 std::unique_ptr<HttpStreamRequest> stream_request_; 238 // The underlying BidirectioanlStreamImpl used for this stream. It is 239 // non-NULL, if the |stream_request_| successfully finishes. 240 std::unique_ptr<BidirectionalStreamImpl> stream_impl_; 241 242 // Buffer used for reading. 243 scoped_refptr<IOBuffer> read_buffer_; 244 // 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_; 248 249 // TODO(xunjieli): Remove this once LoadTimingInfo has response end. 250 base::TimeTicks read_end_time_; 251 252 // Load timing info of this stream. |connect_timing| is obtained when headers 253 // are received. Other fields are populated at different stages of the request 254 LoadTimingInfo load_timing_info_; 255 256 base::WeakPtrFactory<BidirectionalStream> weak_factory_{this}; 257 }; 258 259 } // namespace net 260 261 #endif // NET_HTTP_BIDIRECTIONAL_STREAM_H_ 262