Tue Aug 20 16:35:04 2013

Asterisk developer's documentation


func_curl.c File Reference

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"

Detailed Description

Curl - Load a URL.

Author:
Tilghman Lesher <curl-20050919@the-tilghman.com>
Note:
Brian Wilkins <bwilkins@cfl.rr.com> (Added POST option)
ExtRef:
Depends on the CURL library - http://curl.haxx.se/

Definition in file func_curl.c.


Define Documentation

#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,
 )     ((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.


Enumeration Type Documentation

enum optiontype
Enumerator:
OT_BOOLEAN 
OT_INTEGER 
OT_INTEGER_MS 
OT_STRING 
OT_ENUM 

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 };


Function Documentation

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 }


Variable Documentation

struct ast_custom_function acf_curl [static]

Definition at line 711 of file func_curl.c.

Definition at line 722 of file func_curl.c.

struct ast_datastore_info curl_info [static]
Initial value:
 {
   .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.


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1