提交 60c783c6 authored 作者: Anthony Minessale's avatar Anthony Minessale

rss feeds of your voicemail

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6417 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 86b0bde5
...@@ -763,6 +763,8 @@ SWITCH_DECLARE(switch_size_t) switch_file_get_size(switch_file_t *thefile); ...@@ -763,6 +763,8 @@ SWITCH_DECLARE(switch_size_t) switch_file_get_size(switch_file_t *thefile);
SWITCH_DECLARE(switch_status_t) switch_file_exists(const char *filename, switch_memory_pool_t *pool); SWITCH_DECLARE(switch_status_t) switch_file_exists(const char *filename, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_directory_exists(const char *dirname, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_dir_make(const char *path, switch_fileperms_t perm, SWITCH_DECLARE(switch_status_t) switch_dir_make(const char *path, switch_fileperms_t perm,
switch_memory_pool_t *pool); switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_dir_make_recursive(const char *path, switch_fileperms_t perm, SWITCH_DECLARE(switch_status_t) switch_dir_make_recursive(const char *path, switch_fileperms_t perm,
......
...@@ -49,6 +49,7 @@ SWITCH_BEGIN_EXTERN_C ...@@ -49,6 +49,7 @@ SWITCH_BEGIN_EXTERN_C
s.end = s.data; \ s.end = s.data; \
s.data_size = SWITCH_CMD_CHUNK_LEN; \ s.data_size = SWITCH_CMD_CHUNK_LEN; \
s.write_function = switch_console_stream_write; \ s.write_function = switch_console_stream_write; \
s.raw_write_function = switch_console_stream_raw_write; \
s.alloc_len = SWITCH_CMD_CHUNK_LEN; \ s.alloc_len = SWITCH_CMD_CHUNK_LEN; \
s.alloc_chunk = SWITCH_CMD_CHUNK_LEN s.alloc_chunk = SWITCH_CMD_CHUNK_LEN
...@@ -63,6 +64,8 @@ SWITCH_DECLARE(void) switch_console_loop(void); ...@@ -63,6 +64,8 @@ SWITCH_DECLARE(void) switch_console_loop(void);
SWITCH_DECLARE(void) switch_console_printf(switch_text_channel_t channel, const char *file, const char *func, int line, SWITCH_DECLARE(void) switch_console_printf(switch_text_channel_t channel, const char *file, const char *func, int line,
const char *fmt, ...) PRINTF_FUNCTION(5, 6); const char *fmt, ...) PRINTF_FUNCTION(5, 6);
SWITCH_DECLARE(switch_status_t) switch_console_stream_raw_write(switch_stream_handle_t *handle, uint8_t *data, switch_size_t datalen);
/*! /*!
\brief A method akin to printf for dealing with api streams \brief A method akin to printf for dealing with api streams
*/ */
......
...@@ -81,6 +81,7 @@ struct switch_state_handler_table { ...@@ -81,6 +81,7 @@ struct switch_state_handler_table {
struct switch_stream_handle { struct switch_stream_handle {
switch_stream_handle_write_function_t write_function; switch_stream_handle_write_function_t write_function;
switch_stream_handle_raw_write_function_t raw_write_function;
void *data; void *data;
void *end; void *end;
switch_size_t data_size; switch_size_t data_size;
......
...@@ -1090,6 +1090,7 @@ typedef void (*switch_scheduler_func_t) (switch_scheduler_task_t *task); ...@@ -1090,6 +1090,7 @@ typedef void (*switch_scheduler_func_t) (switch_scheduler_task_t *task);
typedef switch_status_t (*switch_state_handler_t) (switch_core_session_t *); typedef switch_status_t (*switch_state_handler_t) (switch_core_session_t *);
typedef struct switch_stream_handle switch_stream_handle_t; typedef struct switch_stream_handle switch_stream_handle_t;
typedef switch_status_t (*switch_stream_handle_write_function_t) (switch_stream_handle_t *handle, const char *fmt, ...); typedef switch_status_t (*switch_stream_handle_write_function_t) (switch_stream_handle_t *handle, const char *fmt, ...);
typedef switch_status_t (*switch_stream_handle_raw_write_function_t) (switch_stream_handle_t *handle, uint8_t *data, switch_size_t datalen);
typedef switch_status_t (*switch_api_function_t) (const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream); typedef switch_status_t (*switch_api_function_t) (const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream);
......
...@@ -132,7 +132,7 @@ SWITCH_DECLARE(unsigned char) switch_char_to_rfc2833(char key); ...@@ -132,7 +132,7 @@ SWITCH_DECLARE(unsigned char) switch_char_to_rfc2833(char key);
*/ */
#define is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119) #define is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119)
#define end_of(_s) *(_s + strlen(_s) - 1)
/*! /*!
\brief Test for the existance of a flag on an arbitary object \brief Test for the existance of a flag on an arbitary object
\param obj the object to test \param obj the object to test
......
...@@ -3339,7 +3339,16 @@ static void js_thread_launch(const char *text) ...@@ -3339,7 +3339,16 @@ static void js_thread_launch(const char *text)
SWITCH_STANDARD_API(jsapi_function) SWITCH_STANDARD_API(jsapi_function)
{ {
struct request_obj ro = {0}; struct request_obj ro = {0};
char *path_info = NULL;
if (stream->event) {
path_info = switch_event_get_header(stream->event, "http-path-info");
}
if (switch_strlen_zero(cmd) && path_info) {
cmd = path_info;
}
if (switch_strlen_zero(cmd)) { if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "USAGE: %s\n", jsapi_interface.syntax); stream->write_function(stream, "USAGE: %s\n", jsapi_interface.syntax);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
* *
*/ */
#include <switch.h> #include <switch.h>
#include <switch_version.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable:4142) #pragma warning(disable:4142)
#endif #endif
...@@ -117,6 +118,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_xml_rpc_load) ...@@ -117,6 +118,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_xml_rpc_load)
} }
static switch_status_t http_stream_raw_write(switch_stream_handle_t *handle, uint8_t *data, switch_size_t datalen)
{
TSession *r = handle->data;
return HTTPWrite(r, (char *)data, (uint32_t) datalen) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
static switch_status_t http_stream_write(switch_stream_handle_t *handle, const char *fmt, ...) static switch_status_t http_stream_write(switch_stream_handle_t *handle, const char *fmt, ...)
{ {
va_list ap; va_list ap;
...@@ -146,7 +155,8 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name) ...@@ -146,7 +155,8 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
char *pass; char *pass;
const char *mypass1 = NULL, *mypass2 = NULL; const char *mypass1 = NULL, *mypass2 = NULL;
switch_xml_t x_domain, x_domain_root = NULL, x_user, x_params, x_param; switch_xml_t x_domain, x_domain_root = NULL, x_user, x_params, x_param;
const char *box;
p = RequestHeaderValue(r, "authorization"); p = RequestHeaderValue(r, "authorization");
if (p) { if (p) {
...@@ -162,16 +172,21 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name) ...@@ -162,16 +172,21 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
*pass++ = '\0'; *pass++ = '\0';
} }
if (switch_xml_locate_user(user, domain_name, NULL, &x_domain_root, &x_domain, &x_user, NULL) != SWITCH_STATUS_SUCCESS) { if (switch_xml_locate_user(user, domain_name, NULL, &x_domain_root, &x_domain, &x_user, "mailbox=check") != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain_name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain_name);
goto fail; goto fail;
} }
ResponseAddField(r, "freeswitch-user", user);
ResponseAddField(r, "freeswitch-domain", domain_name);
box = switch_xml_attr_soft(x_user, "mailbox");
if (!(x_params = switch_xml_child(x_user, "params"))) { if (!(x_params = switch_xml_child(x_user, "params"))) {
goto authed; goto authed;
} }
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) { for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr_soft(x_param, "name"); const char *var = switch_xml_attr_soft(x_param, "name");
const char *val = switch_xml_attr_soft(x_param, "value"); const char *val = switch_xml_attr_soft(x_param, "value");
...@@ -184,23 +199,53 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name) ...@@ -184,23 +199,53 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
ResponseAddField(r, (char *)var, (char *)val); ResponseAddField(r, (char *)var, (char *)val);
} }
} }
sprintf(z, "%s:%s", user, mypass1);
Base64Encode(z, t);
if (!strcmp(p, t)) { if (!(mypass1 && mypass2)) {
r->user=strdup(user); r->user=strdup(user);
goto authed; goto authed;
} } else {
if (mypass1) {
sprintf(z, "%s:%s", user, mypass1);
Base64Encode(z, t);
if (!strcmp(p, t)) {
r->user=strdup(user);
goto authed;
}
}
sprintf(z, "%s:%s", user, mypass2); if (mypass2) {
Base64Encode(z, t); sprintf(z, "%s:%s", user, mypass2);
Base64Encode(z, t);
if (!strcmp(p, t)) { if (!strcmp(p, t)) {
r->user=strdup(user); r->user=strdup(user);
goto authed; goto authed;
}
}
if (box) {
if (mypass1) {
sprintf(z, "%s:%s", box, mypass1);
Base64Encode(z, t);
if (!strcmp(p, t)) {
r->user=strdup(box);
goto authed;
}
}
if (mypass2) {
sprintf(z, "%s:%s", box, mypass2);
Base64Encode(z, t);
if (!strcmp(p, t)) {
r->user=strdup(box);
goto authed;
}
}
}
} }
goto fail; goto fail;
...@@ -242,15 +287,64 @@ abyss_bool auth_hook(TSession * r) ...@@ -242,15 +287,64 @@ abyss_bool auth_hook(TSession * r)
*e++ = '\0'; *e++ = '\0';
} }
if (!strcmp(domain_name, "this")) {
free(domain_name);
domain_name = strdup(r->host);
}
ret = !http_directory_auth(r, domain_name); ret = !http_directory_auth(r, domain_name);
free(domain_name); free(domain_name);
} else { } else {
if (globals.realm) { char tmp[512];
if (!RequestAuth(r, globals.realm, globals.user, globals.pass)) { const char *list[2] = {"index.html", "index.txt"};
ret = TRUE; int x;
if (!strncmp(r->uri, "/pub", 4)) {
char *p = r->uri;
char *new_uri = p + 4;
if (!new_uri) {
new_uri = "/";
}
snprintf(tmp, sizeof(tmp), "%s%s",
SWITCH_GLOBAL_dirs.htdocs_dir,
new_uri
);
if (switch_directory_exists(tmp, NULL) == SWITCH_STATUS_SUCCESS) {
for (x = 0; x < 2; x++) {
snprintf(tmp, sizeof(tmp), "%s%s%s%s",
SWITCH_GLOBAL_dirs.htdocs_dir,
new_uri,
end_of(new_uri) == *SWITCH_PATH_SEPARATOR ? "" : SWITCH_PATH_SEPARATOR,
list[x]
);
if (switch_file_exists(tmp, NULL) == SWITCH_STATUS_SUCCESS) {
snprintf(tmp, sizeof(tmp), "%s%s%s",
new_uri,
end_of(new_uri) == '/' ? "" : "/",
list[x]
);
new_uri = tmp;
break;
}
}
}
r->uri = strdup(new_uri);
free(p);
} else {
if (globals.realm && strncmp(r->uri, "/pub", 4)) {
if (!RequestAuth(r, globals.realm, globals.user, globals.pass)) {
ret = TRUE;
}
} }
} }
} }
return ret; return ret;
...@@ -265,56 +359,71 @@ abyss_bool handler_hook(TSession * r) ...@@ -265,56 +359,71 @@ abyss_bool handler_hook(TSession * r)
int i, j = 0; int i, j = 0;
TTableItem *ti; TTableItem *ti;
char *dup = NULL; char *dup = NULL;
int auth = 0;
char *fs_user = NULL, *fs_domain = NULL;
char *path_info = NULL;
abyss_bool ret = TRUE;
stream.data = r; stream.data = r;
stream.write_function = http_stream_write; stream.write_function = http_stream_write;
stream.raw_write_function = http_stream_raw_write;
if ((command = strstr(r->uri, "/api/"))) { if ((command = strstr(r->uri, "/api/"))) {
command += 5; command += 5;
} else { } else {
return FALSE; ret = FALSE;
goto end;
}
if ((path_info = strchr(command, '/'))) {
*path_info++ = '\0';
}
if (strncmp(r->uri, "/domains/", 9)) {
goto auth;
} }
for (i=0;i<r->response_headers.size;i++) { for (i=0;i<r->response_headers.size;i++) {
ti=&r->response_headers.item[i]; ti=&r->response_headers.item[i];
if (!strcasecmp(ti->name, "http-allowed-api")) { if (!strcasecmp(ti->name, "freeswitch-user")) {
fs_user = ti->value;
} else if (!strcasecmp(ti->name, "freeswitch-domain")) {
fs_domain = ti->value;
} else if (!strcasecmp(ti->name, "http-allowed-api")) {
int argc, x; int argc, x;
char *argv[256] = { 0 }; char *argv[256] = { 0 };
j++; j++;
if (!strcasecmp(ti->value, "any")) { if (!strcasecmp(ti->value, "any")) {
goto auth; auth++;
}
if (!strcasecmp(ti->value, "none")) {
goto unauth;
} }
dup = strdup(ti->value); dup = strdup(ti->value);
argc = switch_separate_string(dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))); argc = switch_separate_string(dup, ',', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) { for (x = 0; x < argc; x++) {
if (!strcasecmp(command, argv[x])) { if (!strcasecmp(command, argv[x])) {
goto auth; auth++;
} }
} }
goto unauth;
} }
} }
if (r->user && !j) { if (!switch_strlen_zero(r->user) && !j) {
goto unauth; auth = 0;
}
if (auth) {
goto auth;
} }
goto auth; //unauth:
unauth:
ResponseStatus(r, 403); ResponseStatus(r, 403);
ResponseError(r); ResponseError(r);
switch_safe_free(dup); switch_safe_free(dup);
return TRUE; ret = TRUE;
goto end;
auth: auth:
...@@ -322,7 +431,12 @@ abyss_bool handler_hook(TSession * r) ...@@ -322,7 +431,12 @@ abyss_bool handler_hook(TSession * r)
if (switch_event_create(&stream.event, SWITCH_EVENT_API) == SWITCH_STATUS_SUCCESS) { if (switch_event_create(&stream.event, SWITCH_EVENT_API) == SWITCH_STATUS_SUCCESS) {
const char * const content_length = RequestHeaderValue(r, "content-length"); const char * const content_length = RequestHeaderValue(r, "content-length");
if (fs_user)
switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "FreeSWITCH-User", "%s", fs_user);
if (fs_domain)
switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "FreeSWITCH-Domain", "%s", fs_domain);
if (path_info)
switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-Path-Info", "%s", path_info);
if (r->uri) if (r->uri)
switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-URI", "%s", r->uri); switch_event_add_header(stream.event, SWITCH_STACK_BOTTOM, "HTTP-URI", "%s", r->uri);
if (r->query) if (r->query)
...@@ -434,7 +548,7 @@ abyss_bool handler_hook(TSession * r) ...@@ -434,7 +548,7 @@ abyss_bool handler_hook(TSession * r)
} }
/* Generation of the server field */ /* Generation of the server field */
ResponseAddField(r,"Server", SERVER_HVERSION); ResponseAddField(r,"Server", "FreeSWITCH-" SWITCH_VERSION_FULL "-mod_xml_rpc");
for (i=0;i<r->response_headers.size;i++) { for (i=0;i<r->response_headers.size;i++) {
ti=&r->response_headers.item[i]; ti=&r->response_headers.item[i];
...@@ -453,7 +567,10 @@ abyss_bool handler_hook(TSession * r) ...@@ -453,7 +567,10 @@ abyss_bool handler_hook(TSession * r)
} }
//HTTPWriteEnd(r); //HTTPWriteEnd(r);
return TRUE;
end:
return ret;
} }
......
...@@ -364,6 +364,28 @@ SWITCH_DECLARE(switch_size_t) switch_file_get_size(switch_file_t *thefile) ...@@ -364,6 +364,28 @@ SWITCH_DECLARE(switch_size_t) switch_file_get_size(switch_file_t *thefile)
return apr_file_info_get(&finfo, APR_FINFO_SIZE, thefile) == SWITCH_STATUS_SUCCESS ? (switch_size_t)finfo.size : 0; return apr_file_info_get(&finfo, APR_FINFO_SIZE, thefile) == SWITCH_STATUS_SUCCESS ? (switch_size_t)finfo.size : 0;
} }
SWITCH_DECLARE(switch_status_t) switch_directory_exists(const char *dirname, switch_memory_pool_t *pool)
{
apr_dir_t *dir_handle;
switch_memory_pool_t *our_pool = NULL;
switch_status_t status;
if (!pool) {
switch_core_new_memory_pool(&our_pool);
pool = our_pool;
}
if ((status = apr_dir_open(&dir_handle, dirname, pool)) == APR_SUCCESS) {
apr_dir_close(dir_handle);
}
if (our_pool) {
switch_core_destroy_memory_pool(&our_pool);
}
return status;
}
SWITCH_DECLARE(switch_status_t) switch_file_exists(const char *filename, switch_memory_pool_t *pool) SWITCH_DECLARE(switch_status_t) switch_file_exists(const char *filename, switch_memory_pool_t *pool)
{ {
int32_t wanted = APR_FINFO_TYPE; int32_t wanted = APR_FINFO_TYPE;
......
...@@ -34,6 +34,17 @@ ...@@ -34,6 +34,17 @@
#include <switch_version.h> #include <switch_version.h>
#define CMD_BUFLEN 1024; #define CMD_BUFLEN 1024;
SWITCH_DECLARE(switch_status_t) switch_console_stream_raw_write(switch_stream_handle_t *handle, uint8_t *data, switch_size_t datalen)
{
FILE *out = switch_core_get_console();
if (out) {
fwrite(data, datalen, 1, out);
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
SWITCH_DECLARE(switch_status_t) switch_console_stream_write(switch_stream_handle_t *handle, const char *fmt, ...) SWITCH_DECLARE(switch_status_t) switch_console_stream_write(switch_stream_handle_t *handle, const char *fmt, ...)
{ {
......
...@@ -551,6 +551,9 @@ SWITCH_DECLARE(void) switch_core_runtime_loop(int bg) ...@@ -551,6 +551,9 @@ SWITCH_DECLARE(void) switch_core_runtime_loop(int bg)
SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext) SWITCH_DECLARE(const char *) switch_core_mime_ext2type(const char *ext)
{ {
if (!ext) {
return NULL;
}
return (const char *) switch_core_hash_find(runtime.mime_types, ext); return (const char *) switch_core_hash_find(runtime.mime_types, ext);
} }
......
...@@ -1457,7 +1457,8 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_open_cfg(const char *file_path, switch_x ...@@ -1457,7 +1457,8 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_open_cfg(const char *file_path, switch_x
static char *switch_xml_ampencode(const char *s, switch_size_t len, char **dst, switch_size_t *dlen, switch_size_t *max, short a) static char *switch_xml_ampencode(const char *s, switch_size_t len, char **dst, switch_size_t *dlen, switch_size_t *max, short a)
{ {
const char *e = NULL; const char *e = NULL;
int immune = 0;
if (len) { if (len) {
e = s + len; e = s + len;
} }
...@@ -1466,13 +1467,24 @@ static char *switch_xml_ampencode(const char *s, switch_size_t len, char **dst, ...@@ -1466,13 +1467,24 @@ static char *switch_xml_ampencode(const char *s, switch_size_t len, char **dst,
while (*dlen + 10 > *max) while (*dlen + 10 > *max)
*dst = (char *)realloc(*dst, *max += SWITCH_XML_BUFSIZE); *dst = (char *)realloc(*dst, *max += SWITCH_XML_BUFSIZE);
switch (*s) { if (immune) {
if (*s == '\0') {
return *dst;
}
(*dst)[(*dlen)++] = *s;
} else
switch (*s) {
case '\0': case '\0':
return *dst; return *dst;
case '&': case '&':
*dlen += sprintf(*dst + *dlen, "&amp;"); *dlen += sprintf(*dst + *dlen, "&amp;");
break; break;
case '<': case '<':
if (*(s+1) == '!') {
(*dst)[(*dlen)++] = *s;
immune++;
break;
}
*dlen += sprintf(*dst + *dlen, "&lt;"); *dlen += sprintf(*dst + *dlen, "&lt;");
break; break;
case '>': case '>':
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论