From 2544212f41154aa429bf31a4cce3d0a950e2942a Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Fri, 30 Aug 2024 11:04:39 +0200 Subject: [PATCH] MT#60205 http_client: support more methods in http_connect() * lost needs to be updated due changes in http_client API Change-Id: Ic9a78cf7dd31dea8467393a55a4824f75b12b036 --- debian/patches/series | 2 + ...add-method-parameter-to-http_connect.patch | 401 ++++++++++++++++++ ...thod-parameter-to-http_connect-calls.patch | 47 ++ 3 files changed, 450 insertions(+) create mode 100644 debian/patches/sipwise/http_client-add-method-parameter-to-http_connect.patch create mode 100644 debian/patches/sipwise/lost-add-method-parameter-to-http_connect-calls.patch diff --git a/debian/patches/series b/debian/patches/series index dffaea85b..ca1620b17 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -52,6 +52,8 @@ sipwise/app_lua_sr-support-second-str-for-cfgutils-lock.patch sipwise/cfgutils-allow-lock_set_size-14.patch sipwise/pua-get_record_puadb-add-pres_uri-to-the-query.patch sipwise/pua_dialoginfo-use_uuid.patch +sipwise/http_client-add-method-parameter-to-http_connect.patch +sipwise/lost-add-method-parameter-to-http_connect-calls.patch ### active development # ### Don't just put stuff in any order diff --git a/debian/patches/sipwise/http_client-add-method-parameter-to-http_connect.patch b/debian/patches/sipwise/http_client-add-method-parameter-to-http_connect.patch new file mode 100644 index 000000000..36a2c40b3 --- /dev/null +++ b/debian/patches/sipwise/http_client-add-method-parameter-to-http_connect.patch @@ -0,0 +1,401 @@ +From: Victor Seva +Date: Fri, 30 Aug 2024 10:17:53 +0200 +Subject: http_client: add method parameter to http_connect() + +--- + src/modules/http_client/curl_api.h | 3 +- + src/modules/http_client/functions.c | 25 +++++---- + src/modules/http_client/functions.h | 5 +- + src/modules/http_client/http_client.c | 97 +++++++++++++++++++++++++---------- + 4 files changed, 89 insertions(+), 41 deletions(-) + +diff --git a/src/modules/http_client/curl_api.h b/src/modules/http_client/curl_api.h +index cbe4785..2938016 100644 +--- a/src/modules/http_client/curl_api.h ++++ b/src/modules/http_client/curl_api.h +@@ -1,5 +1,6 @@ + /* + * Copyright (C) 2015 Hugh Waite ++ * Copyright (C) 2024 Victor Seva, Sipwise + * + * This file is part of Kamailio, a free SIP server. + * +@@ -35,7 +36,7 @@ + #include "curlcon.h" + + typedef int (*httpcapi_httpconnect_f)(struct sip_msg *msg, +- const str *connection, const str *_url, str *_result, ++ const str *connection, const str *method, const str *_url, str *_result, + const char *contenttype, const str *_post); + typedef int (*httpcapi_httpquery_f)( + struct sip_msg *_m, char *_url, str *_dst, char *_post, char *_hdrs); +diff --git a/src/modules/http_client/functions.c b/src/modules/http_client/functions.c +index dda4721..e3dc768 100644 +--- a/src/modules/http_client/functions.c ++++ b/src/modules/http_client/functions.c +@@ -2,6 +2,7 @@ + * Script functions of http_client module + * + * Copyright (C) 2015 Olle E. Johansson, Edvina AB ++ * Copyright (C) 2024 Victor Seva, Sipwise + * + * Based on functions from siputil + * Copyright (C) 2008 Juha Heinanen +@@ -268,10 +269,11 @@ static int curL_request_url(struct sip_msg *_m, const char *_met, + * - 1 (default) : timeout value is in seconds. + * - 2 : timeout value is in milliseconds. + */ +- if (timeout_mode == 1) { /* timeout is in seconds (default) */ ++ if(timeout_mode == 1) { /* timeout is in seconds (default) */ + res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)params->timeout); +- } else if (timeout_mode == 2) { /* timeout is in milliseconds */ +- res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, (long)params->timeout); ++ } else if(timeout_mode == 2) { /* timeout is in milliseconds */ ++ res |= curl_easy_setopt( ++ curl, CURLOPT_TIMEOUT_MS, (long)params->timeout); + } + + res |= curl_easy_setopt( +@@ -525,11 +527,13 @@ int curl_get_redirect(struct sip_msg *_m, const str *connection, str *result) + + /*! Run a query based on a connection definition */ + int curl_con_query_url_f(struct sip_msg *_m, const str *connection, +- const str *url, str *result, const char *contenttype, const str *post, +- int failover) ++ const str *method, const str *url, str *result, const char *contenttype, ++ const str *post, int failover) + { + curl_con_t *conn = NULL; + curl_con_pkg_t *pconn = NULL; ++ char *met = (method && (method->len > 0) && (method->s != NULL)) ? method->s ++ : NULL; + char *urlbuf = NULL; + char *postdata = NULL; + char *failovercon = NULL; +@@ -629,7 +633,7 @@ int curl_con_query_url_f(struct sip_msg *_m, const str *connection, + LM_DBG("**** Curl HTTP_proxy not set \n"); + } + +- res = curL_request_url(_m, NULL, urlbuf, result, &query_params); ++ res = curL_request_url(_m, met, urlbuf, result, &query_params); + + if(res > 1000 && conn->failover.s) { + int counter = failover + 1; +@@ -639,8 +643,8 @@ int curl_con_query_url_f(struct sip_msg *_m, const str *connection, + goto error; + } + /* Time for failover */ +- res = curl_con_query_url_f( +- _m, &conn->failover, url, result, contenttype, post, counter); ++ res = curl_con_query_url_f(_m, &conn->failover, method, url, result, ++ contenttype, post, counter); + } + + LM_DBG("***** #### ***** CURL DONE: %s (%d)\n", urlbuf, res); +@@ -659,10 +663,11 @@ error: + + /* Wrapper */ + int curl_con_query_url(struct sip_msg *_m, const str *connection, +- const str *url, str *result, const char *contenttype, const str *post) ++ const str *method, const str *url, str *result, const char *contenttype, ++ const str *post) + { + return curl_con_query_url_f( +- _m, connection, url, result, contenttype, post, 0); ++ _m, connection, method, url, result, contenttype, post, 0); + } + + /*! +diff --git a/src/modules/http_client/functions.h b/src/modules/http_client/functions.h +index 2739273..c49ef35 100644 +--- a/src/modules/http_client/functions.h ++++ b/src/modules/http_client/functions.h +@@ -3,6 +3,7 @@ + * + * Copyright (C) 2008 Juha Heinanen + * Copyright (C) 2013 Carsten Bock, ng-voice GmbH ++ * Copyright (C) 2024 Victor Seva, Sipwise + * + * This file is part of Kamailio, a free SIP server. + * +@@ -40,8 +41,8 @@ + /*! Use predefined connection to run HTTP get or post + */ + int curl_con_query_url(struct sip_msg *_m, const str *connection, +- const str *_url, str *_result, const char *contenttype, +- const str *_post); ++ const str *_method, const str *_url, str *_result, ++ const char *contenttype, const str *_post); + + /*! Get redirect URL from last connection pkg memory storage */ + int curl_get_redirect(struct sip_msg *_m, const str *connection, str *result); +diff --git a/src/modules/http_client/http_client.c b/src/modules/http_client/http_client.c +index ca605ec..1cf26a4 100644 +--- a/src/modules/http_client/http_client.c ++++ b/src/modules/http_client/http_client.c +@@ -1,6 +1,7 @@ + /* + * http_client Module + * Copyright (C) 2015-2016 Edvina AB, Olle E. Johansson ++ * Copyright (C) 2024 Victor Seva, Sipwise + * + * Based on part of the utils module and part + * of the json-rpc-c module +@@ -141,7 +142,7 @@ static int fixup_curl_connect_post_raw(void **param, int param_no); + static int fixup_free_curl_connect_post(void **param, int param_no); + static int fixup_free_curl_connect_post_raw(void **param, int param_no); + static int w_curl_connect_post(struct sip_msg *_m, char *_con, char *_url, +- char *_result, char *_ctype, char *_data); ++ char *_result, char *_method, char *_ctype, char *_data); + static int w_curl_connect_post_raw(struct sip_msg *_m, char *_con, char *_url, + char *_result, char *_ctype, char *_data); + +@@ -184,7 +185,7 @@ static cmd_export_t cmds[] = { + {"http_connect", (cmd_function)w_curl_connect, 3, fixup_curl_connect, + fixup_free_curl_connect, + REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, +- {"http_connect", (cmd_function)w_curl_connect_post, 5, fixup_curl_connect_post, ++ {"http_connect", (cmd_function)w_curl_connect_post, 6, fixup_curl_connect_post, + fixup_free_curl_connect_post, + REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, + {"http_connect_raw", (cmd_function)w_curl_connect_post_raw, 5, fixup_curl_connect_post_raw, +@@ -470,7 +471,7 @@ static int fixup_free_http_query_get(void **param, int param_no) + + + /* +- * Fix curl_connect params: connection(string/pvar) url (string that may contain pvars) and ++ * Fix curl_connect params: connection(string) url (string that may contain pvars) and + * result (writable pvar). + */ + static int fixup_curl_connect(void **param, int param_no) +@@ -480,7 +481,7 @@ static int fixup_curl_connect(void **param, int param_no) + /* We want char * strings */ + return 0; + } +- /* URL and data may contain pvar */ ++ /* URL may contain pvar */ + if(param_no == 2) { + return fixup_spve_null(param, 1); + } +@@ -501,22 +502,24 @@ static int fixup_curl_connect(void **param, int param_no) + } + + /* +- * Fix curl_connect params when posting (5 parameters): +- * connection (string/pvar), url (string with pvars), content-type, +- * data (string/pvar, pvar) ++ * Fix curl_connect params when posting (6 parameters): ++ * connection (string), url (string with pvars), method (string with pvars), content-type, ++ * data (string/pvar, pvar) and ++ * result (writable pvar) + */ + static int fixup_curl_connect_post(void **param, int param_no) + { + +- if(param_no == 1 || param_no == 3) { ++ if(param_no == 1 || param_no == 4) { + /* We want char * strings */ + return 0; + } ++ + /* URL and data may contain pvar */ +- if(param_no == 2 || param_no == 4) { ++ if(param_no == 2 || param_no == 3 || param_no == 5) { + return fixup_spve_null(param, 1); + } +- if(param_no == 5) { ++ if(param_no == 6) { + if(fixup_pvar_null(param, 1) != 0) { + LM_ERR("failed to fixup result pseudo variable\n"); + return -1; +@@ -569,15 +572,15 @@ static int fixup_curl_connect_post_raw(void **param, int param_no) + */ + static int fixup_free_curl_connect_post(void **param, int param_no) + { +- if(param_no == 1 || param_no == 3) { ++ if(param_no == 1 || param_no == 4) { + /* Char strings don't need freeing */ + return 0; + } +- if(param_no == 2 || param_no == 4) { ++ if(param_no == 2 || param_no == 3 || param_no == 5) { + return fixup_free_spve_null(param, 1); + } + +- if(param_no == 5) { ++ if(param_no == 6) { + return fixup_free_pvar_null(param, 1); + } + +@@ -631,13 +634,13 @@ static int fixup_free_curl_connect(void **param, int param_no) + * Wrapper for Curl_connect (GET) + */ + static int ki_curl_connect_helper( +- sip_msg_t *_m, str *con, str *url, pv_spec_t *dst) ++ sip_msg_t *_m, str *con, str *method, str *url, pv_spec_t *dst) + { + str result = {NULL, 0}; + pv_value_t val; + int ret = 0; + +- ret = curl_con_query_url(_m, con, url, &result, NULL, NULL); ++ ret = curl_con_query_url(_m, con, method, url, &result, NULL, NULL); + + val.rs = result; + val.flags = PV_VAL_STR; +@@ -658,6 +661,7 @@ static int ki_curl_connect_helper( + */ + static int ki_curl_connect(sip_msg_t *_m, str *con, str *url, str *dpv) + { ++ str met = str_init("GET"); + pv_spec_t *dst; + + dst = pv_cache_get(dpv); +@@ -670,7 +674,7 @@ static int ki_curl_connect(sip_msg_t *_m, str *con, str *url, str *dpv) + return -1; + } + +- return ki_curl_connect_helper(_m, con, url, dst); ++ return ki_curl_connect_helper(_m, con, &met, url, dst); + } + + /* +@@ -679,6 +683,7 @@ static int ki_curl_connect(sip_msg_t *_m, str *con, str *url, str *dpv) + static int w_curl_connect(sip_msg_t *_m, char *_con, char *_url, char *_result) + { + str con = {NULL, 0}; ++ str met = str_init("GET"); + str url = {NULL, 0}; + pv_spec_t *dst; + +@@ -697,20 +702,20 @@ static int w_curl_connect(sip_msg_t *_m, char *_con, char *_url, char *_result) + _result); + dst = (pv_spec_t *)_result; + +- return ki_curl_connect_helper(_m, &con, &url, dst); ++ return ki_curl_connect_helper(_m, &con, &met, &url, dst); + } + + /* + * Wrapper for Curl_connect (POST) + */ +-static int ki_curl_connect_post_helper(sip_msg_t *_m, str *con, str *url, +- str *ctype, str *data, pv_spec_t *dst) ++static int ki_curl_connect_post_helper(sip_msg_t *_m, str *con, str *met, ++ str *url, str *ctype, str *data, pv_spec_t *dst) + { + str result = {NULL, 0}; + pv_value_t val; + int ret = 0; + +- ret = curl_con_query_url(_m, con, url, &result, ctype->s, data); ++ ret = curl_con_query_url(_m, con, met, url, &result, ctype->s, data); + + val.rs = result; + val.flags = PV_VAL_STR; +@@ -732,6 +737,7 @@ static int ki_curl_connect_post_helper(sip_msg_t *_m, str *con, str *url, + static int ki_curl_connect_post( + sip_msg_t *_m, str *con, str *url, str *ctype, str *data, str *dpv) + { ++ str met = str_init("POST"); + pv_spec_t *dst; + + dst = pv_cache_get(dpv); +@@ -744,7 +750,7 @@ static int ki_curl_connect_post( + return -1; + } + +- return ki_curl_connect_post_helper(_m, con, url, ctype, data, dst); ++ return ki_curl_connect_post_helper(_m, con, &met, url, ctype, data, dst); + } + + /* +@@ -754,6 +760,7 @@ static int w_curl_connect_post_raw(struct sip_msg *_m, char *_con, char *_url, + char *_ctype, char *_data, char *_result) + { + str con = {NULL, 0}; ++ str met = str_init("POST"); + str url = {NULL, 0}; + str ctype = {NULL, 0}; + str data = {NULL, 0}; +@@ -782,31 +789,64 @@ static int w_curl_connect_post_raw(struct sip_msg *_m, char *_con, char *_url, + _url, _result); + dst = (pv_spec_t *)_result; + +- return ki_curl_connect_post_helper(_m, &con, &url, &ctype, &data, dst); ++ return ki_curl_connect_post_helper( ++ _m, &con, &met, &url, &ctype, &data, dst); ++} ++ ++static int check_method(const str *method) ++{ ++ switch(method->len) { ++ case 3: ++ if(strncmp("GET", method->s, method->len) == 0) ++ return 0; ++ else if(strncmp("PUT", method->s, method->len) == 0) ++ return 0; ++ break; ++ case 4: ++ if(strncmp("POST", method->s, method->len) == 0) ++ return 0; ++ break; ++ case 6: ++ if(strncmp("DELETE", method->s, method->len) == 0) ++ return 0; ++ break; ++ } ++ return -1; + } + + /* + * 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) ++ char *_method, char *_ctype, char *_data, char *_result) + { + str con = {NULL, 0}; ++ str method = {NULL, 0}; + str url = {NULL, 0}; + str ctype = {NULL, 0}; + str data = {NULL, 0}; + pv_spec_t *dst; + +- if(_con == NULL || _url == NULL || _ctype == NULL || _data == NULL +- || _result == NULL) { +- LM_ERR("http_connect: Invalid parameters\n"); ++ if(_con == NULL || _url == NULL || _method == NULL || _ctype == NULL ++ || _data == NULL || _result == NULL) { ++ LM_ERR("Invalid parameters\n"); + return -1; + } + con.s = _con; + con.len = strlen(con.s); + + if(get_str_fparam(&url, _m, (gparam_p)_url) != 0) { +- LM_ERR("http_connect: URL has no value\n"); ++ LM_ERR("URL has no value\n"); ++ return -1; ++ } ++ ++ if(get_str_fparam(&method, _m, (gparam_p)_method) != 0) { ++ LM_ERR("METHOD has no value\n"); ++ return -1; ++ } ++ ++ if(check_method(&method) < 0) { ++ LM_ERR("HTTP method: '%.*s' unsupported\n", STR_FMT(&method)); + return -1; + } + +@@ -822,7 +862,8 @@ static int w_curl_connect_post(struct sip_msg *_m, char *_con, char *_url, + _url, _result); + dst = (pv_spec_t *)_result; + +- return ki_curl_connect_post_helper(_m, &con, &url, &ctype, &data, dst); ++ return ki_curl_connect_post_helper( ++ _m, &con, &method, &url, &ctype, &data, dst); + } + + /*! diff --git a/debian/patches/sipwise/lost-add-method-parameter-to-http_connect-calls.patch b/debian/patches/sipwise/lost-add-method-parameter-to-http_connect-calls.patch new file mode 100644 index 000000000..2ec79ee8f --- /dev/null +++ b/debian/patches/sipwise/lost-add-method-parameter-to-http_connect-calls.patch @@ -0,0 +1,47 @@ +From: Victor Seva +Date: Fri, 30 Aug 2024 11:23:13 +0200 +Subject: lost: add method parameter to http_connect() calls + +--- + src/modules/lost/functions.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/modules/lost/functions.c b/src/modules/lost/functions.c +index 9495a69..bc75bf4 100644 +--- a/src/modules/lost/functions.c ++++ b/src/modules/lost/functions.c +@@ -188,7 +188,7 @@ int lost_held_function(struct sip_msg *_m, char *_con, char *_pidf, char *_url, + str geo = STR_NULL; /* return value geolocation uri */ + str res = STR_NULL; /* return value pidf */ + str err = STR_NULL; /* return value error */ +- ++ str method = str_init("POST"); + str url = STR_NULL; + str did = STR_NULL; + str que = STR_NULL; +@@ -292,7 +292,7 @@ int lost_held_function(struct sip_msg *_m, char *_con, char *_pidf, char *_url, + LM_DBG("using connection [%.*s]\n", con.len, con.s); + + /* send via connection */ +- curl = httpapi.http_connect(_m, &con, NULL, &res, mtheld, &que); ++ curl = httpapi.http_connect(_m, &con, &method, NULL, &res, mtheld, &que); + } else { + /* we have no connection ... do a NAPTR lookup */ + if(lost_parse_host(did.s, &host, &flag) > 0) { +@@ -819,6 +819,7 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, + str err = STR_NULL; /* return value error */ + + str tmp = STR_NULL; ++ str method = str_init("POST"); + str url = STR_NULL; + str urn = STR_NULL; + str req = STR_NULL; +@@ -1093,7 +1094,7 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, + pkg_free(urlrep); /* clean up */ + urlrep = NULL; + } else { +- curl = httpapi.http_connect(_m, &con, NULL, &ret, mtlost, &req); ++ curl = httpapi.http_connect(_m, &con, &method, NULL, &ret, mtlost, &req); + } + /* only HTTP 2xx responses are accepted */ + if(curl >= 300 || curl < 100) {