Mon Mar 19 11:30:48 2012

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
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  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 = "88eaa8f5c1bd988bedd71113385e0886" , .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_infoast_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 , }
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 , }


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 57 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 54 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 87 of file func_curl.c.

00087                 {
00088    OT_BOOLEAN,
00089    OT_INTEGER,
00090    OT_INTEGER_MS,
00091    OT_STRING,
00092    OT_ENUM,
00093 };


Function Documentation

static void __init_curl_instance ( void   )  [static]

Definition at line 446 of file func_curl.c.

00450 {

static void __init_thread_escapebuf ( void   )  [static]

Definition at line 447 of file func_curl.c.

00450 {

static void __reg_module ( void   )  [static]

Definition at line 659 of file func_curl.c.

static void __unreg_module ( void   )  [static]

Definition at line 659 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 584 of file func_curl.c.

References acf_curl_helper().

00585 {
00586    return acf_curl_helper(chan, cmd, info, NULL, buf, len);
00587 }

static int acf_curl_exec ( struct ast_channel chan,
const char *  cmd,
char *  info,
char *  buf,
size_t  len 
) [static]

Definition at line 579 of file func_curl.c.

References acf_curl_helper().

00580 {
00581    return acf_curl_helper(chan, cmd, info, buf, NULL, len);
00582 }

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 449 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(), curl_info, curl_instance, CURLOPT_SPECIAL_HASHCOMPAT, ast_datastore::data, curl_settings::key, curl_settings::list, LOG_ERROR, LOG_WARNING, name, pbx_builtin_setvar_helper(), S_OR, str, strsep(), thread_escapebuf, url, and curl_settings::value.

Referenced by acf_curl2_exec(), and acf_curl_exec().

00450 {
00451    struct ast_str *escapebuf = ast_str_thread_get(&thread_escapebuf, 16);
00452    struct ast_str *str = ast_str_create(16);
00453    int ret = -1;
00454    AST_DECLARE_APP_ARGS(args,
00455       AST_APP_ARG(url);
00456       AST_APP_ARG(postdata);
00457    );
00458    CURL **curl;
00459    struct curl_settings *cur;
00460    struct ast_datastore *store = NULL;
00461    int hashcompat = 0;
00462    AST_LIST_HEAD(global_curl_info, curl_settings) *list = NULL;
00463 
00464    if (buf) {
00465       *buf = '\0';
00466    }
00467 
00468    if (!str) {
00469       return -1;
00470    }
00471 
00472    if (!escapebuf) {
00473       ast_free(str);
00474       return -1;
00475    }
00476 
00477    if (ast_strlen_zero(info)) {
00478       ast_log(LOG_WARNING, "CURL requires an argument (URL)\n");
00479       ast_free(str);
00480       return -1;
00481    }
00482 
00483    AST_STANDARD_APP_ARGS(args, info);
00484 
00485    if (chan) {
00486       ast_autoservice_start(chan);
00487    }
00488 
00489    if (!(curl = ast_threadstorage_get(&curl_instance, sizeof(*curl)))) {
00490       ast_log(LOG_ERROR, "Cannot allocate curl structure\n");
00491       return -1;
00492    }
00493 
00494    AST_LIST_LOCK(&global_curl_info);
00495    AST_LIST_TRAVERSE(&global_curl_info, cur, list) {
00496       if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) {
00497          hashcompat = (cur->value != NULL) ? 1 : 0;
00498       } else {
00499          curl_easy_setopt(*curl, cur->key, cur->value);
00500       }
00501    }
00502 
00503    if (chan && (store = ast_channel_datastore_find(chan, &curl_info, NULL))) {
00504       list = store->data;
00505       AST_LIST_LOCK(list);
00506       AST_LIST_TRAVERSE(list, cur, list) {
00507          if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) {
00508             hashcompat = (cur->value != NULL) ? 1 : 0;
00509          } else {
00510             curl_easy_setopt(*curl, cur->key, cur->value);
00511          }
00512       }
00513    }
00514 
00515    curl_easy_setopt(*curl, CURLOPT_URL, args.url);
00516    curl_easy_setopt(*curl, CURLOPT_FILE, (void *) &str);
00517 
00518    if (args.postdata) {
00519       curl_easy_setopt(*curl, CURLOPT_POST, 1);
00520       curl_easy_setopt(*curl, CURLOPT_POSTFIELDS, args.postdata);
00521    }
00522 
00523    curl_easy_perform(*curl);
00524 
00525    if (store) {
00526       AST_LIST_UNLOCK(list);
00527    }
00528    AST_LIST_UNLOCK(&global_curl_info);
00529 
00530    if (args.postdata) {
00531       curl_easy_setopt(*curl, CURLOPT_POST, 0);
00532    }
00533 
00534    if (ast_str_strlen(str)) {
00535       ast_str_trim_blanks(str);
00536 
00537       ast_debug(3, "str='%s'\n", ast_str_buffer(str));
00538       if (hashcompat) {
00539          char *remainder = ast_str_buffer(str);
00540          char *piece;
00541          struct ast_str *fields = ast_str_create(ast_str_strlen(str) / 2);
00542          struct ast_str *values = ast_str_create(ast_str_strlen(str) / 2);
00543          int rowcount = 0;
00544          while (fields && values && (piece = strsep(&remainder, "&"))) {
00545             char *name = strsep(&piece, "=");
00546             if (piece) {
00547                ast_uri_decode(piece);
00548             }
00549             ast_uri_decode(name);
00550             ast_str_append(&fields, 0, "%s%s", rowcount ? "," : "", ast_str_set_escapecommas(&escapebuf, 0, name, INT_MAX));
00551             ast_str_append(&values, 0, "%s%s", rowcount ? "," : "", ast_str_set_escapecommas(&escapebuf, 0, S_OR(piece, ""), INT_MAX));
00552             rowcount++;
00553          }
00554          pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", ast_str_buffer(fields));
00555          if (buf) {
00556             ast_copy_string(buf, ast_str_buffer(values), len);
00557          } else {
00558             ast_str_set(input_str, len, "%s", ast_str_buffer(values));
00559          }
00560          ast_free(fields);
00561          ast_free(values);
00562       } else {
00563          if (buf) {
00564             ast_copy_string(buf, ast_str_buffer(str), len);
00565          } else {
00566             ast_str_set(input_str, len, "%s", ast_str_buffer(str));
00567          }
00568       }
00569       ret = 0;
00570    }
00571    ast_free(str);
00572 
00573    if (chan)
00574       ast_autoservice_stop(chan);
00575 
00576    return ret;
00577 }

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 283 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(), curl_info, ast_datastore::data, 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().

