diff --git a/doc/CHANGES-staging/func_curl_headers.txt b/doc/CHANGES-staging/func_curl_headers.txt new file mode 100644 index 0000000000..9d5c8c3e18 --- /dev/null +++ b/doc/CHANGES-staging/func_curl_headers.txt @@ -0,0 +1,6 @@ +Subject: func_curl + +A new parameter, httpheader, has been added to CURLOPT function. This parameter +allows to set custom http headers for subsequent calls off CURL function. +Any setting of headers will replace the default curl headers +(e.g. "Content-type: application/x-www-form-urlencoded") diff --git a/funcs/func_curl.c b/funcs/func_curl.c index 89a4688e7a..06a8b5354e 100644 --- a/funcs/func_curl.c +++ b/funcs/func_curl.c @@ -99,6 +99,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") Include header information in the result (boolean) + + Add HTTP header. Multiple calls add multiple headers. + Setting of any header will remove the default + "Content-Type application/x-www-form-urlencoded" + For HTTP(S) URIs, number of seconds to wait for a server response @@ -159,7 +164,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") Options may be set globally or per channel. Per-channel - settings will override global settings. + settings will override global settings. Only HTTP headers are added instead of overriding CURL @@ -221,6 +226,9 @@ static int parse_curlopt_key(const char *name, CURLoption *key, enum optiontype if (!strcasecmp(name, "header")) { *key = CURLOPT_HEADER; *ot = OT_BOOLEAN; + } else if (!strcasecmp(name, "httpheader")) { + *key = CURLOPT_HTTPHEADER; + *ot = OT_STRING; } else if (!strcasecmp(name, "proxy")) { *key = CURLOPT_PROXY; *ot = OT_STRING; @@ -390,16 +398,18 @@ yuck: return -1; } - /* Remove any existing entry */ + /* Remove any existing entry, only http headers are left */ AST_LIST_LOCK(list); - AST_LIST_TRAVERSE_SAFE_BEGIN(list, cur, list) { - if (cur->key == new->key) { - AST_LIST_REMOVE_CURRENT(list); - free(cur); - break; + if (new->key != CURLOPT_HTTPHEADER) { + AST_LIST_TRAVERSE_SAFE_BEGIN(list, cur, list) { + if (cur->key == new->key) { + AST_LIST_REMOVE_CURRENT(list); + free(cur); + break; + } } + AST_LIST_TRAVERSE_SAFE_END } - AST_LIST_TRAVERSE_SAFE_END /* Insert new entry */ ast_debug(1, "Inserting entry %p with key %d and value %p\n", new, new->key, new->value); @@ -605,6 +615,7 @@ static int acf_curl_helper(struct ast_channel *chan, const char *cmd, char *info ); CURL **curl; struct curl_settings *cur; + struct curl_slist *headers = NULL; struct ast_datastore *store = NULL; int hashcompat = 0; AST_LIST_HEAD(global_curl_info, curl_settings) *list = NULL; @@ -650,6 +661,8 @@ static int acf_curl_helper(struct ast_channel *chan, const char *cmd, char *info AST_LIST_TRAVERSE(&global_curl_info, cur, list) { if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) { hashcompat = (long) cur->value; + } else if (cur->key == CURLOPT_HTTPHEADER) { + headers = curl_slist_append(headers, (char*) cur->value); } else { curl_easy_setopt(*curl, cur->key, cur->value); } @@ -666,6 +679,8 @@ static int acf_curl_helper(struct ast_channel *chan, const char *cmd, char *info AST_LIST_TRAVERSE(list, cur, list) { if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) { hashcompat = (long) cur->value; + } else if (cur->key == CURLOPT_HTTPHEADER) { + headers = curl_slist_append(headers, (char*) cur->value); } else { curl_easy_setopt(*curl, cur->key, cur->value); } @@ -681,6 +696,10 @@ static int acf_curl_helper(struct ast_channel *chan, const char *cmd, char *info curl_easy_setopt(*curl, CURLOPT_POSTFIELDS, args.postdata); } + if (headers) { + curl_easy_setopt(*curl, CURLOPT_HTTPHEADER, headers); + } + /* Temporarily assign a buffer for curl to write errors to. */ curl_errbuf[0] = curl_errbuf[CURL_ERROR_SIZE] = '\0'; curl_easy_setopt(*curl, CURLOPT_ERRORBUFFER, curl_errbuf); @@ -698,6 +717,7 @@ static int acf_curl_helper(struct ast_channel *chan, const char *cmd, char *info if (store) { AST_LIST_UNLOCK(list); } + curl_slist_free_all(headers); if (args.postdata) { curl_easy_setopt(*curl, CURLOPT_POST, 0); @@ -781,6 +801,7 @@ static struct ast_custom_function acf_curlopt = { " ftptext - For FTP, force a text transfer (boolean)\n" " ftptimeout - For FTP, the server response timeout\n" " header - Retrieve header information (boolean)\n" +" httpheader - Add new custom http header (string)\n" " httptimeout - Number of seconds to wait for HTTP response\n" " maxredirs - Maximum number of redirects to follow\n" " proxy - Hostname or IP to use as a proxy\n"