You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/modules_s/xcap/xcap_mod.c

196 lines
4.7 KiB

#include "../../sr_module.h"
#include "../../mem/mem.h"
#include "../../mem/shm_mem.h"
#include <libxml/parser.h>
#include <curl/curl.h>
#include <cds/memory.h>
#include <cds/logger.h>
#include <cds/cds.h>
#include <xcap/xcap_client.h>
#include <cds/sstr.h>
#include <cds/dstring.h>
#include "xcap_params.h"
MODULE_VERSION
int xcap_mod_init(void);
void xcap_mod_destroy(void);
int xcap_child_init(int _rank);
int xcap_query_impl(const char *uri, xcap_query_params_t *params, char **buf, int *bsize);
/** Exported functions */
static cmd_export_t cmds[]={
{"xcap_query", (cmd_function)xcap_query_impl, 0, 0, -1},
{"fill_xcap_params", (cmd_function)fill_xcap_params_impl, 0, 0, -1},
{"set_xcap_root", set_xcap_root, 1, 0, REQUEST_ROUTE | FAILURE_ROUTE},
{"set_xcap_filename", set_xcap_filename, 1, 0, REQUEST_ROUTE | FAILURE_ROUTE},
{0, 0, 0, 0, 0}
};
/** Exported parameters */
static param_export_t params[]={
{"xcap_root", PARAM_STR, &default_xcap_root },
{0, 0, 0}
};
struct module_exports exports = {
"xcap",
cmds, /* Exported functions */
0, /* RPC methods */
params, /* Exported parameters */
xcap_mod_init, /* module initialization function */
0, /* response function*/
xcap_mod_destroy, /* pa_destroy, / * destroy function */
0, /* oncancel function */
xcap_child_init /* per-child init function */
};
int xcap_mod_init(void)
{
INFO("xcap module initialization\n");
/* ??? if other module uses this libraries it might be a problem ??? */
DEBUG_LOG(" ... libxml\n");
xmlInitParser();
DEBUG_LOG(" ... libcurl\n");
curl_global_init(CURL_GLOBAL_ALL);
return 0;
}
int xcap_child_init(int _rank)
{
return 0;
}
void xcap_mod_destroy(void)
{
/*int i, cnt;
char *s;*/
DEBUG_LOG("xcap module cleanup\n");
/* ??? if other module uses this libraries it might be a problem ??? */
/* xmlCleanupParser();
curl_global_cleanup();*/
DEBUG_LOG("xcap module cleanup finished\n");
}
/* --------------------------------------------------------- */
static size_t write_data_func(void *ptr, size_t size, size_t nmemb, void *stream)
{
int s = size * nmemb;
/* TRACE_LOG("%d bytes writen\n", s);*/
if (s != 0) {
if (dstr_append((dstring_t*)stream, ptr, s) != 0) {
ERROR_LOG("can't append %d bytes into data buffer\n", s);
return 0;
}
}
return s;
}
/* helper functions for XCAP queries */
int xcap_query_impl(const char *uri, xcap_query_params_t *params, char **buf, int *bsize)
{
CURLcode res = -1;
static CURL *handle = NULL;
dstring_t data;
char *auth = NULL;
int i;
long auth_methods;
if (!uri) {
ERR("BUG: no uri given\n");
return -1;
}
if (!buf) {
ERR("BUG: no buf given\n");
return -1;
}
i = 0;
if (params) {
i += params->auth_user.len;
i += params->auth_pass.len;
}
if (i > 0) {
/* do authentication */
auth = (char *)cds_malloc_pkg(i + 2);
if (!auth) return -1;
sprintf(auth, "%.*s:%.*s", FMT_STR(params->auth_user),
FMT_STR(params->auth_pass));
}
auth_methods = CURLAUTH_BASIC | CURLAUTH_DIGEST;
dstr_init(&data, 512);
if (!handle) handle = curl_easy_init();
if (handle) {
curl_easy_setopt(handle, CURLOPT_URL, uri);
/* TRACE_LOG("uri: %s\n", uri ? uri : "<null>"); */
/* do not store data into a file - store them in memory */
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data_func);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
#ifdef CURLOPT_MUTE
/* be quiet */
curl_easy_setopt(handle, CURLOPT_MUTE, 1);
#endif /* CURLOPT_MUTE */
/* non-2xx => error */
curl_easy_setopt(handle, CURLOPT_FAILONERROR, 1);
/* auth */
curl_easy_setopt(handle, CURLOPT_HTTPAUTH, auth_methods); /* TODO possibility of selection */
curl_easy_setopt(handle, CURLOPT_NETRC, CURL_NETRC_IGNORED);
curl_easy_setopt(handle, CURLOPT_USERPWD, auth);
/* SSL */
if (params) {
if (params->enable_unverified_ssl_peer) {
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0);
}
}
/* follow redirects (needed for apache mod_speling - case insesitive names) */
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
/* curl_easy_setopt(handle, CURLOPT_TCP_NODELAY, 1);
curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 10);*/
/* Accept headers */
res = curl_easy_perform(handle);
/* curl_easy_cleanup(handle); */ /* FIXME: experimental */
}
else ERROR_LOG("can't initialize curl handle\n");
if (res == 0) {
*bsize = dstr_get_data_length(&data);
if (*bsize) {
*buf = (char*)cds_malloc(*bsize);
if (!*buf) {
ERROR_LOG("can't allocate %d bytes\n", *bsize);
res = -1;
*bsize = 0;
}
else dstr_get_data(&data, *buf);
}
}
else DBG("curl error: %d\n", res); /* see curl/curl.h for possible values*/
dstr_destroy(&data);
if (auth) cds_free_pkg(auth);
return res;
}