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_HTTP_HTTP_STREAM_PARSER_H_ 6 #define NET_HTTP_HTTP_STREAM_PARSER_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <string> 13 #include <string_view> 14 15 #include "base/memory/raw_ptr.h" 16 #include "base/memory/scoped_refptr.h" 17 #include "base/memory/weak_ptr.h" 18 #include "base/time/time.h" 19 #include "crypto/ec_private_key.h" 20 #include "net/base/completion_once_callback.h" 21 #include "net/base/completion_repeating_callback.h" 22 #include "net/base/net_errors.h" 23 #include "net/base/net_export.h" 24 #include "net/base/upload_data_stream.h" 25 #include "net/log/net_log_with_source.h" 26 #include "net/traffic_annotation/network_traffic_annotation.h" 27 #include "url/gurl.h" 28 29 namespace net { 30 31 class DrainableIOBuffer; 32 class GrowableIOBuffer; 33 class HttpChunkedDecoder; 34 class HttpRequestHeaders; 35 class HttpResponseInfo; 36 class IOBuffer; 37 class StreamSocket; 38 class UploadDataStream; 39 40 class NET_EXPORT_PRIVATE HttpStreamParser { 41 public: 42 // |connection_is_reused| must be |true| if |stream_socket| has previously 43 // been used successfully for an HTTP/1.x request. 44 // 45 // Any data in |read_buffer| will be used before reading from the socket 46 // and any data left over after parsing the stream will be put into 47 // |read_buffer|. The left over data will start at offset 0 and the 48 // buffer's offset will be set to the first free byte. |read_buffer| may 49 // have its capacity changed. 50 // 51 // It is not safe to call into the HttpStreamParser after destroying the 52 // |stream_socket|. 53 // 54 // `upload_data_stream` must remain valid until the SendRequest() callback is 55 // invoked or the HttpStreamParser has been destroyed. 56 HttpStreamParser(StreamSocket* stream_socket, 57 bool connection_is_reused, 58 const GURL& url, 59 const std::string& method, 60 UploadDataStream* upload_data_stream, 61 GrowableIOBuffer* read_buffer, 62 const NetLogWithSource& net_log); 63 64 HttpStreamParser(const HttpStreamParser&) = delete; 65 HttpStreamParser& operator=(const HttpStreamParser&) = delete; 66 67 virtual ~HttpStreamParser(); 68 69 // These functions implement the interface described in HttpStream with 70 // some additional functionality 71 int SendRequest(const std::string& request_line, 72 const HttpRequestHeaders& headers, 73 const NetworkTrafficAnnotationTag& traffic_annotation, 74 HttpResponseInfo* response, 75 CompletionOnceCallback callback); 76 77 int ConfirmHandshake(CompletionOnceCallback callback); 78 79 int ReadResponseHeaders(CompletionOnceCallback callback); 80 81 int ReadResponseBody(IOBuffer* buf, 82 int buf_len, 83 CompletionOnceCallback callback); 84 85 bool IsResponseBodyComplete() const; 86 87 bool CanFindEndOfResponse() const; 88 89 bool IsMoreDataBuffered() const; 90 91 // Returns true if the underlying connection can be reused. 92 // The connection can be reused if: 93 // * It's still connected. 94 // * The response headers indicate the connection can be kept alive. 95 // * The end of the response can be found, though it may not have yet been 96 // received. 97 // 98 // Note that if response headers have yet to be received, this will return 99 // false. 100 bool CanReuseConnection() const; 101 102 // Called when stream is closed. 103 void OnConnectionClose(); 104 url()105 const GURL& url() { return url_; } method()106 const std::string& method() { return method_; } 107 received_bytes()108 int64_t received_bytes() const { return received_bytes_; } 109 sent_bytes()110 int64_t sent_bytes() const { return sent_bytes_; } 111 first_response_start_time()112 base::TimeTicks first_response_start_time() const { 113 return first_response_start_time_; 114 } non_informational_response_start_time()115 base::TimeTicks non_informational_response_start_time() const { 116 return non_informational_response_start_time_; 117 } first_early_hints_time()118 base::TimeTicks first_early_hints_time() { return first_early_hints_time_; } 119 120 // Encodes the given |payload| in the chunked format to |output|. 121 // Returns the number of bytes written to |output|. output.size() should 122 // be large enough to store the encoded chunk, which is payload.size() + 123 // kChunkHeaderFooterSize. Returns ERR_INVALID_ARGUMENT if output.size() 124 // is not large enough. 125 // 126 // The output will look like: "HEX\r\n[payload]\r\n" 127 // where HEX is a length in hexadecimal (without the "0x" prefix). 128 static int EncodeChunk(std::string_view payload, base::span<uint8_t> output); 129 130 // Returns true if request headers and body should be merged (i.e. the 131 // sum is small enough and the body is in memory, and not chunked). 132 static bool ShouldMergeRequestHeadersAndBody( 133 const std::string& request_headers, 134 const UploadDataStream* request_body); 135 136 // The number of extra bytes required to encode a chunk. 137 static const size_t kChunkHeaderFooterSize; 138 139 private: 140 class SeekableIOBuffer; 141 142 // FOO_COMPLETE states implement the second half of potentially asynchronous 143 // operations and don't necessarily mean that FOO is complete. 144 enum State { 145 // STATE_NONE indicates that this is waiting on an external call before 146 // continuing. 147 STATE_NONE, 148 STATE_SEND_HEADERS, 149 STATE_SEND_HEADERS_COMPLETE, 150 STATE_SEND_BODY, 151 STATE_SEND_BODY_COMPLETE, 152 STATE_SEND_REQUEST_READ_BODY_COMPLETE, 153 STATE_SEND_REQUEST_COMPLETE, 154 STATE_READ_HEADERS, 155 STATE_READ_HEADERS_COMPLETE, 156 STATE_READ_BODY, 157 STATE_READ_BODY_COMPLETE, 158 STATE_DONE 159 }; 160 161 // The number of bytes by which the header buffer is grown when it reaches 162 // capacity. 163 static const int kHeaderBufInitialSize = 4 * 1024; // 4K 164 165 // |kMaxHeaderBufSize| is the number of bytes that the response headers can 166 // grow to. If the body start is not found within this range of the 167 // response, the transaction will fail with ERR_RESPONSE_HEADERS_TOO_BIG. 168 // Note: |kMaxHeaderBufSize| should be a multiple of |kHeaderBufInitialSize|. 169 static const int kMaxHeaderBufSize = kHeaderBufInitialSize * 64; // 256K 170 171 // The maximum sane buffer size. 172 static const int kMaxBufSize = 2 * 1024 * 1024; // 2M 173 174 // Handle callbacks. 175 void OnIOComplete(int result); 176 177 // Try to make progress sending/receiving the request/response. 178 int DoLoop(int result); 179 180 // The implementations of each state of the state machine. 181 int DoSendHeaders(); 182 int DoSendHeadersComplete(int result); 183 int DoSendBody(); 184 int DoSendBodyComplete(int result); 185 int DoSendRequestReadBodyComplete(int result); 186 int DoSendRequestComplete(int result); 187 int DoReadHeaders(); 188 int DoReadHeadersComplete(int result); 189 int DoReadBody(); 190 int DoReadBodyComplete(int result); 191 192 // This handles most of the logic for DoReadHeadersComplete. 193 int HandleReadHeaderResult(int result); 194 195 void RunConfirmHandshakeCallback(int rv); 196 197 // Examines |read_buf_| to find the start and end of the headers. If they are 198 // found, parse them with DoParseResponseHeaders(). Return the offset for 199 // the end of the headers, or -1 if the complete headers were not found, or 200 // with a net::Error if we encountered an error during parsing. 201 // 202 // |new_bytes| is the number of new bytes that have been appended to the end 203 // of |read_buf_| since the last call to this method (which must have returned 204 // -1). 205 int FindAndParseResponseHeaders(int new_bytes); 206 207 // Parse the headers into response_. Returns OK on success or a net::Error on 208 // failure. 209 int ParseResponseHeaders(size_t end_of_header_offset); 210 211 // Examine the parsed headers to try to determine the response body size. 212 void CalculateResponseBodySize(); 213 214 // Check if buffers used to send the request are empty. 215 bool SendRequestBuffersEmpty(); 216 217 // Next state of the request, when the current one completes. 218 State io_state_ = STATE_NONE; 219 220 const GURL url_; 221 const std::string method_; 222 223 // Only non-null while writing the request headers and body. 224 raw_ptr<UploadDataStream> upload_data_stream_; 225 226 // The request header data. May include a merged request body. 227 scoped_refptr<DrainableIOBuffer> request_headers_; 228 229 // Size of just the request headers. May be less than the length of 230 // |request_headers_| if the body was merged with the headers. 231 int request_headers_length_ = 0; 232 233 // Temporary buffer for reading. 234 scoped_refptr<GrowableIOBuffer> read_buf_; 235 236 // Offset of the first unused byte in |read_buf_|. May be nonzero due to 237 // body data in the same packet as header data but is zero when reading 238 // headers. 239 size_t read_buf_unused_offset_ = 0; 240 241 // The amount beyond |read_buf_unused_offset_| where the status line starts; 242 // std::string::npos if not found yet. 243 size_t response_header_start_offset_; 244 245 // The amount of received data. If connection is reused then intermediate 246 // value may be bigger than final. 247 int64_t received_bytes_ = 0; 248 249 // The amount of sent data. 250 int64_t sent_bytes_ = 0; 251 252 // The parsed response headers. Owned by the caller of SendRequest. This 253 // cannot be safely accessed after reading the final set of headers, as the 254 // caller of SendRequest may have been destroyed - this happens in the case an 255 // HttpResponseBodyDrainer is used. 256 raw_ptr<HttpResponseInfo> response_ = nullptr; 257 258 // Time at which the first bytes of the first header response including 259 // informational responses (1xx) are about to be parsed. This corresponds to 260 // |LoadTimingInfo::receive_headers_start|. See also comments there. 261 base::TimeTicks first_response_start_time_; 262 263 // Time at which the first bytes of the current header response are about to 264 // be parsed. This is reset every time new response headers including 265 // non-informational responses (1xx) are parsed. 266 base::TimeTicks current_response_start_time_; 267 268 // Time at which the first byte of the non-informational header response 269 // (non-1xx) are about to be parsed. This corresponds to 270 // |LoadTimingInfo::receive_non_informational_headers_start|. See also 271 // comments there. 272 base::TimeTicks non_informational_response_start_time_; 273 274 // Time at which the first 103 Early Hints response is received. This 275 // corresponds to |LoadTimingInfo::first_early_hints_time|. 276 base::TimeTicks first_early_hints_time_; 277 278 // Indicates the content length. If this value is less than zero 279 // (and chunked_decoder_ is null), then we must read until the server 280 // closes the connection. 281 int64_t response_body_length_ = -1; 282 283 // True if reading a keep-alive response. False if not, or if don't yet know. 284 bool response_is_keep_alive_ = false; 285 286 // True if we've seen a response that has an HTTP status line. This is 287 // persistent across multiple response parsing. If we see a status line 288 // for a response, this will remain true forever. 289 bool has_seen_status_line_ = false; 290 291 // Keep track of the number of response body bytes read so far. 292 int64_t response_body_read_ = 0; 293 294 // Helper if the data is chunked. 295 std::unique_ptr<HttpChunkedDecoder> chunked_decoder_; 296 297 // Where the caller wants the body data. 298 scoped_refptr<IOBuffer> user_read_buf_; 299 size_t user_read_buf_len_ = 0; 300 301 // The callback to notify a user that the handshake has been confirmed. 302 CompletionOnceCallback confirm_handshake_callback_; 303 304 // The callback to notify a user that their request or response is 305 // complete or there was an error 306 CompletionOnceCallback callback_; 307 308 // The underlying socket, owned by the caller. The HttpStreamParser must be 309 // destroyed before the caller destroys the socket, or relinquishes ownership 310 // of it. 311 raw_ptr<StreamSocket> stream_socket_; 312 313 // Whether the socket has already been used. Only used in HTTP/0.9 detection 314 // logic. 315 const bool connection_is_reused_; 316 317 NetLogWithSource net_log_; 318 319 // Callback to be used when doing IO. 320 CompletionRepeatingCallback io_callback_; 321 322 // Buffer used to read the request body from UploadDataStream. 323 scoped_refptr<SeekableIOBuffer> request_body_read_buf_; 324 // Buffer used to send the request body. This points the same buffer as 325 // |request_body_read_buf_| unless the data is chunked. 326 scoped_refptr<SeekableIOBuffer> request_body_send_buf_; 327 bool sent_last_chunk_ = false; 328 329 // Whether the Content-Length was known and extra data was discarded. 330 bool discarded_extra_data_ = false; 331 332 // Whether the response body should be truncated to the Content-Length. 333 const bool truncate_to_content_length_enabled_; 334 335 // Error received when uploading the body, if any. 336 int upload_error_ = OK; 337 338 MutableNetworkTrafficAnnotationTag traffic_annotation_; 339 340 base::WeakPtrFactory<HttpStreamParser> weak_ptr_factory_{this}; 341 }; 342 343 } // namespace net 344 345 #endif // NET_HTTP_HTTP_STREAM_PARSER_H_ 346