separate xml gateway code from mod_xml_rpc into it's own mod_xml_curl

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3592 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-12-10 02:02:30 +00:00
parent d3dca0313b
commit 01ddfdcba5
5 changed files with 240 additions and 113 deletions

View File

@ -28,6 +28,7 @@
<!-- XML Interfaces --> <!-- XML Interfaces -->
<!-- <load module="mod_xml_rpc"/> --> <!-- <load module="mod_xml_rpc"/> -->
<!-- <load module="mod_xml_curl"/> -->
<!-- Event Handlers --> <!-- Event Handlers -->
<!-- <load module="mod_cdr"/> --> <!-- <load module="mod_cdr"/> -->
@ -334,6 +335,16 @@
</configuration> </configuration>
<configuration name="xml_curl.conf" description="cURL XML Gateway">
<settings>
<!-- The url to a gateway cgi that can generate xml similar to
what's in this file only on-the-fly (leave it commented if you dont
need it) -->
<!-- one or more |-delim of configuration|directory|dialplan -->
<!--<param name="gateway-url" value="http://www.mydomain.com/test.cgi" bindings="dialplan"/>-->
</settings>
</configuration>
<configuration name="xml_rpc.conf" description="XML RPC"> <configuration name="xml_rpc.conf" description="XML RPC">
<settings> <settings>
<!-- The port where you want to run the http service (default 8080) --> <!-- The port where you want to run the http service (default 8080) -->
@ -342,10 +353,6 @@
<param name="auth-realm" value="freeswitch"/> <param name="auth-realm" value="freeswitch"/>
<param name="auth-user" value="freeswitch"/> <param name="auth-user" value="freeswitch"/>
<param name="auth-pass" value="works"/> <param name="auth-pass" value="works"/>
<!-- The url to a gateway cgi that can generate xml similar to what's in -->
<!-- this file only on-the-fly (leave it commented if you dont need it)-->
<!-- one or more |-delim of configuration|directory|dialplan -->
<!-- <param name="gateway-url" value="http://www.server.com/gateway.cgi" bindings="configuration"/> -->
</settings> </settings>
</configuration> </configuration>

View File

@ -0,0 +1,18 @@
LDFLAGS += -lcurl
all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN)
depends:
MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install curl-7.15.2.tar.gz --prefix=$(PREFIX)
$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c
$(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o
$(CC) $(SOLINK) -o $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(MODNAME).o $(LDFLAGS)
clean:
rm -fr *.$(DYNAMIC_LIB_EXTEN) *.o *~
install:
cp -f $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(PREFIX)/mod

View File

@ -0,0 +1,196 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthmct@yahoo.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthmct@yahoo.com>
*
* mod_xml_curl.c -- CURL XML Gateway
*
*/
#include <switch.h>
#include <curl/curl.h>
static const char modname[] = "mod_xml_curl";
static struct {
char *url;
char *bindings;
} globals;
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_url, globals.url);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_bindings, globals.bindings);
struct config_data {
char *name;
int fd;
};
static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
{
register unsigned int realsize = (unsigned int)(size * nmemb);
struct config_data *config_data = data;
write(config_data->fd, ptr, realsize);
return realsize;
}
static switch_xml_t xml_url_fetch(char *section,
char *tag_name,
char *key_name,
char *key_value,
char *params)
{
char filename[512] = "";
CURL *curl_handle = NULL;
struct config_data config_data;
switch_xml_t xml = NULL;
char *data = NULL;
switch_uuid_t uuid;
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
if (!(data = switch_mprintf("section=%s&tag_name=%s&key_name=%s&key_value=%s%s%s\n",
section,
tag_name ? tag_name : "",
key_name ? key_name : "",
key_value ? key_value : "",
params ? "&" : "", params ? params : ""))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
return NULL;
}
switch_uuid_get(&uuid);
switch_uuid_format(uuid_str, &uuid);
snprintf(filename, sizeof(filename), "%s%s.tmp.xml", SWITCH_GLOBAL_dirs.temp_dir, uuid_str);
curl_handle = curl_easy_init();
if (!strncasecmp(globals.url, "https", 5)) {
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
}
config_data.name = filename;
if ((config_data.fd = open(filename, O_CREAT | O_RDWR | O_TRUNC)) > -1) {
curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(curl_handle, CURLOPT_URL, globals.url);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, file_callback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&config_data);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-xml/1.0");
curl_easy_perform(curl_handle);
curl_easy_cleanup(curl_handle);
close(config_data.fd);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
}
switch_safe_free(data);
if (!(xml = switch_xml_parse_file(filename))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result!\n");
}
unlink(filename);
return xml;
}
static switch_loadable_module_interface_t xml_curl_module_interface = {
/*.module_name */ modname,
/*.endpoint_interface */ NULL,
/*.timer_interface */ NULL,
/*.dialplan_interface */ NULL,
/*.codec_interface */ NULL,
/*.application_interface */ NULL,
/*.api_interface */ NULL,
/*.file_interface */ NULL,
/*.speech_interface */ NULL,
/*.directory_interface */ NULL
};
static switch_status_t do_config(void)
{
char *cf = "xml_curl.conf";
switch_xml_t cfg, xml, settings, param;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
return SWITCH_STATUS_TERM;
}
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "gateway-url")) {
char *bindings = (char *) switch_xml_attr_soft(param, "bindings");
set_global_bindings(bindings);
set_global_url(val);
}
}
}
switch_xml_free(xml);
return globals.url ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
{
/* connect my internal structure to the blank pointer passed to me */
*module_interface = &xml_curl_module_interface;
if (do_config() == SWITCH_STATUS_SUCCESS) {
curl_global_init(CURL_GLOBAL_ALL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding XML Fetch Function [%s] [%s]\n",
globals.url, globals.bindings ? globals.bindings : "all");
switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(globals.bindings));
} else {
return SWITCH_STATUS_FALSE;
}
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void)
{
curl_global_cleanup();
return SWITCH_STATUS_SUCCESS;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:nil
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
*/

View File

@ -1,9 +1,8 @@
LDFLAGS += -lxmlrpc -lxmlrpc_abyss -lxmlrpc_server -lxmlrpc_server_abyss -lxmlrpc_xmlparse -lcurl LDFLAGS += -lxmlrpc -lxmlrpc_abyss -lxmlrpc_server -lxmlrpc_server_abyss -lxmlrpc_xmlparse
all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN) all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN)
depends: depends:
MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install curl-7.15.2.tar.gz --prefix=$(PREFIX)
MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install xmlrpc-c-1.03.14.tgz --prefix=$(PREFIX) --disable-cplusplus --disable-wininet-client --disable-libwww-client MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install xmlrpc-c-1.03.14.tgz --prefix=$(PREFIX) --disable-cplusplus --disable-wininet-client --disable-libwww-client