00284 {
00285    struct ast_datastore *store;
00286    struct global_curl_info *list[2] = { &global_curl_info, NULL };
00287    struct curl_settings *cur = NULL;
00288    CURLoption key;
00289    enum optiontype ot;
00290    int i;
00291 
00292    if (parse_curlopt_key(data, &key, &ot)) {
00293       ast_log(LOG_ERROR, "Unrecognized option: '%s'\n", data);
00294       return -1;
00295    }
00296 
00297    if (chan && (store = ast_channel_datastore_find(chan, &curl_info, NULL))) {
00298       list[0] = store->data;
00299       list[1] = &global_curl_info;
00300    }
00301 
00302    for (i = 0; i < 2; i++) {
00303       if (!list[i]) {
00304          break;
00305       }
00306       AST_LIST_LOCK(list[i]);
00307       AST_LIST_TRAVERSE(list[i], cur, list) {
00308          if (cur->key == key) {
00309             if (ot == OT_BOOLEAN || ot == OT_INTEGER) {
00310                if (buf) {
00311                   snprintf(buf, len, "%ld", (long) cur->value);
00312                } else {
00313                   ast_str_set(bufstr, len, "%ld", (long) cur->value);
00314                }
00315             } else if (ot == OT_INTEGER_MS) {
00316                if ((long) cur->value % 1000 == 0) {
00317                   if (buf) {
00318                      snprintf(buf, len, "%ld", (long)cur->value / 1000);
00319                   } else {
00320                      ast_str_set(bufstr, len, "%ld", (long) cur->value / 1000);
00321                   }
00322                } else {
00323                   if (buf) {
00324                      snprintf(buf, len, "%.3f", (double) ((long) cur->value) / 1000.0);
00325                   } else {
00326                      ast_str_set(bufstr, len, "%.3f", (double) ((long) cur->value) / 1000.0);
00327                   }
00328                }
00329             } else if (ot == OT_STRING) {
00330                ast_debug(1, "Found entry %p, with key %d and value %p\n", cur, cur->key, cur->value);
00331                if (buf) {
00332                   ast_copy_string(buf, cur->value, len);
00333                } else {
00334                   ast_str_set(bufstr, 0, "%s", (char *) cur->value);
00335                }
00336             } else if (key == CURLOPT_PROXYTYPE) {
00337                if (0) {
00338 #if CURLVERSION_ATLEAST(7,15,2)
00339                } else if ((long)cur->value == CURLPROXY_SOCKS4) {
00340                   if (buf) {
00341                      ast_copy_string(buf, "socks4", len);
00342                   } else {
00343                      ast_str_set(bufstr, 0, "socks4");
00344                   }
00345 #endif
00346 #if CURLVERSION_ATLEAST(7,18,0)
00347                } else if ((long)cur->value == CURLPROXY_SOCKS4A) {
00348                   if (buf) {
00349                      ast_copy_string(buf, "socks4a", len);
00350                   } else {
00351                      ast_str_set(bufstr, 0, "socks4a");
00352                   }
00353 #endif
00354                } else if ((long)cur->value == CURLPROXY_SOCKS5) {
00355                   if (buf) {
00356                      ast_copy_string(buf, "socks5", len);
00357                   } else {
00358                      ast_str_set(bufstr, 0, "socks5");
00359                   }
00360 #if CURLVERSION_ATLEAST(7,18,0)
00361                } else if ((long)cur->value == CURLPROXY_SOCKS5_HOSTNAME) {
00362                   if (buf) {
00363                      ast_copy_string(buf, "socks5hostname", len);
00364                   } else {
00365                      ast_str_set(bufstr, 0, "socks5hostname");
00366                   }
00367 #endif
00368 #if CURLVERSION_ATLEAST(7,10,0)
00369                } else if ((long)cur->value == CURLPROXY_HTTP) {
00370                   if (buf) {
00371                      ast_copy_string(buf, "http", len);
00372                   } else {
00373                      ast_str_set(bufstr, 0, "http");
00374                   }
00375 #endif
00376                } else {
00377                   if (buf) {
00378                      ast_copy_string(buf, "unknown", len);
00379                   } else {
00380                      ast_str_set(bufstr, 0, "unknown");
00381                   }
00382                }
00383             }
00384             break;
00385          }
00386       }
00387       AST_LIST_UNLOCK(list[i]);
00388       if (cur) {
00389          break;
00390       }
00391    }
00392 
00393    return cur ? 0 : -1;
00394 }

