mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-13 20:50:41 +00:00
initial support of http handing in mod_verto
This commit is contained in:
parent
602e82d483
commit
b2554848a1
@ -1279,6 +1279,167 @@ static void jsock_check_event_queue(jsock_t *jsock)
|
|||||||
switch_mutex_unlock(jsock->write_mutex);
|
switch_mutex_unlock(jsock->write_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DO NOT use this unless you know what you are doing, you are WARNNED!!! */
|
||||||
|
static uint8_t *http_stream_read(switch_stream_handle_t *handle, int *len)
|
||||||
|
{
|
||||||
|
switch_http_request_t *r = (switch_http_request_t *) handle->data;
|
||||||
|
jsock_t *jsock = r->user_data;
|
||||||
|
wsh_t *wsh = &jsock->ws;
|
||||||
|
|
||||||
|
*len = r->_unparsed_len;
|
||||||
|
|
||||||
|
if (*len) { // we already read part of the body
|
||||||
|
r->_unparsed_len = 0; // reset for the next read
|
||||||
|
return (uint8_t *)r->_unparsed_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*len = ws_raw_read(wsh, wsh->buffer, 4096, wsh->block)) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint8_t *)wsh->buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static switch_status_t http_stream_raw_write(switch_stream_handle_t *handle, uint8_t *data, switch_size_t datalen)
|
||||||
|
{
|
||||||
|
switch_http_request_t *r = (switch_http_request_t *) handle->data;
|
||||||
|
jsock_t *jsock = r->user_data;
|
||||||
|
|
||||||
|
return ws_raw_write(&jsock->ws, 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, ...)
|
||||||
|
{
|
||||||
|
switch_http_request_t *r = (switch_http_request_t *) handle->data;
|
||||||
|
jsock_t *jsock = r->user_data;
|
||||||
|
int ret = 1;
|
||||||
|
char *data;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ret = switch_vasprintf(&data, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
if (ret) {
|
||||||
|
ret = ws_raw_write(&jsock->ws, data, (uint32_t)strlen(data));
|
||||||
|
}
|
||||||
|
switch_safe_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void http_static_handler(switch_http_request_t *request)
|
||||||
|
{
|
||||||
|
jsock_t *jsock = request->user_data;
|
||||||
|
char path[512];
|
||||||
|
switch_file_t *fd;
|
||||||
|
char *ext;
|
||||||
|
uint8_t chunk[4096];
|
||||||
|
const char *mime_type = "text/html", *new_type;
|
||||||
|
|
||||||
|
switch_snprintf(path, sizeof(path), "%s%s", jsock->profile->htdocs, request->uri);
|
||||||
|
|
||||||
|
printf("local path: %s\n", path);
|
||||||
|
|
||||||
|
if (end_of(path) == '/') {
|
||||||
|
char *data = "HTTP/1.1 500 Internal Error\r\n"
|
||||||
|
"Connection: close\r\n"
|
||||||
|
"Content-Type: text/plain\r\n\r\n"
|
||||||
|
"Directory indexing is UNSUPPORTED!\r\n";
|
||||||
|
ws_raw_write(&jsock->ws, data, strlen(data));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ext = strrchr(path, '.'))) {
|
||||||
|
ext++;
|
||||||
|
if ((new_type = switch_core_mime_ext2type(ext))) {
|
||||||
|
mime_type = new_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_file_open(&fd, path, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, jsock->pool) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_size_t flen = switch_file_get_size(fd);
|
||||||
|
switch_snprintf((char *)chunk, sizeof(chunk),
|
||||||
|
"HTTP/1.1 200 OK\r\n"
|
||||||
|
"Connection: close\r\n"
|
||||||
|
"Date: %s\r\n"
|
||||||
|
"Server: FreeSWITCH-%s-mod_verto\r\n"
|
||||||
|
"Content-Type: %s\r\n"
|
||||||
|
"Content-Length: %" SWITCH_SIZE_T_FMT "\r\n\r\n",
|
||||||
|
switch_event_get_header(request->headers, "Event-Date-GMT"),
|
||||||
|
switch_version_full(),
|
||||||
|
mime_type,
|
||||||
|
flen);
|
||||||
|
|
||||||
|
ws_raw_write(&jsock->ws, chunk, strlen((char *)chunk));
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
switch_status_t status;
|
||||||
|
|
||||||
|
flen = sizeof(chunk);
|
||||||
|
status = switch_file_read(fd, chunk, &flen);
|
||||||
|
|
||||||
|
if (status != SWITCH_STATUS_SUCCESS || flen == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws_raw_write(&jsock->ws, chunk, flen);
|
||||||
|
}
|
||||||
|
switch_file_close(fd);
|
||||||
|
} else {
|
||||||
|
char *data = "HTTP/1.1 404 Not Found\r\n"
|
||||||
|
"Connection: close\r\n\r\n";
|
||||||
|
ws_raw_write(&jsock->ws, data, strlen(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void http_run(jsock_t *jsock)
|
||||||
|
{
|
||||||
|
switch_http_request_t request = { 0 };
|
||||||
|
switch_stream_handle_t stream = { 0 };
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
request.user_data = jsock;
|
||||||
|
|
||||||
|
if (switch_event_create(&stream.param_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
request.headers = stream.param_event;
|
||||||
|
if (switch_http_parse_header(jsock->ws.buffer, jsock->ws.datalen, &request) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_destroy(&stream.param_event);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_http_dump_request(&request);
|
||||||
|
|
||||||
|
/* TODO: parse virtual hosts here */
|
||||||
|
|
||||||
|
stream.data = &request;
|
||||||
|
stream.read_function = http_stream_read;
|
||||||
|
stream.write_function = http_stream_write;
|
||||||
|
stream.raw_write_function = http_stream_raw_write;
|
||||||
|
|
||||||
|
switch_event_add_header_string(request.headers, SWITCH_STACK_BOTTOM, "Request-Method", request.method);
|
||||||
|
switch_event_add_header_string(request.headers, SWITCH_STACK_BOTTOM, "HTTP-URI", request.uri);
|
||||||
|
|
||||||
|
if (!strncmp(request.uri, "/rest/", 6)) {
|
||||||
|
switch_api_execute("lua", "__rest_init__.lua", NULL, &stream);
|
||||||
|
} else {
|
||||||
|
http_static_handler(&request);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_http_free_request(&request);
|
||||||
|
return;
|
||||||
|
|
||||||
|
err:
|
||||||
|
data = "HTTP/1.1 500 Internal Server Error\r\n"
|
||||||
|
"Connection: close\r\n\r\n";
|
||||||
|
ws_raw_write(&jsock->ws, data, strlen(data));
|
||||||
|
}
|
||||||
|
|
||||||
static void client_run(jsock_t *jsock)
|
static void client_run(jsock_t *jsock)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -1287,8 +1448,14 @@ static void client_run(jsock_t *jsock)
|
|||||||
jsock->local_addr.sin_port = 0;
|
jsock->local_addr.sin_port = 0;
|
||||||
|
|
||||||
|
|
||||||
if (ws_init(&jsock->ws, jsock->client_socket, (jsock->ptype & PTYPE_CLIENT_SSL) ? jsock->profile->ssl_ctx : NULL, 0, 1) < 0) {
|
if (ws_init(&jsock->ws, jsock->client_socket, (jsock->ptype & PTYPE_CLIENT_SSL) ? jsock->profile->ssl_ctx : NULL, 0, 1, !!jsock->profile->htdocs) < 0) {
|
||||||
die("%s WS SETUP FAILED", jsock->name);
|
if (jsock->profile->htdocs) {
|
||||||
|
http_run(jsock);
|
||||||
|
ws_close(&jsock->ws, WS_NONE);
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
die("%s WS SETUP FAILED [%s]", jsock->name, jsock->ws.buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while(jsock->profile->running) {
|
while(jsock->profile->running) {
|
||||||
@ -3654,6 +3821,8 @@ static switch_status_t parse_config(const char *cf)
|
|||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max Bindings Reached!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max Bindings Reached!\n");
|
||||||
}
|
}
|
||||||
|
} else if (!strcasecmp(var, "htdocs-directory")) {
|
||||||
|
profile->htdocs = switch_core_strdup(profile->pool, val);
|
||||||
} else if (!strcasecmp(var, "secure-combined")) {
|
} else if (!strcasecmp(var, "secure-combined")) {
|
||||||
set_string(profile->cert, val);
|
set_string(profile->cert, val);
|
||||||
set_string(profile->key, val);
|
set_string(profile->key, val);
|
||||||
|
@ -220,7 +220,7 @@ struct verto_profile_s {
|
|||||||
char *timer_name;
|
char *timer_name;
|
||||||
char *local_network;
|
char *local_network;
|
||||||
|
|
||||||
|
char *htdocs;
|
||||||
|
|
||||||
struct verto_profile_s *next;
|
struct verto_profile_s *next;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user