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