obs-StreamFX/source/util/util-curl.cpp
Michael Fabian 'Xaymar' Dirks 5a3954ae0e project: Fix License, License headers and Copyright information
Fixes several files incorrectly stated a different license from the actual project, as well as the copyright headers included in all files. This change has no effect on the licensing terms, it should clear up a bit of confusion by contributors. Plus the files get a bit smaller, and we have less duplicated information across the entire project.

Overall the project is GPLv2 if not built with Qt, and GPLv3 if it is built with Qt. There are no parts licensed under a different license, all have been adapted from other compatible licenses into GPLv2 or GPLv3.
2023-04-05 18:59:08 +02:00

205 lines
5.4 KiB
C++

// AUTOGENERATED COPYRIGHT HEADER START
// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
// Copyright (C) 2022 lainon <GermanAizek@yandex.ru>
// AUTOGENERATED COPYRIGHT HEADER END
#include "util-curl.hpp"
#include "warning-disable.hpp"
#include <sstream>
#include "warning-enable.hpp"
int32_t streamfx::util::curl::debug_helper(CURL* handle, curl_infotype type, char* data, size_t size,
streamfx::util::curl* self)
{
if (self->_debug_callback) {
self->_debug_callback(handle, type, data, size);
} else {
#ifdef _DEBUG_CURL
std::stringstream hd;
for (size_t n = 0; n < size; n++) {
hd << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << static_cast<int32_t>(data[n])
<< " ";
if (n % 16 == 15) {
hd << "\n ";
}
}
std::string hds = hd.str();
switch (type) {
case CURLINFO_TEXT:
DLOG_DEBUG("<CURL> %.*s", size - 1, data);
break;
case CURLINFO_HEADER_IN:
DLOG_DEBUG("<CURL> << Header: %.*s", size - 1, data);
break;
case CURLINFO_HEADER_OUT:
DLOG_DEBUG("<CURL> >> Header: %.*s", size - 1, data);
break;
case CURLINFO_DATA_IN:
DLOG_DEBUG("<CURL> << %lld bytes of data:\n %s", size, hds.c_str());
break;
case CURLINFO_DATA_OUT:
DLOG_DEBUG("<CURL> >> %lld bytes of data:\n %s", size, hds.c_str());
break;
case CURLINFO_SSL_DATA_IN:
DLOG_DEBUG("<CURL> << %lld bytes of SSL data:\n %s", size, hds.c_str());
break;
case CURLINFO_SSL_DATA_OUT:
DLOG_DEBUG("<CURL> >> %lld bytes of SSL data:\n %s", size, hds.c_str());
break;
}
#endif
}
return 0;
}
size_t streamfx::util::curl::read_helper(void* ptr, size_t size, size_t count, streamfx::util::curl* self)
{
if (self->_read_callback) {
return self->_read_callback(ptr, size, count);
} else {
return size * count;
}
}
size_t streamfx::util::curl::write_helper(void* ptr, size_t size, size_t count, streamfx::util::curl* self)
{
if (self->_write_callback) {
return self->_write_callback(ptr, size, count);
} else {
return size * count;
}
}
int32_t streamfx::util::curl::xferinfo_callback(streamfx::util::curl* self, curl_off_t dlt, curl_off_t dln,
curl_off_t ult, curl_off_t uln)
{
if (self->_xferinfo_callback) {
return self->_xferinfo_callback(static_cast<uint64_t>(dlt), static_cast<uint64_t>(dln),
static_cast<uint64_t>(ult), static_cast<uint64_t>(uln));
} else {
return 0;
}
}
streamfx::util::curl::curl() : _curl(), _read_callback(), _write_callback(), _headers()
{
_curl = curl_easy_init();
set_read_callback(nullptr);
set_write_callback(nullptr);
set_xferinfo_callback(nullptr);
set_debug_callback(nullptr);
// Default settings.
set_option(CURLOPT_NOPROGRESS, false);
set_option(CURLOPT_PATH_AS_IS, false);
set_option(CURLOPT_CRLF, false);
#ifdef _DEBUG
set_option(CURLOPT_VERBOSE, true);
#else
set_option(CURLOPT_VERBOSE, false);
#endif
}
streamfx::util::curl::~curl()
{
curl_easy_cleanup(_curl);
}
void streamfx::util::curl::clear_headers()
{
_headers.clear();
}
void streamfx::util::curl::clear_header(std::string_view header)
{
_headers.erase(header.data());
}
void streamfx::util::curl::set_header(std::string header, std::string value)
{
_headers.insert_or_assign(header, value);
}
size_t perform_get_kv_size(std::string_view a, std::string_view b)
{
return a.size() + 2 + b.size() + 1;
};
CURLcode streamfx::util::curl::perform()
{
std::vector<char> buffer;
struct curl_slist* headers = nullptr;
if (_headers.size() > 0) {
// Calculate full buffer size.
{
size_t buffer_size = 0;
for (const auto& kv : _headers) {
buffer_size += perform_get_kv_size(kv.first, kv.second);
}
buffer.resize(buffer_size * 2);
}
// Create HTTP Headers.
{
size_t buffer_offset = 0;
for (const auto& kv : _headers) {
size_t size = perform_get_kv_size(kv.first, kv.second);
snprintf(&buffer.at(buffer_offset), size, "%s: %s", kv.first.c_str(), kv.second.c_str());
headers = curl_slist_append(headers, &buffer.at(buffer_offset));
buffer_offset += size;
}
}
set_option<struct curl_slist*>(CURLOPT_HTTPHEADER, headers);
}
CURLcode res = curl_easy_perform(_curl);
if (headers) {
set_option<struct curl_slist*>(CURLOPT_HTTPHEADER, nullptr);
curl_slist_free_all(headers);
}
return res;
}
void streamfx::util::curl::reset()
{
curl_easy_reset(_curl);
}
CURLcode streamfx::util::curl::set_read_callback(curl_io_callback_t cb)
{
_read_callback = std::move(cb);
if (CURLcode res = curl_easy_setopt(_curl, CURLOPT_READDATA, this); res != CURLE_OK)
return res;
return curl_easy_setopt(_curl, CURLOPT_READFUNCTION, &read_helper);
}
CURLcode streamfx::util::curl::set_write_callback(curl_io_callback_t cb)
{
_write_callback = std::move(cb);
if (CURLcode res = curl_easy_setopt(_curl, CURLOPT_WRITEDATA, this); res != CURLE_OK)
return res;
return curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, &write_helper);
}
CURLcode streamfx::util::curl::set_xferinfo_callback(curl_xferinfo_callback_t cb)
{
_xferinfo_callback = std::move(cb);
if (CURLcode res = curl_easy_setopt(_curl, CURLOPT_XFERINFODATA, this); res != CURLE_OK)
return res;
return curl_easy_setopt(_curl, CURLOPT_XFERINFOFUNCTION, &xferinfo_callback);
}
CURLcode streamfx::util::curl::set_debug_callback(curl_debug_callback_t cb)
{
_debug_callback = std::move(cb);
if (CURLcode res = curl_easy_setopt(_curl, CURLOPT_DEBUGDATA, this); res != CURLE_OK)
return res;
return curl_easy_setopt(_curl, CURLOPT_DEBUGFUNCTION, &debug_helper);
}