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