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