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 |
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 | optiontype { OT_BOOLEAN, OT_INTEGER, OT_INTEGER_MS, OT_STRING, OT_ENUM } |
Functions | |
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) |
AST_LIST_HEAD_STATIC (global_curl_info, curl_settings) | |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Load external URL",.load=load_module,.unload=unload_module,.load_pri=AST_MODPRI_REALTIME_DEPEND2,) | |
AST_THREADSTORAGE (thread_escapebuf) | |
AST_THREADSTORAGE_CUSTOM (curl_instance, curl_instance_init, curl_instance_cleanup) | |
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_custom_function | acf_curl |
static struct ast_custom_function | acf_curlopt |
static struct ast_datastore_info | curl_info |
static const char *const | global_useragent = "asterisk-libcurl-agent/1.0" |
Curl - Load a URL.
Definition in file func_curl.c.
#define CURLOPT_SPECIAL_HASHCOMPAT -500 |
Definition at line 164 of file func_curl.c.
Referenced by acf_curl_helper(), 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 161 of file func_curl.c.
enum optiontype |
Definition at line 194 of file func_curl.c.
00194 { 00195 OT_BOOLEAN, 00196 OT_INTEGER, 00197 OT_INTEGER_MS, 00198 OT_STRING, 00199 OT_ENUM, 00200 };
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 706 of file func_curl.c.
References acf_curl_helper().
00707 { 00708 return acf_curl_helper(chan, cmd, info, NULL, buf, len); 00709 }
static int acf_curl_exec | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | info, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 701 of file func_curl.c.
References acf_curl_helper().
00702 { 00703 return acf_curl_helper(chan, cmd, info, buf, NULL, len); 00704 }
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 557 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(), CURLOPT_SPECIAL_HASHCOMPAT, ast_datastore::data, LOG_ERROR, LOG_WARNING, name, pbx_builtin_setvar_helper(), S_OR, str, and url.
Referenced by acf_curl2_exec(), and acf_curl_exec().
00558 { 00559 struct ast_str *escapebuf = ast_str_thread_get(&thread_escapebuf, 16); 00560 struct ast_str *str = ast_str_create(16); 00561 int ret = -1; 00562 AST_DECLARE_APP_ARGS(args, 00563 AST_APP_ARG(url); 00564 AST_APP_ARG(postdata); 00565 ); 00566 CURL **curl; 00567 struct curl_settings *cur; 00568 struct ast_datastore *store = NULL; 00569 int hashcompat = 0; 00570 AST_LIST_HEAD(global_curl_info, curl_settings) *list = NULL; 00571 char curl_errbuf[CURL_ERROR_SIZE + 1]; /* add one to be safe */ 00572 00573 if (buf) { 00574 *buf = '\0'; 00575 } 00576 00577 if (!str) { 00578 return -1; 00579 } 00580 00581 if (!escapebuf) { 00582 ast_free(str); 00583 return -1; 00584 } 00585 00586 if (ast_strlen_zero(info)) { 00587 ast_log(LOG_WARNING, "CURL requires an argument (URL)\n"); 00588 ast_free(str); 00589 return -1; 00590 } 00591 00592 AST_STANDARD_APP_ARGS(args, info); 00593 00594 if (chan) { 00595 ast_autoservice_start(chan); 00596 } 00597 00598 if (!(curl = ast_threadstorage_get(&curl_instance, sizeof(*curl)))) { 00599 ast_log(LOG_ERROR, "Cannot allocate curl structure\n"); 00600 ast_free(str); 00601 return -1; 00602 } 00603 00604 AST_LIST_LOCK(&global_curl_info); 00605 AST_LIST_TRAVERSE(&global_curl_info, cur, list) { 00606 if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) { 00607 hashcompat = (cur->value != NULL) ? 1 : 0; 00608 } else { 00609 curl_easy_setopt(*curl, cur->key, cur->value); 00610 } 00611 } 00612 00613 if (chan && (store = ast_channel_datastore_find(chan, &curl_info, NULL))) { 00614 list = store->data; 00615 AST_LIST_LOCK(list); 00616 AST_LIST_TRAVERSE(list, cur, list) { 00617 if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) { 00618 hashcompat = (cur->value != NULL) ? 1 : 0; 00619 } else { 00620 curl_easy_setopt(*curl, cur->key, cur->value); 00621 } 00622 } 00623 } 00624 00625 curl_easy_setopt(*curl, CURLOPT_URL, args.url); 00626 curl_easy_setopt(*curl, CURLOPT_FILE, (void *) &str); 00627 00628 if (args.postdata) { 00629 curl_easy_setopt(*curl, CURLOPT_POST, 1); 00630 curl_easy_setopt(*curl, CURLOPT_POSTFIELDS, args.postdata); 00631 } 00632 00633 /* Temporarily assign a buffer for curl to write errors to. */ 00634 curl_errbuf[0] = curl_errbuf[CURL_ERROR_SIZE] = '\0'; 00635 curl_easy_setopt(*curl, CURLOPT_ERRORBUFFER, curl_errbuf); 00636 00637 if (curl_easy_perform(*curl) != 0) { 00638 ast_log(LOG_WARNING, "%s ('%s')\n", curl_errbuf, args.url); 00639 } 00640 00641 /* Reset buffer to NULL so curl doesn't try to write to it when the 00642 * buffer is deallocated. Documentation is vague about allowing NULL 00643 * here, but the source allows it. See: "typecheck: allow NULL to unset 00644 * CURLOPT_ERRORBUFFER" (62bcf005f4678a93158358265ba905bace33b834). */ 00645 curl_easy_setopt(*curl, CURLOPT_ERRORBUFFER, (char*)NULL); 00646 00647 if (store) { 00648 AST_LIST_UNLOCK(list); 00649 } 00650 AST_LIST_UNLOCK(&global_curl_info); 00651 00652 if (args.postdata) { 00653 curl_easy_setopt(*curl, CURLOPT_POST, 0); 00654 } 00655 00656 if (ast_str_strlen(str)) { 00657 ast_str_trim_blanks(str); 00658 00659 ast_debug(3, "str='%s'\n", ast_str_buffer(str)); 00660 if (hashcompat) { 00661 char *remainder = ast_str_buffer(str); 00662 char *piece; 00663 struct ast_str *fields = ast_str_create(ast_str_strlen(str) / 2); 00664 struct ast_str *values = ast_str_create(ast_str_strlen(str) / 2); 00665 int rowcount = 0; 00666 while (fields && values && (piece = strsep(&remainder, "&"))) { 00667 char *name = strsep(&piece, "="); 00668 if (piece) { 00669 ast_uri_decode(piece); 00670 } 00671 ast_uri_decode(name); 00672 ast_str_append(&fields, 0, "%s%s", rowcount ? "," : "", ast_str_set_escapecommas(&escapebuf, 0, name, INT_MAX)); 00673 ast_str_append(&values, 0, "%s%s", rowcount ? "," : "", ast_str_set_escapecommas(&escapebuf, 0, S_OR(piece, ""), INT_MAX)); 00674 rowcount++; 00675 } 00676 pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", ast_str_buffer(fields)); 00677 if (buf) { 00678 ast_copy_string(buf, ast_str_buffer(values), len); 00679 } else { 00680 ast_str_set(input_str, len, "%s", ast_str_buffer(values)); 00681 } 00682 ast_free(fields); 00683 ast_free(values); 00684 } else { 00685 if (buf) { 00686 ast_copy_string(buf, ast_str_buffer(str), len); 00687 } else { 00688 ast_str_set(input_str, len, "%s", ast_str_buffer(str)); 00689 } 00690 } 00691 ret = 0; 00692 } 00693 ast_free(str); 00694 00695 if (chan) 00696 ast_autoservice_stop(chan); 00697 00698 return ret; 00699 }
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 391 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(), ast_datastore::data, LOG_ERROR, OT_BOOLEAN, OT_INTEGER, OT_INTEGER_MS, OT_STRING, and parse_curlopt_key().
Referenced by acf_curlopt_read(), and acf_curlopt_read2().
00392 { 00393 struct ast_datastore *store; 00394 struct global_curl_info *list[2] = { &global_curl_info, NULL }; 00395 struct curl_settings *cur = NULL; 00396 CURLoption key; 00397 enum optiontype ot; 00398 int i; 00399 00400 if (parse_curlopt_key(data, &key, &ot)) { 00401 ast_log(LOG_ERROR, "Unrecognized option: '%s'\n", data); 00402 return -1; 00403 } 00404 00405 if (chan && (store = ast_channel_datastore_find(chan, &curl_info, NULL))) { 00406 list[0] = store->data; 00407 list[1] = &global_curl_info; 00408 } 00409 00410 for (i = 0; i < 2; i++) { 00411 if (!list[i]) { 00412 break; 00413 } 00414 AST_LIST_LOCK(list[i]); 00415 AST_LIST_TRAVERSE(list[i], cur, list) { 00416 if (cur->key == key) { 00417 if (ot == OT_BOOLEAN || ot == OT_INTEGER) { 00418 if (buf) { 00419 snprintf(buf, len, "%ld", (long) cur->value); 00420 } else { 00421 ast_str_set(bufstr, len, "%ld", (long) cur->value); 00422 } 00423 } else if (ot == OT_INTEGER_MS) { 00424 if ((long) cur->value % 1000 == 0) { 00425 if (buf) { 00426 snprintf(buf, len, "%ld", (long)cur->value / 1000); 00427 } else { 00428 ast_str_set(bufstr, len, "%ld", (long) cur->value / 1000); 00429 } 00430 } else { 00431 if (buf) { 00432 snprintf(buf, len, "%.3f", (double) ((long) cur->value) / 1000.0); 00433 } else { 00434 ast_str_set(bufstr, len, "%.3f", (double) ((long) cur->value) / 1000.0); 00435 } 00436 } 00437 } else if (ot == OT_STRING) { 00438 ast_debug(1, "Found entry %p, with key %d and value %p\n", cur, cur->key, cur->value); 00439 if (buf) { 00440 ast_copy_string(buf, cur->value, len); 00441 } else { 00442 ast_str_set(bufstr, 0, "%s", (char *) cur->value); 00443 } 00444 } else if (key == CURLOPT_PROXYTYPE) { 00445 if (0) { 00446 #if CURLVERSION_ATLEAST(7,15,2) 00447 } else if ((long)cur->value == CURLPROXY_SOCKS4) { 00448 if (buf) { 00449 ast_copy_string(buf, "socks4", len); 00450 } else { 00451 ast_str_set(bufstr, 0, "socks4"); 00452 } 00453 #endif 00454 #if CURLVERSION_ATLEAST(7,18,0) 00455 } else if ((long)cur->value == CURLPROXY_SOCKS4A) { 00456 if (buf) { 00457 ast_copy_string(buf, "socks4a", len); 00458 } else { 00459 ast_str_set(bufstr, 0, "socks4a"); 00460 } 00461 #endif 00462 } else if ((long)cur->value == CURLPROXY_SOCKS5) { 00463 if (buf) { 00464 ast_copy_string(buf, "socks5", len); 00465 } else { 00466 ast_str_set(bufstr, 0, "socks5"); 00467 } 00468 #if CURLVERSION_ATLEAST(7,18,0) 00469 } else if ((long)cur->value == CURLPROXY_SOCKS5_HOSTNAME) { 00470 if (buf) { 00471 ast_copy_string(buf, "socks5hostname", len); 00472 } else { 00473 ast_str_set(bufstr, 0, "socks5hostname"); 00474 } 00475 #endif 00476 #if CURLVERSION_ATLEAST(7,10,0) 00477 } else if ((long)cur->value == CURLPROXY_HTTP) { 00478 if (buf) { 00479 ast_copy_string(buf, "http", len); 00480 } else { 00481 ast_str_set(bufstr, 0, "http"); 00482 } 00483 #endif 00484 } else { 00485 if (buf) { 00486 ast_copy_string(buf, "unknown", len); 00487 } else { 00488 ast_str_set(bufstr, 0, "unknown"); 00489 } 00490 } 00491 } 00492 break; 00493 } 00494 } 00495 AST_LIST_UNLOCK(list[i]); 00496 if (cur) { 00497 break; 00498 } 00499 } 00500 00501 return cur ? 0 : -1; 00502 }
static int acf_curlopt_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 504 of file func_curl.c.
References acf_curlopt_helper().
00505 { 00506 return acf_curlopt_helper(chan, cmd, data, buf, NULL, len); 00507 }
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 509 of file func_curl.c.
References acf_curlopt_helper().
00510 { 00511 return acf_curlopt_helper(chan, cmd, data, NULL, buf, len); 00512 }
static int acf_curlopt_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | name, | |||
const char * | value | |||
) | [static] |
Definition at line 271 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(), ast_datastore::data, free, LOG_ERROR, OT_BOOLEAN, OT_ENUM, OT_INTEGER, OT_INTEGER_MS, OT_STRING, and parse_curlopt_key().
00272 { 00273 struct ast_datastore *store; 00274 struct global_curl_info *list; 00275 struct curl_settings *cur, *new = NULL; 00276 CURLoption key; 00277 enum optiontype ot; 00278 00279 if (chan) { 00280 if (!(store = ast_channel_datastore_find(chan, &curl_info, NULL))) { 00281 /* Create a new datastore */ 00282 if (!(store = ast_datastore_alloc(&curl_info, NULL))) { 00283 ast_log(LOG_ERROR, "Unable to allocate new datastore. Cannot set any CURL options\n"); 00284 return -1; 00285 } 00286 00287 if (!(list = ast_calloc(1, sizeof(*list)))) { 00288 ast_log(LOG_ERROR, "Unable to allocate list head. Cannot set any CURL options\n"); 00289 ast_datastore_free(store); 00290 return -1; 00291 } 00292 00293 store->data = list; 00294 AST_LIST_HEAD_INIT(list); 00295 ast_channel_datastore_add(chan, store); 00296 } else { 00297 list = store->data; 00298 } 00299 } else { 00300 /* Populate the global structure */ 00301 list = &global_curl_info; 00302 } 00303 00304 if (!parse_curlopt_key(name, &key, &ot)) { 00305 if (ot == OT_BOOLEAN) { 00306 if ((new = ast_calloc(1, sizeof(*new)))) { 00307 new->value = (void *)((long) ast_true(value)); 00308 } 00309 } else if (ot == OT_INTEGER) { 00310 long tmp = atol(value); 00311 if ((new = ast_calloc(1, sizeof(*new)))) { 00312 new->value = (void *)tmp; 00313 } 00314 } else if (ot == OT_INTEGER_MS) { 00315 long tmp = atof(value) * 1000.0; 00316 if ((new = ast_calloc(1, sizeof(*new)))) { 00317 new->value = (void *)tmp; 00318 } 00319 } else if (ot == OT_STRING) { 00320 if ((new = ast_calloc(1, sizeof(*new) + strlen(value) + 1))) { 00321 new->value = (char *)new + sizeof(*new); 00322 strcpy(new->value, value); 00323 } 00324 } else if (ot == OT_ENUM) { 00325 if (key == CURLOPT_PROXYTYPE) { 00326 long ptype = 00327 #if CURLVERSION_ATLEAST(7,10,0) 00328 CURLPROXY_HTTP; 00329 #else 00330 CURLPROXY_SOCKS5; 00331 #endif 00332 if (0) { 00333 #if CURLVERSION_ATLEAST(7,15,2) 00334 } else if (!strcasecmp(value, "socks4")) { 00335 ptype = CURLPROXY_SOCKS4; 00336 #endif 00337 #if CURLVERSION_ATLEAST(7,18,0) 00338 } else if (!strcasecmp(value, "socks4a")) { 00339 ptype = CURLPROXY_SOCKS4A; 00340 #endif 00341 #if CURLVERSION_ATLEAST(7,18,0) 00342 } else if (!strcasecmp(value, "socks5")) { 00343 ptype = CURLPROXY_SOCKS5; 00344 #endif 00345 #if CURLVERSION_ATLEAST(7,18,0) 00346 } else if (!strncasecmp(value, "socks5", 6)) { 00347 ptype = CURLPROXY_SOCKS5_HOSTNAME; 00348 #endif 00349 } 00350 00351 if ((new = ast_calloc(1, sizeof(*new)))) { 00352 new->value = (void *)ptype; 00353 } 00354 } else { 00355 /* Highly unlikely */ 00356 goto yuck; 00357 } 00358 } 00359 00360 /* Memory allocation error */ 00361 if (!new) { 00362 return -1; 00363 } 00364 00365 new->key = key; 00366 } else { 00367 yuck: 00368 ast_log(LOG_ERROR, "Unrecognized option: %s\n", name); 00369 return -1; 00370 } 00371 00372 /* Remove any existing entry */ 00373 AST_LIST_LOCK(list); 00374 AST_LIST_TRAVERSE_SAFE_BEGIN(list, cur, list) { 00375 if (cur->key == new->key) { 00376 AST_LIST_REMOVE_CURRENT(list); 00377 free(cur); 00378 break; 00379 } 00380 } 00381 AST_LIST_TRAVERSE_SAFE_END 00382 00383 /* Insert new entry */ 00384 ast_debug(1, "Inserting entry %p with key %d and value %p\n", new, new->key, new->value); 00385 AST_LIST_INSERT_TAIL(list, new, list); 00386 AST_LIST_UNLOCK(list); 00387 00388 return 0; 00389 }
AST_LIST_HEAD_STATIC | ( | global_curl_info | , | |
curl_settings | ||||
) |
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_LOAD_ORDER | , | |||
"Load external URL" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | load_pri = AST_MODPRI_REALTIME_DEPEND2 | |||
) |
AST_THREADSTORAGE | ( | thread_escapebuf | ) |
AST_THREADSTORAGE_CUSTOM | ( | curl_instance | , | |
curl_instance_init | , | |||
curl_instance_cleanup | ||||
) |
static void curl_instance_cleanup | ( | void * | data | ) | [static] |
Definition at line 545 of file func_curl.c.
References ast_free.
00546 { 00547 CURL **curl = data; 00548 00549 curl_easy_cleanup(*curl); 00550 00551 ast_free(data); 00552 }
static int curl_instance_init | ( | void * | data | ) | [static] |
Definition at line 530 of file func_curl.c.
References WriteMemoryCallback().
00531 { 00532 CURL **curl = data; 00533 00534 if (!(*curl = curl_easy_init())) 00535 return -1; 00536 00537 curl_easy_setopt(*curl, CURLOPT_NOSIGNAL, 1); 00538 curl_easy_setopt(*curl, CURLOPT_TIMEOUT, 180); 00539 curl_easy_setopt(*curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 00540 curl_easy_setopt(*curl, CURLOPT_USERAGENT, global_useragent); 00541 00542 return 0; 00543 }
static void curlds_free | ( | void * | data | ) | [static] |
Definition at line 181 of file func_curl.c.
References AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_REMOVE_HEAD, and free.
00182 { 00183 AST_LIST_HEAD(global_curl_info, curl_settings) *list = data; 00184 struct curl_settings *setting; 00185 if (!list) { 00186 return; 00187 } 00188 while ((setting = AST_LIST_REMOVE_HEAD(list, list))) { 00189 free(setting); 00190 } 00191 AST_LIST_HEAD_DESTROY(list); 00192 }
static int load_module | ( | void | ) | [static] |
Definition at line 760 of file func_curl.c.
References ast_custom_function_register, ast_load_resource(), ast_log(), ast_module_check(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and LOG_ERROR.
00761 { 00762 int res; 00763 00764 if (!ast_module_check("res_curl.so")) { 00765 if (ast_load_resource("res_curl.so") != AST_MODULE_LOAD_SUCCESS) { 00766 ast_log(LOG_ERROR, "Cannot load res_curl, so func_curl cannot be loaded\n"); 00767 return AST_MODULE_LOAD_DECLINE; 00768 } 00769 } 00770 00771 res = ast_custom_function_register(&acf_curl); 00772 res |= ast_custom_function_register(&acf_curlopt); 00773 00774 return res; 00775 }
static int parse_curlopt_key | ( | const char * | name, | |
CURLoption * | key, | |||
enum optiontype * | ot | |||
) | [static] |
Definition at line 202 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().
00203 { 00204 if (!strcasecmp(name, "header")) { 00205 *key = CURLOPT_HEADER; 00206 *ot = OT_BOOLEAN; 00207 } else if (!strcasecmp(name, "proxy")) { 00208 *key = CURLOPT_PROXY; 00209 *ot = OT_STRING; 00210 } else if (!strcasecmp(name, "proxyport")) { 00211 *key = CURLOPT_PROXYPORT; 00212 *ot = OT_INTEGER; 00213 } else if (!strcasecmp(name, "proxytype")) { 00214 *key = CURLOPT_PROXYTYPE; 00215 *ot = OT_ENUM; 00216 } else if (!strcasecmp(name, "dnstimeout")) { 00217 *key = CURLOPT_DNS_CACHE_TIMEOUT; 00218 *ot = OT_INTEGER; 00219 } else if (!strcasecmp(name, "userpwd")) { 00220 *key = CURLOPT_USERPWD; 00221 *ot = OT_STRING; 00222 } else if (!strcasecmp(name, "proxyuserpwd")) { 00223 *key = CURLOPT_PROXYUSERPWD; 00224 *ot = OT_STRING; 00225 } else if (!strcasecmp(name, "maxredirs")) { 00226 *key = CURLOPT_MAXREDIRS; 00227 *ot = OT_INTEGER; 00228 } else if (!strcasecmp(name, "referer")) { 00229 *key = CURLOPT_REFERER; 00230 *ot = OT_STRING; 00231 } else if (!strcasecmp(name, "useragent")) { 00232 *key = CURLOPT_USERAGENT; 00233 *ot = OT_STRING; 00234 } else if (!strcasecmp(name, "cookie")) { 00235 *key = CURLOPT_COOKIE; 00236 *ot = OT_STRING; 00237 } else if (!strcasecmp(name, "ftptimeout")) { 00238 *key = CURLOPT_FTP_RESPONSE_TIMEOUT; 00239 *ot = OT_INTEGER; 00240 } else if (!strcasecmp(name, "httptimeout")) { 00241 #if CURLVERSION_ATLEAST(7,16,2) 00242 *key = CURLOPT_TIMEOUT_MS; 00243 *ot = OT_INTEGER_MS; 00244 #else 00245 *key = CURLOPT_TIMEOUT; 00246 *ot = OT_INTEGER; 00247 #endif 00248 } else if (!strcasecmp(name, "conntimeout")) { 00249 #if CURLVERSION_ATLEAST(7,16,2) 00250 *key = CURLOPT_CONNECTTIMEOUT_MS; 00251 *ot = OT_INTEGER_MS; 00252 #else 00253 *key = CURLOPT_CONNECTTIMEOUT; 00254 *ot = OT_INTEGER; 00255 #endif 00256 } else if (!strcasecmp(name, "ftptext")) { 00257 *key = CURLOPT_TRANSFERTEXT; 00258 *ot = OT_BOOLEAN; 00259 } else if (!strcasecmp(name, "ssl_verifypeer")) { 00260 *key = CURLOPT_SSL_VERIFYPEER; 00261 *ot = OT_BOOLEAN; 00262 } else if (!strcasecmp(name, "hashcompat")) { 00263 *key = CURLOPT_SPECIAL_HASHCOMPAT; 00264 *ot = OT_BOOLEAN; 00265 } else { 00266 return -1; 00267 } 00268 return 0; 00269 }
static int unload_module | ( | void | ) | [static] |
Definition at line 750 of file func_curl.c.
References ast_custom_function_unregister().
00751 { 00752 int res; 00753 00754 res = ast_custom_function_unregister(&acf_curl); 00755 res |= ast_custom_function_unregister(&acf_curlopt); 00756 00757 return res; 00758 }
static size_t WriteMemoryCallback | ( | void * | ptr, | |
size_t | size, | |||
size_t | nmemb, | |||
void * | data | |||
) | [static] |
Definition at line 514 of file func_curl.c.
References ast_debug, ast_str_append_substr(), ast_str_size(), and ast_str_strlen().
Referenced by curl_instance_init().
00515 { 00516 register int realsize = size * nmemb; 00517 struct ast_str **pstr = (struct ast_str **)data; 00518 00519 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)); 00520 00521 ast_str_append_substr(pstr, 0, ptr, realsize); 00522 00523 ast_debug(3, "Now, len=%zu, used=%zu\n", ast_str_size(*pstr), ast_str_strlen(*pstr)); 00524 00525 return realsize; 00526 }
struct ast_custom_function acf_curl [static] |
Definition at line 711 of file func_curl.c.
struct ast_custom_function acf_curlopt [static] |
Definition at line 722 of file func_curl.c.
struct ast_datastore_info curl_info [static] |
{ .type = "CURL", .destroy = curlds_free, }
Definition at line 168 of file func_curl.c.
const char* const global_useragent = "asterisk-libcurl-agent/1.0" [static] |
Definition at line 528 of file func_curl.c.