diff --git a/modules/utils/functions.c b/modules/utils/functions.c index d32d970ab88..a5b62dd3afb 100644 --- a/modules/utils/functions.c +++ b/modules/utils/functions.c @@ -77,12 +77,12 @@ size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream_ptr) * 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, char* _dst, char* _post, char* _hdr) { CURL *curl; CURLcode res; - str value, post_value; - char *url, *at, *post; + str value, post_value, hdr_value; + char *url, *at, *post = NULL, *hdr = NULL; http_res_stream_t stream; long stat; pv_spec_t *dst; @@ -112,6 +112,28 @@ int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post) *(url + value.len) = (char)0; curl_easy_setopt(curl, CURLOPT_URL, url); + if (_hdr) { + if (fixup_get_svalue(_m, (gparam_p)_hdr, &hdr_value) != 0) { + LM_ERR("cannot get Header value\n"); + curl_easy_cleanup(curl); + pkg_free(url); + return -1; + } + if (hdr_value.len > 0) { + hdr = pkg_malloc(hdr_value.len + 1); + if (hdr == NULL) { + curl_easy_cleanup(curl); + pkg_free(url); + LM_ERR("cannot allocate pkg memory for header\n"); + return -1; + } + memcpy(hdr, hdr_value.s, hdr_value.len); + *(hdr + hdr_value.len) = (char)0; + + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hdr); + } + } + if (_post) { /* Now specify we want to POST data */ curl_easy_setopt(curl, CURLOPT_POST, 1L); @@ -120,18 +142,22 @@ int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post) LM_ERR("cannot get post value\n"); curl_easy_cleanup(curl); pkg_free(url); + if (hdr) pkg_free(hdr); return -1; } - post = pkg_malloc(post_value.len + 1); - if (post == NULL) { - curl_easy_cleanup(curl); - pkg_free(url); - LM_ERR("cannot allocate pkg memory for post\n"); - return -1; + if (post_value.len > 0) { + post = pkg_malloc(post_value.len + 1); + if (post == NULL) { + curl_easy_cleanup(curl); + pkg_free(url); + if (hdr) pkg_free(hdr); + LM_ERR("cannot allocate pkg memory for post\n"); + return -1; + } + memcpy(post, post_value.s, post_value.len); + *(post + post_value.len) = (char)0; + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post); } - memcpy(post, post_value.s, post_value.len); - *(post + post_value.len) = (char)0; - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post); } @@ -146,6 +172,9 @@ int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post) if (_post) { pkg_free(post); } + if (_hdr) { + pkg_free(hdr); + } if (res != CURLE_OK) { /* http://curl.haxx.se/libcurl/c/libcurl-errors.html */ diff --git a/modules/utils/functions.h b/modules/utils/functions.h index 230d119ab44..09b06b99f87 100644 --- a/modules/utils/functions.h +++ b/modules/utils/functions.h @@ -40,7 +40,7 @@ * 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, char* _dst, char* _post, char* _hdr); #endif /* UTILS_FUNCTIONS_H */ diff --git a/modules/utils/utils.c b/modules/utils/utils.c index f506fa5e975..8e4c1a21cc2 100644 --- a/modules/utils/utils.c +++ b/modules/utils/utils.c @@ -88,11 +88,14 @@ static void destroy(void); static int fixup_http_query_get(void** param, int param_no); static int fixup_free_http_query_get(void** param, int param_no); static int fixup_http_query_post(void** param, int param_no); +static int fixup_http_query_post_hdr(void** param, int param_no); static int fixup_free_http_query_post(void** param, int param_no); +static int fixup_free_http_query_post_hdr(void** param, int param_no); /* Wrappers for http_query to be defined later */ static int w_http_query(struct sip_msg* _m, char* _url, char* _result); static int w_http_query_post(struct sip_msg* _m, char* _url, char* _post, char* _result); +static int w_http_query_post_hdr(struct sip_msg* _m, char* _url, char* _post, char* _hdr, char* _result); /* forward function */ int utils_forward(struct sip_msg *msg, int id, int proto); @@ -105,6 +108,9 @@ static cmd_export_t cmds[] = { {"http_query", (cmd_function)w_http_query_post, 3, fixup_http_query_post, fixup_free_http_query_post, REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, + {"http_query", (cmd_function)w_http_query_post_hdr, 4, fixup_http_query_post_hdr, + fixup_free_http_query_post_hdr, + REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE}, {"xcap_auth_status", (cmd_function)xcap_auth_status, 2, fixup_pvar_pvar, fixup_free_pvar_pvar, REQUEST_ROUTE}, {0, 0, 0, 0, 0, 0} @@ -390,6 +396,32 @@ static int fixup_http_query_post(void** param, int param_no) return -1; } +/* + * Fix http_query params: url (string that may contain pvars) and + * result (writable pvar). + */ +static int fixup_http_query_post_hdr(void** param, int param_no) +{ + if ((param_no >= 1) || (param_no <= 3)) { + return fixup_spve_null(param, 1); + } + + if (param_no == 4) { + if (fixup_pvar_null(param, 1) != 0) { + LM_ERR("failed to fixup result pvar\n"); + return -1; + } + if (((pv_spec_t *)(*param))->setf == NULL) { + LM_ERR("result pvar is not writeble\n"); + return -1; + } + return 0; + } + + LM_ERR("invalid parameter number <%d>\n", param_no); + return -1; +} + /* * Free http_query params. */ @@ -408,19 +440,43 @@ static int fixup_free_http_query_post(void** param, int param_no) return -1; } +/* + * Free http_query params. + */ +static int fixup_free_http_query_post_hdr(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; + } + + if (param_no == 3) { + return fixup_free_pvar_null(param, 1); + } + + LM_ERR("invalid parameter number <%d>\n", param_no); + return -1; +} + /* * 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); + return http_query(_m, _url, _result, NULL, NULL); } - /* * 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); + return http_query(_m, _url, _result, _post, NULL); +} + +/* + * Wrapper for HTTP-Query (POST-Variant) + */ +static int w_http_query_post_hdr(struct sip_msg* _m, char* _url, char* _post, char* _hdr, char* _result) { + return http_query(_m, _url, _result, _post, _hdr); } /*!