Merge "func_curl.c: Support custom http headers" into 17

17.1
Friendly Automation 6 years ago committed by Gerrit Code Review
commit ecdc5405f9

@ -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")

@ -121,6 +121,11 @@
<para>Include header information in the result <para>Include header information in the result
(boolean)</para> (boolean)</para>
</enum> </enum>
<enum name="httpheader">
<para>Add HTTP header. Multiple calls add multiple headers.
Setting of any header will remove the default
"Content-Type application/x-www-form-urlencoded"</para>
</enum>
<enum name="httptimeout"> <enum name="httptimeout">
<para>For HTTP(S) URIs, number of seconds to wait for a <para>For HTTP(S) URIs, number of seconds to wait for a
server response</para> server response</para>
@ -181,7 +186,7 @@
</syntax> </syntax>
<description> <description>
<para>Options may be set globally or per channel. Per-channel <para>Options may be set globally or per channel. Per-channel
settings will override global settings.</para> settings will override global settings. Only HTTP headers are added instead of overriding</para>
</description> </description>
<see-also> <see-also>
<ref type="function">CURL</ref> <ref type="function">CURL</ref>
@ -243,6 +248,9 @@ static int parse_curlopt_key(const char *name, CURLoption *key, enum optiontype
if (!strcasecmp(name, "header")) { if (!strcasecmp(name, "header")) {
*key = CURLOPT_HEADER; *key = CURLOPT_HEADER;
*ot = OT_BOOLEAN; *ot = OT_BOOLEAN;
} else if (!strcasecmp(name, "httpheader")) {
*key = CURLOPT_HTTPHEADER;
*ot = OT_STRING;
} else if (!strcasecmp(name, "proxy")) { } else if (!strcasecmp(name, "proxy")) {
*key = CURLOPT_PROXY; *key = CURLOPT_PROXY;
*ot = OT_STRING; *ot = OT_STRING;
@ -412,8 +420,9 @@ yuck:
return -1; return -1;
} }
/* Remove any existing entry */ /* Remove any existing entry, only http headers are left */
AST_LIST_LOCK(list); AST_LIST_LOCK(list);
if (new->key != CURLOPT_HTTPHEADER) {
AST_LIST_TRAVERSE_SAFE_BEGIN(list, cur, list) { AST_LIST_TRAVERSE_SAFE_BEGIN(list, cur, list) {
if (cur->key == new->key) { if (cur->key == new->key) {
AST_LIST_REMOVE_CURRENT(list); AST_LIST_REMOVE_CURRENT(list);
@ -422,6 +431,7 @@ yuck:
} }
} }
AST_LIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
}
/* Insert new entry */ /* Insert new entry */
ast_debug(1, "Inserting entry %p with key %d and value %p\n", new, new->key, new->value); ast_debug(1, "Inserting entry %p with key %d and value %p\n", new, new->key, new->value);
@ -639,6 +649,7 @@ static int acf_curl_helper(struct ast_channel *chan, struct curl_args *args)
int ret = -1; int ret = -1;
CURL **curl; CURL **curl;
struct curl_settings *cur; struct curl_settings *cur;
struct curl_slist *headers = NULL;
struct ast_datastore *store = NULL; struct ast_datastore *store = NULL;
int hashcompat = 0; int hashcompat = 0;
AST_LIST_HEAD(global_curl_info, curl_settings) *list = NULL; AST_LIST_HEAD(global_curl_info, curl_settings) *list = NULL;
@ -666,6 +677,8 @@ static int acf_curl_helper(struct ast_channel *chan, struct curl_args *args)
AST_LIST_TRAVERSE(&global_curl_info, cur, list) { AST_LIST_TRAVERSE(&global_curl_info, cur, list) {
if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) { if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) {
hashcompat = (long) cur->value; hashcompat = (long) cur->value;
} else if (cur->key == CURLOPT_HTTPHEADER) {
headers = curl_slist_append(headers, (char*) cur->value);
} else { } else {
curl_easy_setopt(*curl, cur->key, cur->value); curl_easy_setopt(*curl, cur->key, cur->value);
} }
@ -682,6 +695,8 @@ static int acf_curl_helper(struct ast_channel *chan, struct curl_args *args)
AST_LIST_TRAVERSE(list, cur, list) { AST_LIST_TRAVERSE(list, cur, list) {
if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) { if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) {
hashcompat = (long) cur->value; hashcompat = (long) cur->value;
} else if (cur->key == CURLOPT_HTTPHEADER) {
headers = curl_slist_append(headers, (char*) cur->value);
} else { } else {
curl_easy_setopt(*curl, cur->key, cur->value); curl_easy_setopt(*curl, cur->key, cur->value);
} }
@ -697,6 +712,10 @@ static int acf_curl_helper(struct ast_channel *chan, struct curl_args *args)
curl_easy_setopt(*curl, CURLOPT_POSTFIELDS, args->postdata); 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. */ /* Temporarily assign a buffer for curl to write errors to. */
curl_errbuf[0] = curl_errbuf[CURL_ERROR_SIZE] = '\0'; curl_errbuf[0] = curl_errbuf[CURL_ERROR_SIZE] = '\0';
curl_easy_setopt(*curl, CURLOPT_ERRORBUFFER, curl_errbuf); curl_easy_setopt(*curl, CURLOPT_ERRORBUFFER, curl_errbuf);
@ -714,6 +733,7 @@ static int acf_curl_helper(struct ast_channel *chan, struct curl_args *args)
if (store) { if (store) {
AST_LIST_UNLOCK(list); AST_LIST_UNLOCK(list);
} }
curl_slist_free_all(headers);
if (args->postdata) { if (args->postdata) {
curl_easy_setopt(*curl, CURLOPT_POST, 0); curl_easy_setopt(*curl, CURLOPT_POST, 0);
@ -841,6 +861,7 @@ static struct ast_custom_function acf_curlopt = {
" ftptext - For FTP, force a text transfer (boolean)\n" " ftptext - For FTP, force a text transfer (boolean)\n"
" ftptimeout - For FTP, the server response timeout\n" " ftptimeout - For FTP, the server response timeout\n"
" header - Retrieve header information (boolean)\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" " httptimeout - Number of seconds to wait for HTTP response\n"
" maxredirs - Maximum number of redirects to follow\n" " maxredirs - Maximum number of redirects to follow\n"
" proxy - Hostname or IP to use as a proxy\n" " proxy - Hostname or IP to use as a proxy\n"

Loading…
Cancel
Save