mirror of https://github.com/sipwise/kamailio.git
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.
196 lines
4.7 KiB
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;
|
|
}
|
|
|