Move low-level network stuff to CURLWrapper.
This commit is contained in:
parent
d9c92d5273
commit
a7a861351f
92
include/curl_wrapper.hpp
Normal file
92
include/curl_wrapper.hpp
Normal file
@ -0,0 +1,92 @@
|
||||
/* This file is part of mastodonpp.
|
||||
* Copyright © 2020 tastytea <tastytea@tastytea.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MASTODONPP_CURL_WRAPPER_HPP
|
||||
#define MASTODONPP_CURL_WRAPPER_HPP
|
||||
|
||||
#include "curl/curl.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
using std::string;
|
||||
|
||||
//! Internal use only.
|
||||
extern bool curl_initialized;
|
||||
|
||||
/*!
|
||||
* @brief Handles the details of network connections.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @headerfile curl_wrapper.hpp mastodonpp/curl_wrapper.hpp
|
||||
*/
|
||||
class CURLWrapper
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* @brief Constructs a CURLWrapper object.
|
||||
*
|
||||
* The first construction of an CurlWrapper object will call
|
||||
* `curl_global_init`, which is not thread-safe. For more information
|
||||
* consult [curl_global_init(3)]
|
||||
* (https://curl.haxx.se/libcurl/c/curl_global_init.html).
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
CURLWrapper();
|
||||
|
||||
//! Copy constructor
|
||||
CURLWrapper(const CURLWrapper &other) = default;
|
||||
|
||||
//! Move constructor
|
||||
CURLWrapper(CURLWrapper &&other) noexcept = default;
|
||||
|
||||
//! Destructor
|
||||
virtual ~CURLWrapper() noexcept;
|
||||
|
||||
//! Copy assignment operator
|
||||
CURLWrapper& operator=(const CURLWrapper &other) = default;
|
||||
|
||||
//! Move assignment operator
|
||||
CURLWrapper& operator=(CURLWrapper &&other) noexcept = default;
|
||||
|
||||
private:
|
||||
CURL *_connection;
|
||||
char _curl_buffer_error[CURL_ERROR_SIZE];
|
||||
string _curl_buffer;
|
||||
|
||||
/*!
|
||||
* @brief libcurl write callback function.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
static int writer(char *data, size_t size, size_t nmemb,
|
||||
string *writerData);
|
||||
|
||||
/*!
|
||||
* @brief Setup libcurl connection.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void setup_curl();
|
||||
};
|
||||
|
||||
} // namespace mastodonpp
|
||||
|
||||
#endif // MASTODONPP_CURL_WRAPPER_HPP
|
@ -17,7 +17,7 @@
|
||||
#ifndef MASTODONPP_INSTANCE_HPP
|
||||
#define MASTODONPP_INSTANCE_HPP
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_wrapper.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -26,27 +26,19 @@ namespace mastodonpp
|
||||
|
||||
using std::string;
|
||||
|
||||
//! Internal use only.
|
||||
extern bool curl_initialized;
|
||||
|
||||
/*!
|
||||
* @brief Holds the access data of and the connection to an instance.
|
||||
* @brief Holds the access data of an instance.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @headerfile instance.hpp mastodonpp/instance.hpp
|
||||
*/
|
||||
class Instance
|
||||
class Instance : public CURLWrapper
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* @brief Construct a new Instance object.
|
||||
*
|
||||
* The first construction of an Instance object will call
|
||||
* `curl_global_init`, which is not thread-safe. For more information
|
||||
* consult [curl_global_init(3)]
|
||||
* (https://curl.haxx.se/libcurl/c/curl_global_init.html).
|
||||
*
|
||||
* @param instance The hostname of the instance.
|
||||
* @param access_token Your access token.
|
||||
*
|
||||
@ -54,43 +46,9 @@ public:
|
||||
*/
|
||||
explicit Instance(string instance, string access_token);
|
||||
|
||||
//! Copy constructor
|
||||
Instance(const Instance &other) = default;
|
||||
|
||||
//! Move constructor
|
||||
Instance(Instance &&other) = default;
|
||||
|
||||
//! Destructor
|
||||
virtual ~Instance();
|
||||
|
||||
//! Copy assignment operator
|
||||
Instance& operator=(const Instance &other) = delete;
|
||||
|
||||
//! Move assignment operator
|
||||
Instance& operator=(Instance &&other) = delete;
|
||||
|
||||
private:
|
||||
const string _instance;
|
||||
string _access_token;
|
||||
CURL *_connection;
|
||||
char _curl_buffer_error[CURL_ERROR_SIZE];
|
||||
string _curl_buffer;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief libcurl write callback function.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
static int writer(char *data, size_t size, size_t nmemb,
|
||||
string *writerData);
|
||||
|
||||
/*!
|
||||
* @brief Setup libcurl connection.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
void setup_curl();
|
||||
};
|
||||
|
||||
} // namespace mastodonpp
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define MASTODONPP_REQUEST_HPP
|
||||
|
||||
#include "api.hpp"
|
||||
#include "curl_wrapper.hpp"
|
||||
#include "instance.hpp"
|
||||
#include "return_types.hpp"
|
||||
|
||||
@ -35,7 +36,7 @@ using std::string;
|
||||
*
|
||||
* @headerfile request.hpp mastodonpp/request.hpp
|
||||
*/
|
||||
class Request
|
||||
class Request : public CURLWrapper
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
@ -50,11 +51,24 @@ public:
|
||||
/*!
|
||||
* @brief Make a HTTP GET call.
|
||||
*
|
||||
* @param endpoint Endpoint as API::endpoint_type, for example:
|
||||
* `mastodonpp::API::v1::instance`.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
[[nodiscard]]
|
||||
answer_type get(API::endpoint_type endpoint) const;
|
||||
|
||||
/*!
|
||||
* @brief Make a HTTP GET call.
|
||||
*
|
||||
* @param endpoint Endpoint as string, for example: "/api/v1/instance".
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
[[nodiscard]]
|
||||
answer_type get(string endpoint) const;
|
||||
|
||||
private:
|
||||
Instance &_instance;
|
||||
};
|
||||
|
90
src/curl_wrapper.cpp
Normal file
90
src/curl_wrapper.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/* This file is part of mastodonpp.
|
||||
* Copyright © 2020 tastytea <tastytea@tastytea.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "curl_wrapper.hpp"
|
||||
#include "exceptions.hpp"
|
||||
|
||||
namespace mastodonpp
|
||||
{
|
||||
|
||||
bool curl_initialized{false};
|
||||
|
||||
CURLWrapper::CURLWrapper()
|
||||
: _curl_buffer_error{}
|
||||
{
|
||||
if (!curl_initialized)
|
||||
{
|
||||
curl_global_init(CURL_GLOBAL_ALL); // NOLINT(hicpp-signed-bitwise)
|
||||
curl_initialized = true;
|
||||
}
|
||||
_connection = curl_easy_init();
|
||||
setup_curl();
|
||||
}
|
||||
CURLWrapper::~CURLWrapper() noexcept
|
||||
{
|
||||
curl_easy_cleanup(_connection);
|
||||
|
||||
if (curl_initialized)
|
||||
{
|
||||
curl_global_cleanup();
|
||||
curl_initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
int CURLWrapper::writer(char *data, size_t size, size_t nmemb, string *writerData)
|
||||
{
|
||||
if(writerData == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
writerData->append(data, size*nmemb);
|
||||
|
||||
return static_cast<int>(size * nmemb);
|
||||
}
|
||||
|
||||
void CURLWrapper::setup_curl()
|
||||
{
|
||||
if (_connection == nullptr)
|
||||
{
|
||||
throw CURLException{CURLE_FAILED_INIT, "Failed to initialize curl."};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
CURLcode code{curl_easy_setopt(_connection, CURLOPT_ERRORBUFFER,
|
||||
_curl_buffer_error)};
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set error buffer."};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, writer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set writer", _curl_buffer_error};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_WRITEDATA, &_curl_buffer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set write data",
|
||||
_curl_buffer_error};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mastodonpp
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include "instance.hpp"
|
||||
#include "exceptions.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
@ -24,73 +23,9 @@ namespace mastodonpp
|
||||
|
||||
using std::move;
|
||||
|
||||
bool curl_initialized{false};
|
||||
|
||||
Instance::Instance(string instance, string access_token)
|
||||
: _instance{move(instance)}
|
||||
, _access_token{move(access_token)}
|
||||
, _curl_buffer_error{}
|
||||
{
|
||||
if (!curl_initialized)
|
||||
{
|
||||
curl_global_init(CURL_GLOBAL_ALL); // NOLINT(hicpp-signed-bitwise)
|
||||
curl_initialized = true;
|
||||
}
|
||||
_connection = curl_easy_init();
|
||||
setup_curl();
|
||||
}
|
||||
Instance::~Instance()
|
||||
{
|
||||
curl_easy_cleanup(_connection);
|
||||
|
||||
if (curl_initialized)
|
||||
{
|
||||
curl_global_cleanup();
|
||||
curl_initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
int Instance::writer(char *data, size_t size, size_t nmemb, string *writerData)
|
||||
{
|
||||
if(writerData == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
writerData->append(data, size*nmemb);
|
||||
|
||||
return static_cast<int>(size * nmemb);
|
||||
}
|
||||
|
||||
void Instance::setup_curl()
|
||||
{
|
||||
if (_connection == nullptr)
|
||||
{
|
||||
throw CURLException{CURLE_FAILED_INIT, "Failed to initialize curl."};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
CURLcode code{curl_easy_setopt(_connection, CURLOPT_ERRORBUFFER,
|
||||
_curl_buffer_error)};
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set error buffer."};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_WRITEFUNCTION, writer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set writer", _curl_buffer_error};
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
code = curl_easy_setopt(_connection, CURLOPT_WRITEDATA, &_curl_buffer);
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
throw CURLException{code, "Failed to set write data",
|
||||
_curl_buffer_error};
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
} // namespace mastodonpp
|
||||
|
@ -30,4 +30,11 @@ answer_type Request::get(API::endpoint_type endpoint) const
|
||||
return answer;
|
||||
}
|
||||
|
||||
answer_type Request::get(string endpoint) const
|
||||
{
|
||||
answer_type answer;
|
||||
answer.body = endpoint;
|
||||
return answer;
|
||||
}
|
||||
|
||||
} // namespace mastodonpp
|
||||
|
Loading…
x
Reference in New Issue
Block a user