Curl - Load a URL. More...
#include "asterisk.h"#include <curl/curl.h>#include "asterisk/lock.h"#include "asterisk/file.h"#include "asterisk/channel.h"#include "asterisk/pbx.h"#include "asterisk/cli.h"#include "asterisk/module.h"#include "asterisk/app.h"#include "asterisk/utils.h"#include "asterisk/threadstorage.h"
Go to the source code of this file.
Data Structures | |
| struct | curl_settings |
| struct | global_curl_info |
Defines | |
| #define | CURLOPT_SPECIAL_HASHCOMPAT -500 |
| #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)))) |
Enumerations | |
| enum | hashcompat { HASHCOMPAT_NO = 0, HASHCOMPAT_YES, HASHCOMPAT_LEGACY } |
| enum | optiontype { OT_BOOLEAN, OT_INTEGER, OT_INTEGER_MS, OT_STRING, OT_ENUM } |
Functions | |
| static void | __init_curl_instance (void) |
| static void | __init_thread_escapebuf (void) |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | acf_curl2_exec (struct ast_channel *chan, const char *cmd, char *info, struct ast_str **buf, ssize_t len) |
| static int | acf_curl_exec (struct ast_channel *chan, const char *cmd, char *info, char *buf, size_t len) |
| static int | acf_curl_helper (struct ast_channel *chan, const char *cmd, char *info, char *buf, struct ast_str **input_str, ssize_t len) |
| static int | acf_curlopt_helper (struct ast_channel *chan, const char *cmd, char *data, char *buf, struct ast_str **bufstr, ssize_t len) |
| static int | acf_curlopt_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| static int | acf_curlopt_read2 (struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len) |
| static int | acf_curlopt_write (struct ast_channel *chan, const char *cmd, char *name, const char *value) |
| static void | curl_instance_cleanup (void *data) |
| static int | curl_instance_init (void *data) |
| static void | curlds_free (void *data) |
| static int | load_module (void) |
| static int | parse_curlopt_key (const char *name, CURLoption *key, enum optiontype *ot) |
| static int | unload_module (void) |
| static size_t | WriteMemoryCallback (void *ptr, size_t size, size_t nmemb, void *data) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Load external URL" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DEPEND2, } |
| static struct ast_custom_function | acf_curl |
| static struct ast_custom_function | acf_curlopt |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ast_datastore_info | curl_info |
| static struct ast_threadstorage | curl_instance = { .once = PTHREAD_ONCE_INIT , .key_init = __init_curl_instance , .custom_init = curl_instance_init , } |
| struct global_curl_info | global_curl_info |
| static const char *const | global_useragent = "asterisk-libcurl-agent/1.0" |
| static struct ast_threadstorage | thread_escapebuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_escapebuf , .custom_init = NULL , } |
Curl - Load a URL.
Definition in file func_curl.c.
| #define CURLOPT_SPECIAL_HASHCOMPAT -500 |
Definition at line 173 of file func_curl.c.
Referenced by acf_curl_helper(), acf_curlopt_helper(), acf_curlopt_write(), and parse_curlopt_key().
| #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)))) |
Definition at line 170 of file func_curl.c.
| enum hashcompat |
Definition at line 211 of file func_curl.c.
{
HASHCOMPAT_NO = 0,
HASHCOMPAT_YES,
HASHCOMPAT_LEGACY,
};
| enum optiontype |
Definition at line 203 of file func_curl.c.
{
OT_BOOLEAN,
OT_INTEGER,
OT_INTEGER_MS,
OT_STRING,
OT_ENUM,
};
| static void __init_curl_instance | ( | void | ) | [static] |
Definition at line 567 of file func_curl.c.
{
| static void __init_thread_escapebuf | ( | void | ) | [static] |
Definition at line 568 of file func_curl.c.
{
| static void __reg_module | ( | void | ) | [static] |
Definition at line 796 of file func_curl.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 796 of file func_curl.c.
| static int acf_curl2_exec | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | info, | ||
| struct ast_str ** | buf, | ||
| ssize_t | len | ||
| ) | [static] |
Definition at line 720 of file func_curl.c.
References acf_curl_helper().
{
return acf_curl_helper(chan, cmd, info, NULL, buf, len);
}
| static int acf_curl_exec | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | info, | ||
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
Definition at line 715 of file func_curl.c.
References acf_curl_helper().
{
return acf_curl_helper(chan, cmd, info, buf, NULL, len);
}
| static int acf_curl_helper | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | info, | ||
| char * | buf, | ||
| struct ast_str ** | input_str, | ||
| ssize_t | len | ||
| ) | [static] |
Definition at line 570 of file func_curl.c.
References args, AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_datastore_find(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_free, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_str_set_escapecommas(), ast_str_strlen(), ast_str_thread_get(), ast_str_trim_blanks(), ast_strlen_zero(), ast_threadstorage_get(), ast_uri_decode(), ast_uri_http, ast_uri_http_legacy, curl_instance, CURLOPT_SPECIAL_HASHCOMPAT, ast_datastore::data, HASHCOMPAT_LEGACY, curl_settings::key, curl_settings::list, LOG_ERROR, LOG_WARNING, name, pbx_builtin_setvar_helper(), S_OR, str, thread_escapebuf, url, and curl_settings::value.
Referenced by acf_curl2_exec(), and acf_curl_exec().
{
struct ast_str *escapebuf = ast_str_thread_get(&thread_escapebuf, 16);
struct ast_str *str = ast_str_create(16);
int ret = -1;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(url);
AST_APP_ARG(postdata);
);
CURL **curl;
struct curl_settings *cur;
struct ast_datastore *store = NULL;
int hashcompat = 0;
AST_LIST_HEAD(global_curl_info, curl_settings) *list = NULL;
char curl_errbuf[CURL_ERROR_SIZE + 1]; /* add one to be safe */
if (buf) {
*buf = '\0';
}
if (!str) {
return -1;
}
if (!escapebuf) {
ast_free(str);
return -1;
}
if (ast_strlen_zero(info)) {
ast_log(LOG_WARNING, "CURL requires an argument (URL)\n");
ast_free(str);
return -1;
}
AST_STANDARD_APP_ARGS(args, info);
if (chan) {
ast_autoservice_start(chan);
}
if (!(curl = ast_threadstorage_get(&curl_instance, sizeof(*curl)))) {
ast_log(LOG_ERROR, "Cannot allocate curl structure\n");
ast_free(str);
return -1;
}
AST_LIST_LOCK(&global_curl_info);
AST_LIST_TRAVERSE(&global_curl_info, cur, list) {
if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) {
hashcompat = (long) cur->value;
} 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) {
if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) {
hashcompat = (long) cur->value;
} else {
curl_easy_setopt(*curl, cur->key, cur->value);
}
}
}
curl_easy_setopt(*curl, CURLOPT_URL, args.url);
curl_easy_setopt(*curl, CURLOPT_FILE, (void *) &str);
if (args.postdata) {
curl_easy_setopt(*curl, CURLOPT_POST, 1);
curl_easy_setopt(*curl, CURLOPT_POSTFIELDS, args.postdata);
}
/* 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);
if (curl_easy_perform(*curl) != 0) {
ast_log(LOG_WARNING, "%s ('%s')\n", curl_errbuf, args.url);
}
/* Reset buffer to NULL so curl doesn't try to write to it when the
* buffer is deallocated. Documentation is vague about allowing NULL
* here, but the source allows it. See: "typecheck: allow NULL to unset
* CURLOPT_ERRORBUFFER" (62bcf005f4678a93158358265ba905bace33b834). */
curl_easy_setopt(*curl, CURLOPT_ERRORBUFFER, (char*)NULL);
if (store) {
AST_LIST_UNLOCK(list);
}
AST_LIST_UNLOCK(&global_curl_info);
if (args.postdata) {
curl_easy_setopt(*curl, CURLOPT_POST, 0);
}
if (ast_str_strlen(str)) {
ast_str_trim_blanks(str);
ast_debug(3, "str='%s'\n", ast_str_buffer(str));
if (hashcompat) {
char *remainder = ast_str_buffer(str);
char *piece;
struct ast_str *fields = ast_str_create(ast_str_strlen(str) / 2);
struct ast_str *values = ast_str_create(ast_str_strlen(str) / 2);
int rowcount = 0;
while (fields && values && (piece = strsep(&remainder, "&"))) {
char *name = strsep(&piece, "=");
struct ast_flags mode = (hashcompat == HASHCOMPAT_LEGACY ? ast_uri_http_legacy : ast_uri_http);
if (piece) {
ast_uri_decode(piece, mode);
}
ast_uri_decode(name, mode);
ast_str_append(&fields, 0, "%s%s", rowcount ? "," : "", ast_str_set_escapecommas(&escapebuf, 0, name, INT_MAX));
ast_str_append(&values, 0, "%s%s", rowcount ? "," : "", ast_str_set_escapecommas(&escapebuf, 0, S_OR(piece, ""), INT_MAX));
rowcount++;
}
pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", ast_str_buffer(fields));
if (buf) {
ast_copy_string(buf, ast_str_buffer(values), len);
} else {
ast_str_set(input_str, len, "%s", ast_str_buffer(values));
}
ast_free(fields);
ast_free(values);
} else {
if (buf) {
ast_copy_string(buf, ast_str_buffer(str), len);
} else {
ast_str_set(input_str, len, "%s", ast_str_buffer(str));
}
}
ret = 0;
}
ast_free(str);
if (chan)
ast_autoservice_stop(chan);
return ret;
}
| static int acf_curlopt_helper | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| char * | buf, | ||
| struct ast_str ** | bufstr, | ||
| ssize_t | len | ||
| ) | [static] |
Definition at line 410 of file func_curl.c.
References ast_channel_datastore_find(), ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_str_set(), CURLOPT_SPECIAL_HASHCOMPAT, ast_datastore::data, global_curl_info, HASHCOMPAT_LEGACY, HASHCOMPAT_NO, HASHCOMPAT_YES, curl_settings::key, curl_settings::list, LOG_ERROR, OT_BOOLEAN, OT_INTEGER, OT_INTEGER_MS, OT_STRING, parse_curlopt_key(), and curl_settings::value.
Referenced by acf_curlopt_read(), and acf_curlopt_read2().
{
struct ast_datastore *store;
struct global_curl_info *list[2] = { &global_curl_info, NULL };
struct curl_settings *cur = NULL;
CURLoption key;
enum optiontype ot;
int i;
if (parse_curlopt_key(data, &key, &ot)) {
ast_log(LOG_ERROR, "Unrecognized option: '%s'\n", data);
return -1;
}
if (chan && (store = ast_channel_datastore_find(chan, &curl_info, NULL))) {
list[0] = store->data;
list[1] = &global_curl_info;
}
for (i = 0; i < 2; i++) {
if (!list[i]) {
break;
}
AST_LIST_LOCK(list[i]);
AST_LIST_TRAVERSE(list[i], cur, list) {
if (cur->key == key) {
if (ot == OT_BOOLEAN || ot == OT_INTEGER) {
if (buf) {
snprintf(buf, len, "%ld", (long) cur->value);
} else {
ast_str_set(bufstr, len, "%ld", (long) cur->value);
}
} else if (ot == OT_INTEGER_MS) {
if ((long) cur->value % 1000 == 0) {
if (buf) {
snprintf(buf, len, "%ld", (long)cur->value / 1000);
} else {
ast_str_set(bufstr, len, "%ld", (long) cur->value / 1000);
}
} else {
if (buf) {
snprintf(buf, len, "%.3f", (double) ((long) cur->value) / 1000.0);
} else {
ast_str_set(bufstr, len, "%.3f", (double) ((long) cur->value) / 1000.0);
}
}
} else if (ot == OT_STRING) {
ast_debug(1, "Found entry %p, with key %d and value %p\n", cur, cur->key, cur->value);
if (buf) {
ast_copy_string(buf, cur->value, len);
} else {
ast_str_set(bufstr, 0, "%s", (char *) cur->value);
}
} else if (key == CURLOPT_PROXYTYPE) {
const char *strval = "unknown";
if (0) {
#if CURLVERSION_ATLEAST(7,15,2)
} else if ((long)cur->value == CURLPROXY_SOCKS4) {
strval = "socks4";
#endif
#if CURLVERSION_ATLEAST(7,18,0)
} else if ((long)cur->value == CURLPROXY_SOCKS4A) {
strval = "socks4a";
#endif
} else if ((long)cur->value == CURLPROXY_SOCKS5) {
strval = "socks5";
#if CURLVERSION_ATLEAST(7,18,0)
} else if ((long)cur->value == CURLPROXY_SOCKS5_HOSTNAME) {
strval = "socks5hostname";
#endif
#if CURLVERSION_ATLEAST(7,10,0)
} else if ((long)cur->value == CURLPROXY_HTTP) {
strval = "http";
#endif
}
if (buf) {
ast_copy_string(buf, strval, len);
} else {
ast_str_set(bufstr, 0, "%s", strval);
}
} else if (key == CURLOPT_SPECIAL_HASHCOMPAT) {
const char *strval = "unknown";
if ((long) cur->value == HASHCOMPAT_LEGACY) {
strval = "legacy";
} else if ((long) cur->value == HASHCOMPAT_YES) {
strval = "yes";
} else if ((long) cur->value == HASHCOMPAT_NO) {
strval = "no";
}
if (buf) {
ast_copy_string(buf, strval, len);
} else {
ast_str_set(bufstr, 0, "%s", strval);
}
}
break;
}
}
AST_LIST_UNLOCK(list[i]);
if (cur) {
break;
}
}
return cur ? 0 : -1;
}
| static int acf_curlopt_read | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
Definition at line 517 of file func_curl.c.
References acf_curlopt_helper().
{
return acf_curlopt_helper(chan, cmd, data, buf, NULL, len);
}
| static int acf_curlopt_read2 | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| struct ast_str ** | buf, | ||
| ssize_t | len | ||
| ) | [static] |
Definition at line 522 of file func_curl.c.
References acf_curlopt_helper().
{
return acf_curlopt_helper(chan, cmd, data, NULL, buf, len);
}
| static int acf_curlopt_write | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | name, | ||
| const char * | value | ||
| ) | [static] |
Definition at line 286 of file func_curl.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc(), ast_datastore_free(), ast_debug, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_true(), CURLOPT_SPECIAL_HASHCOMPAT, ast_datastore::data, free, global_curl_info, HASHCOMPAT_LEGACY, HASHCOMPAT_NO, HASHCOMPAT_YES, curl_settings::key, curl_settings::list, LOG_ERROR, OT_BOOLEAN, OT_ENUM, OT_INTEGER, OT_INTEGER_MS, OT_STRING, and parse_curlopt_key().
{
struct ast_datastore *store;
struct global_curl_info *list;
struct curl_settings *cur, *new = NULL;
CURLoption key;
enum optiontype ot;
if (chan) {
if (!(store = ast_channel_datastore_find(chan, &curl_info, NULL))) {
/* Create a new datastore */
if (!(store = ast_datastore_alloc(&curl_info, NULL))) {
ast_log(LOG_ERROR, "Unable to allocate new datastore. Cannot set any CURL options\n");
return -1;
}
if (!(list = ast_calloc(1, sizeof(*list)))) {
ast_log(LOG_ERROR, "Unable to allocate list head. Cannot set any CURL options\n");
ast_datastore_free(store);
return -1;
}
store->data = list;
AST_LIST_HEAD_INIT(list);
ast_channel_datastore_add(chan, store);
} else {
list = store->data;
}
} else {
/* Populate the global structure */
list = &global_curl_info;
}
if (!parse_curlopt_key(name, &key, &ot)) {
if (ot == OT_BOOLEAN) {
if ((new = ast_calloc(1, sizeof(*new)))) {
new->value = (void *)((long) ast_true(value));
}
} else if (ot == OT_INTEGER) {
long tmp = atol(value);
if ((new = ast_calloc(1, sizeof(*new)))) {
new->value = (void *)tmp;
}
} else if (ot == OT_INTEGER_MS) {
long tmp = atof(value) * 1000.0;
if ((new = ast_calloc(1, sizeof(*new)))) {
new->value = (void *)tmp;
}
} else if (ot == OT_STRING) {
if ((new = ast_calloc(1, sizeof(*new) + strlen(value) + 1))) {
new->value = (char *)new + sizeof(*new);
strcpy(new->value, value);
}
} else if (ot == OT_ENUM) {
if (key == CURLOPT_PROXYTYPE) {
long ptype =
#if CURLVERSION_ATLEAST(7,10,0)
CURLPROXY_HTTP;
#else
CURLPROXY_SOCKS5;
#endif
if (0) {
#if CURLVERSION_ATLEAST(7,15,2)
} else if (!strcasecmp(value, "socks4")) {
ptype = CURLPROXY_SOCKS4;
#endif
#if CURLVERSION_ATLEAST(7,18,0)
} else if (!strcasecmp(value, "socks4a")) {
ptype = CURLPROXY_SOCKS4A;
#endif
#if CURLVERSION_ATLEAST(7,18,0)
} else if (!strcasecmp(value, "socks5")) {
ptype = CURLPROXY_SOCKS5;
#endif
#if CURLVERSION_ATLEAST(7,18,0)
} else if (!strncasecmp(value, "socks5", 6)) {
ptype = CURLPROXY_SOCKS5_HOSTNAME;
#endif
}
if ((new = ast_calloc(1, sizeof(*new)))) {
new->value = (void *)ptype;
}
} else if (key == CURLOPT_SPECIAL_HASHCOMPAT) {
if ((new = ast_calloc(1, sizeof(*new)))) {
new->value = (void *) (long) (!strcasecmp(value, "legacy") ? HASHCOMPAT_LEGACY : ast_true(value) ? HASHCOMPAT_YES : HASHCOMPAT_NO);
}
} else {
/* Highly unlikely */
goto yuck;
}
}
/* Memory allocation error */
if (!new) {
return -1;
}
new->key = key;
} else {
yuck:
ast_log(LOG_ERROR, "Unrecognized option: %s\n", name);
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);
free(cur);
break;
}
}
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);
AST_LIST_INSERT_TAIL(list, new, list);
AST_LIST_UNLOCK(list);
return 0;
}
| static void curl_instance_cleanup | ( | void * | data | ) | [static] |
Definition at line 558 of file func_curl.c.
References ast_free.
{
CURL **curl = data;
curl_easy_cleanup(*curl);
ast_free(data);
}
| static int curl_instance_init | ( | void * | data | ) | [static] |
Definition at line 543 of file func_curl.c.
References global_useragent, and WriteMemoryCallback().
{
CURL **curl = data;
if (!(*curl = curl_easy_init()))
return -1;
curl_easy_setopt(*curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(*curl, CURLOPT_TIMEOUT, 180);
curl_easy_setopt(*curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(*curl, CURLOPT_USERAGENT, global_useragent);
return 0;
}
| static void curlds_free | ( | void * | data | ) | [static] |
Definition at line 190 of file func_curl.c.
References AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_REMOVE_HEAD, and free.
{
AST_LIST_HEAD(global_curl_info, curl_settings) *list = data;
struct curl_settings *setting;
if (!list) {
return;
}
while ((setting = AST_LIST_REMOVE_HEAD(list, list))) {
free(setting);
}
AST_LIST_HEAD_DESTROY(list);
}
| static int load_module | ( | void | ) | [static] |
Definition at line 775 of file func_curl.c.
References acf_curl, acf_curlopt, ast_custom_function_register, ast_load_resource(), ast_log(), ast_module_check(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and LOG_ERROR.
{
int res;
if (!ast_module_check("res_curl.so")) {
if (ast_load_resource("res_curl.so") != AST_MODULE_LOAD_SUCCESS) {
ast_log(LOG_ERROR, "Cannot load res_curl, so func_curl cannot be loaded\n");
return AST_MODULE_LOAD_DECLINE;
}
}
res = ast_custom_function_register(&acf_curl);
res |= ast_custom_function_register(&acf_curlopt);
return res;
}
| static int parse_curlopt_key | ( | const char * | name, |
| CURLoption * | key, | ||
| enum optiontype * | ot | ||
| ) | [static] |
Definition at line 217 of file func_curl.c.
References CURLOPT_SPECIAL_HASHCOMPAT, OT_BOOLEAN, OT_ENUM, OT_INTEGER, OT_INTEGER_MS, and OT_STRING.
Referenced by acf_curlopt_helper(), and acf_curlopt_write().
{
if (!strcasecmp(name, "header")) {
*key = CURLOPT_HEADER;
*ot = OT_BOOLEAN;
} else if (!strcasecmp(name, "proxy")) {
*key = CURLOPT_PROXY;
*ot = OT_STRING;
} else if (!strcasecmp(name, "proxyport")) {
*key = CURLOPT_PROXYPORT;
*ot = OT_INTEGER;
} else if (!strcasecmp(name, "proxytype")) {
*key = CURLOPT_PROXYTYPE;
*ot = OT_ENUM;
} else if (!strcasecmp(name, "dnstimeout")) {
*key = CURLOPT_DNS_CACHE_TIMEOUT;
*ot = OT_INTEGER;
} else if (!strcasecmp(name, "userpwd")) {
*key = CURLOPT_USERPWD;
*ot = OT_STRING;
} else if (!strcasecmp(name, "proxyuserpwd")) {
*key = CURLOPT_PROXYUSERPWD;
*ot = OT_STRING;
} else if (!strcasecmp(name, "maxredirs")) {
*key = CURLOPT_MAXREDIRS;
*ot = OT_INTEGER;
} else if (!strcasecmp(name, "referer")) {
*key = CURLOPT_REFERER;
*ot = OT_STRING;
} else if (!strcasecmp(name, "useragent")) {
*key = CURLOPT_USERAGENT;
*ot = OT_STRING;
} else if (!strcasecmp(name, "cookie")) {
*key = CURLOPT_COOKIE;
*ot = OT_STRING;
} else if (!strcasecmp(name, "ftptimeout")) {
*key = CURLOPT_FTP_RESPONSE_TIMEOUT;
*ot = OT_INTEGER;
} else if (!strcasecmp(name, "httptimeout")) {
#if CURLVERSION_ATLEAST(7,16,2)
*key = CURLOPT_TIMEOUT_MS;
*ot = OT_INTEGER_MS;
#else
*key = CURLOPT_TIMEOUT;
*ot = OT_INTEGER;
#endif
} else if (!strcasecmp(name, "conntimeout")) {
#if CURLVERSION_ATLEAST(7,16,2)
*key = CURLOPT_CONNECTTIMEOUT_MS;
*ot = OT_INTEGER_MS;
#else
*key = CURLOPT_CONNECTTIMEOUT;
*ot = OT_INTEGER;
#endif
} else if (!strcasecmp(name, "ftptext")) {
*key = CURLOPT_TRANSFERTEXT;
*ot = OT_BOOLEAN;
} else if (!strcasecmp(name, "ssl_verifypeer")) {
*key = CURLOPT_SSL_VERIFYPEER;
*ot = OT_BOOLEAN;
} else if (!strcasecmp(name, "hashcompat")) {
*key = CURLOPT_SPECIAL_HASHCOMPAT;
*ot = OT_ENUM;
} else {
return -1;
}
return 0;
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 765 of file func_curl.c.
References acf_curl, acf_curlopt, and ast_custom_function_unregister().
{
int res;
res = ast_custom_function_unregister(&acf_curl);
res |= ast_custom_function_unregister(&acf_curlopt);
return res;
}
| static size_t WriteMemoryCallback | ( | void * | ptr, |
| size_t | size, | ||
| size_t | nmemb, | ||
| void * | data | ||
| ) | [static] |
Definition at line 527 of file func_curl.c.
References ast_debug, ast_str_append_substr(), ast_str_size(), and ast_str_strlen().
Referenced by curl_instance_init().
{
register int realsize = size * nmemb;
struct ast_str **pstr = (struct ast_str **)data;
ast_debug(3, "Called with data=%p, str=%p, realsize=%d, len=%zu, used=%zu\n", data, *pstr, realsize, ast_str_size(*pstr), ast_str_strlen(*pstr));
ast_str_append_substr(pstr, 0, ptr, realsize);
ast_debug(3, "Now, len=%zu, used=%zu\n", ast_str_size(*pstr), ast_str_strlen(*pstr));
return realsize;
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Load external URL" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DEPEND2, } [static] |
Definition at line 796 of file func_curl.c.
struct ast_custom_function acf_curl [static] |
Definition at line 725 of file func_curl.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function acf_curlopt [static] |
Definition at line 736 of file func_curl.c.
Referenced by load_module(), and unload_module().
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 796 of file func_curl.c.
struct ast_datastore_info curl_info [static] |
{
.type = "CURL",
.destroy = curlds_free,
}
Definition at line 177 of file func_curl.c.
struct ast_threadstorage curl_instance = { .once = PTHREAD_ONCE_INIT , .key_init = __init_curl_instance , .custom_init = curl_instance_init , } [static] |
Definition at line 567 of file func_curl.c.
Referenced by acf_curl_helper().
| struct global_curl_info global_curl_info |
Referenced by acf_curlopt_helper(), and acf_curlopt_write().
const char* const global_useragent = "asterisk-libcurl-agent/1.0" [static] |
Definition at line 541 of file func_curl.c.
Referenced by curl_instance_init().
struct ast_threadstorage thread_escapebuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_escapebuf , .custom_init = NULL , } [static] |
Definition at line 568 of file func_curl.c.
Referenced by acf_curl_helper().