1 // 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 LIBBRILLO_BRILLO_HTTP_HTTP_UTILS_H_
6 #define LIBBRILLO_BRILLO_HTTP_HTTP_UTILS_H_
7 
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include <brillo/brillo_export.h>
13 #include <brillo/errors/error.h>
14 #include <brillo/http/http_form_data.h>
15 #include <brillo/http/http_request.h>
16 
17 namespace base {
18 class Value;
19 class DictionaryValue;
20 }  // namespace base
21 
22 namespace brillo {
23 namespace http {
24 
25 using FormFieldList = std::vector<std::pair<std::string, std::string>>;
26 
27 ////////////////////////////////////////////////////////////////////////////////
28 // The following are simple utility helper functions for common HTTP operations
29 // that use http::Request object behind the scenes and set it up accordingly.
30 // The values for request method, data MIME type, request header names should
31 // not be directly encoded in most cases, but use predefined constants from
32 // http_request.h.
33 // So, instead of calling:
34 //    SendRequestAndBlock("POST",
35 //                        "http://url",
36 //                        "data", 4,
37 //                        "text/plain",
38 //                        {{"Authorization", "Bearer TOKEN"}},
39 //                        transport, error);
40 // You should do use this instead:
41 //    SendRequestAndBlock(brillo::http::request_type::kPost,
42 //                        "http://url",
43 //                        "data", 4,
44 //                        brillo::mime::text::kPlain,
45 //                        {{brillo::http::request_header::kAuthorization,
46 //                          "Bearer TOKEN"}},
47 //                        transport, error);
48 //
49 // For more advanced functionality you need to use Request/Response objects
50 // directly.
51 ////////////////////////////////////////////////////////////////////////////////
52 
53 // Performs a generic HTTP request with binary data. Success status,
54 // returned data and additional information (such as returned HTTP headers)
55 // can be obtained from the returned Response object.
56 BRILLO_EXPORT std::unique_ptr<Response> SendRequestAndBlock(
57     const std::string& method,
58     const std::string& url,
59     const void* data,
60     size_t data_size,
61     const std::string& mime_type,
62     const HeaderList& headers,
63     std::shared_ptr<Transport> transport,
64     brillo::ErrorPtr* error);
65 
66 // Same as above, but without sending the request body.
67 // This is especially useful for requests like "GET" and "HEAD".
68 BRILLO_EXPORT std::unique_ptr<Response> SendRequestWithNoDataAndBlock(
69     const std::string& method,
70     const std::string& url,
71     const HeaderList& headers,
72     std::shared_ptr<Transport> transport,
73     brillo::ErrorPtr* error);
74 
75 // Same as above but asynchronous. On success, |success_callback| is called
76 // with the response object. On failure, |error_callback| is called with the
77 // error details.
78 // Returns the ID of the request which can be used to cancel the pending
79 // request using Transport::CancelRequest().
80 BRILLO_EXPORT RequestID SendRequest(
81     const std::string& method,
82     const std::string& url,
83     StreamPtr stream,
84     const std::string& mime_type,
85     const HeaderList& headers,
86     std::shared_ptr<Transport> transport,
87     const SuccessCallback& success_callback,
88     const ErrorCallback& error_callback);
89 
90 // Same as above, but takes a memory buffer. The pointer should be valid only
91 // until the function returns. The data is copied into an internal buffer to be
92 // available for the duration of the asynchronous operation.
93 // Returns the ID of the request which can be used to cancel the pending
94 // request using Transport::CancelRequest().
95 BRILLO_EXPORT RequestID SendRequest(
96     const std::string& method,
97     const std::string& url,
98     const void* data,
99     size_t data_size,
100     const std::string& mime_type,
101     const HeaderList& headers,
102     std::shared_ptr<Transport> transport,
103     const SuccessCallback& success_callback,
104     const ErrorCallback& error_callback);
105 
106 // Asynchronous version of SendRequestNoData().
107 // Returns the ID of the request which can be used to cancel the pending
108 // request using Transport::CancelRequest().
109 BRILLO_EXPORT RequestID SendRequestWithNoData(
110     const std::string& method,
111     const std::string& url,
112     const HeaderList& headers,
113     std::shared_ptr<Transport> transport,
114     const SuccessCallback& success_callback,
115     const ErrorCallback& error_callback);
116 
117 // Performs a GET request. Success status, returned data and additional
118 // information (such as returned HTTP headers) can be obtained from
119 // the returned Response object.
120 BRILLO_EXPORT std::unique_ptr<Response> GetAndBlock(
121     const std::string& url,
122     const HeaderList& headers,
123     std::shared_ptr<Transport> transport,
124     brillo::ErrorPtr* error);
125 
126 // Asynchronous version of http::Get().
127 // Returns the ID of the request which can be used to cancel the pending
128 // request using Transport::CancelRequest().
129 BRILLO_EXPORT RequestID Get(
130     const std::string& url,
131     const HeaderList& headers,
132     std::shared_ptr<Transport> transport,
133     const SuccessCallback& success_callback,
134     const ErrorCallback& error_callback);
135 
136 // Performs a HEAD request. Success status and additional
137 // information (such as returned HTTP headers) can be obtained from
138 // the returned Response object.
139 BRILLO_EXPORT std::unique_ptr<Response> HeadAndBlock(
140     const std::string& url,
141     std::shared_ptr<Transport> transport,
142     brillo::ErrorPtr* error);
143 
144 // Performs an asynchronous HEAD request.
145 // Returns the ID of the request which can be used to cancel the pending
146 // request using Transport::CancelRequest().
147 BRILLO_EXPORT RequestID Head(
148     const std::string& url,
149     std::shared_ptr<Transport> transport,
150     const SuccessCallback& success_callback,
151     const ErrorCallback& error_callback);
152 
153 // Performs a POST request with binary data. Success status, returned data
154 // and additional information (such as returned HTTP headers) can be obtained
155 // from the returned Response object.
156 BRILLO_EXPORT std::unique_ptr<Response> PostBinaryAndBlock(
157     const std::string& url,
158     const void* data,
159     size_t data_size,
160     const std::string& mime_type,
161     const HeaderList& headers,
162     std::shared_ptr<Transport> transport,
163     brillo::ErrorPtr* error);
164 
165 // Async version of PostBinary().
166 // Returns the ID of the request which can be used to cancel the pending
167 // request using Transport::CancelRequest().
168 BRILLO_EXPORT RequestID PostBinary(
169     const std::string& url,
170     StreamPtr stream,
171     const std::string& mime_type,
172     const HeaderList& headers,
173     std::shared_ptr<Transport> transport,
174     const SuccessCallback& success_callback,
175     const ErrorCallback& error_callback);
176 
177 // Same as above, but takes a memory buffer. The pointer should be valid only
178 // until the function returns. The data is copied into an internal buffer
179 // to be available for the duration of the asynchronous operation.
180 // Returns the ID of the request which can be used to cancel the pending
181 // request using Transport::CancelRequest().
182 BRILLO_EXPORT RequestID PostBinary(
183     const std::string& url,
184     const void* data,
185     size_t data_size,
186     const std::string& mime_type,
187     const HeaderList& headers,
188     std::shared_ptr<Transport> transport,
189     const SuccessCallback& success_callback,
190     const ErrorCallback& error_callback);
191 
192 // Performs a POST request with text data. Success status, returned data
193 // and additional information (such as returned HTTP headers) can be obtained
194 // from the returned Response object.
195 BRILLO_EXPORT std::unique_ptr<Response> PostTextAndBlock(
196     const std::string& url,
197     const std::string& data,
198     const std::string& mime_type,
199     const HeaderList& headers,
200     std::shared_ptr<Transport> transport,
201     brillo::ErrorPtr* error);
202 
203 // Async version of PostText().
204 // Returns the ID of the request which can be used to cancel the pending
205 // request using Transport::CancelRequest().
206 BRILLO_EXPORT RequestID PostText(
207     const std::string& url,
208     const std::string& data,
209     const std::string& mime_type,
210     const HeaderList& headers,
211     std::shared_ptr<Transport> transport,
212     const SuccessCallback& success_callback,
213     const ErrorCallback& error_callback);
214 
215 // Performs a POST request with form data. Success status, returned data
216 // and additional information (such as returned HTTP headers) can be obtained
217 // from the returned Response object. The form data is a list of key/value
218 // pairs. The data is posed as "application/x-www-form-urlencoded".
219 BRILLO_EXPORT std::unique_ptr<Response> PostFormDataAndBlock(
220     const std::string& url,
221     const FormFieldList& data,
222     const HeaderList& headers,
223     std::shared_ptr<Transport> transport,
224     brillo::ErrorPtr* error);
225 
226 // Async version of PostFormData() above.
227 // Returns the ID of the request which can be used to cancel the pending
228 // request using Transport::CancelRequest().
229 BRILLO_EXPORT RequestID PostFormData(
230     const std::string& url,
231     const FormFieldList& data,
232     const HeaderList& headers,
233     std::shared_ptr<Transport> transport,
234     const SuccessCallback& success_callback,
235     const ErrorCallback& error_callback);
236 
237 // Performs a POST request with form data, including binary file uploads.
238 // Success status, returned data and additional information (such as returned
239 // HTTP headers) can be obtained from the returned Response object.
240 // The data is posed as "multipart/form-data".
241 BRILLO_EXPORT std::unique_ptr<Response> PostFormDataAndBlock(
242     const std::string& url,
243     std::unique_ptr<FormData> form_data,
244     const HeaderList& headers,
245     std::shared_ptr<Transport> transport,
246     brillo::ErrorPtr* error);
247 
248 // Async version of PostFormData() above.
249 // Returns the ID of the request which can be used to cancel the pending
250 // request using Transport::CancelRequest().
251 BRILLO_EXPORT RequestID PostFormData(
252     const std::string& url,
253     std::unique_ptr<FormData> form_data,
254     const HeaderList& headers,
255     std::shared_ptr<Transport> transport,
256     const SuccessCallback& success_callback,
257     const ErrorCallback& error_callback);
258 
259 // Performs a POST request with JSON data. Success status, returned data
260 // and additional information (such as returned HTTP headers) can be obtained
261 // from the returned Response object. If a JSON response is expected,
262 // use ParseJsonResponse() method on the returned Response object.
263 BRILLO_EXPORT std::unique_ptr<Response> PostJsonAndBlock(
264     const std::string& url,
265     const base::Value* json,
266     const HeaderList& headers,
267     std::shared_ptr<Transport> transport,
268     brillo::ErrorPtr* error);
269 
270 // Async version of PostJson().
271 // Returns the ID of the request which can be used to cancel the pending
272 // request using Transport::CancelRequest().
273 BRILLO_EXPORT RequestID PostJson(
274     const std::string& url,
275     std::unique_ptr<base::Value> json,
276     const HeaderList& headers,
277     std::shared_ptr<Transport> transport,
278     const SuccessCallback& success_callback,
279     const ErrorCallback& error_callback);
280 
281 // Performs a PATCH request with JSON data. Success status, returned data
282 // and additional information (such as returned HTTP headers) can be obtained
283 // from the returned Response object. If a JSON response is expected,
284 // use ParseJsonResponse() method on the returned Response object.
285 BRILLO_EXPORT std::unique_ptr<Response> PatchJsonAndBlock(
286     const std::string& url,
287     const base::Value* json,
288     const HeaderList& headers,
289     std::shared_ptr<Transport> transport,
290     brillo::ErrorPtr* error);
291 
292 // Async version of PatchJson().
293 // Returns the ID of the request which can be used to cancel the pending
294 // request using Transport::CancelRequest().
295 BRILLO_EXPORT RequestID PatchJson(
296     const std::string& url,
297     std::unique_ptr<base::Value> json,
298     const HeaderList& headers,
299     std::shared_ptr<Transport> transport,
300     const SuccessCallback& success_callback,
301     const ErrorCallback& error_callback);
302 
303 // Given an http::Response object, parse the body data into Json object.
304 // Returns null if failed. Optional |error| can be passed in to
305 // get the extended error information as to why the parse failed.
306 BRILLO_EXPORT std::unique_ptr<base::DictionaryValue> ParseJsonResponse(
307     Response* response,
308     int* status_code,
309     brillo::ErrorPtr* error);
310 
311 // Converts a request header name to canonical form (lowercase with uppercase
312 // first letter and each letter after a hyphen ('-')).
313 // "content-TYPE" will be converted to "Content-Type".
314 BRILLO_EXPORT std::string GetCanonicalHeaderName(const std::string& name);
315 
316 }  // namespace http
317 }  // namespace brillo
318 
319 #endif  // LIBBRILLO_BRILLO_HTTP_HTTP_UTILS_H_
320