Add support for parameters (GET).

This commit is contained in:
tastytea 2020-01-08 12:56:16 +01:00
parent 15c1e15466
commit c07fb1db71
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
5 changed files with 84 additions and 23 deletions

View File

@ -24,12 +24,16 @@
#include <string>
#include <string_view>
#include <variant>
namespace mastodonpp
{
using std::string;
using std::string_view;
using std::variant;
using endpoint_variant = variant<API::endpoint_type,string>;
/*!
* @brief Represents a connection to an instance. Used for requests.
@ -51,25 +55,43 @@ public:
explicit Connection(Instance &instance);
/*!
* @brief Make a HTTP GET call.
* @brief Make a HTTP GET call with parameters.
*
* Example:
* @code
* auto answer{connection.get(mastodonpp::API::v1::accounts_id_followers,
* {
* {"id", "12"},
* {"limit", "10"}
* })};
* @endcode
*
* @param endpoint Endpoint as API::endpoint_type or `std::string`.
* @param parameters A map of parameters.
*
* @param endpoint Endpoint as API::endpoint_type, for example:
* `mastodonpp::API::v1::instance`.
*
* @since 0.1.0
*/
[[nodiscard]]
answer_type get(const API::endpoint_type &endpoint);
answer_type get(const endpoint_variant &endpoint,
const parametermap &parameters);
/*!
* @brief Make a HTTP GET call.
* Example:
* @code
* auto answer{connection.get("/api/v1/instance")};
* @endcode
*
* @param endpoint Endpoint as string, for example: "/api/v1/instance".
* @param endpoint Endpoint as API::endpoint_type or `std::string`.
*
* @since 0.1.0
*/
[[nodiscard]]
answer_type get(const string_view &endpoint);
inline answer_type get(const endpoint_variant &endpoint)
{
return get(endpoint, {});
}
private:
Instance &_instance;

View File

@ -129,15 +129,17 @@ public:
protected:
/*!
* @brief Make a request.
* @brief Make a HTTP request.
*
* @param method The HTTP method.
* @param uri The full URI.
* @param method The HTTP method.
* @param uri The full URI.
* @param parameters A map of parameters.
*
* @since 0.1.0
*/
[[nodiscard]]
answer_type make_request(const http_method &method, const string_view &uri);
answer_type make_request(const http_method &method, string uri,
const parametermap &parameters);
private:
CURL *_connection;

View File

@ -19,21 +19,27 @@
namespace mastodonpp
{
using std::holds_alternative;
Connection::Connection(Instance &instance)
: _instance{instance}
, _baseuri{instance.get_baseuri()}
{}
answer_type Connection::get(const API::endpoint_type &endpoint)
answer_type Connection::get(const endpoint_variant &endpoint,
const parametermap &parameters)
{
return make_request(
http_method::GET,
string(_baseuri).append(API{endpoint}.to_string_view()));
}
string uri{[&]
{
if (holds_alternative<API::endpoint_type>(endpoint))
{
return string(_baseuri).append(
API{std::get<API::endpoint_type>(endpoint)}.to_string_view());
}
answer_type Connection::get(const string_view &endpoint)
{
return make_request(http_method::GET, string(_baseuri).append(endpoint));
return std::get<string>(endpoint);
}()};
return make_request(http_method::GET, uri, parameters);
}
} // namespace mastodonpp

View File

@ -26,6 +26,8 @@
namespace mastodonpp
{
using std::get;
using std::holds_alternative;
using std::atomic;
using std::uint8_t;
using std::uint16_t;
@ -57,11 +59,9 @@ CURLWrapper::~CURLWrapper() noexcept
}
}
answer_type CURLWrapper::make_request(const http_method &method,
const string_view &uri)
answer_type CURLWrapper::make_request(const http_method &method, string uri,
const parametermap &parameters)
{
debuglog << "Making request to: " << uri << '\n';
CURLcode code;
switch (method)
{
@ -69,6 +69,36 @@ answer_type CURLWrapper::make_request(const http_method &method,
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
code = curl_easy_setopt(_connection, CURLOPT_HTTPGET, 1L);
for (const auto &param : parameters)
{
static bool first{true};
if (first)
{
uri.append("?");
first = false;
}
else
{
uri.append("&");
}
if (holds_alternative<string>(param.second))
{
uri.append(param.first + '=' + get<string>(param.second));
}
else
{
for (const auto &arg : get<vector<string>>(param.second))
{
uri.append(param.first + "[]=" + arg);
if (arg != *get<vector<string>>(param.second).rbegin())
{
uri.append("&");
}
}
}
}
break;
}
case http_method::POST:
@ -101,6 +131,7 @@ answer_type CURLWrapper::make_request(const http_method &method,
throw CURLException{code, "Failed to set HTTP method",
_curl_buffer_error};
}
debuglog << "Making request to: " << uri << '\n';
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
code = curl_easy_setopt(_connection, CURLOPT_URL, uri.data());

View File

@ -40,7 +40,7 @@ uint64_t Instance::get_max_chars()
{
debuglog << "Querying " << _hostname << " for max_toot_chars…\n";
const auto answer{make_request(http_method::GET,
_baseuri + "/api/v1/instance")};
_baseuri + "/api/v1/instance", {})};
if (!answer)
{
debuglog << "Could not get instance info.\n";