Mon Mar 12 2012 21:39:52

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"
Include dependency graph for func_curl.c:

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 = 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_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 , }
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 , }

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.


Function Documentation

static void __init_curl_instance ( void  ) [static]

Definition at line 446 of file func_curl.c.

{
static void __init_thread_escapebuf ( void  ) [static]

Definition at line 447 of file func_curl.c.

{
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().

{
   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 579 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 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_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().

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

   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");
      return -1;
   }

   AST_LIST_LOCK(&global_curl_info);
   AST_LIST_TRAVERSE(&global_curl_info, cur, list) {
      if (cur->key == CURLOPT_SPECIAL_HASHCOMPAT) {
         hashcompat = (cur->value != NULL) ? 1 : 0;
      } 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 = (cur->value != NULL) ? 1 : 0;
         } 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);
   }

   curl_easy_perform(*curl);

   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, "=");
            if (piece) {
               ast_uri_decode(piece);
            }
            ast_uri_decode(name);
            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 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(), ast_datastore::data, global_curl_info, 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) {
               if (0) {
#if CURLVERSION_ATLEAST(7,15,2)
               } else if ((long)cur->value == CURLPROXY_SOCKS4) {
                  if (buf) {
                     ast_copy_string(buf, "socks4", len);
                  } else {
                     ast_str_set(bufstr, 0, "socks4");
                  }
#endif
#if CURLVERSION_ATLEAST(7,18,0)
               } else if ((long)cur->value == CURLPROXY_SOCKS4A) {
                  if (buf) {
                     ast_copy_string(buf, "socks4a", len);
                  } else {
                     ast_str_set(bufstr, 0, "socks4a");
                  }
#endif
               } else if ((long)cur->value == CURLPROXY_SOCKS5) {
                  if (buf) {
                     ast_copy_string(buf, "socks5", len);
                  } else {
                     ast_str_set(bufstr, 0, "socks5");
                  }
#if CURLVERSION_ATLEAST(7,18,0)
               } else if ((long)cur->value == CURLPROXY_SOCKS5_HOSTNAME) {
                  if (buf) {
                     ast_copy_string(buf, "socks5hostname", len);
                  } else {
                     ast_str_set(bufstr, 0, "socks5hostname");
                  }
#endif
#if CURLVERSION_ATLEAST(7,10,0)
               } else if ((long)cur->value == CURLPROXY_HTTP) {
                  if (buf) {
                     ast_copy_string(buf, "http", len);
                  } else {
                     ast_str_set(bufstr, 0, "http");
                  }
#endif
               } else {
                  if (buf) {
                     ast_copy_string(buf, "unknown", len);
                  } else {
                     ast_str_set(bufstr, 0, "unknown");
                  }
               }
            }
            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 396 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 401 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 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(), ast_datastore::data, free, global_curl_info, 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);
         }

         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 {
            /* 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 437 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 422 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 74 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 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.

{
   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 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().

{
   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_BOOLEAN;
   } else {
      return -1;
   }
   return 0;
}
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().

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

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

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

Definition at line 600 of file func_curl.c.

Referenced by load_module(), and unload_module().

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.

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.

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

Referenced by acf_curl_helper().