From e3a6ad7173d8746af0fde87a1ead69c1c7d61bfa Mon Sep 17 00:00:00 2001 From: John-Mark Bell Date: Wed, 27 Dec 2023 19:12:07 +0000 Subject: Fetch/curl: expose socket open/close via fetch vtable This allows frontends to customise the behaviour of sockets. The default implementation simply maps to socket(2)/close(2). --- content/fetchers/curl.c | 20 ++++++++++++++++++++ desktop/gui_factory.c | 9 +++++++++ include/netsurf/fetch.h | 17 +++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c index b1907448e..680e60456 100644 --- a/content/fetchers/curl.c +++ b/content/fetchers/curl.c @@ -1792,6 +1792,24 @@ fetch_curl_debug(CURL *handle, } +static curl_socket_t fetch_curl_socket_open(void *clientp, + curlsocktype purpose, struct curl_sockaddr *address) +{ + (void) clientp; + (void) purpose; + + return (curl_socket_t) guit->fetch->socket_open( + address->family, address->socktype, + address->protocol); +} + +static int fetch_curl_socket_close(void *clientp, curl_socket_t item) +{ + (void) clientp; + + return guit->fetch->socket_close((int) item); +} + /** * Callback function for cURL. */ @@ -2047,6 +2065,8 @@ nserror fetch_curl_register(void) SETOPT(CURLOPT_LOW_SPEED_TIME, 180L); SETOPT(CURLOPT_NOSIGNAL, 1L); SETOPT(CURLOPT_CONNECTTIMEOUT, nsoption_uint(curl_fetch_timeout)); + SETOPT(CURLOPT_OPENSOCKETFUNCTION, fetch_curl_socket_open); + SETOPT(CURLOPT_CLOSESOCKETFUNCTION, fetch_curl_socket_close); if (nsoption_charp(ca_bundle) && strcmp(nsoption_charp(ca_bundle), "")) { diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c index 89f2e373f..c9dcd8b2b 100644 --- a/desktop/gui_factory.c +++ b/desktop/gui_factory.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include "utils/config.h" #include "utils/errors.h" @@ -498,6 +501,12 @@ static nserror verify_fetch_register(struct gui_fetch_table *gft) if (gft->mimetype == NULL) { gft->mimetype = gui_default_mimetype; } + if (gft->socket_open == NULL) { + gft->socket_open = socket; + } + if (gft->socket_close == NULL) { + gft->socket_close = close; + } return NSERROR_OK; } diff --git a/include/netsurf/fetch.h b/include/netsurf/fetch.h index 30b204868..156f4d1ef 100644 --- a/include/netsurf/fetch.h +++ b/include/netsurf/fetch.h @@ -99,6 +99,23 @@ struct gui_fetch_table { */ char *(*mimetype)(const char *ro_path); + /** + * Open a socket + * + * \param domain Communication domain + * \param type Socket type + * \param protocol Protocol + * \return Socket descriptor on success, -1 on error and errno set + */ + int (*socket_open)(int domain, int type, int protocol); + + /** + * Close a socket + * + * \param socket Socket descriptor + * \return 0 on success, -1 on error and errno set + */ + int (*socket_close)(int socket); }; #endif -- cgit v1.2.3