• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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