From 26ae0b6ff05d79a858aec7ad92af3d65c9ce0745 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 30 Mar 2025 11:42:17 -0400 Subject: [PATCH] curl: add code to check the output of curl_easy_*() --- src/netcode/d_netfil.c | 54 +++++++++++++++++++++++++++---------- src/netcode/http-mserv.c | 58 ++++++++++++++++++++++++++++------------ 2 files changed, 81 insertions(+), 31 deletions(-) diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index 94e5449a8..622d61d4b 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -112,6 +112,7 @@ static pauseddownload_t *pauseddownload = NULL; file_download_t filedownload; static CURL *http_handle; +static char curl_errbuf[CURL_ERROR_SIZE]; static CURLM *multi_handle; static UINT32 curl_dlnow; static UINT32 curl_dltotal; @@ -1638,6 +1639,10 @@ boolean CURLPrepareFile(const char* url, int dfilenum) { CURLMcode mc; + cc = curl_easy_setopt(http_handle, CURLOPT_ERRORBUFFER, curl_errbuf); + if (cc != CURLE_OK) I_OutputMsg("libcurl: CURLOPT_ERRORBUFFER failed\n"); + curl_errbuf[0] = 0x00; + I_mkdir(downloaddir, 0755); curl_curfile = &fileneeded[dfilenum]; @@ -1651,44 +1656,62 @@ boolean CURLPrepareFile(const char* url, int dfilenum) for (INT32 j = 0; j < 16; j++) sprintf(&md5tmp[j*2], "%02x", curl_curfile->md5sum[j]); - curl_easy_setopt(http_handle, CURLOPT_URL, va("%s/%s?md5=%s", url, curl_realname, md5tmp)); + cc = curl_easy_setopt(http_handle, CURLOPT_URL, va("%s/%s?md5=%s", url, curl_realname, md5tmp)); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); // Only allow HTTP and HTTPS #if (LIBCURL_VERSION_MAJOR <= 7) && (LIBCURL_VERSION_MINOR < 85) - curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); + cc = curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); #else - curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS_STR, "http,https"); + cc = curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS_STR, "http,https"); #endif + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); // Set user agent, as some servers won't accept invalid user agents. - curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("Sonic Robo Blast 2/%s", VERSIONSTRING)); + cc = curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("Sonic Robo Blast 2/%s", VERSIONSTRING)); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); // Authenticate if the user so wishes login = CURLGetLogin(url, NULL); if (login) { - curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + cc = curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); } // Follow a redirect request, if sent by the server. - curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); + cc = curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); - curl_easy_setopt(http_handle, CURLOPT_FAILONERROR, 1L); + cc = curl_easy_setopt(http_handle, CURLOPT_FAILONERROR, 1L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); CONS_Printf("Downloading addon \"%s\" from %s\n", curl_realname, url); strcatbf(curl_curfile->filename, downloaddir, "/"); curl_curfile->file = fopen(curl_curfile->filename, "wb"); - curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, curl_curfile->file); - curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, curlwrite_data); - curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0L); - curl_easy_setopt(http_handle, CURLOPT_XFERINFOFUNCTION, curlprogress_callback); + + cc = curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, curl_curfile->file); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); + + cc = curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, curlwrite_data); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); + + cc = curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); + + cc = curl_easy_setopt(http_handle, CURLOPT_XFERINFOFUNCTION, curlprogress_callback); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); curl_curfile->status = FS_DOWNLOADING; - curl_multi_add_handle(multi_handle, http_handle); - curl_multi_perform(multi_handle, &curl_runninghandles); + mc = curl_multi_add_handle(multi_handle, http_handle); + if (mc != CURLM_OK) I_OutputMsg("libcurl: %s\n", curl_multi_strerror(mc)); + + mc = curl_multi_perform(multi_handle, &curl_runninghandles); + if (mc != CURLM_OK) I_OutputMsg("libcurl: %s\n", curl_multi_strerror(mc)); + curl_starttime = time(NULL); filedownload.current = dfilenum; @@ -1767,7 +1790,10 @@ void CURLGetFile(void) long response_code = 0; if (easyres == CURLE_HTTP_RETURNED_ERROR) - curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code); + { + CURLcode cc = curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); + } if (response_code == 404) curl_curfile->failed = FDOWNLOAD_FAIL_NOTFOUND; diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index eeac2beb5..fd0b4aaf7 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -84,7 +84,8 @@ struct HMS_buffer CURL *curl; char *buffer; int needle; - int end; + int end; + char *errbuf; }; static void @@ -158,6 +159,7 @@ HMS_connect (int proto, const char *format, ...) size_t seek; size_t token_length; struct HMS_buffer *buffer; + CURLcode cc; #ifdef NO_IPV6 if (proto == PROTO_V6) @@ -181,7 +183,7 @@ HMS_connect (int proto, const char *format, ...) curl = curl_easy_init(); - if (! curl) + if (!curl) { Contact_error(); Blame("From curl_easy_init.\n"); @@ -227,40 +229,62 @@ HMS_connect (int proto, const char *format, ...) buffer->end = DEFAULT_BUFFER_SIZE; buffer->buffer = malloc(buffer->end); buffer->needle = 0; + buffer->errbuf = malloc(CURL_ERROR_SIZE); + buffer->errbuf[0] = 0x00; + + cc = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer->errbuf); if (cv_masterserver_debug.value) { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(curl, CURLOPT_STDERR, logstream); + cc = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + + cc = curl_easy_setopt(curl, CURLOPT_STDERR, logstream); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); } - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + cc = curl_easy_setopt(curl, CURLOPT_URL, url); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + + cc = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); #ifndef NO_IPV6 if (proto == PROTO_V6 || (proto == PROTO_ANY && !hms_allow_ipv4)) { - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); + cc = curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + if (M_CheckParm("-bindaddr6") && M_IsNextParm()) { - curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + cc = curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); } } if (proto == PROTO_V4 || (proto == PROTO_ANY && !hms_allow_ipv6)) #endif { - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + cc = curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + if (M_CheckParm("-bindaddr") && M_IsNextParm()) { - curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + cc = curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); } } - curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer); + cc = curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); - curl_easy_setopt(curl, CURLOPT_USERAGENT, hms_useragent); + cc = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + + cc = curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + + cc = curl_easy_setopt(curl, CURLOPT_USERAGENT, hms_useragent); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); curl_free(quack_token); free(url); @@ -282,15 +306,15 @@ HMS_do (struct HMS_buffer *buffer) { Contact_error(); Blame( - "From curl_easy_perform: %s\n", - curl_easy_strerror(cc) + "From curl_easy_perform: %s\n", buffer->errbuf ); return 0; } buffer->buffer[buffer->needle] = '\0'; - curl_easy_getinfo(buffer->curl, CURLINFO_RESPONSE_CODE, &status); + cc = curl_easy_getinfo(buffer->curl, CURLINFO_RESPONSE_CODE, &status); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); if (status != 200) {