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