[Asterisk-code-review] func_curl.c: Support custom http headers (asterisk[16])

Martin Tomec asteriskteam at digium.com
Thu Nov 7 12:11:06 CST 2019


Martin Tomec has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/13168 )


Change subject: func_curl.c: Support custom http headers
......................................................................

func_curl.c: Support custom http headers

When user wants to send json data, the default Content-Type header
is incorect (application/x-www-form-urlencoded). This patch allows
to set any custom headers so the Content-Type header can be
overriden. User can set multiple headers by multiple calls of
curlopt(). This approach is not consistent with other parameters,
but is more readable in dialplan than one call with multiple
headers.

ASTERISK-28613

Change-Id: I4dd68c3f4e25362ef941d73a3861f58348dcfbf9
---
M funcs/func_curl.c
1 file changed, 30 insertions(+), 9 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/68/13168/1

diff --git a/funcs/func_curl.c b/funcs/func_curl.c
index 9e8f882..0f8d48a 100644
--- a/funcs/func_curl.c
+++ b/funcs/func_curl.c
@@ -121,6 +121,11 @@
 						<para>Include header information in the result
 						(boolean)</para>
 					</enum>
+					<enum name="httpheader">
+						<para>Add HTTP header. Multiple calls adds multiple headers.
+						Setting of any header will remove the default
+						"Content-Type application/x-www-form-urlencoded"</para>
+					</enum>
 					<enum name="httptimeout">
 						<para>For HTTP(S) URIs, number of seconds to wait for a
 						server response</para>
@@ -181,7 +186,7 @@
 		</syntax>
 		<description>
 			<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>
 		<see-also>
 			<ref type="function">CURL</ref>
@@ -243,6 +248,9 @@
 	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;
@@ -412,16 +420,18 @@
 		return -1;
 	}
 
-	/* Remove any existing entry */
-	AST_LIST_LOCK(list);
-	AST_LIST_TRAVERSE_SAFE_BEGIN(list, cur, list) {
-		if (cur->key == new->key) {
-			AST_LIST_REMOVE_CURRENT(list);
-			ast_free(cur);
-			break;
+	/* Remove any existing entry, only http headers are left */
+	if (new->key != CURLOPT_HTTPHEADER) {
+		AST_LIST_LOCK(list);
+		AST_LIST_TRAVERSE_SAFE_BEGIN(list, cur, list) {
+			if (cur->key == new->key) {
+				AST_LIST_REMOVE_CURRENT(list);
+				ast_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);
@@ -639,6 +649,7 @@
 	int ret = -1;
 	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;
@@ -666,6 +677,8 @@
 	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);
 		}
@@ -682,6 +695,8 @@
 			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);
 				}
@@ -697,6 +712,10 @@
 		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);
@@ -714,6 +733,7 @@
 	if (store) {
 		AST_LIST_UNLOCK(list);
 	}
+	curl_slist_free_all(headers);
 
 	if (args->postdata) {
 		curl_easy_setopt(*curl, CURLOPT_POST, 0);
@@ -841,6 +861,7 @@
 "  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"

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/13168
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 16
Gerrit-Change-Id: I4dd68c3f4e25362ef941d73a3861f58348dcfbf9
Gerrit-Change-Number: 13168
Gerrit-PatchSet: 1
Gerrit-Owner: Martin Tomec <tomec.martin at gmail.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20191107/1adc9bae/attachment.html>


More information about the asterisk-code-review mailing list