blob: e5b9710858c642e681bd83a26fe8df2f9fe924ab [file] [log] [blame]
Chris Sosa45d9f102014-03-24 11:18:54 -07001// Copyright 2014 The Chromium OS 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 BUFFET_HTTP_REQUEST_H_
6#define BUFFET_HTTP_REQUEST_H_
7
Alex Vakulenko96c84d32014-06-06 11:07:32 -07008#include <limits>
Alex Vakulenkoa3062c52014-04-21 17:05:51 -07009#include <map>
Chris Sosa45d9f102014-03-24 11:18:54 -070010#include <memory>
11#include <string>
Alex Vakulenkob3aac252014-05-07 17:35:24 -070012#include <utility>
Alex Vakulenkoa3062c52014-04-21 17:05:51 -070013#include <vector>
14
Chris Sosa45d9f102014-03-24 11:18:54 -070015#include <base/basictypes.h>
16
Alex Vakulenkoa3062c52014-04-21 17:05:51 -070017#include "buffet/http_connection.h"
18#include "buffet/http_transport.h"
Alex Vakulenkob3aac252014-05-07 17:35:24 -070019#include "buffet/error.h"
Chris Sosa45d9f102014-03-24 11:18:54 -070020
Alex Vakulenkoaf23b322014-05-08 16:25:45 -070021namespace buffet {
Chris Sosa45d9f102014-03-24 11:18:54 -070022namespace http {
23
24// HTTP request verbs
25namespace request_type {
26 extern const char kOptions[];
27 extern const char kGet[];
28 extern const char kHead[];
29 extern const char kPost[];
30 extern const char kPut[];
31 extern const char kPatch[]; // Not a standard HTTP/1.1 request method
32 extern const char kDelete[];
33 extern const char kTrace[];
34 extern const char kConnect[];
35 extern const char kCopy[]; // Not a standard HTTP/1.1 request method
36 extern const char kMove[]; // Not a standard HTTP/1.1 request method
Alex Vakulenkob3aac252014-05-07 17:35:24 -070037} // namespace request_type
Chris Sosa45d9f102014-03-24 11:18:54 -070038
39// HTTP request header names
40namespace request_header {
41 extern const char kAccept[];
42 extern const char kAcceptCharset[];
43 extern const char kAcceptEncoding[];
44 extern const char kAcceptLanguage[];
45 extern const char kAllow[];
46 extern const char kAuthorization[];
47 extern const char kCacheControl[];
48 extern const char kConnection[];
49 extern const char kContentEncoding[];
50 extern const char kContentLanguage[];
51 extern const char kContentLength[];
52 extern const char kContentLocation[];
53 extern const char kContentMd5[];
54 extern const char kContentRange[];
55 extern const char kContentType[];
56 extern const char kCookie[];
57 extern const char kDate[];
58 extern const char kExpect[];
59 extern const char kExpires[];
60 extern const char kFrom[];
61 extern const char kHost[];
62 extern const char kIfMatch[];
63 extern const char kIfModifiedSince[];
64 extern const char kIfNoneMatch[];
65 extern const char kIfRange[];
66 extern const char kIfUnmodifiedSince[];
67 extern const char kLastModified[];
68 extern const char kMaxForwards[];
69 extern const char kPragma[];
70 extern const char kProxyAuthorization[];
71 extern const char kRange[];
72 extern const char kReferer[];
73 extern const char kTE[];
74 extern const char kTrailer[];
75 extern const char kTransferEncoding[];
76 extern const char kUpgrade[];
77 extern const char kUserAgent[];
78 extern const char kVia[];
79 extern const char kWarning[];
Alex Vakulenkob3aac252014-05-07 17:35:24 -070080} // namespace request_header
Chris Sosa45d9f102014-03-24 11:18:54 -070081
82// HTTP response header names
83namespace response_header {
84 extern const char kAcceptRanges[];
85 extern const char kAge[];
86 extern const char kAllow[];
87 extern const char kCacheControl[];
88 extern const char kConnection[];
89 extern const char kContentEncoding[];
90 extern const char kContentLanguage[];
91 extern const char kContentLength[];
92 extern const char kContentLocation[];
93 extern const char kContentMd5[];
94 extern const char kContentRange[];
95 extern const char kContentType[];
96 extern const char kDate[];
97 extern const char kETag[];
98 extern const char kExpires[];
99 extern const char kLastModified[];
100 extern const char kLocation[];
101 extern const char kPragma[];
102 extern const char kProxyAuthenticate[];
103 extern const char kRetryAfter[];
104 extern const char kServer[];
105 extern const char kSetCookie[];
106 extern const char kTrailer[];
107 extern const char kTransferEncoding[];
108 extern const char kUpgrade[];
109 extern const char kVary[];
110 extern const char kVia[];
111 extern const char kWarning[];
112 extern const char kWwwAuthenticate[];
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700113} // namespace response_header
Chris Sosa45d9f102014-03-24 11:18:54 -0700114
115// HTTP request status (error) codes
116namespace status_code {
117 // OK to continue with request
118 static const int Continue = 100;
119 // Server has switched protocols in upgrade header
120 static const int SwitchProtocols = 101;
121
122 // Request completed
123 static const int Ok = 200;
124 // Object created, reason = new URI
125 static const int Created = 201;
126 // Async completion (TBS)
127 static const int Accepted = 202;
128 // Partial completion
129 static const int Partial = 203;
130 // No info to return
131 static const int NoContent = 204;
132 // Request completed, but clear form
133 static const int ResetContent = 205;
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700134 // Partial GET fulfilled
Chris Sosa45d9f102014-03-24 11:18:54 -0700135 static const int PartialContent = 206;
136
137 // Server couldn't decide what to return
138 static const int Ambiguous = 300;
139 // Object permanently moved
140 static const int Moved = 301;
141 // Object temporarily moved
142 static const int Redirect = 302;
143 // Redirection w/ new access method
144 static const int RedirectMethod = 303;
145 // If-Modified-Since was not modified
146 static const int NotModified = 304;
147 // Redirection to proxy, location header specifies proxy to use
148 static const int UseProxy = 305;
149 // HTTP/1.1: keep same verb
150 static const int RedirectKeepVerb = 307;
151
152 // Invalid syntax
153 static const int BadRequest = 400;
154 // Access denied
155 static const int Denied = 401;
156 // Payment required
157 static const int PaymentRequired = 402;
158 // Request forbidden
159 static const int Forbidden = 403;
160 // Object not found
161 static const int NotFound = 404;
162 // Method is not allowed
163 static const int BadMethod = 405;
164 // No response acceptable to client found
165 static const int NoneAcceptable = 406;
166 // Proxy authentication required
167 static const int ProxyAuthRequired = 407;
168 // Server timed out waiting for request
169 static const int RequestTimeout = 408;
170 // User should resubmit with more info
171 static const int Conflict = 409;
172 // The resource is no longer available
173 static const int Gone = 410;
174 // The server refused to accept request w/o a length
175 static const int LengthRequired = 411;
176 // Precondition given in request failed
177 static const int PrecondionFailed = 412;
178 // Request entity was too large
179 static const int RequestTooLarge = 413;
180 // Request URI too long
181 static const int UriTooLong = 414;
182 // Unsupported media type
183 static const int UnsupportedMedia = 415;
184 // Retry after doing the appropriate action.
185 static const int RetryWith = 449;
186
187 // Internal server error
188 static const int InternalServerError = 500;
189 // Request not supported
190 static const int NotSupported = 501;
191 // Error response received from gateway
192 static const int BadGateway = 502;
193 // Temporarily overloaded
194 static const int ServiceUnavailable = 503;
195 // Timed out waiting for gateway
196 static const int GatewayTimeout = 504;
197 // HTTP version not supported
198 static const int VersionNotSupported = 505;
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700199} // namespace status_code
Chris Sosa45d9f102014-03-24 11:18:54 -0700200
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700201class Response; // Just a forward declaration.
Chris Sosa45d9f102014-03-24 11:18:54 -0700202
203///////////////////////////////////////////////////////////////////////////////
204// Request class is the main object used to set up and initiate an HTTP
205// communication session. It is used to specify the HTTP request method,
206// request URL and many optional parameters (such as HTTP headers, user agent,
207// referer URL and so on.
208//
209// Once everything is setup, GetResponse() method is used to send the request
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700210// and obtain the server response. The returned Response object can be
Chris Sosa45d9f102014-03-24 11:18:54 -0700211// used to inspect the response code, HTTP headers and/or response body.
212///////////////////////////////////////////////////////////////////////////////
213class Request {
214 public:
215 // The main constructor. |url| specifies the remote host address/path
Alex Vakulenkoa3062c52014-04-21 17:05:51 -0700216 // to send the request to. |method| is the HTTP request verb and
217 // |transport| is the HTTP transport implementation for server communications.
218 Request(const std::string& url, const char* method,
219 std::shared_ptr<Transport> transport);
220 ~Request();
Chris Sosa45d9f102014-03-24 11:18:54 -0700221
222 // Gets/Sets "Accept:" header value. The default value is "*/*" if not set.
Alex Vakulenkob8ba5952014-04-17 11:35:56 -0700223 void SetAccept(const char* accept_mime_types);
Chris Sosa45d9f102014-03-24 11:18:54 -0700224 std::string GetAccept() const;
225
226 // Gets/Sets "Content-Type:" header value
Alex Vakulenkob8ba5952014-04-17 11:35:56 -0700227 void SetContentType(const char* content_type);
Chris Sosa45d9f102014-03-24 11:18:54 -0700228 std::string GetContentType() const;
229
230 // Adds additional HTTP request header
Alex Vakulenkob8ba5952014-04-17 11:35:56 -0700231 void AddHeader(const char* header, const char* value);
232 void AddHeaders(const HeaderList& headers);
Chris Sosa45d9f102014-03-24 11:18:54 -0700233
234 // Removes HTTP request header
Alex Vakulenkob8ba5952014-04-17 11:35:56 -0700235 void RemoveHeader(const char* header);
Chris Sosa45d9f102014-03-24 11:18:54 -0700236
237 // Adds a request body. This is not to be used with GET method
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700238 bool AddRequestBody(const void* data, size_t size, ErrorPtr* error);
Chris Sosa45d9f102014-03-24 11:18:54 -0700239
240 // Makes a request for a subrange of data. Specifies a partial range with
241 // either from beginning of the data to the specified offset (if |bytes| is
242 // negative) or from the specified offset to the end of data (if |bytes| is
243 // positive).
244 // All individual ranges will be sent as part of "Range:" HTTP request header.
245 void AddRange(int64_t bytes);
246
247 // Makes a request for a subrange of data. Specifies a full range with
248 // start and end bytes from the beginning of the requested data.
249 // All individual ranges will be sent as part of "Range:" HTTP request header.
250 void AddRange(uint64_t from_byte, uint64_t to_byte);
251
Chris Sosa45d9f102014-03-24 11:18:54 -0700252 // Returns the request URL
253 std::string GetRequestURL() const;
254
255 // Gets/Sets a request referer URL (sent as "Referer:" request header).
Alex Vakulenkob8ba5952014-04-17 11:35:56 -0700256 void SetReferer(const char* referer);
Chris Sosa45d9f102014-03-24 11:18:54 -0700257 std::string GetReferer() const;
258
259 // Gets/Sets a user agent string (sent as "User-Agent:" request header).
Alex Vakulenkob8ba5952014-04-17 11:35:56 -0700260 void SetUserAgent(const char* user_agent);
Chris Sosa45d9f102014-03-24 11:18:54 -0700261 std::string GetUserAgent() const;
262
263 // Sends the request to the server and returns the response object.
264 // In case the server couldn't be reached for whatever reason, returns
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700265 // empty unique_ptr (null). In such a case, the additional error information
266 // can be returned through the optional supplied |error| parameter.
267 std::unique_ptr<Response> GetResponse(ErrorPtr* error);
Chris Sosa45d9f102014-03-24 11:18:54 -0700268
269 private:
Alex Vakulenkoa3062c52014-04-21 17:05:51 -0700270 // Helper function to create an http::Connection and send off request headers.
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700271 bool SendRequestIfNeeded(ErrorPtr* error);
Alex Vakulenkoa3062c52014-04-21 17:05:51 -0700272
273 // Implementation that provides particular HTTP transport.
274 std::shared_ptr<Transport> transport_;
275
276 // An established connection for adding request body. This connection
277 // is maintained by the request object after the headers have been
278 // sent and before the response is requested.
279 std::unique_ptr<Connection> connection_;
280
281 // Full request URL, such as "http://www.host.com/path/to/object"
282 std::string request_url_;
283 // HTTP request verb, such as "GET", "POST", "PUT", ...
284 std::string method_;
285
286 // Referrer URL, if any. Sent to the server via "Referer: " header.
287 std::string referer_;
288 // User agent string, if any. Sent to the server via "User-Agent: " header.
289 std::string user_agent_;
290 // Content type of the request body data.
291 // Sent to the server via "Content-Type: " header.
292 std::string content_type_;
293 // List of acceptable response data types.
294 // Sent to the server via "Accept: " header.
295 std::string accept_ = "*/*";
296
297 // List of optional request headers provided by the caller.
298 // After request has been sent, contains the received response headers.
299 std::map<std::string, std::string> headers_;
300 // List of optional data ranges to request partial content from the server.
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700301 // Sent to the server as "Range: " header.
Alex Vakulenkoa3062c52014-04-21 17:05:51 -0700302 std::vector<std::pair<uint64_t, uint64_t>> ranges_;
303
304 // range_value_omitted is used in |ranges_| list to indicate omitted value.
305 // E.g. range (10,range_value_omitted) represents bytes from 10 to the end
306 // of the data stream.
Alex Vakulenko96c84d32014-06-06 11:07:32 -0700307 const uint64_t range_value_omitted = std::numeric_limits<uint64_t>::max();
Alex Vakulenkoa3062c52014-04-21 17:05:51 -0700308
Chris Sosa45d9f102014-03-24 11:18:54 -0700309 DISALLOW_COPY_AND_ASSIGN(Request);
310};
311
312///////////////////////////////////////////////////////////////////////////////
313// Response class is returned from Request::GetResponse() and is a way
314// to get to response status, error codes, response HTTP headers and response
315// data (body) if available.
316///////////////////////////////////////////////////////////////////////////////
317class Response {
318 public:
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700319 explicit Response(std::unique_ptr<Connection> connection);
Alex Vakulenkoa3062c52014-04-21 17:05:51 -0700320 ~Response();
Chris Sosa45d9f102014-03-24 11:18:54 -0700321
322 // Returns true if server returned a success code (status code below 400).
323 bool IsSuccessful() const;
324
325 // Returns the HTTP status code (e.g. 200 for success)
326 int GetStatusCode() const;
327
328 // Returns the status text (e.g. for error 403 it could be "NOT AUTHORIZED").
329 std::string GetStatusText() const;
330
331 // Returns the content type of the response data.
332 std::string GetContentType() const;
333
334 // Returns response data as a byte array
Alex Vakulenkoa3062c52014-04-21 17:05:51 -0700335 const std::vector<unsigned char>& GetData() const;
Chris Sosa45d9f102014-03-24 11:18:54 -0700336
337 // Returns response data as a string
338 std::string GetDataAsString() const;
339
340 // Returns a value of a given response HTTP header.
Alex Vakulenkob8ba5952014-04-17 11:35:56 -0700341 std::string GetHeader(const char* header_name) const;
Chris Sosa45d9f102014-03-24 11:18:54 -0700342
343 private:
Alex Vakulenkoa3062c52014-04-21 17:05:51 -0700344 std::unique_ptr<Connection> connection_;
345 std::vector<unsigned char> response_data_;
Chris Sosa45d9f102014-03-24 11:18:54 -0700346 DISALLOW_COPY_AND_ASSIGN(Response);
347};
348
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700349} // namespace http
Alex Vakulenkoaf23b322014-05-08 16:25:45 -0700350} // namespace buffet
Chris Sosa45d9f102014-03-24 11:18:54 -0700351
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700352#endif // BUFFET_HTTP_REQUEST_H_