exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 5eb9e43bb063caa873ade4a0a8f767d4107fd5b3
parent 9f36568776f6592206a99b6d4790e218b0ad0922
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue, 11 Aug 2026 23:28:24 +0200

propagate enforcment of HTTP/1.1 also to auditor lib if set for exchange

Diffstat:
Msrc/lib/exchange_api_curl_defaults.c | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+), 0 deletions(-)

diff --git a/src/lib/exchange_api_curl_defaults.c b/src/lib/exchange_api_curl_defaults.c @@ -21,6 +21,7 @@ */ #include "taler/taler_curl_lib.h" #include "exchange_api_curl_defaults.h" +#include "taler/taler_auditor_service.h" #include "taler/exchange/common.h" @@ -34,6 +35,104 @@ void TALER_EXCHANGE_setup (enum TALER_EXCHANGE_GlobalOptions go) { eglobal_options = go; + if (TALER_EXCHANGE_GO_FORCE_HTTP1_1) + { + /* libtalerexchange also makes connections via libtalerauditor + to the auditor, so do enforce HTTP/1.1 there as well. */ + TALER_AUDITOR_setup (TALER_AUDITOR_GO_FORCE_HTTP1_1); + } +} + + +#include <curl/curl.h> +#include <stdbool.h> +#include <string.h> + + +/** + * Check if feature @a name is in the @a vi + * + * @param vi version data to test + * @param name feature to test for + * @true if feature is supported by curl + */ +static bool +has_feature (const curl_version_info_data *vi, + const char *name) +{ + if (! vi->feature_names) + return false; + + for (const char * const *p = vi->feature_names; *p; ++p) + if (0 == + strcmp (*p, + name)) + return true; + return false; +} + + +/** + * Check if @a s is non-NULL and starts with @a prefix + */ +static bool +starts_with (const char *s, + const char *prefix) +{ + return ( (NULL != s) && + (0 == strncmp (s, + prefix, + strlen (prefix)) ) ); +} + + +/** + * Check if using HTTP3 is likely OK with our version of libcurl. + * + * @return true if HTTP3 should be well-supported + */ +static bool +curl_http3_is_conservative_ok (void) +{ + const curl_version_info_data *vi = + curl_version_info (CURLVERSION_NOW); + + if (! has_feature (vi, + "HTTP3")) + return false; + + /* + * Require a QUIC backend we regard as production-ready. + * + * curl currently considers ngtcp2 non-experimental. + * quiche is still experimental. + */ + if (! starts_with (vi->quic_version, + "ngtcp2/")) + return false; + + /* + * Conservative policy: don't use HTTP/3 with GnuTLS. + * (too many bugs in recent releases still) + */ + if (starts_with (vi->ssl_version, + "GnuTLS/")) + return false; + + /* + * At this point the remaining ngtcp2 TLS configurations + * are the OpenSSL family and wolfSSL. + * + * We deliberately whitelist them rather than assuming + * every possible future TLS backend is safe. + */ + if (starts_with (vi->ssl_version, + "OpenSSL/")) + return true; + if (starts_with (vi->ssl_version, + "wolfSSL/")) + return true; + return false; } @@ -65,9 +164,30 @@ TALER_EXCHANGE_curl_easy_get_ (const char *url) CURLOPT_TCP_FASTOPEN, 1L)); if (TALER_EXCHANGE_GO_FORCE_HTTP1_1 & eglobal_options) + { GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1)); + } + else + { + static enum GNUNET_GenericReturnValue http3 = GNUNET_SYSERR; + + if (GNUNET_SYSERR == http3) + http3 = curl_http3_is_conservative_ok () ? GNUNET_YES : GNUNET_NO; + if (GNUNET_YES == http3) + { + /* HTTP/3 support with GnuTLS remains spotty, prefer HTTP/2 */ + curl_easy_setopt (eh, + CURLOPT_HTTP_VERSION, + CURL_HTTP_VERSION_2TLS); + } + else + { + curl_easy_setopt (eh, CURLOPT_HTTP_VERSION, + CURL_HTTP_VERSION_3); + } + } return eh; }