Index: funcs/func_curl.c =================================================================== --- funcs/func_curl.c (revision 79894) +++ funcs/func_curl.c (working copy) @@ -70,16 +70,18 @@ static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) { - register int realsize = size * nmemb; + size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct *)data; + char *tmp = (char *)myrealloc(mem->memory, mem->size + realsize + 1); - mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1); - if (mem->memory) { + if (tmp) { + mem->memory = tmp; memcpy(&(mem->memory[mem->size]), ptr, realsize); mem->size += realsize; mem->memory[mem->size] = 0; - } - return realsize; + return realsize; + } else + return 0; } static const char *global_useragent = "asterisk-libcurl-agent/1.0"; @@ -96,6 +98,7 @@ static int curl_internal(struct MemoryStruct *chunk, char *url, char *post) { CURL **curl; + CURLcode res; if (!(curl = ast_threadstorage_get(&curl_instance, sizeof(*curl)))) return -1; @@ -112,23 +115,24 @@ curl_easy_setopt(*curl, CURLOPT_URL, url); curl_easy_setopt(*curl, CURLOPT_WRITEDATA, (void *) chunk); - if (post) { + if (!ast_strlen_zero(post)) { curl_easy_setopt(*curl, CURLOPT_POST, 1); curl_easy_setopt(*curl, CURLOPT_POSTFIELDS, post); } - curl_easy_perform(*curl); + res = curl_easy_perform(*curl); - if (post) + if (!ast_strlen_zero(post)) curl_easy_setopt(*curl, CURLOPT_POST, 0); - return 0; + return res ? (int)res : 0; } static int acf_curl_exec(struct ast_channel *chan, char *cmd, char *info, char *buf, size_t len) { struct ast_module_user *u; struct MemoryStruct chunk = { NULL, 0 }; + int res; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(url); AST_APP_ARG(postdata); @@ -138,6 +142,8 @@ if (ast_strlen_zero(info)) { ast_log(LOG_WARNING, "CURL requires an argument (URL)\n"); + pbx_builtin_setvar_helper(chan, "CURLSTATUS", "FAILURE"); + pbx_builtin_setvar_helper(chan, "CURLCODE", "-1"); return -1; } @@ -145,7 +151,7 @@ AST_STANDARD_APP_ARGS(args, info); - if (!curl_internal(&chunk, args.url, args.postdata)) { + if (!(res = curl_internal(&chunk, args.url, args.postdata))) { if (chunk.memory) { chunk.memory[chunk.size] = '\0'; if (chunk.memory[chunk.size - 1] == 10) @@ -154,7 +160,16 @@ ast_copy_string(buf, chunk.memory, len); free(chunk.memory); } + pbx_builtin_setvar_helper(chan, "CURLSTATUS", "OK"); + } else if (res > 0) { + char tmp[12]; + snprintf(tmp, sizeof(tmp), "%d", (int)res); + pbx_builtin_setvar_helper(chan, "CURLCODE", tmp); + pbx_builtin_setvar_helper(chan, "CURLSTATUS", "FAILURE"); + ast_log(LOG_WARNING, "Internal CURL error: %s\n", curl_easy_strerror(res)); } else { + pbx_builtin_setvar_helper(chan, "CURLSTATUS", "FAILURE"); + pbx_builtin_setvar_helper(chan, "CURLCODE", "-1"); ast_log(LOG_ERROR, "Cannot allocate curl structure\n"); } @@ -169,7 +184,9 @@ .syntax = "CURL(url[|post-data])", .desc = " url - URL to retrieve\n" - " post-data - Optional data to send as a POST (GET is default action)\n", + " post-data - Optional data to send as a POST (GET is default action)\n\n" + "CURLSTATUS will contain OK or FAILURE. If FAILURE, CURLCODE will be set\n" + "with the internal libcurl error code (or -1 on failure to initialize).\n", .read = acf_curl_exec, };