1 // Copyright 2012 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_SPDY_SPDY_HTTP_STREAM_H_ 6 #define NET_SPDY_SPDY_HTTP_STREAM_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <set> 12 #include <string_view> 13 14 #include "base/memory/raw_ptr.h" 15 #include "base/memory/raw_ptr_exclusion.h" 16 #include "base/memory/scoped_refptr.h" 17 #include "base/memory/weak_ptr.h" 18 #include "base/timer/timer.h" 19 #include "net/base/completion_once_callback.h" 20 #include "net/base/load_timing_info.h" 21 #include "net/base/net_export.h" 22 #include "net/log/net_log_source.h" 23 #include "net/spdy/multiplexed_http_stream.h" 24 #include "net/spdy/spdy_read_queue.h" 25 #include "net/spdy/spdy_session.h" 26 #include "net/spdy/spdy_stream.h" 27 28 namespace net { 29 30 struct HttpRequestInfo; 31 class HttpResponseInfo; 32 class IOBuffer; 33 class SpdySession; 34 class UploadDataStream; 35 36 // The SpdyHttpStream is a HTTP-specific type of stream known to a SpdySession. 37 class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, 38 public MultiplexedHttpStream { 39 public: 40 static const size_t kRequestBodyBufferSize; 41 // |spdy_session| must not be NULL. 42 SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session, 43 NetLogSource source_dependency, 44 std::set<std::string> dns_aliases); 45 46 SpdyHttpStream(const SpdyHttpStream&) = delete; 47 SpdyHttpStream& operator=(const SpdyHttpStream&) = delete; 48 49 ~SpdyHttpStream() override; 50 stream()51 SpdyStream* stream() { return stream_; } 52 53 // Cancels any callbacks from being invoked and deletes the stream. 54 void Cancel(); 55 56 // HttpStream implementation. 57 void RegisterRequest(const HttpRequestInfo* request_info) override; 58 int InitializeStream(bool can_send_early, 59 RequestPriority priority, 60 const NetLogWithSource& net_log, 61 CompletionOnceCallback callback) override; 62 63 int SendRequest(const HttpRequestHeaders& headers, 64 HttpResponseInfo* response, 65 CompletionOnceCallback callback) override; 66 int ReadResponseHeaders(CompletionOnceCallback callback) override; 67 int ReadResponseBody(IOBuffer* buf, 68 int buf_len, 69 CompletionOnceCallback callback) override; 70 void Close(bool not_reusable) override; 71 bool IsResponseBodyComplete() const override; 72 73 // Must not be called if a NULL SpdySession was pssed into the 74 // constructor. 75 bool IsConnectionReused() const override; 76 77 // Total number of bytes received over the network of SPDY data, headers, and 78 // push_promise frames associated with this stream, including the size of 79 // frame headers, after SSL decryption and not including proxy overhead. 80 int64_t GetTotalReceivedBytes() const override; 81 // Total number of bytes sent over the network of SPDY frames associated with 82 // this stream, including the size of frame headers, before SSL encryption and 83 // not including proxy overhead. Note that some SPDY frames such as pings are 84 // not associated with any stream, and are not included in this value. 85 int64_t GetTotalSentBytes() const override; 86 bool GetAlternativeService( 87 AlternativeService* alternative_service) const override; 88 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; 89 int GetRemoteEndpoint(IPEndPoint* endpoint) override; 90 void PopulateNetErrorDetails(NetErrorDetails* details) override; 91 void SetPriority(RequestPriority priority) override; 92 const std::set<std::string>& GetDnsAliases() const override; 93 std::string_view GetAcceptChViaAlps() const override; 94 95 // SpdyStream::Delegate implementation. 96 void OnHeadersSent() override; 97 void OnEarlyHintsReceived(const spdy::Http2HeaderBlock& headers) override; 98 void OnHeadersReceived( 99 const spdy::Http2HeaderBlock& response_headers) override; 100 void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; 101 void OnDataSent() override; 102 void OnTrailers(const spdy::Http2HeaderBlock& trailers) override; 103 void OnClose(int status) override; 104 bool CanGreaseFrameType() const override; 105 NetLogSource source_dependency() const override; 106 107 private: 108 // Helper function used to initialize private members and to set delegate on 109 // stream when stream is created. 110 void InitializeStreamHelper(); 111 112 // Helper function used for resetting stream from inside the stream. 113 void ResetStream(int error); 114 115 // Must be called only when |request_info_| is non-NULL. 116 bool HasUploadData() const; 117 118 void OnStreamCreated(CompletionOnceCallback callback, int rv); 119 120 // Reads the remaining data (whether chunked or not) from the 121 // request body stream and sends it if there's any. The read and 122 // subsequent sending may happen asynchronously. Must be called only 123 // when HasUploadData() is true. 124 void ReadAndSendRequestBodyData(); 125 126 // Send an empty body. Must only be called if there is no upload data and 127 // sending greased HTTP/2 frames is enabled. This allows SpdyStream to 128 // prepend a greased HTTP/2 frame to the empty DATA frame that closes the 129 // stream. 130 void SendEmptyBody(); 131 132 // Called when data has just been read from the request body stream; 133 // does the actual sending of data. 134 void OnRequestBodyReadCompleted(int status); 135 136 // Call the user callback associated with sending the request. 137 void DoRequestCallback(int rv); 138 139 // Method to PostTask for calling request callback asynchronously. 140 void MaybeDoRequestCallback(int rv); 141 142 // Post the request callback if not null. 143 // This is necessary because the request callback might destroy |stream_|, 144 // which does not support that. 145 void MaybePostRequestCallback(int rv); 146 147 // Call the user callback associated with reading the response. 148 void DoResponseCallback(int rv); 149 150 void MaybeScheduleBufferedReadCallback(); 151 void DoBufferedReadCallback(); 152 153 const base::WeakPtr<SpdySession> spdy_session_; 154 155 bool is_reused_; 156 SpdyStreamRequest stream_request_; 157 const NetLogSource source_dependency_; 158 159 // |stream_| is owned by SpdySession. 160 // Before InitializeStream() is called, stream_ == nullptr. 161 // After InitializeStream() is called but before OnClose() is called, 162 // |*stream_| is guaranteed to be valid. 163 // After OnClose() is called, stream_ == nullptr. 164 raw_ptr<SpdyStream> stream_ = nullptr; 165 166 // False before OnClose() is called, true after. 167 bool stream_closed_ = false; 168 169 // Set only when |stream_closed_| is true. 170 int closed_stream_status_ = ERR_FAILED; 171 spdy::SpdyStreamId closed_stream_id_ = 0; 172 bool closed_stream_has_load_timing_info_; 173 LoadTimingInfo closed_stream_load_timing_info_; 174 // After |stream_| has been closed, this keeps track of the total number of 175 // bytes received over the network for |stream_| while it was open. 176 int64_t closed_stream_received_bytes_ = 0; 177 // After |stream_| has been closed, this keeps track of the total number of 178 // bytes sent over the network for |stream_| while it was open. 179 int64_t closed_stream_sent_bytes_ = 0; 180 181 // The request to send. 182 // Set to null before response body is starting to be read. This is to allow 183 // |this| to be shared for reading and to possibly outlive request_info_'s 184 // owner. Setting to null happens after headers are completely read or upload 185 // data stream is uploaded, whichever is later. 186 raw_ptr<const HttpRequestInfo> request_info_ = nullptr; 187 188 // |response_info_| is the HTTP response data object which is filled in 189 // when a response HEADERS comes in for the stream. 190 // It is not owned by this stream object. 191 raw_ptr<HttpResponseInfo> response_info_ = nullptr; 192 193 bool response_headers_complete_ = false; 194 195 bool upload_stream_in_progress_ = false; 196 197 // We buffer the response body as it arrives asynchronously from the stream. 198 SpdyReadQueue response_body_queue_; 199 200 CompletionOnceCallback request_callback_; 201 CompletionOnceCallback response_callback_; 202 203 // User provided buffer for the ReadResponseBody() response. 204 scoped_refptr<IOBuffer> user_buffer_; 205 int user_buffer_len_ = 0; 206 207 // Temporary buffer used to read the request body from UploadDataStream. 208 scoped_refptr<IOBufferWithSize> request_body_buf_; 209 int request_body_buf_size_ = 0; 210 211 // Timer to execute DoBufferedReadCallback() with a delay. 212 base::OneShotTimer buffered_read_timer_; 213 214 // Stores any DNS aliases for the remote endpoint. Includes all known aliases, 215 // e.g. from A, AAAA, or HTTPS, not just from the address used for the 216 // connection, in no particular order. These are stored in the stream instead 217 // of the session due to complications related to IP-pooling. 218 std::set<std::string> dns_aliases_; 219 220 // Keep track of the priority of the request for setting the priority header 221 // right before sending the request. 222 RequestPriority priority_ = RequestPriority::DEFAULT_PRIORITY; 223 224 base::WeakPtrFactory<SpdyHttpStream> weak_factory_{this}; 225 }; 226 227 } // namespace net 228 229 #endif // NET_SPDY_SPDY_HTTP_STREAM_H_ 230