mastodonpp  0.5.7
C++ wrapper for the Mastodon and Pleroma APIs.
curl_wrapper.hpp
1 /* This file is part of mastodonpp.
2  * Copyright © 2020 tastytea <tastytea@tastytea.de>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Affero General Public License as published by
6  * the Free Software Foundation, version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Affero General Public License for more details.
12  *
13  * You should have received a copy of the GNU Affero General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #ifndef MASTODONPP_CURL_WRAPPER_HPP
18 #define MASTODONPP_CURL_WRAPPER_HPP
19 
20 #include "curl/curl.h"
21 #include "types.hpp"
22 
23 #include <mutex>
24 #include <string>
25 #include <string_view>
26 
27 namespace mastodonpp
28 {
29 
30 using std::mutex;
31 using std::string;
32 using std::string_view;
33 
39 enum class http_method
40 {
41  GET, // NOLINT(readability-identifier-naming)
42  POST, // NOLINT(readability-identifier-naming)
43  PATCH, // NOLINT(readability-identifier-naming)
44  PUT, // NOLINT(readability-identifier-naming)
45  DELETE // NOLINT(readability-identifier-naming)
46 };
47 
58 {
59 public:
70  CURLWrapper();
71 
77  CURLWrapper(const CURLWrapper &);
78 
80  CURLWrapper(CURLWrapper &&other) noexcept = delete;
81 
91  virtual ~CURLWrapper() noexcept;
92 
94  CURLWrapper &operator=(const CURLWrapper &other) = delete;
95 
97  CURLWrapper &operator=(CURLWrapper &&other) noexcept = delete;
98 
108  inline CURL *get_curl_easy_handle()
109  {
110  return _connection;
111  }
112 
125  [[nodiscard]] inline string escape_url(const string_view url) const
126  {
127  char *cbuf{curl_easy_escape(_connection, url.data(),
128  static_cast<int>(url.size()))};
129  string sbuf{cbuf};
130  curl_free(cbuf);
131  return sbuf;
132  }
133 
146  [[nodiscard]] inline string unescape_url(const string_view url) const
147  {
148  char *cbuf{curl_easy_unescape(_connection, url.data(),
149  static_cast<int>(url.size()), nullptr)};
150  string sbuf{cbuf};
151  curl_free(cbuf);
152  return sbuf;
153  }
154 
162  void setup_connection_properties(string_view proxy,
163  string_view access_token,
164  string_view cainfo, string_view useragent);
165 
166 protected:
176 
186  [[nodiscard]] answer_type make_request(const http_method &method,
187  string uri,
188  const parametermap &parameters);
189 
195  [[nodiscard]] inline string &get_buffer()
196  {
197  return _curl_buffer_body;
198  }
199 
209  inline void cancel_stream()
210  {
211  _stream_cancelled = true;
212  }
213 
224  virtual void set_proxy(string_view proxy);
225 
231  void set_access_token(string_view access_token);
232 
238  virtual void set_cainfo(string_view path);
239 
245  virtual void set_useragent(string_view useragent);
246 
247 private:
248  CURL *_connection{nullptr};
249  char _curl_buffer_error[CURL_ERROR_SIZE]{'\0'};
250  string _curl_buffer_headers;
251  string _curl_buffer_body;
252  bool _stream_cancelled{false};
253 
259  void init();
260 
266  size_t writer_body(char *data, size_t size, size_t nmemb);
267 
276  static inline size_t writer_body_wrapper(char *data, size_t sz,
277  size_t nmemb, void *f)
278  {
279  return static_cast<CURLWrapper *>(f)->writer_body(data, sz, nmemb);
280  }
281 
283  size_t writer_header(char *data, size_t size, size_t nmemb);
284 
286  static inline size_t writer_header_wrapper(char *data, size_t sz,
287  size_t nmemb, void *f)
288  {
289  return static_cast<CURLWrapper *>(f)->writer_header(data, sz, nmemb);
290  }
291 
299  int progress(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
300  curl_off_t ultotal, curl_off_t ulnow) const;
301 
303  static inline int progress_wrapper(void *f, void *clientp,
304  curl_off_t dltotal, curl_off_t dlnow,
305  curl_off_t ultotal, curl_off_t ulnow)
306  {
307  return static_cast<CURLWrapper *>(f)->progress(clientp, dltotal, dlnow,
308  ultotal, ulnow);
309  }
310 
316  void setup_curl();
317 
328  static bool replace_parameter_in_uri(string &uri,
329  const parameterpair &parameter);
330 
339  static void add_parameters_to_uri(string &uri,
340  const parametermap &parameters);
341 
351  static void add_mime_part(curl_mime *mime, string_view name,
352  string_view data);
353 
368  curl_mime *parameters_to_curl_mime(string &uri,
369  const parametermap &parameters);
370 };
371 
372 } // namespace mastodonpp
373 
374 #endif // MASTODONPP_CURL_WRAPPER_HPP
Handles the details of network connections.
Definition: curl_wrapper.hpp:58
void setup_connection_properties(string_view proxy, string_view access_token, string_view cainfo, string_view useragent)
Set some properties of the connection.
Definition: curl_wrapper.cpp:203
string & get_buffer()
Returns a reference to the buffer libcurl writes into.
Definition: curl_wrapper.hpp:195
string escape_url(const string_view url) const
URL encodes the given string.
Definition: curl_wrapper.hpp:125
virtual void set_proxy(string_view proxy)
Set the proxy to use.
Definition: curl_wrapper.cpp:229
CURL * get_curl_easy_handle()
Returns pointer to the CURL easy handle.
Definition: curl_wrapper.hpp:108
virtual ~CURLWrapper() noexcept
Cleans up curl and connection.
Definition: curl_wrapper.cpp:68
CURLWrapper(CURLWrapper &&other) noexcept=delete
Move constructor.
CURLWrapper()
Initializes curl and sets up connection.
Definition: curl_wrapper.cpp:58
void cancel_stream()
Cancel the stream.
Definition: curl_wrapper.hpp:209
void set_access_token(string_view access_token)
Set OAuth 2.0 Bearer Access Token.
Definition: curl_wrapper.cpp:240
answer_type make_request(const http_method &method, string uri, const parametermap &parameters)
Make a HTTP request.
Definition: curl_wrapper.cpp:80
virtual void set_useragent(string_view useragent)
Sets the User-Agent.
Definition: curl_wrapper.cpp:276
string unescape_url(const string_view url) const
URL decodes the given string.
Definition: curl_wrapper.hpp:146
virtual void set_cainfo(string_view path)
Set path to Certificate Authority (CA) bundle.
Definition: curl_wrapper.cpp:266
mutex _buffer_mutex
Mutex for get_buffer a.k.a. _curl_buffer_body.
Definition: curl_wrapper.hpp:175
C++ wrapper for the Mastodon API.
Definition: api.hpp:25
pair< string_view, variant< string_view, vector< string_view > >> parameterpair
A single parameter of a parametermap.
Definition: types.hpp:72
http_method
The HTTP method.
Definition: curl_wrapper.hpp:40
map< string_view, variant< string_view, vector< string_view > >> parametermap
std::map of parameters for API calls.
Definition: types.hpp:64
Return type for Requests.
Definition: types.hpp:80