diff --git a/modules/curl/curl.c b/modules/curl/curl.c index 1e253a7f658..510de293a56 100644 --- a/modules/curl/curl.c +++ b/modules/curl/curl.c @@ -59,10 +59,12 @@ #include "../../rpc.h" #include "../../rpc_lookup.h" #include "../../config.h" +#include "../../lvalue.h" #include "functions.h" #include "curlcon.h" #include "curlrpc.h" +#include "curl_api.h" MODULE_VERSION @@ -126,6 +128,7 @@ static cmd_export_t cmds[] = { {"curl_connect", (cmd_function)w_curl_connect_post, 5, fixup_curl_connect_post, fixup_free_curl_connect_post, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, + {"bind_curl", (cmd_function)bind_curl_api, 0, 0, 0, 0}, }; @@ -343,8 +346,7 @@ static int fixup_http_query_get(void** param, int param_no) static int fixup_free_http_query_get(void** param, int param_no) { if (param_no == 1) { - LM_WARN("free function has not been defined for spve\n"); - return 0; + return fixup_free_spve_null(param, 1); } if (param_no == 2) { @@ -363,10 +365,14 @@ static int fixup_free_http_query_get(void** param, int param_no) static int fixup_curl_connect(void** param, int param_no) { - if ((param_no == 1) || (param_no == 2)) { + if (param_no == 1) { /* We want char * strings */ return 0; - } + } + /* URL and data may contain pvar */ + if (param_no == 2) { + return fixup_spve_null(param, 1); + } if (param_no == 3) { if (fixup_pvar_null(param, 1) != 0) { LM_ERR("failed to fixup result pvar\n"); @@ -391,24 +397,13 @@ static int fixup_curl_connect(void** param, int param_no) static int fixup_curl_connect_post(void** param, int param_no) { - str s; - pv_elem_t *pv = NULL; - if (param_no == 1 || param_no == 3) { /* We want char * strings */ return 0; - } + } /* URL and data may contain pvar */ - if (param_no == 4 || param_no == 2) { - s.s = (char*)(*param); - s.len = strlen(s.s); - - if(pv_parse_format(&s, &pv) < 0) { - LM_ERR("failed to parse postdata \n"); - return -1; - } - *param = (void*)pv; - return 0; + if (param_no == 2 || param_no == 4) { + return fixup_spve_null(param, 1); } if (param_no == 5) { if (fixup_pvar_null(param, 1) != 0) { @@ -432,13 +427,16 @@ static int fixup_curl_connect_post(void** param, int param_no) */ static int fixup_free_curl_connect_post(void** param, int param_no) { - if (param_no == 1 || param_no == 2 || param_no == 3 || param_no == 4) { - LM_WARN("free function has not been defined for spve\n"); + if (param_no == 1 || param_no == 3) { + /* Char strings don't need freeing */ return 0; } + if (param_no == 2 || param_no == 4) { + return fixup_free_spve_null(param, 1); + } if (param_no == 5) { - return fixup_free_pvar_null(param, 5); + return fixup_free_pvar_null(param, 1); } LM_ERR("invalid parameter number <%d>\n", param_no); @@ -450,13 +448,16 @@ static int fixup_free_curl_connect_post(void** param, int param_no) */ static int fixup_free_curl_connect(void** param, int param_no) { - if ((param_no == 1) || (param_no == 2)) { - LM_WARN("free function has not been defined for spve\n"); + if (param_no == 1) { + /* Char strings don't need freeing */ return 0; } + if (param_no == 2) { + return fixup_free_spve_null(param, 1); + } - if (param_no == 5) { - return fixup_free_pvar_null(param, 5); + if (param_no == 3) { + return fixup_free_pvar_null(param, 1); } LM_ERR("invalid parameter number <%d>\n", param_no); @@ -467,17 +468,81 @@ static int fixup_free_curl_connect(void** param, int param_no) * Wrapper for Curl_connect (GET) */ static int w_curl_connect(struct sip_msg* _m, char* _con, char * _url, char* _result) { -// curl_con_query_url(struct sip_msg* _m, char *connection, char* _url, char* _result, const char *contenttype, char* _post) +/* int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* _url, str* _result, const str *contenttype, const str* _post); */ + + str con = {NULL,0}; + str url = {NULL,0}; + str result = {NULL,0}; + pv_spec_t *dst; + pv_value_t val; + int ret = 0; + + if (_con == NULL || _url == NULL || _result == NULL) { + LM_ERR("Invalid parameter\n"); + } + con.s = _con; + con.len = strlen(con.s); + + if (get_str_fparam(&url, _m, (gparam_p)_url) != 0) { + LM_ERR("_url has no value\n"); + return -1; + } + LM_DBG("**** Curl Connection %s URL %s Result var %s\n", _con, _url, _result); - return curl_con_query_url(_m, _con, _url, _result, NULL, NULL); + ret = curl_con_query_url(_m, &con, &url, &result, NULL, NULL); + + val.rs = result; + val.flags = PV_VAL_STR; + dst = (pv_spec_t *)_result; + dst->setf(_m, &dst->pvp, (int)EQ_T, &val); + + if (result.s != NULL) + pkg_free(result.s); + + return ret; } /* * Wrapper for Curl_connect (POST) */ static int w_curl_connect_post(struct sip_msg* _m, char* _con, char * _url, char* _ctype, char* _data, char *_result) { - return curl_con_query_url(_m, _con, _url, _result, _ctype, _data); + str con = {NULL,0}; + str url = {NULL,0}; + str data = {NULL, 0}; + str result = {NULL,0}; + pv_spec_t *dst; + pv_value_t val; + int ret = 0; + + if (_con == NULL || _url == NULL || _data == NULL || _result == NULL) { + LM_ERR("Invalid parameter\n"); + } + con.s = _con; + con.len = strlen(con.s); + + if (get_str_fparam(&url, _m, (gparam_p)_url) != 0) { + LM_ERR("_url has no value\n"); + return -1; + } + if (get_str_fparam(&data, _m, (gparam_p)_data) != 0) { + LM_ERR("_data has no value\n"); + return -1; + } + + LM_DBG("**** Curl Connection %s URL %s Result var %s\n", _con, _url, _result); + + ret = curl_con_query_url(_m, &con, &url, &result, _ctype, &data); + + val.rs = result; + val.flags = PV_VAL_STR; + dst = (pv_spec_t *)_result; + dst->setf(_m, &dst->pvp, (int)EQ_T, &val); + + if (result.s != NULL) + pkg_free(result.s); + + return ret; } @@ -513,8 +578,7 @@ static int fixup_http_query_post(void** param, int param_no) static int fixup_free_http_query_post(void** param, int param_no) { if ((param_no == 1) || (param_no == 2)) { - LM_WARN("free function has not been defined for spve\n"); - return 0; + return fixup_free_spve_null(param, 1); } if (param_no == 3) { @@ -529,7 +593,27 @@ static int fixup_free_http_query_post(void** param, int param_no) * Wrapper for HTTP-Query (GET) */ static int w_http_query(struct sip_msg* _m, char* _url, char* _result) { - return http_query(_m, _url, _result, NULL); + int ret = 0; + str url = {NULL, 0}; + str result = {NULL, 0}; + pv_spec_t *dst; + pv_value_t val; + + if (get_str_fparam(&url, _m, (gparam_p)_url) != 0) { + LM_ERR("_url has no value\n"); + return -1; + } + + ret = http_query(_m, url.s, &result, NULL); + + val.rs = result; + val.flags = PV_VAL_STR; + dst = (pv_spec_t *)_result; + dst->setf(_m, &dst->pvp, (int)EQ_T, &val); + + if (result.s != NULL) + pkg_free(result.s); + return ret; } @@ -537,7 +621,31 @@ static int w_http_query(struct sip_msg* _m, char* _url, char* _result) { * Wrapper for HTTP-Query (POST-Variant) */ static int w_http_query_post(struct sip_msg* _m, char* _url, char* _post, char* _result) { - return http_query(_m, _url, _result, _post); + int ret = 0; + str url = {NULL, 0}; + str post = {NULL, 0}; + str result = {NULL, 0}; + pv_spec_t *dst; + pv_value_t val; + + if (get_str_fparam(&url, _m, (gparam_p)_url) != 0) { + LM_ERR("_url has no value\n"); + return -1; + } + if (get_str_fparam(&post, _m, (gparam_p)_post) != 0) { + LM_ERR("_data has no value\n"); + return -1; + } + + ret = http_query(_m, url.s, &result, post.s); + val.rs = result; + val.flags = PV_VAL_STR; + dst = (pv_spec_t *)_result; + dst->setf(_m, &dst->pvp, (int)EQ_T, &val); + + if (result.s != NULL) + pkg_free(result.s); + return ret; } /*! diff --git a/modules/curl/curl_api.c b/modules/curl/curl_api.c new file mode 100644 index 00000000000..74c6cad7d63 --- /dev/null +++ b/modules/curl/curl_api.c @@ -0,0 +1,12 @@ +#include "functions.h" +#include "curl_api.h" +int bind_curl_api(curl_api_t *api) +{ + if (!api) { + ERR("Invalid parameter value\n"); + return -1; + } + api->curl_connect = curl_con_query_url; + + return 0; +} diff --git a/modules/curl/curl_api.h b/modules/curl/curl_api.h new file mode 100644 index 00000000000..cc610692211 --- /dev/null +++ b/modules/curl/curl_api.h @@ -0,0 +1,36 @@ +#ifndef _CURL_CPI_H_ +#define _CURL_API_H_ + +#include "../../sr_module.h" +#include "functions.h" + +typedef int (*curlapi_curlconnect_f)(struct sip_msg *msg, const str *connection, const str* _url, str* _result, const char *contenttype, const str* _post); + +typedef struct curl_api { + curlapi_curlconnect_f curl_connect; +} curl_api_t; + +typedef int (*bind_curl_api_f)(curl_api_t *api); +int bind_curl_api(curl_api_t *api); + +/** + * @brief Load the CURL API + */ +static inline int curl_load_api(curl_api_t *api) +{ + bind_curl_api_f bindcurl; + + bindcurl = (bind_curl_api_f)find_export("bind_curl", 0, 0); + if(bindcurl == 0) { + LM_ERR("cannot find bind_curl\n"); + return -1; + } + if (bindcurl(api) < 0) + { + LM_ERR("cannot bind curl api\n"); + return -1; + } + return 0; +} + +#endif diff --git a/modules/curl/functions.c b/modules/curl/functions.c index 76f608c936d..8d77b92beb5 100644 --- a/modules/curl/functions.c +++ b/modules/curl/functions.c @@ -41,14 +41,13 @@ #include "../../ut.h" #include "../../mem/mem.h" #include "../../parser/msg_parser.h" -#include "../../lvalue.h" #include "curl.h" #include "curlcon.h" /* Forward declaration */ -static int curL_query_url(struct sip_msg* _m, char* _url, char* _dst, const char *username, - const char *secret, const char *contenttype, char* _post, const unsigned int timeout, +static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const char *username, + const char *secret, const char *contenttype, const char* _post, const unsigned int timeout, unsigned int http_follow_redirect, unsigned int oneline, unsigned int maxdatasize); /* @@ -64,19 +63,19 @@ size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream_ptr) if (stream->max_size == 0 || stream->curr_size < stream->max_size) { - stream->buf = (char *) pkg_realloc(stream->buf, stream->curr_size + (size * nmemb) + 1); + char *tmp = (char *) pkg_realloc(stream->buf, stream->curr_size + (size * nmemb)); - if (stream->buf == NULL) { - LM_ERR("cannot allocate memory for stream\n"); - return CURLE_WRITE_ERROR; + if (tmp == NULL) { + LM_ERR("cannot allocate memory for stream\n"); + return CURLE_WRITE_ERROR; } + stream->buf = tmp; memcpy(&stream->buf[stream->pos], (char *) ptr, (size * nmemb)); - stream->curr_size += ((size * nmemb) + 1); + stream->curr_size += ((size * nmemb)); stream->pos += (size * nmemb); - stream->buf[stream->pos + 1] = '\0'; } else { LM_DBG("****** ##### CURL Max datasize exceeded: max %u current %u\n", (unsigned int) stream->max_size, (unsigned int)stream->curr_size); } @@ -87,16 +86,14 @@ size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream_ptr) /*! Send query to server, optionally post data. */ -static int curL_query_url(struct sip_msg* _m, char* _url, char* _dst, const char *_username, const char *_secret, const char *contenttype, char* _post, unsigned int timeout, unsigned int http_follow_redirect, unsigned int oneline, unsigned int maxdatasize) +static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const char *_username, const char *_secret, const char *contenttype, const char* _post, unsigned int timeout, unsigned int http_follow_redirect, unsigned int oneline, unsigned int maxdatasize) { CURL *curl; CURLcode res; - str value; - char *url, *at = NULL; + char *at = NULL; curl_res_stream_t stream; long stat; - pv_spec_t *dst; - pv_value_t val; + str rval; double download_size; double total_time; struct curl_slist *headerlist = NULL; @@ -104,25 +101,14 @@ static int curL_query_url(struct sip_msg* _m, char* _url, char* _dst, const char memset(&stream, 0, sizeof(curl_res_stream_t)); stream.max_size = (size_t) maxdatasize; - value.s = _url; - value.len = strlen(_url); - curl = curl_easy_init(); if (curl == NULL) { LM_ERR("failed to initialize curl\n"); return -1; } - url = pkg_malloc(value.len + 1); - if (url == NULL) { - curl_easy_cleanup(curl); - LM_ERR("cannot allocate pkg memory for url %d\n", (value.len + 1)); - return -1; - } - memcpy(url, value.s, value.len); - *(url + value.len) = (char)0; - LM_DBG("****** ##### CURL URL %s _url [%.*s]\n", url, value.len, value.s); - res = curl_easy_setopt(curl, CURLOPT_URL, url); + LM_DBG("****** ##### CURL URL [%s] \n", _url); + res = curl_easy_setopt(curl, CURLOPT_URL, _url); if (_post) { char ctype[256]; @@ -139,7 +125,7 @@ static int curL_query_url(struct sip_msg* _m, char* _url, char* _dst, const char /* Tell CURL we want to upload using POST */ res |= curl_easy_setopt(curl, CURLOPT_POSTFIELDS, _post); - + } if (maxdatasize) { @@ -156,7 +142,6 @@ static int curL_query_url(struct sip_msg* _m, char* _url, char* _dst, const char res |= curl_easy_setopt(curl, CURLOPT_PASSWORD, _secret); } - res |= curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long) 1); res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long) timeout); @@ -172,7 +157,6 @@ static int curL_query_url(struct sip_msg* _m, char* _url, char* _dst, const char } else { res = curl_easy_perform(curl); } - pkg_free(url); if (headerlist) { curl_slist_free_all(headerlist); } @@ -202,7 +186,7 @@ static int curL_query_url(struct sip_msg* _m, char* _url, char* _dst, const char /* ask for the content-type of the response */ res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct); - + if(ct) { LM_DBG("We received Content-Type: %s\n", ct); } @@ -215,6 +199,8 @@ static int curL_query_url(struct sip_msg* _m, char* _url, char* _dst, const char curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time); LM_DBG(" -- curl download size: %u Time : %ld \n", (unsigned int)download_size, (long) total_time); + if (download_size > 0) { + if (oneline) { /* search for line feed */ at = memchr(stream.buf, (char)10, download_size); @@ -233,128 +219,120 @@ static int curL_query_url(struct sip_msg* _m, char* _url, char* _dst, const char //at = stream.buf + (unsigned int) download_size; } } - /* Create a STR object */ - val.rs.s = stream.buf; - val.rs.len = datasize; - LM_DBG("curl query result: Length %d %.*s \n", val.rs.len, val.rs.len, val.rs.s); - val.flags = PV_VAL_STR; - dst = (pv_spec_t *)_dst; - dst->setf(_m, &dst->pvp, (int)EQ_T, &val); - LM_DBG("---------- curl result pvar set. \n"); + /* Create a STR object */ + + rval.s = stream.buf; + rval.len = datasize; + /* Duplicate string to return */ + pkg_str_dup(_dst, &rval); + LM_DBG("curl query result: Length %d %.*s \n", rval.len, rval.len, rval.s); + } else { + _dst->s = NULL; + _dst->len = 0; + } } if (stat == 200) { counter_inc(connok); } else { counter_inc(connfail); } - + /* CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... ); */ curl_easy_cleanup(curl); - pkg_free(stream.buf); + if (stream.buf != NULL) + pkg_free(stream.buf); return stat; } /*! Run a query based on a connection definition */ -int curl_con_query_url(struct sip_msg* _m, char *connection, char* _url, char* _result, const char *contenttype, char* _post) +int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url, str* result, const char *contenttype, const str* post) { curl_con_t *conn = NULL; - str connstr; - char usernamebuf[BUFSIZ/2]; - char passwordbuf[BUFSIZ/2]; - char connurlbuf[BUFSIZ/2]; - char urlbuf[512]; - str urlbuf2; - char *urlbuf3 = NULL; - - str postdatabuf; + char *urlbuf = NULL; + char *username_str = NULL; + char *password_str = NULL; char *postdata = NULL; + unsigned int maxdatasize = default_maxdatasize; int res; - memset(usernamebuf,0,sizeof(usernamebuf)); - memset(passwordbuf,0,sizeof(passwordbuf)); - memset(connurlbuf,0,sizeof(connurlbuf)); - memset(urlbuf,0,sizeof(urlbuf)); - /* Find connection if it exists */ if (!connection) { LM_ERR("No cURL connection specified\n"); return -1; } - LM_DBG("******** CURL Connection %s\n", connection); - connstr.s = connection; - connstr.len = strlen(connection); - conn = curl_get_connection(&connstr); + LM_DBG("******** CURL Connection %.*s\n", connection->len, connection->s); + conn = curl_get_connection((str*)connection); if (conn == NULL) { - LM_ERR("No cURL connection found: %s\n", connection); + LM_ERR("No cURL connection found: %.*s\n", connection->len, connection->s); return -1; } - strncpy(usernamebuf, conn->username.s, conn->username.len); - strncpy(passwordbuf, conn->password.s, conn->password.len); - strncpy(connurlbuf, conn->url.s, conn->url.len); - maxdatasize = conn->maxdatasize; - - LM_DBG("******** CURL Connection found %s\n", connection); - - if (_url && *_url) { - if(pv_printf_s(_m, (pv_elem_t*) _url, &urlbuf2) != 0) { - LM_ERR("curl :: unable to handle post data %s\n", _url); - return -1; - } - if(urlbuf2.s==NULL || urlbuf2.len == 0) { - LM_ERR("curl :: invalid url parameter\n"); - return -1; - } - LM_DBG("******** CURL Connection URL parsed for %s\n", connection); - /* Allocated using pkg_memory */ - urlbuf3 = as_asciiz(&urlbuf2); - if (urlbuf3 == NULL) { - ERR("Curl: No memory left\n"); - return -1; - } - LM_DBG("******** CURL URL string after PV parsing %s\n", urlbuf3); - } else { - LM_DBG("******** CURL URL string NULL no PV parsing %s\n", _url); + LM_DBG("******** CURL Connection found %.*s\n", connection->len, connection->s); + if (conn->username.s != NULL && conn->username.len > 0) + { + username_str = as_asciiz(&conn->username); } - strncpy(urlbuf, conn->schema.s, conn->schema.len); - if (urlbuf3 != NULL) { - snprintf(&urlbuf[conn->schema.len],(sizeof(urlbuf) - conn->schema.len), "://%s%s%s", connurlbuf, - (urlbuf3[0] && urlbuf3[0] == '/')?"":(urlbuf3[0] != '\0' ? "/": ""), urlbuf3); - } else { - snprintf(&urlbuf[conn->schema.len],(sizeof(urlbuf) - conn->schema.len), "://%s%s%s", connurlbuf, - (_url[0] && _url[0] == '/')?"":(_url[0] != '\0' ? "/": ""), _url); + if (conn->password.s != NULL && conn->password.len > 0) + { + password_str = as_asciiz(&conn->password); } + maxdatasize = conn->maxdatasize; + - /* Release the memory allocated by as_asciiz */ - if (urlbuf3 != NULL) { - pkg_free(urlbuf3); + if (url && (url->len > 0) && (url->s != NULL)) { + int url_len = conn->schema.len + 3 + conn->url.len + 1 + url->len + 1; + urlbuf = pkg_malloc(url_len); + if (urlbuf == NULL) + { + res = -1; + goto error; + } + snprintf(urlbuf, url_len, "%.*s://%.*s%s%.*s", + conn->schema.len, conn->schema.s, + conn->url.len, conn->url.s, + (url->s[0] == '/')? "" : "/", + url->len, url->s); + } else { + int url_len = conn->schema.len + 3 + conn->url.len + 1; + urlbuf = pkg_malloc(url_len); + if (urlbuf == NULL) + { + res = -1; + goto error; + } + snprintf(urlbuf, url_len, "%.*s://%.*s", + conn->schema.len, conn->schema.s, + conn->url.len, conn->url.s); } LM_DBG("***** #### ***** CURL URL: %s \n", urlbuf); - if (_post && *_post) { - if(pv_printf_s(_m, (pv_elem_t*)_post, &postdatabuf) != 0) { - LM_ERR("curl :: unable to handle post data %s\n", _post); - return -1; - } - if(postdatabuf.s==NULL || postdatabuf.len == 0) { - LM_ERR("curl :: invalid post data parameter\n"); - return -1; - } + + if (post && (post->len > 0) && (post->s != NULL)) { + /* Allocated using pkg_memory */ - postdata = as_asciiz(&postdatabuf); + postdata = as_asciiz((str*)post); if (postdata == NULL) { ERR("Curl: No memory left\n"); - return -1; + res = -1; + goto error; } LM_DBG("***** #### ***** CURL POST data: %s Content-type %s\n", postdata, contenttype); - } - /* TODO: Concatenate URL in connection with URL given in function */ - res = curL_query_url(_m, urlbuf, _result, usernamebuf, passwordbuf, (contenttype ? contenttype : "text/plain"), postdata, + res = curL_query_url(_m, urlbuf, result, username_str, password_str, (contenttype ? contenttype : "text/plain"), postdata, conn->timeout, conn->http_follow_redirect, 0, (unsigned int) maxdatasize ); LM_DBG("***** #### ***** CURL DONE : %s \n", urlbuf); +error: + if (urlbuf != NULL) { + pkg_free(urlbuf); + } + if (username_str != NULL) { + pkg_free(username_str); + } + if (password_str != NULL) { + pkg_free(password_str); + } if (postdata != NULL) { pkg_free(postdata); } @@ -367,7 +345,7 @@ int curl_con_query_url(struct sip_msg* _m, char *connection, char* _url, char* _ * to pvar. * This is the same http_query as used to be in the utils module. */ -int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post) +int http_query(struct sip_msg* _m, char* _url, str* _dst, char* _post) { int res; diff --git a/modules/curl/functions.h b/modules/curl/functions.h index 7d3718ca80a..82ae0844d8e 100644 --- a/modules/curl/functions.h +++ b/modules/curl/functions.h @@ -30,14 +30,14 @@ */ -#ifndef UTILS_FUNCTIONS_H -#define UTILS_FUNCTIONS_H +#ifndef CURL_FUNCTIONS_H +#define CURL_FUNCTIONS_H #include "../../parser/msg_parser.h" /*! Use predefined connection to run HTTP get or post */ -int curl_con_query_url(struct sip_msg* _m, char *connection, char* _url, char* _result, const char *contenttype, char* _post); +int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* _url, str* _result, const char *contenttype, const str* _post); @@ -45,7 +45,7 @@ int curl_con_query_url(struct sip_msg* _m, char *connection, char* _url, char* _ * Performs http_query and saves possible result (first body line of reply) * to pvar. */ -int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post); +int http_query(struct sip_msg* _m, char* _url, str* _dst, char* _post); -#endif /* UTILS_FUNCTIONS_H */ +#endif /* CURL_FUNCTIONS_H */