From 5966077030330f6dc6960fea4467516bc245b7b8 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Mon, 24 Jul 2023 14:43:14 +0300 Subject: [PATCH] [Core, mod_cidlookup, mod_curl, mod_httapi, mod_http_cache, mod_kazoo, mod_shout] Add new switch_curl_mime APIs replacing switch_curl_process_form_post_params() and make code be compatible with libcurl>=7.87.0 --- src/include/switch_curl.h | 7 ++- .../mod_cidlookup/mod_cidlookup.c | 4 +- src/mod/applications/mod_curl/mod_curl.c | 36 +++++++++++ src/mod/applications/mod_httapi/mod_httapi.c | 10 ++- src/mod/applications/mod_http_cache/azure.c | 4 ++ .../mod_http_cache/mod_http_cache.c | 2 + .../event_handlers/mod_kazoo/kazoo_commands.c | 2 + src/mod/formats/mod_shout/mod_shout.c | 9 +++ src/switch_curl.c | 61 +++++++++++++++++-- 9 files changed, 121 insertions(+), 14 deletions(-) diff --git a/src/include/switch_curl.h b/src/include/switch_curl.h index 5872527865..bad116daf2 100644 --- a/src/include/switch_curl.h +++ b/src/include/switch_curl.h @@ -40,6 +40,9 @@ typedef int switch_CURLINFO; typedef int switch_CURLcode; typedef int switch_CURLoption; +#define HAVE_SWITCH_CURL_MIME +typedef void switch_curl_mime; + SWITCH_DECLARE(switch_CURL *) switch_curl_easy_init(void); SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_perform(switch_CURL *handle); SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_getinfo(switch_CURL *curl, switch_CURLINFO info, ... ); @@ -50,7 +53,9 @@ SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_setopt(CURL *handle, switch_CUR SWITCH_DECLARE(const char *) switch_curl_easy_strerror(switch_CURLcode errornum ); SWITCH_DECLARE(void) switch_curl_init(void); SWITCH_DECLARE(void) switch_curl_destroy(void); -SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, struct curl_httppost **formpostp); +SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event, switch_CURL *curl_handle, switch_curl_mime **mimep); +SWITCH_DECLARE(void) switch_curl_mime_free(switch_curl_mime **mimep); +SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_setopt_mime(switch_CURL *curl_handle, switch_curl_mime *mime); #define switch_curl_easy_setopt curl_easy_setopt SWITCH_END_EXTERN_C diff --git a/src/mod/applications/mod_cidlookup/mod_cidlookup.c b/src/mod/applications/mod_cidlookup/mod_cidlookup.c index 55d7aa0d90..5531222197 100644 --- a/src/mod/applications/mod_cidlookup/mod_cidlookup.c +++ b/src/mod/applications/mod_cidlookup/mod_cidlookup.c @@ -347,7 +347,7 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data) return realsize; } -static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, struct curl_httppost *post, +static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, switch_curl_mime *post, switch_curl_slist_t *headers, int timeout) { switch_time_t start_time = switch_micro_time_now(); @@ -373,7 +373,7 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0); } if (post) { - switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, post); + switch_curl_easy_setopt_mime(curl_handle, post); } else { switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1); } diff --git a/src/mod/applications/mod_curl/mod_curl.c b/src/mod/applications/mod_curl/mod_curl.c index 02079d6767..c780e6947e 100644 --- a/src/mod/applications/mod_curl/mod_curl.c +++ b/src/mod/applications/mod_curl/mod_curl.c @@ -104,8 +104,13 @@ struct http_sendfile_data_obj { char *extrapost_elements; switch_CURL *curl_handle; char *cacert; +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_mime *mime; + curl_mimepart *part; +#else struct curl_httppost *formpost; struct curl_httppost *lastptr; +#endif uint8_t flags; /* This is for where to send output of the curl_sendfile commands */ switch_stream_handle_t *stream; char *sendfile_response; @@ -456,8 +461,19 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data) curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEFUNCTION, http_sendfile_response_callback); curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEDATA, (void *) http_data); + /* Initial http_data->mime */ +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + http_data->mime = curl_mime_init(http_data->curl_handle); +#endif + /* Add the file to upload as a POST form field */ +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + http_data->part = curl_mime_addpart(http_data->mime); + curl_mime_name(http_data->part, http_data->filename_element_name); + curl_mime_filedata(http_data->part, http_data->filename_element); +#else curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, http_data->filename_element_name, CURLFORM_FILE, http_data->filename_element, CURLFORM_END); +#endif if(!zstr(http_data->extrapost_elements)) { @@ -476,16 +492,32 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data) if(argc2 == 2) { switch_url_decode(argv2[0]); switch_url_decode(argv2[1]); +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + http_data->part = curl_mime_addpart(http_data->mime); + curl_mime_name(http_data->part, argv2[0]); + curl_mime_data(http_data->part, argv2[1], CURL_ZERO_TERMINATED); +#else curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, argv2[0], CURLFORM_COPYCONTENTS, argv2[1], CURLFORM_END); +#endif } } } /* Fill in the submit field too, even if this isn't really needed */ +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + http_data->part = curl_mime_addpart(http_data->mime); + curl_mime_name(http_data->part, "submit"); + curl_mime_data(http_data->part, "or_die", CURL_ZERO_TERMINATED); +#else curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "or_die", CURLFORM_END); +#endif /* what URL that receives this POST */ +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_easy_setopt(http_data->curl_handle, CURLOPT_MIMEPOST, http_data->mime); +#else curl_easy_setopt(http_data->curl_handle, CURLOPT_HTTPPOST, http_data->formpost); +#endif // This part actually fires off the curl, captures the HTTP response code, and then frees up the handle. curl_easy_perform(http_data->curl_handle); @@ -494,7 +526,11 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data) curl_easy_cleanup(http_data->curl_handle); // Clean up the form data from POST +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_mime_free(http_data->mime); +#else curl_formfree(http_data->formpost); +#endif } static switch_status_t http_sendfile_test_file_open(http_sendfile_data_t *http_data, switch_event_t *event) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 4b32d87c6d..1254a6f93c 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -1419,7 +1419,7 @@ static switch_status_t httapi_sync(client_t *client) switch_status_t status = SWITCH_STATUS_FALSE; int get_style_method = 0; char *method = NULL; - struct curl_httppost *formpost=NULL; + switch_curl_mime *formpost = NULL; switch_event_t *save_params = NULL; const char *put_file; FILE *fd = NULL; @@ -1476,7 +1476,7 @@ static switch_status_t httapi_sync(client_t *client) } if (!put_file) { - switch_curl_process_form_post_params(client->params, curl_handle, &formpost); + switch_curl_process_mime(client->params, curl_handle, &formpost); } if (formpost) { @@ -1588,7 +1588,7 @@ static switch_status_t httapi_sync(client_t *client) curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, put_file_read); } else if (formpost) { - curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, formpost); + switch_curl_easy_setopt_mime(curl_handle, formpost); } else { switch_curl_easy_setopt(curl_handle, CURLOPT_POST, !get_style_method); } @@ -1670,9 +1670,7 @@ static switch_status_t httapi_sync(client_t *client) switch_curl_easy_cleanup(curl_handle); switch_curl_slist_free_all(headers); - if (formpost) { - curl_formfree(formpost); - } + switch_curl_mime_free(&formpost); if (client->err) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error encountered! [%s]\ndata: [%s]\n", client->profile->url, data); diff --git a/src/mod/applications/mod_http_cache/azure.c b/src/mod/applications/mod_http_cache/azure.c index f1e4cf8925..a16d2e9f94 100644 --- a/src/mod/applications/mod_http_cache/azure.c +++ b/src/mod/applications/mod_http_cache/azure.c @@ -279,7 +279,11 @@ switch_status_t azure_blob_finalise_put(http_profile_t *profile, const char *url goto done; } +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x070c01) + switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1); +#else switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1); +#endif switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url); diff --git a/src/mod/applications/mod_http_cache/mod_http_cache.c b/src/mod/applications/mod_http_cache/mod_http_cache.c index 9d19099e56..365ba27425 100644 --- a/src/mod/applications/mod_http_cache/mod_http_cache.c +++ b/src/mod/applications/mod_http_cache/mod_http_cache.c @@ -393,7 +393,9 @@ static switch_status_t http_put(url_cache_t *cache, http_profile_t *profile, swi goto done; } switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1); +#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070c01) switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1); +#endif switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url); diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c index 6d956376a8..16f00ad1a0 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c @@ -366,7 +366,9 @@ SWITCH_STANDARD_API(kz_http_put) goto done; } switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1); +#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070c01) switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1); +#endif switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers); switch_curl_easy_setopt(curl_handle, CURLOPT_URL, url); diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index 14cba068d3..7012cb808d 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -463,7 +463,11 @@ static size_t stream_callback(void *ptr, size_t size, size_t nmemb, void *data) return 0; } +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x072000) +static int progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) +#else static int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +#endif { shout_context_t *context = (shout_context_t *) clientp; return context->err; @@ -496,8 +500,13 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void switch_mutex_unlock(context->audio_mutex); curl_handle = switch_curl_easy_init(); switch_curl_easy_setopt(curl_handle, CURLOPT_URL, context->stream_url); +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x072000) + curl_easy_setopt(curl_handle, CURLOPT_XFERINFOFUNCTION, progress_callback); + curl_easy_setopt(curl_handle, CURLOPT_XFERINFODATA, (void *)context); +#else curl_easy_setopt(curl_handle, CURLOPT_PROGRESSFUNCTION, progress_callback); curl_easy_setopt(curl_handle, CURLOPT_PROGRESSDATA, (void *)context); +#endif switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10); switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, stream_callback); diff --git a/src/switch_curl.c b/src/switch_curl.c index c99a5f61de..c899261ab5 100644 --- a/src/switch_curl.c +++ b/src/switch_curl.c @@ -58,11 +58,16 @@ SWITCH_DECLARE(void) switch_curl_destroy(void) curl_global_cleanup(); } -SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, struct curl_httppost **formpostp) +SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event, switch_CURL *curl_handle, switch_curl_mime **mimep) { - +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_mime *mime = NULL; + curl_mimepart *part = NULL; + uint8_t added = 0; +#else struct curl_httppost *formpost=NULL; struct curl_httppost *lastptr=NULL; +#endif switch_event_header_t *hp; int go = 0; @@ -77,39 +82,85 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_even return SWITCH_STATUS_FALSE; } - for (hp = event->headers; hp; hp = hp->next) { +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + mime = curl_mime_init(curl_handle); +#endif + for (hp = event->headers; hp; hp = hp->next) { if (!strncasecmp(hp->name, "attach_file:", 12)) { char *pname = strdup(hp->name + 12); if (pname) { char *fname = strchr(pname, ':'); + if (fname) { *fname++ = '\0'; +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + part = curl_mime_addpart(mime); + curl_mime_name(part, pname); + curl_mime_filename(part, fname); + curl_mime_filedata(part, hp->value); + added++; +#else curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, pname, CURLFORM_FILENAME, fname, CURLFORM_FILE, hp->value, CURLFORM_END); +#endif } + free(pname); } } else { +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + part = curl_mime_addpart(mime); + curl_mime_name(part, hp->name); + curl_mime_data(part, hp->value, CURL_ZERO_TERMINATED); + added++; +#else curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, hp->name, CURLFORM_COPYCONTENTS, hp->value, CURLFORM_END); - +#endif } } - *formpostp = formpost; +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + if (!added) { + curl_mime_free(mime); + mime = NULL; + } +#endif + + *mimep = mime; return SWITCH_STATUS_SUCCESS; +} +SWITCH_DECLARE(void) switch_curl_mime_free(switch_curl_mime **mimep) +{ + if (mimep && *mimep) { +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + curl_mime_free(*mimep); +#else + curl_formfree(*mimep); +#endif + mimep = NULL; + } +} + +SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_setopt_mime(switch_CURL *curl_handle, switch_curl_mime *mime) +{ +#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800) + return curl_easy_setopt(curl_handle, CURLOPT_MIMEPOST, mime); +#else + return curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, mime); +#endif } /* For Emacs: