Implement HTTP POST in CURLWrapper.
This commit is contained in:
parent
529e4bca6d
commit
f222215116
@ -1,5 +1,5 @@
|
|||||||
include(CMakeFindDependencyMacro)
|
include(CMakeFindDependencyMacro)
|
||||||
|
|
||||||
find_dependency(CURL 7.32 REQUIRED)
|
find_dependency(CURL 7.56 REQUIRED)
|
||||||
|
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||||
|
@ -263,6 +263,18 @@ private:
|
|||||||
*/
|
*/
|
||||||
void setup_curl();
|
void setup_curl();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Replace parameter in URI.
|
||||||
|
*
|
||||||
|
* @param uri Reference to the URI.
|
||||||
|
* @param parameter The parameter.
|
||||||
|
*
|
||||||
|
* @return true if parameter was replaced.
|
||||||
|
*
|
||||||
|
* @since 0.1.0
|
||||||
|
*/
|
||||||
|
bool replace_parameter_in_uri(string &uri, const parameterpair ¶meter);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Add parameters to URI.
|
* @brief Add parameters to URI.
|
||||||
*
|
*
|
||||||
@ -272,6 +284,23 @@ private:
|
|||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
void add_parameters_to_uri(string &uri, const parametermap ¶meters);
|
void add_parameters_to_uri(string &uri, const parametermap ¶meters);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Convert parametermap to `*curl_mime`.
|
||||||
|
*
|
||||||
|
* For more information consult [curl_mime_init(3)]
|
||||||
|
* (https://curl.haxx.se/libcurl/c/curl_mime_init.html). Calls
|
||||||
|
* replace_parameter_in_uri().
|
||||||
|
*
|
||||||
|
* @param uri Reference to the URI.
|
||||||
|
* @param parameters The parametermap.
|
||||||
|
*
|
||||||
|
* @return `*curl_mime`.
|
||||||
|
*
|
||||||
|
* @since 0.1.0
|
||||||
|
*/
|
||||||
|
curl_mime *parameters_to_curl_mime(string &uri,
|
||||||
|
const parametermap ¶meters);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mastodonpp
|
} // namespace mastodonpp
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
find_package(CURL 7.32 REQUIRED)
|
find_package(CURL 7.56 REQUIRED)
|
||||||
|
|
||||||
# Write version in header.
|
# Write version in header.
|
||||||
configure_file ("version.hpp.in"
|
configure_file ("version.hpp.in"
|
||||||
|
@ -68,7 +68,7 @@ CURLWrapper::~CURLWrapper() noexcept
|
|||||||
void CURLWrapper::set_proxy(const string_view proxy)
|
void CURLWrapper::set_proxy(const string_view proxy)
|
||||||
{
|
{
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
CURLcode code = curl_easy_setopt(_connection, CURLOPT_PROXY, proxy);
|
CURLcode code{curl_easy_setopt(_connection, CURLOPT_PROXY, proxy)};
|
||||||
if (code != CURLE_OK)
|
if (code != CURLE_OK)
|
||||||
{
|
{
|
||||||
throw CURLException{code, "Failed to set proxy", _curl_buffer_error};
|
throw CURLException{code, "Failed to set proxy", _curl_buffer_error};
|
||||||
@ -101,8 +101,11 @@ answer_type CURLWrapper::make_request(const http_method &method, string uri,
|
|||||||
}
|
}
|
||||||
case http_method::POST:
|
case http_method::POST:
|
||||||
{
|
{
|
||||||
|
curl_mime *mime{parameters_to_curl_mime(uri, parameters)};
|
||||||
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||||
code = curl_easy_setopt(_connection, CURLOPT_POST, 1L);
|
code = curl_easy_setopt(_connection, CURLOPT_MIMEPOST, mime);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case http_method::PATCH:
|
case http_method::PATCH:
|
||||||
@ -247,27 +250,38 @@ void CURLWrapper::setup_curl()
|
|||||||
curl_easy_setopt(_connection, CURLOPT_MAXREDIRS, 10L);
|
curl_easy_setopt(_connection, CURLOPT_MAXREDIRS, 10L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CURLWrapper::replace_parameter_in_uri(string &uri,
|
||||||
|
const parameterpair ¶meter)
|
||||||
|
{
|
||||||
|
static constexpr array replace
|
||||||
|
{
|
||||||
|
"id", "nickname", "nickname_or_id",
|
||||||
|
"hashtag", "permission_group"
|
||||||
|
};
|
||||||
|
if (any_of(replace.begin(), replace.end(),
|
||||||
|
[¶meter](const auto &s) { return s == parameter.first; }))
|
||||||
|
{
|
||||||
|
const auto pos{uri.find('<')};
|
||||||
|
if (pos != string::npos)
|
||||||
|
{
|
||||||
|
uri.replace(pos, parameter.first.size() + 2,
|
||||||
|
get<string_view>(parameter.second));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CURLWrapper::add_parameters_to_uri(string &uri,
|
void CURLWrapper::add_parameters_to_uri(string &uri,
|
||||||
const parametermap ¶meters)
|
const parametermap ¶meters)
|
||||||
{
|
{
|
||||||
// Replace <ID> with the value of parameter “id” and so on.
|
// Replace <ID> with the value of parameter “id” and so on.
|
||||||
for (const auto ¶m : parameters)
|
for (const auto ¶m : parameters)
|
||||||
{
|
{
|
||||||
static constexpr array replace_in_uri
|
if (replace_parameter_in_uri(uri, param))
|
||||||
{
|
|
||||||
"id", "nickname", "nickname_or_id",
|
|
||||||
"hashtag", "permission_group"
|
|
||||||
};
|
|
||||||
if (any_of(replace_in_uri.begin(), replace_in_uri.end(),
|
|
||||||
[¶m](const auto &s) { return s == param.first; }))
|
|
||||||
{
|
{
|
||||||
const auto pos{uri.find('<')};
|
continue;
|
||||||
if (pos != string::npos)
|
|
||||||
{
|
|
||||||
uri.replace(pos, param.first.size() + 2,
|
|
||||||
get<string_view>(param.second));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool first{true};
|
static bool first{true};
|
||||||
@ -298,4 +312,64 @@ void CURLWrapper::add_parameters_to_uri(string &uri,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curl_mime *CURLWrapper::parameters_to_curl_mime(string &uri,
|
||||||
|
const parametermap ¶meters)
|
||||||
|
{
|
||||||
|
debuglog << "Building HTTP form.\n";
|
||||||
|
|
||||||
|
curl_mime *mime{curl_mime_init(_connection)};
|
||||||
|
for (const auto ¶m : parameters)
|
||||||
|
{
|
||||||
|
if (replace_parameter_in_uri(uri, param))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_mimepart *part{curl_mime_addpart(mime)};
|
||||||
|
if (part == nullptr)
|
||||||
|
{
|
||||||
|
throw CURLException{"Could not build HTTP form."};
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode code;
|
||||||
|
if (holds_alternative<string_view>(param.second))
|
||||||
|
{
|
||||||
|
code = curl_mime_name(part, param.first.data());
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
throw CURLException{code, "Could not build HTTP form."};
|
||||||
|
}
|
||||||
|
|
||||||
|
code = curl_mime_data(part, get<string_view>(param.second).data(),
|
||||||
|
CURL_ZERO_TERMINATED);
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
throw CURLException{code, "Could not build HTTP form."};
|
||||||
|
}
|
||||||
|
debuglog << "Set form part: " << param.first << " = "
|
||||||
|
<< get<string_view>(param.second) << '\n';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto &arg : get<vector<string_view>>(param.second))
|
||||||
|
{
|
||||||
|
const string name{string(param.first) += "[]"};
|
||||||
|
code = curl_mime_name(part, name.c_str());
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
throw CURLException{code, "Could not build HTTP form."};
|
||||||
|
}
|
||||||
|
code = curl_mime_data(part, arg.data(), CURL_ZERO_TERMINATED);
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
throw CURLException{code, "Could not build HTTP form."};
|
||||||
|
}
|
||||||
|
debuglog << "Set form part: " << name << " = " << arg << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mime;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mastodonpp
|
} // namespace mastodonpp
|
||||||
|
Loading…
x
Reference in New Issue
Block a user