Sat Nov 25 00:45:28 2006

Asterisk developer's documentation


app_curl.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C)  2004 - 2005, Tilghman Lesher
00005  *
00006  * Tilghman Lesher <curl-20050919@the-tilghman.com>
00007  * and Brian Wilkins <bwilkins@cfl.rr.com> (Added POST option)
00008  *
00009  * app_curl.c is distributed with no restrictions on usage or
00010  * redistribution.
00011  *
00012  * See http://www.asterisk.org for more information about
00013  * the Asterisk project. Please do not directly contact
00014  * any of the maintainers of this project for assistance;
00015  * the project provides a web site, mailing lists and IRC
00016  * channels for your use.
00017  *
00018  */
00019 
00020 /*! \file
00021  * \brief Curl - App to load a URL
00022  * 
00023  * \ingroup applications
00024  */
00025  
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <curl/curl.h>
00030 
00031 #include "asterisk.h"
00032 
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00034 
00035 #include "asterisk/lock.h"
00036 #include "asterisk/file.h"
00037 #include "asterisk/logger.h"
00038 #include "asterisk/channel.h"
00039 #include "asterisk/pbx.h"
00040 #include "asterisk/cli.h"
00041 #include "asterisk/options.h"
00042 #include "asterisk/module.h"
00043 
00044 static char *tdesc = "Load external URL";
00045 
00046 static char *app = "Curl";
00047 
00048 static char *synopsis = "Load an external URL";
00049 
00050 static char *descrip = 
00051 "  Curl(URL[|postdata]): This application will request the specified URL.\n"
00052 "It is mainly used for signalling external applications of an event.\n"
00053 "Parameters:\n"
00054 "  URL      - This is the external URL to request.\n"
00055 "  postdata - This information will be treated as POST data.\n"
00056 "This application will set the following variable:\n"
00057 "  CURL - This variable will contain the resulting page.\n"
00058 "This application has been deprecated in favor of the CURL function.\n";
00059 
00060 STANDARD_LOCAL_USER;
00061 
00062 LOCAL_USER_DECL;
00063 
00064 struct MemoryStruct {
00065    char *memory;
00066    size_t size;
00067 };
00068 
00069 static void *myrealloc(void *ptr, size_t size)
00070 {
00071    /* There might be a realloc() out there that doesn't like reallocing
00072       NULL pointers, so we take care of it here */
00073    if (ptr)
00074       return realloc(ptr, size);
00075    else
00076       return malloc(size);
00077 }
00078 
00079 static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
00080 {
00081    register int realsize = size * nmemb;
00082    struct MemoryStruct *mem = (struct MemoryStruct *)data;
00083 
00084    mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
00085    if (mem->memory) {
00086       memcpy(&(mem->memory[mem->size]), ptr, realsize);
00087       mem->size += realsize;
00088       mem->memory[mem->size] = 0;
00089    }
00090    return realsize;
00091 }
00092 
00093 static int curl_internal(struct MemoryStruct *chunk, char *url, char *post)
00094 {
00095    CURL *curl;
00096 
00097    curl_global_init(CURL_GLOBAL_ALL);
00098    curl = curl_easy_init();
00099 
00100    if (!curl) {
00101       return -1;
00102    }
00103 
00104    curl_easy_setopt(curl, CURLOPT_URL, url);
00105    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
00106    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)chunk);
00107    curl_easy_setopt(curl, CURLOPT_USERAGENT, "asterisk-libcurl-agent/1.0");
00108 
00109    if (post) {
00110       curl_easy_setopt(curl, CURLOPT_POST, 1);
00111       curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);
00112    }
00113 
00114    curl_easy_perform(curl);
00115    curl_easy_cleanup(curl);
00116    return 0;
00117 }
00118 
00119 static int curl_exec(struct ast_channel *chan, void *data)
00120 {
00121    int res = 0;
00122    struct localuser *u;
00123    char *info, *post_data=NULL, *url;
00124    struct MemoryStruct chunk = { NULL, 0 };
00125    static int dep_warning = 0;
00126    
00127    if (!dep_warning) {
00128       ast_log(LOG_WARNING, "The application Curl is deprecated.  Please use the CURL() function instead.\n");
00129       dep_warning = 1;
00130    }
00131 
00132    if (ast_strlen_zero(data)) {
00133       ast_log(LOG_WARNING, "Curl requires an argument (URL)\n");
00134       return -1;
00135    }
00136    
00137    LOCAL_USER_ADD(u);
00138    
00139    if ((info = ast_strdupa(data))) {
00140       url = strsep(&info, "|");
00141       post_data = info;
00142    } else {
00143       ast_log(LOG_ERROR, "Out of memory\n");
00144       LOCAL_USER_REMOVE(u);
00145       return -1;
00146    }
00147 
00148    if (! curl_internal(&chunk, url, post_data)) {
00149       if (chunk.memory) {
00150          chunk.memory[chunk.size] = '\0';
00151          if (chunk.memory[chunk.size - 1] == 10)
00152             chunk.memory[chunk.size - 1] = '\0';
00153 
00154          pbx_builtin_setvar_helper(chan, "CURL", chunk.memory);
00155 
00156          free(chunk.memory);
00157       }
00158    } else {
00159       ast_log(LOG_ERROR, "Cannot allocate curl structure\n");
00160       res = -1;
00161    }
00162 
00163    LOCAL_USER_REMOVE(u);
00164    return res;
00165 }
00166 
00167 static char *acf_curl_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
00168 {
00169    struct localuser *u;
00170    char *info, *post_data=NULL, *url;
00171    struct MemoryStruct chunk = { NULL, 0 };
00172 
00173    *buf = '\0';
00174    
00175    if (ast_strlen_zero(data)) {
00176       ast_log(LOG_WARNING, "CURL requires an argument (URL)\n");
00177       return buf;
00178    }
00179 
00180    LOCAL_USER_ACF_ADD(u);
00181 
00182    info = ast_strdupa(data);
00183    if (!info) {
00184       ast_log(LOG_ERROR, "Out of memory\n");
00185       LOCAL_USER_REMOVE(u);
00186       return buf;
00187    }
00188    
00189    url = strsep(&info, "|");
00190    post_data = info;
00191    
00192    if (! curl_internal(&chunk, url, post_data)) {
00193       if (chunk.memory) {
00194          chunk.memory[chunk.size] = '\0';
00195          if (chunk.memory[chunk.size - 1] == 10)
00196             chunk.memory[chunk.size - 1] = '\0';
00197 
00198          ast_copy_string(buf, chunk.memory, len);
00199          free(chunk.memory);
00200       }
00201    } else {
00202       ast_log(LOG_ERROR, "Cannot allocate curl structure\n");
00203    }
00204 
00205    LOCAL_USER_REMOVE(u);
00206    return buf;
00207 }
00208 
00209 struct ast_custom_function acf_curl = {
00210    .name = "CURL",
00211    .synopsis = "Retrieves the contents of a URL",
00212    .syntax = "CURL(url[|post-data])",
00213    .desc =
00214    "  url       - URL to retrieve\n"
00215    "  post-data - Optional data to send as a POST (GET is default action)\n",
00216    .read = acf_curl_exec,
00217 };
00218 
00219 int unload_module(void)
00220 {
00221    int res;
00222 
00223    res = ast_custom_function_unregister(&acf_curl);
00224    res |= ast_unregister_application(app);
00225 
00226    STANDARD_HANGUP_LOCALUSERS;
00227    
00228    return res;
00229 }
00230 
00231 int load_module(void)
00232 {
00233    int res;
00234 
00235    res = ast_custom_function_register(&acf_curl);
00236    res |= ast_register_application(app, curl_exec, synopsis, descrip);
00237 
00238    return res;
00239 }
00240 
00241 char *description(void)
00242 {
00243    return tdesc;
00244 }
00245 
00246 int usecount(void)
00247 {
00248    int res;
00249    STANDARD_USECOUNT(res);
00250    return res;
00251 }
00252 
00253 char *key()
00254 {
00255    return ASTERISK_GPL_KEY;
00256 }

Generated on Sat Nov 25 00:45:28 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6