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
17namespace base {
18class Value;
19class DictionaryValue;
20}  // namespace base
21
22namespace brillo {
23namespace http {
24
25using 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.
56BRILLO_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".
68BRILLO_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().
80BRILLO_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().
95BRILLO_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().
109BRILLO_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.
120BRILLO_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().
129BRILLO_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.
139BRILLO_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().
147BRILLO_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.
156BRILLO_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().
168BRILLO_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().
182BRILLO_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.
195BRILLO_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().
206BRILLO_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".
219BRILLO_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().
229BRILLO_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".
241BRILLO_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().
251BRILLO_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.
263BRILLO_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().
273BRILLO_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.
285BRILLO_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().
295BRILLO_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.
306BRILLO_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".
314BRILLO_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