static int acf_curlopt_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 396 of file func_curl.c.

References acf_curlopt_helper().

00397 {
00398    return acf_curlopt_helper(chan, cmd, data, buf, NULL, len);
00399 }

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 401 of file func_curl.c.

References acf_curlopt_helper().

00402 {
00403    return acf_curlopt_helper(chan, cmd, data, NULL, buf, len);
00404 }

static int acf_curlopt_write ( struct ast_channel chan,
const char *  cmd,
char *  name,
const char *  value 
) [static]

Definition at line 164 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(), curl_info, ast_datastore::data, free, curl_settings::key, curl_settings::list, LOG_ERROR, OT_BOOLEAN, OT_ENUM, OT_INTEGER, OT_INTEGER_MS, OT_STRING, and parse_curlopt_key().

00165 {
00166    struct ast_datastore *store;
00167    struct global_curl_info *list;
00168    struct curl_settings *cur, *new = NULL;
00169    CURLoption key;
00170    enum optiontype ot;
00171 
00172    if (chan) {
00173       if (!(store = ast_channel_datastore_find(chan, &curl_info, NULL))) {
00174          /* Create a new datastore */
00175          if (!(store = ast_datastore_alloc(&curl_info, NULL))) {
00176             ast_log(LOG_ERROR, "Unable to allocate new datastore.  Cannot set any CURL options\n");
00177             return -1;
00178          }
00179 
00180          if (!(list = ast_calloc(1, sizeof(*list)))) {
00181             ast_log(LOG_ERROR, "Unable to allocate list head.  Cannot set any CURL options\n");
00182             ast_datastore_free(store);
00183          }
00184 
00185          store->data = list;
00186          AST_LIST_HEAD_INIT(list);
00187          ast_channel_datastore_add(chan, store);
00188       } else {
00189          list = store->data;
00190       }
00191    } else {
00192       /* Populate the global structure */
00193       list = &global_curl_info;
00194    }
00195 
00196    if (!parse_curlopt_key(name, &key, &ot)) {
00197       if (ot == OT_BOOLEAN) {
00198          if ((new = ast_calloc(1, sizeof(*new)))) {
00199             new->value = (void *)((long) ast_true(value));
00200          }
00201       } else if (ot == OT_INTEGER) {
00202          long tmp = atol(value);
00203          if ((new = ast_calloc(1, sizeof(*new)))) {
00204             new->value = (void *)tmp;
00205          }
00206       } else if (ot == OT_INTEGER_MS) {
00207          long tmp = atof(value) * 1000.0;
00208          if ((new = ast_calloc(1, sizeof(*new)))) {
00209             new->value = (void *)tmp;
00210          }
00211       } else if (ot == OT_STRING) {
00212          if ((new = ast_calloc(1, sizeof(*new) + strlen(value) + 1))) {
00213             new->value = (char *)new + sizeof(*new);
00214             strcpy(new->value, value);
00215          }
00216       } else if (ot == OT_ENUM) {
00217          if (key == CURLOPT_PROXYTYPE) {
00218             long ptype =
00219 #if CURLVERSION_ATLEAST(7,10,0)
00220                CURLPROXY_HTTP;
00221 #else
00222                CURLPROXY_SOCKS5;
00223 #endif
00224             if (0) {
00225 #if CURLVERSION_ATLEAST(7,15,2)
00226             } else if (!strcasecmp(value, "socks4")) {
00227                ptype = CURLPROXY_SOCKS4;
00228 #endif
00229 #if CURLVERSION_ATLEAST(7,18,0)
00230             } else if (!strcasecmp(value, "socks4a")) {
00231                ptype = CURLPROXY_SOCKS4A;
00232 #endif
00233 #if CURLVERSION_ATLEAST(7,18,0)
00234             } else if (!strcasecmp(value, "socks5")) {
00235                ptype = CURLPROXY_SOCKS5;
00236 #endif
00237 #if CURLVERSION_ATLEAST(7,18,0)
00238             } else if (!strncasecmp(value, "socks5", 6)) {
00239                ptype = CURLPROXY_SOCKS5_HOSTNAME;
00240 #endif
00241             }
00242 
00243             if ((new = ast_calloc(1, sizeof(*new)))) {
00244                new->value = (void *)ptype;
00245             }
00246          } else {
00247             /* Highly unlikely */
00248             goto yuck;
00249          }
00250       }
00251 
00252       /* Memory allocation error */
00253       if (!new) {
00254          return -1;
00255       }
00256 
00257       new->key = key;
00258    } else {
00259 yuck:
00260       ast_log(LOG_ERROR, "Unrecognized option: %s\n", name);
00261       return -1;
00262    }
00263 
00264    /* Remove any existing entry */
00265    AST_LIST_LOCK(list);
00266    AST_LIST_TRAVERSE_SAFE_BEGIN(list, cur, list) {
00267       if (cur->key == new->key) {
00268          AST_LIST_REMOVE_CURRENT(list);
00269          free(cur);
00270          break;
00271       }
00272    }
00273    AST_LIST_TRAVERSE_SAFE_END
00274 
00275    /* Insert new entry */
00276    ast_debug(1, "Inserting entry %p with key %d and value %p\n", new, new->key, new->value);
00277    AST_LIST_INSERT_TAIL(list, new, list);
00278    AST_LIST_UNLOCK(list);
00279 
00280    return 0;
00281 }

