• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 namespace net {
18 
19 class ClientSocketHandle;
20 class DrainableIOBuffer;
21 class GrowableIOBuffer;
22 struct HttpRequestInfo;
23 class HttpRequestHeaders;
24 class HttpResponseInfo;
25 class IOBuffer;
26 class SSLCertRequestInfo;
27 class SSLInfo;
28 
29 class 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