View File

@ -37,104 +37,9 @@
#include <xmlrpc-c/abyss.h> #include <xmlrpc-c/abyss.h>
#include <xmlrpc-c/server.h> #include <xmlrpc-c/server.h>
#include <xmlrpc-c/server_abyss.h> #include <xmlrpc-c/server_abyss.h>
#include <curl/curl.h>
static const char modname[] = "mod_xml_rpc"; static const char modname[] = "mod_xml_rpc";
static struct {
uint16_t port;
uint8_t running;
char *url;
char *bindings;
char *realm;
char *user;
char *pass;
} globals;
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_url, globals.url);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_bindings, globals.bindings);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_realm, globals.realm);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_user, globals.user);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_pass, globals.pass);
struct config_data {
char *name;
int fd;
};
static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
{
register unsigned int realsize = (unsigned int)(size * nmemb);
struct config_data *config_data = data;
write(config_data->fd, ptr, realsize);
return realsize;
}
static switch_xml_t xml_url_fetch(char *section,
char *tag_name,
char *key_name,
char *key_value,
char *params)
{
char filename[1024] = "";
CURL *curl_handle = NULL;
struct config_data config_data;
switch_xml_t xml = NULL;
char *data = NULL;
if (!(data = switch_mprintf("section=%s&tag_name=%s&key_name=%s&key_value=%s%s%s\n",
section,
tag_name ? tag_name : "",
key_name ? key_name : "",
key_value ? key_value : "",
params ? "&" : "", params ? params : ""))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
return NULL;
}
srand((unsigned int)(time(NULL) + strlen(globals.url)));
snprintf(filename, sizeof(filename), "%s%04x.tmp", SWITCH_GLOBAL_dirs.temp_dir, (rand() & 0xffff));
curl_handle = curl_easy_init();
if (!strncasecmp(globals.url, "https", 5)) {
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
}
config_data.name = filename;
if ((config_data.fd = open(filename, O_CREAT | O_RDWR | O_TRUNC)) > -1) {
curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(curl_handle, CURLOPT_URL, globals.url);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, file_callback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&config_data);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-xml/1.0");
curl_easy_perform(curl_handle);
curl_easy_cleanup(curl_handle);
close(config_data.fd);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!\n");
}
switch_safe_free(data);
if (!(xml = switch_xml_parse_file(filename))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing Result!\n");
}
unlink(filename);
return xml;
}
static switch_loadable_module_interface_t xml_rpc_module_interface = { static switch_loadable_module_interface_t xml_rpc_module_interface = {
/*.module_name */ modname, /*.module_name */ modname,
/*.endpoint_interface */ NULL, /*.endpoint_interface */ NULL,
@ -148,6 +53,18 @@ static switch_loadable_module_interface_t xml_rpc_module_interface = {
/*.directory_interface */ NULL /*.directory_interface */ NULL
}; };
static struct {
uint16_t port;
uint8_t running;
char *realm;
char *user;
char *pass;
} globals;
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_realm, globals.realm);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_user, globals.user);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_pass, globals.pass);
static switch_status_t do_config(void) static switch_status_t do_config(void)
{ {
char *cf = "xml_rpc.conf"; char *cf = "xml_rpc.conf";
@ -171,10 +88,6 @@ static switch_status_t do_config(void)
user = val; user = val;
} else if (!strcasecmp(var, "auth-pass")) { } else if (!strcasecmp(var, "auth-pass")) {
pass = val; pass = val;
} else if (!strcasecmp(var, "gateway-url")) {
char *bindings = (char *) switch_xml_attr_soft(param, "bindings");
set_global_bindings(bindings);
set_global_url(val);
} else if (!strcasecmp(var, "http-port")) { } else if (!strcasecmp(var, "http-port")) {
globals.port = (uint16_t)atoi(val); globals.port = (uint16_t)atoi(val);
} }
@ -191,7 +104,7 @@ static switch_status_t do_config(void)
} }
switch_xml_free(xml); switch_xml_free(xml);
return globals.url ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; return SWITCH_STATUS_SUCCESS;
} }
@ -202,12 +115,7 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
memset(&globals, 0, sizeof(globals)); memset(&globals, 0, sizeof(globals));
if (do_config() == SWITCH_STATUS_SUCCESS) { do_config();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding XML Fetch Function [%s] [%s]\n", globals.url, globals.bindings ? globals.bindings : "all");
switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(globals.bindings));
}
curl_global_init(CURL_GLOBAL_ALL);
/* indicate that the module should continue to be loaded */ /* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
@ -353,7 +261,6 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void) SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void)
{ {
globals.running = 0; globals.running = 0;
curl_global_cleanup();
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }