mastodonpp  0.5.3
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 "types.hpp"
21 
22 #include "curl/curl.h"
23 
24 #include <mutex>
25 #include <string>
26 #include <string_view>
27 
28 namespace mastodonpp
29 {
30 
31 using std::mutex;
32 using std::string;
33 using std::string_view;
34 
40 enum class http_method
41 {
42  GET, // NOLINT(readability-identifier-naming)
43  POST, // NOLINT(readability-identifier-naming)
44  PATCH, // NOLINT(readability-identifier-naming)
45  PUT, // NOLINT(readability-identifier-naming)
46  DELETE // NOLINT(readability-identifier-naming)
47 };
48 
59 {
60 public:
71  CURLWrapper();
72 
78  CURLWrapper(const CURLWrapper &);
79 
81  CURLWrapper(CURLWrapper &&other) noexcept = delete;
82 
92  virtual ~CURLWrapper() noexcept;
93 
95  CURLWrapper& operator=(const CURLWrapper &other) = delete;
96 
98  CURLWrapper& operator=(CURLWrapper &&other) noexcept = delete;
99 
109  inline CURL *get_curl_easy_handle()
110  {
111  return _connection;
112  }
113 
126  [[nodiscard]]
127  inline string escape_url(const string_view url) const
128  {
129  char *cbuf{curl_easy_escape(_connection, url.data(),
130  static_cast<int>(url.size()))};
131  const string sbuf{cbuf};
132  curl_free(cbuf);
133  return sbuf;
134  }
135 
148  [[nodiscard]]
149  inline string unescape_url(const string_view url) const
150  {
151  char *cbuf{curl_easy_unescape(_connection, url.data(),
152  static_cast<int>(url.size()), nullptr)};
153  const string sbuf{cbuf};
154  curl_free(cbuf);
155  return sbuf;
156  }
157 
165  void setup_connection_properties(string_view proxy,
166  string_view access_token,
167  string_view cainfo,
168  string_view useragent);
169 
170 protected:
180 
190  [[nodiscard]]
191  answer_type make_request(const http_method &method, string uri,
192  const parametermap &parameters);
193 
199  [[nodiscard]]
200  inline string &get_buffer()
201  {
202  return _curl_buffer_body;
203  }
204 
214  inline void cancel_stream()
215  {
216  _stream_cancelled = true;
217  }
218 
229  virtual void set_proxy(string_view proxy);
230 
236  void set_access_token(string_view access_token);
237 
238 
244  virtual void set_cainfo(string_view path);
245 
251  virtual void set_useragent(string_view useragent);
252 
253 private:
254  CURL *_connection;
255  char _curl_buffer_error[CURL_ERROR_SIZE];
256  string _curl_buffer_headers;
257  string _curl_buffer_body;
258  bool _stream_cancelled;
259 
265  void init();
266 
272  size_t writer_body(char *data, size_t size, size_t nmemb);
273 
282  static inline size_t writer_body_wrapper(char *data, size_t sz,
283  size_t nmemb, void *f)
284  {
285  return static_cast<CURLWrapper*>(f)->writer_body(data, sz, nmemb);
286  }
287 
289  size_t writer_header(char *data, size_t size, size_t nmemb);
290 
292  static inline size_t writer_header_wrapper(char *data, size_t sz,
293  size_t nmemb, void *f)
294  {
295  return static_cast<CURLWrapper*>(f)->writer_header(data, sz, nmemb);
296  }
297 
305  int progress(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
306  curl_off_t ultotal, curl_off_t ulnow);
307 
309  static inline int progress_wrapper(void *f, void *clientp,
310  curl_off_t dltotal, curl_off_t dlnow,
311  curl_off_t ultotal, curl_off_t ulnow)
312  {
313  return static_cast<CURLWrapper*>(f)->progress(clientp, dltotal, dlnow,
314  ultotal, ulnow);
315  }
316 
322  void setup_curl();
323 
334  static bool replace_parameter_in_uri(string &uri,
335  const parameterpair &parameter);
336 
345  static void add_parameters_to_uri(string &uri,
346  const parametermap &parameters);
347 
357  static void add_mime_part(curl_mime *mime,
358  string_view name, string_view data);
359 
374  curl_mime *parameters_to_curl_mime(string &uri,
375  const parametermap &parameters);
376 };
377 
378 } // namespace mastodonpp
379 
380 #endif // MASTODONPP_CURL_WRAPPER_HPP
mastodonpp::http_method
http_method
The HTTP method.
Definition: curl_wrapper.hpp:40
mastodonpp::CURLWrapper::_buffer_mutex
mutex _buffer_mutex
Mutex for get_buffer a.k.a. _curl_buffer_body.
Definition: curl_wrapper.hpp:179
mastodonpp::CURLWrapper::CURLWrapper
CURLWrapper()
Initializes curl and sets up connection.
Definition: curl_wrapper.cpp:57
mastodonpp::CURLWrapper::get_curl_easy_handle
CURL * get_curl_easy_handle()
Returns pointer to the CURL easy handle.
Definition: curl_wrapper.hpp:109
mastodonpp::parametermap
map< string_view, variant< string_view, vector< string_view > >> parametermap
std::map of parameters for API calls.
Definition: types.hpp:64
mastodonpp::CURLWrapper::unescape_url
string unescape_url(const string_view url) const
URL decodes the given string.
Definition: curl_wrapper.hpp:149
mastodonpp
C++ wrapper for the Mastodon API.
Definition: api.cpp:19
mastodonpp::CURLWrapper::get_buffer
string & get_buffer()
Returns a reference to the buffer libcurl writes into.
Definition: curl_wrapper.hpp:200
mastodonpp::CURLWrapper::set_proxy
virtual void set_proxy(string_view proxy)
Set the proxy to use.
Definition: curl_wrapper.cpp:234
mastodonpp::answer_type
Return type for Requests.
Definition: types.hpp:79
mastodonpp::parameterpair
pair< string_view, variant< string_view, vector< string_view > >> parameterpair
A single parameter of a parametermap.
Definition: types.hpp:72
mastodonpp::CURLWrapper::set_cainfo
virtual void set_cainfo(string_view path)
Set path to Certificate Authority (CA) bundle.
Definition: curl_wrapper.cpp:271
mastodonpp::CURLWrapper::operator=
CURLWrapper & operator=(const CURLWrapper &other)=delete
Copy assignment operator.
mastodonpp::CURLWrapper::set_useragent
virtual void set_useragent(string_view useragent)
Sets the User-Agent.
Definition: curl_wrapper.cpp:281
mastodonpp::CURLWrapper
Handles the details of network connections.
Definition: curl_wrapper.hpp:58
mastodonpp::CURLWrapper::make_request
answer_type make_request(const http_method &method, string uri, const parametermap &parameters)
Make a HTTP request.
Definition: curl_wrapper.cpp:85
mastodonpp::CURLWrapper::~CURLWrapper
virtual ~CURLWrapper() noexcept
Cleans up curl and connection.
Definition: curl_wrapper.cpp:73
mastodonpp::CURLWrapper::cancel_stream
void cancel_stream()
Cancel the stream.
Definition: curl_wrapper.hpp:214
mastodonpp::CURLWrapper::escape_url
string escape_url(const string_view url) const
URL encodes the given string.
Definition: curl_wrapper.hpp:127
mastodonpp::CURLWrapper::set_access_token
void set_access_token(string_view access_token)
Set OAuth 2.0 Bearer Access Token.
Definition: curl_wrapper.cpp:245
mastodonpp::CURLWrapper::setup_connection_properties
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:208