From bbd860dc6578fd1a7f62ebdd7e2c8e5d9869d38f Mon Sep 17 00:00:00 2001 From: Tilghman Lesher Date: Wed, 24 Sep 2008 06:43:05 +0000 Subject: Create a 'hashcompat' option that permits the results of a CURL() able to be passed directly into the HASH() function. Requested via the -users list, and committed at Astricon in the Code Zone. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@144199 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- funcs/func_curl.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) (limited to 'funcs') diff --git a/funcs/func_curl.c b/funcs/func_curl.c index 47f0bb9b6..107b4e11e 100644 --- a/funcs/func_curl.c +++ b/funcs/func_curl.c @@ -53,6 +53,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define CURLVERSION_ATLEAST(a,b,c) \ ((LIBCURL_VERSION_MAJOR > (a)) || ((LIBCURL_VERSION_MAJOR == (a)) && (LIBCURL_VERSION_MINOR > (b))) || ((LIBCURL_VERSION_MAJOR == (a)) && (LIBCURL_VERSION_MINOR == (b)) && (LIBCURL_VERSION_PATCH >= (c)))) +#define CURLOPT_SPECIAL_HASHCOMPAT -500 + static void curlds_free(void *data); static struct ast_datastore_info curl_info = { @@ -146,6 +148,9 @@ static int parse_curlopt_key(const char *name, CURLoption *key, enum optiontype } else if (!strcasecmp(name, "ftptext")) { *key = CURLOPT_TRANSFERTEXT; *ot = OT_BOOLEAN; + } else if (!strcasecmp(name, "hashcompat")) { + *key = CURLOPT_SPECIAL_HASHCOMPAT; + *ot = OT_BOOLEAN; } else { return -1; } @@ -351,7 +356,7 @@ static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *da ast_debug(3, "Called with data=%p, str=%p, realsize=%d, len=%zu, used=%zu\n", data, *pstr, realsize, (*pstr)->len, (*pstr)->used); - if (ast_str_make_space(pstr, (((*pstr)->used + realsize + 1) / 512 + 1) * 512 + 470) == 0) { + if (ast_str_make_space(pstr, (((*pstr)->used + realsize + 1) / 512 + 1) * 512 + 230) == 0) { memcpy(&((*pstr)->str[(*pstr)->used]), ptr, realsize); (*pstr)->used += realsize; } @@ -399,6 +404,7 @@ static int acf_curl_exec(struct ast_channel *chan, const char *cmd, char *info, CURL **curl; struct curl_settings *cur; struct ast_datastore *store = NULL; + int hashcompat = 0; AST_LIST_HEAD(global_curl_info, curl_settings) *list = NULL; *buf = '\0'; @@ -422,14 +428,22 @@ static int acf_curl_exec(struct ast_channel *chan, const char *cmd, char *info, AST_LIST_LOCK(&global_curl_info); AST_LIST_TRAVERSE(&global_curl_info, cur, list) { - curl_easy_setopt(*curl, cur->key, cur->value); + if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) { + hashcompat = (cur->value != NULL) ? 1 : 0; + } else { + curl_easy_setopt(*curl, cur->key, cur->value); + } } if (chan && (store = ast_channel_datastore_find(chan, &curl_info, NULL))) { list = store->data; AST_LIST_LOCK(list); AST_LIST_TRAVERSE(list, cur, list) { - curl_easy_setopt(*curl, cur->key, cur->value); + if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) { + hashcompat = (cur->value != NULL) ? 1 : 0; + } else { + curl_easy_setopt(*curl, cur->key, cur->value); + } } } @@ -458,7 +472,28 @@ static int acf_curl_exec(struct ast_channel *chan, const char *cmd, char *info, str->str[str->used - 1] = '\0'; } - ast_copy_string(buf, str->str, len); + ast_log(LOG_NOTICE, "str='%s'\n", str->str); + if (hashcompat) { + char *remainder = str->str; + char *piece; + struct ast_str *fields = ast_str_create(str->used / 2); + struct ast_str *values = ast_str_create(str->used / 2); + int rowcount = 0; + while ((piece = strsep(&remainder, "&"))) { + char *name = strsep(&piece, "="); + ast_uri_decode(piece); + ast_uri_decode(name); + ast_str_append(&fields, 0, "%s%s", rowcount ? "," : "", name); + ast_str_append(&values, 0, "%s%s", rowcount ? "," : "", piece); + rowcount++; + } + pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", fields->str); + ast_copy_string(buf, values->str, len); + ast_free(fields); + ast_free(values); + } else { + ast_copy_string(buf, str->str, len); + } } ast_free(str); @@ -498,6 +533,7 @@ struct ast_custom_function acf_curlopt = { " referer - Referer URL to use for the request\n" " useragent - UserAgent string to use\n" " userpwd - A : to use for authentication\n" +" hashcompat - Result data will be compatible for use with HASH()\n" "", .read = acf_curlopt_read, .write = acf_curlopt_write, -- cgit v1.2.3