Use PBD::CCurl for Ardour GUI HTTP/S requests

This commit is contained in:
Robin Gareus 2025-05-19 23:38:46 +02:00
parent 4f300b5474
commit 7b6ca334df
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
5 changed files with 23 additions and 99 deletions

View file

@ -37,10 +37,6 @@
#include "gtk2ardour-version.h"
#endif
#ifndef ARDOUR_CURL_TIMEOUT
#define ARDOUR_CURL_TIMEOUT (60)
#endif
#ifdef ARDOURCURLDEBUG
#define CCERR(msg) do { if (cc != CURLE_OK) { std::cerr << string_compose ("curl_easy_setopt(%1) failed: %2", msg, cc) << std::endl; } } while (0)
#else
@ -49,66 +45,6 @@
using namespace ArdourCurl;
const char* HttpGet::ca_path = NULL;
const char* HttpGet::ca_info = NULL;
void
HttpGet::ca_setopt (CURL* c)
{
if (ca_info) {
curl_easy_setopt (c, CURLOPT_CAINFO, ca_info);
}
if (ca_path) {
curl_easy_setopt (c, CURLOPT_CAPATH, ca_path);
}
if (ca_info || ca_path) {
curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 1);
} else {
curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
}
}
void
HttpGet::setup_certificate_paths ()
{
/* this is only needed for Linux Bundles.
* (on OSX, Windows, we use system-wide ssl (darwinssl, winssl)
* Gnu/Linux distro will link against system-wide libcurl.
*
* but for linux-bundles we get to enjoy:
* https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
*
* (we do ship curl + nss + nss-pem)
*
* Short of this mess: we could simply bundle a .crt of
* COMODO (ardour) and ghandi (freesound) and be done with it.
* Alternatively, ship the Mozilla CA list, perhaps using https://mkcert.org/ .
*/
assert (!ca_path && !ca_info); // call once
if (Glib::file_test ("/etc/pki/tls/certs/ca-bundle.crt", Glib::FILE_TEST_IS_REGULAR)) {
// Fedora / RHEL, Arch
ca_info = "/etc/pki/tls/certs/ca-bundle.crt";
}
else if (Glib::file_test ("/etc/ssl/certs/ca-certificates.crt", Glib::FILE_TEST_IS_REGULAR)) {
// Debian and derivatives
ca_info = "/etc/ssl/certs/ca-certificates.crt";
}
else if (Glib::file_test ("/etc/pki/tls/cert.pem", Glib::FILE_TEST_IS_REGULAR)) {
// GNU/TLS can keep extra stuff here
ca_info = "/etc/pki/tls/cert.pem";
}
// else NULL: use default (currently) "/etc/ssl/certs/ca-certificates.crt" if it exists
/* If we don't set anything, defaults are used. At the time of writing we compile bundled curl on debian
* and it'll default to ca_path = /etc/ssl/certs and ca_info = /etc/ssl/certs/ca-certificates.crt .
* That works on Debian and derivs + openSUSE. It has historically not
* worked on RHEL / Fedora, but worst case the directory exists and doesn't
* prevent ca_info from working. https://bugzilla.redhat.com/show_bug.cgi?id=1053882
*/
}
static size_t
WriteMemoryCallback (void *ptr, size_t size, size_t nmemb, void *data) {
size_t realsize = size * nmemb;
@ -146,13 +82,13 @@ static size_t headerCallback (char* ptr, size_t size, size_t nmemb, void* data)
return realsize;
}
HttpGet::HttpGet (bool p, bool ssl)
HttpGet::HttpGet (bool p)
: persist (p)
, _status (-1)
, _result (-1)
{
CURL* _curl = curl ();
error_buffer[0] = 0;
_curl = curl_easy_init ();
if (!_curl) {
std::cerr << "HttpGet::HttpGet curl_easy_init() failed." << std::endl;
@ -165,23 +101,12 @@ HttpGet::HttpGet (bool p, bool ssl)
cc = curl_easy_setopt (_curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); CCERR ("CURLOPT_WRITEFUNCTION");
cc = curl_easy_setopt (_curl, CURLOPT_HEADERDATA, (void *)&nfo); CCERR ("CURLOPT_HEADERDATA");
cc = curl_easy_setopt (_curl, CURLOPT_HEADERFUNCTION, headerCallback); CCERR ("CURLOPT_HEADERFUNCTION");
cc = curl_easy_setopt (_curl, CURLOPT_USERAGENT, PROGRAM_NAME VERSIONSTRING); CCERR ("CURLOPT_USERAGENT");
cc = curl_easy_setopt (_curl, CURLOPT_TIMEOUT, ARDOUR_CURL_TIMEOUT); CCERR ("CURLOPT_TIMEOUT");
cc = curl_easy_setopt (_curl, CURLOPT_NOSIGNAL, 1); CCERR ("CURLOPT_NOSIGNAL");
cc = curl_easy_setopt (_curl, CURLOPT_ERRORBUFFER, error_buffer); CCERR ("CURLOPT_ERRORBUFFER");
// cc = curl_easy_setopt (_curl, CURLOPT_FOLLOWLOCATION, 1); CCERR ("CURLOPT_FOLLOWLOCATION");
// by default use curl's default.
if (ssl) {
ca_setopt (_curl);
}
}
HttpGet::~HttpGet ()
{
if (_curl) {
curl_easy_cleanup (_curl);
}
if (!persist) {
::free (mem.data);
}
@ -190,6 +115,7 @@ HttpGet::~HttpGet ()
char*
HttpGet::get (const char* url, bool with_error_logging)
{
CURL* _curl = curl ();
#ifdef ARDOURCURLDEBUG
std::cerr << "HttpGet::get() ---- new request ---"<< std::endl;
#endif

View file

@ -18,15 +18,16 @@
#pragma once
#include <curl/curl.h>
#include <string>
#include <map>
#include "pbd/ccurl.h"
namespace ArdourCurl {
class HttpGet {
public:
HttpGet (bool persist = false, bool ssl = true);
HttpGet (bool persist = false);
~HttpGet ();
struct MemStruct {
@ -54,11 +55,11 @@ public:
std::map<std::string, std::string> header () const { return nfo.h; }
char* escape (const char* s, int l) const {
return curl_easy_escape (_curl, s, l);
return curl_easy_escape (_ccurl.curl (), s, l);
}
char* unescape (const char* s, int l, int *o) const {
return curl_easy_unescape (_curl, s, l, o);
return curl_easy_unescape (_ccurl.curl (), s, l, o);
}
/* this is only to be used for data returned by from
@ -69,15 +70,13 @@ public:
std::string error () const;
CURL* curl () const { return _curl; }
// called from fixup_bundle_environment
static void setup_certificate_paths ();
CURL* curl () const { return _ccurl.curl (); }
static void ca_setopt (CURL*);
private:
CURL* _curl;
PBD::CCurl _ccurl;
bool persist;
long int _status;
@ -87,9 +86,6 @@ private:
struct MemStruct mem;
struct HeaderInfo nfo;
static const char* ca_path;
static const char* ca_info;
};
char* http_get (const char* url, int* status, bool with_error_logging);

View file

@ -115,8 +115,6 @@ fixup_bundle_environment (int /*argc*/, char* argv[], string & localedir)
from looking outside the bundle to find the charset.alias file.
*/
g_setenv ("CHARSETALIASDIR", dir_path.c_str(), 1);
ArdourCurl::HttpGet::setup_certificate_paths ();
}
void

View file

@ -59,7 +59,6 @@
#include "widgets/prompter.h"
#include "ardour_dialog.h"
#include "ardour_http.h"
#include "sfdb_freesound_mootcher.h"
#include "gui_thread.h"
#include "ui_config.h"
@ -79,7 +78,6 @@ static const std::string fields = "id,name,duration,filesize,samplerate,license,
//------------------------------------------------------------------------
Mootcher::Mootcher(const std::string &the_token)
: curl(curl_easy_init())
{
DEBUG_TRACE(PBD::DEBUG::Freesound, "Created new Mootcher, oauth_token =\"" + the_token + "\"\n");
custom_headers = NULL;
@ -95,7 +93,6 @@ Mootcher::Mootcher(const std::string &the_token)
//------------------------------------------------------------------------
Mootcher:: ~Mootcher()
{
curl_easy_cleanup(curl);
if (custom_headers) {
curl_slist_free_all (custom_headers);
}
@ -166,6 +163,11 @@ std::string Mootcher::sortMethodString(enum sortMethod sort)
//------------------------------------------------------------------------
void Mootcher::setcUrlOptions()
{
CURL* curl = ccurl.curl ();
if (!curl) {
return;
}
// some servers don't like requests that are made without a user-agent field, so we provide one
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
// setup curl error buffer
@ -176,9 +178,6 @@ void Mootcher::setcUrlOptions()
// Allow connections to time out (without using signals)
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30);
/* set ca-certificates to use for bundled versions of ardour */
ArdourCurl::HttpGet::ca_setopt (curl);
}
std::string Mootcher::doRequest(std::string uri, std::string params)
@ -188,6 +187,7 @@ std::string Mootcher::doRequest(std::string uri, std::string params)
xml_page.memory = NULL;
xml_page.size = 0;
CURL* curl = ccurl.curl ();
setcUrlOptions();
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &xml_page);
@ -292,6 +292,7 @@ std::string Mootcher::auth_code_to_oauth_token(const std::string &auth_code)
json_page.size = 0;
CURLcode res;
CURL* curl = ccurl.curl ();
setcUrlOptions();
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &json_page);
@ -351,6 +352,7 @@ std::string Mootcher::searchText(std::string query, int page, std::string filter
params += buf;
}
CURL* curl = ccurl.curl ();
char *eq = curl_easy_escape(curl, query.c_str(), query.length());
params += "query=\"" + std::string(eq) + "\"";
curl_free(eq);
@ -444,6 +446,7 @@ void *
Mootcher::threadFunc()
{
CURLcode res;
CURL* curl = ccurl.curl ();
DEBUG_TRACE(PBD::DEBUG::Freesound, "threadFunc\n");
res = curl_easy_perform (curl);
@ -538,6 +541,7 @@ Mootcher::fetchAudioFile(std::string originalFileName, std::string theID, std::s
ID = theID;
audioFileName = Glib::build_filename (basePath, ID + "-" + originalFileName);
CURL* curl = ccurl.curl ();
if (!curl) {
return false;
}

View file

@ -47,7 +47,7 @@
#include "sfdb_ui.h"
#include "curl/curl.h"
#include "pbd/ccurl.h"
//--- struct to store XML file
struct SfdbMemoryStruct {
@ -105,7 +105,7 @@ private:
std::string sortMethodString (enum sortMethod sort);
std::string getSoundResourceFile (std::string ID);
CURL *curl;
PBD::CCurl ccurl;
char errorBuffer[CURL_ERROR_SIZE]; // storage for cUrl error message
FILE* theFile;