1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_HTTP_HTTP_STREAM_PARSER_H_
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_HTTP_HTTP_STREAM_PARSER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string>
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/completion_callback.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/upload_data_stream.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_chunked_decoder.h"
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ClientSocketHandle;
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass DrainableIOBuffer;
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass GrowableIOBuffer;
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct HttpRequestInfo;
234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass HttpRequestHeaders;
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass HttpResponseInfo;
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass IOBuffer;
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SSLCertRequestInfo;
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SSLInfo;
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass HttpStreamParser  : public ChunkCallback {
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Any data in |read_buffer| will be used before reading from the socket
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and any data left over after parsing the stream will be put into
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // |read_buffer|.  The left over data will start at offset 0 and the
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // buffer's offset will be set to the first free byte. |read_buffer| may
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // have its capacity changed.
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  HttpStreamParser(ClientSocketHandle* connection,
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   const HttpRequestInfo* request,
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                   GrowableIOBuffer* read_buffer,
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   const BoundNetLog& net_log);
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~HttpStreamParser();
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // These functions implement the interface described in HttpStream with
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // some additional functionality
444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int SendRequest(const std::string& request_line,
454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                  const HttpRequestHeaders& headers,
464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                  UploadDataStream* request_body,
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  HttpResponseInfo* response, CompletionCallback* callback);
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int ReadResponseHeaders(CompletionCallback* callback);
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int ReadResponseBody(IOBuffer* buf, int buf_len,
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                       CompletionCallback* callback);
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void Close(bool not_reusable);
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  uint64 GetUploadProgress() const;
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  HttpResponseInfo* GetResponseInfo();
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool IsResponseBodyComplete() const;
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool CanFindEndOfResponse() const;
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool IsMoreDataBuffered() const;
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool IsConnectionReused() const;
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void SetConnectionReused();
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool IsConnectionReusable() const;
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void GetSSLInfo(SSLInfo* ssl_info);
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // ChunkCallback methods.
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void OnChunkAvailable();
7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // FOO_COMPLETE states implement the second half of potentially asynchronous
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // operations and don't necessarily mean that FOO is complete.
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  enum State {
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_NONE,
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_SENDING_HEADERS,
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_SENDING_BODY,
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_REQUEST_SENT,
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_READ_HEADERS,
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_READ_HEADERS_COMPLETE,
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_BODY_PENDING,
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_READ_BODY,
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_READ_BODY_COMPLETE,
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    STATE_DONE
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The number of bytes by which the header buffer is grown when it reaches
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // capacity.
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  enum { kHeaderBufInitialSize = 4096 };
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // |kMaxHeaderBufSize| is the number of bytes that the response headers can
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // grow to. If the body start is not found within this range of the
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // response, the transaction will fail with ERR_RESPONSE_HEADERS_TOO_BIG.
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Note: |kMaxHeaderBufSize| should be a multiple of |kHeaderBufInitialSize|.
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  enum { kMaxHeaderBufSize = 256 * 1024 };  // 256 kilobytes.
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The maximum sane buffer size.
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  enum { kMaxBufSize = 2 * 1024 * 1024 };  // 2 megabytes.
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Handle callbacks.
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void OnIOComplete(int result);
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Try to make progress sending/receiving the request/response.
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoLoop(int result);
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The implementations of each state of the state machine.
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoSendHeaders(int result);
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoSendBody(int result);
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoReadHeaders();
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoReadHeadersComplete(int result);
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoReadBody();
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int DoReadBodyComplete(int result);
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Examines |read_buf_| to find the start and end of the headers. If they are
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // found, parse them with DoParseResponseHeaders().  Return the offset for
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // the end of the headers, or -1 if the complete headers were not found, or
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // with a net::Error if we encountered an error during parsing.
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int ParseResponseHeaders();
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Parse the headers into response_.  Returns OK on success or a net::Error on
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // failure.
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int DoParseResponseHeaders(int end_of_header_offset);
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Examine the parsed headers to try to determine the response body size.
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void CalculateResponseBodySize();
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Current state of the request.
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  State io_state_;
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The request to send.
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const HttpRequestInfo* request_;
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The request header data.
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<DrainableIOBuffer> request_headers_;
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The request body data.
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<UploadDataStream> request_body_;
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Temporary buffer for reading.
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<GrowableIOBuffer> read_buf_;
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Offset of the first unused byte in |read_buf_|.  May be nonzero due to
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // a 1xx header, or body data in the same packet as header data.
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int read_buf_unused_offset_;
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The amount beyond |read_buf_unused_offset_| where the status line starts;
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // -1 if not found yet.
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int response_header_start_offset_;
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The parsed response headers.  Owned by the caller.
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  HttpResponseInfo* response_;
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Indicates the content length.  If this value is less than zero
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (and chunked_decoder_ is null), then we must read until the server
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // closes the connection.
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int64 response_body_length_;
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Keep track of the number of response body bytes read so far.
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int64 response_body_read_;
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Helper if the data is chunked.
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<HttpChunkedDecoder> chunked_decoder_;
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Where the caller wants the body data.
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<IOBuffer> user_read_buf_;
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int user_read_buf_len_;
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The callback to notify a user that their request or response is
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // complete or there was an error
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CompletionCallback* user_callback_;
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // In the client callback, the client can do anything, including
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // destroying this class, so any pending callback must be issued
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // after everything else is done.  When it is time to issue the client
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // callback, move it from |user_callback_| to |scheduled_callback_|.
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CompletionCallback* scheduled_callback_;
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The underlying socket.
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocketHandle* const connection_;
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BoundNetLog net_log_;
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Callback to be used when doing IO.
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CompletionCallbackImpl<HttpStreamParser> io_callback_;
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Stores an encoded chunk for chunked uploads.
195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Note: This should perhaps be improved to not create copies of the data.
196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<IOBuffer> chunk_buf_;
197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  size_t chunk_length_;
198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  size_t chunk_length_without_encoding_;
199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool sent_last_chunk_;
200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(HttpStreamParser);
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // NET_HTTP_HTTP_STREAM_PARSER_H_
207