static void curl_instance_cleanup ( void *  data  )  [static]

Definition at line 437 of file func_curl.c.

References ast_free.

00438 {
00439    CURL **curl = data;
00440 
00441    curl_easy_cleanup(*curl);
00442 
00443    ast_free(data);
00444 }

static int curl_instance_init ( void *  data  )  [static]

Definition at line 422 of file func_curl.c.

References global_useragent, and WriteMemoryCallback().

00423 {
00424    CURL **curl = data;
00425 
00426    if (!(*curl = curl_easy_init()))
00427       return -1;
00428 
00429    curl_easy_setopt(*curl, CURLOPT_NOSIGNAL, 1);
00430    curl_easy_setopt(*curl, CURLOPT_TIMEOUT, 180);
00431    curl_easy_setopt(*curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
00432    curl_easy_setopt(*curl, CURLOPT_USERAGENT, global_useragent);
00433 
00434    return 0;
00435 }

static void curlds_free ( void *  data  )  [static]

Definition at line 74 of file func_curl.c.

References AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_REMOVE_HEAD, free, and curl_settings::list.

00075 {
00076    AST_LIST_HEAD(global_curl_info, curl_settings) *list = data;
00077    struct curl_settings *setting;
00078    if (!list) {
00079       return;
00080    }
00081    while ((setting = AST_LIST_REMOVE_HEAD(list, list))) {
00082       free(setting);
00083    }
00084    AST_LIST_HEAD_DESTROY(list);
00085 }

static int load_module ( void   )  [static]

Definition at line 638 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.

00639 {
00640    int res;
00641 
00642    if (!ast_module_check("res_curl.so")) {
00643       if (ast_load_resource("res_curl.so") != AST_MODULE_LOAD_SUCCESS) {
00644          ast_log(LOG_ERROR, "Cannot load res_curl, so func_curl cannot be loaded\n");
00645          return AST_MODULE_LOAD_DECLINE;
00646       }
00647    }
00648 
00649    res = ast_custom_function_register(&acf_curl);
00650    res |= ast_custom_function_register(&acf_curlopt);
00651 
00652    return res;
00653 }

static int parse_curlopt_key ( const char *  name,
CURLoption *  key,
enum optiontype ot 
) [static]

Definition at line 95 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().

00096 {
00097    if (!strcasecmp(name, "header")) {
00098       *key = CURLOPT_HEADER;
00099       *ot = OT_BOOLEAN;
00100    } else if (!strcasecmp(name, "proxy")) {
00101       *key = CURLOPT_PROXY;
00102       *ot = OT_STRING;
00103    } else if (!strcasecmp(name, "proxyport")) {
00104       *key = CURLOPT_PROXYPORT;
00105       *ot = OT_INTEGER;
00106    } else if (!strcasecmp(name, "proxytype")) {
00107       *key = CURLOPT_PROXYTYPE;
00108       *ot = OT_ENUM;
00109    } else if (!strcasecmp(name, "dnstimeout")) {
00110       *key = CURLOPT_DNS_CACHE_TIMEOUT;
00111       *ot = OT_INTEGER;
00112    } else if (!strcasecmp(name, "userpwd")) {
00113       *key = CURLOPT_USERPWD;
00114       *ot = OT_STRING;
00115    } else if (!strcasecmp(name, "proxyuserpwd")) {
00116       *key = CURLOPT_PROXYUSERPWD;
00117       *ot = OT_STRING;
00118    } else if (!strcasecmp(name, "maxredirs")) {
00119       *key = CURLOPT_MAXREDIRS;
00120       *ot = OT_INTEGER;
00121    } else if (!strcasecmp(name, "referer")) {
00122       *key = CURLOPT_REFERER;
00123       *ot = OT_STRING;
00124    } else if (!strcasecmp(name, "useragent")) {
00125       *key = CURLOPT_USERAGENT;
00126       *ot = OT_STRING;
00127    } else if (!strcasecmp(name, "cookie")) {
00128       *key = CURLOPT_COOKIE;
00129       *ot = OT_STRING;
00130    } else if (!strcasecmp(name, "ftptimeout")) {
00131       *key = CURLOPT_FTP_RESPONSE_TIMEOUT;
00132       *ot = OT_INTEGER;
00133    } else if (!strcasecmp(name, "httptimeout")) {
00134 #if CURLVERSION_ATLEAST(7,16,2)
00135       *key = CURLOPT_TIMEOUT_MS;
00136       *ot = OT_INTEGER_MS;
00137 #else
00138       *key = CURLOPT_TIMEOUT;
00139       *ot = OT_INTEGER;
00140 #endif
00141    } else if (!strcasecmp(name, "conntimeout")) {
00142 #if CURLVERSION_ATLEAST(7,16,2)
00143       *key = CURLOPT_CONNECTTIMEOUT_MS;
00144       *ot = OT_INTEGER_MS;
00145 #else
00146       *key = CURLOPT_CONNECTTIMEOUT;
00147       *ot = OT_INTEGER;
00148 #endif
00149    } else if (!strcasecmp(name, "ftptext")) {
00150       *key = CURLOPT_TRANSFERTEXT;
00151       *ot = OT_BOOLEAN;
00152    } else if (!strcasecmp(name, "ssl_verifypeer")) {
00153       *key = CURLOPT_SSL_VERIFYPEER;
00154       *ot = OT_BOOLEAN;
00155    } else if (!strcasecmp(name, "hashcompat")) {
00156       *key = CURLOPT_SPECIAL_HASHCOMPAT;
00157       *ot = OT_BOOLEAN;
00158    } else {
00159       return -1;
00160    }
00161    return 0;
00162 }

static int unload_module ( void   )  [static]

Definition at line 628 of file func_curl.c.

References acf_curl, acf_curlopt, and ast_custom_function_unregister().

00629 {
00630    int res;
00631 
00632    res = ast_custom_function_unregister(&acf_curl);
00633    res |= ast_custom_function_unregister(&acf_curlopt);
00634 
00635    return res;
00636 }

static size_t WriteMemoryCallback ( void *  ptr,
size_t  size,
size_t  nmemb,
void *  data 
) [static]

Definition at line 406 of file func_curl.c.

References ast_debug, ast_str_append_substr(), ast_str_size(), and ast_str_strlen().

Referenced by curl_instance_init().

00407 {
00408    register int realsize = size * nmemb;
00409    struct ast_str **pstr = (struct ast_str **)data;
00410 
00411    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));
00412 
00413    ast_str_append_substr(pstr, 0, ptr, realsize);
00414 
00415    ast_debug(3, "Now, len=%zu, used=%zu\n", ast_str_size(*pstr), ast_str_strlen(*pstr));
00416 
00417    return realsize;
00418 }


Variable Documentation

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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_REALTIME_DEPEND2, } [static]

Definition at line 659 of file func_curl.c.

struct ast_custom_function acf_curl [static]

Definition at line 589 of file func_curl.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function acf_curlopt [static]

Definition at line 600 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 659 of file func_curl.c.

struct ast_datastore_info curl_info [static]

Initial value:

 {
   .type = "CURL",
   .destroy = curlds_free,
}

Definition at line 61 of file func_curl.c.

Referenced by acf_curl_helper(), acf_curlopt_helper(), and acf_curlopt_write().

struct ast_threadstorage curl_instance = { .once = PTHREAD_ONCE_INIT , .key_init = __init_curl_instance , .custom_init = curl_instance_init , } [static]

Definition at line 446 of file func_curl.c.

Referenced by acf_curl_helper().

const char* const global_useragent = "asterisk-libcurl-agent/1.0" [static]

Definition at line 420 of file func_curl.c.

struct ast_threadstorage thread_escapebuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_thread_escapebuf , .custom_init = NULL , } [static]

Definition at line 447 of file func_curl.c.

Referenced by acf_curl_helper().


Generated on Mon Mar 19 11:30:48 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7