mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-01-03 14:56:34 -05:00
make admin and web root pages use file serving thread to send back responses
svn path=/icecast/trunk/icecast/; revision=9464
This commit is contained in:
parent
4f4e7be98f
commit
e9adc91bee
100
src/admin.c
100
src/admin.c
@ -32,6 +32,7 @@
|
||||
#include "stats.h"
|
||||
#include "os.h"
|
||||
#include "xslt.h"
|
||||
#include "fserve.h"
|
||||
|
||||
#include "format.h"
|
||||
|
||||
@ -111,6 +112,7 @@
|
||||
#define RAW 1
|
||||
#define TRANSFORMED 2
|
||||
#define PLAINTEXT 3
|
||||
|
||||
int admin_get_command(char *command)
|
||||
{
|
||||
if(!strcmp(command, FALLBACK_RAW_REQUEST))
|
||||
@ -195,7 +197,6 @@ static void admin_handle_mount_request(client_t *client, source_t *source,
|
||||
static void admin_handle_general_request(client_t *client, int command);
|
||||
static void admin_send_response(xmlDocPtr doc, client_t *client,
|
||||
int response, char *xslt_template);
|
||||
static void html_write(client_t *client, char *fmt, ...);
|
||||
|
||||
/* build an XML doc containing information about currently running sources.
|
||||
* If a mountpoint is passed then that source will not be added to the XML
|
||||
@ -257,42 +258,42 @@ xmlDocPtr admin_build_sourcelist (const char *mount)
|
||||
void admin_send_response(xmlDocPtr doc, client_t *client,
|
||||
int response, char *xslt_template)
|
||||
{
|
||||
xmlChar *buff = NULL;
|
||||
int len = 0;
|
||||
ice_config_t *config;
|
||||
char *fullpath_xslt_template;
|
||||
int fullpath_xslt_template_len;
|
||||
char *adminwebroot;
|
||||
|
||||
client->respcode = 200;
|
||||
if (response == RAW) {
|
||||
xmlDocDumpMemory(doc, &buff, &len);
|
||||
html_write(client, "HTTP/1.0 200 OK\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
if (response == RAW)
|
||||
{
|
||||
xmlChar *buff = NULL;
|
||||
int len = 0;
|
||||
unsigned int buf_len;
|
||||
const char *http = "HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: text/xml\r\n"
|
||||
"\r\n", len);
|
||||
html_write(client, "%s", buff);
|
||||
"Content-Length: ";
|
||||
xmlDocDumpMemory(doc, &buff, &len);
|
||||
buf_len = strlen (http) + len + 20;
|
||||
client->refbuf = refbuf_new (buf_len);
|
||||
snprintf (client->refbuf->data, buf_len, "%s%d\r\n\r\n%s", http, len, buff);
|
||||
xmlFree(buff);
|
||||
client->respcode = 200;
|
||||
fserve_add_client (client, NULL);
|
||||
}
|
||||
if (response == TRANSFORMED) {
|
||||
config = config_get_config();
|
||||
adminwebroot = config->adminroot_dir;
|
||||
fullpath_xslt_template_len = strlen(adminwebroot) +
|
||||
strlen(xslt_template) + 2;
|
||||
if (response == TRANSFORMED)
|
||||
{
|
||||
char *fullpath_xslt_template;
|
||||
int fullpath_xslt_template_len;
|
||||
ice_config_t *config = config_get_config();
|
||||
|
||||
fullpath_xslt_template_len = strlen (config->adminroot_dir) +
|
||||
strlen (xslt_template) + 2;
|
||||
fullpath_xslt_template = malloc(fullpath_xslt_template_len);
|
||||
snprintf(fullpath_xslt_template, fullpath_xslt_template_len, "%s%s%s",
|
||||
adminwebroot, PATH_SEPARATOR, xslt_template);
|
||||
config->adminroot_dir, PATH_SEPARATOR, xslt_template);
|
||||
config_release_config();
|
||||
html_write(client, "HTTP/1.0 200 OK\r\n"
|
||||
"Content-Type: text/html\r\n"
|
||||
"\r\n");
|
||||
|
||||
DEBUG1("Sending XSLT (%s)", fullpath_xslt_template);
|
||||
xslt_transform(doc, fullpath_xslt_template, client);
|
||||
free(fullpath_xslt_template);
|
||||
}
|
||||
if (buff) {
|
||||
xmlFree(buff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void admin_handle_request(client_t *client, char *uri)
|
||||
{
|
||||
char *mount, *command_string;
|
||||
@ -544,16 +545,6 @@ static void html_success(client_t *client, char *message)
|
||||
client_destroy(client);
|
||||
}
|
||||
|
||||
static void html_write(client_t *client, char *fmt, ...)
|
||||
{
|
||||
int bytes;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
bytes = sock_write_fmt(client->con->sock, fmt, ap);
|
||||
va_end(ap);
|
||||
if(bytes > 0) client->con->sent_bytes = bytes;
|
||||
}
|
||||
|
||||
static void command_move_clients(client_t *client, source_t *source,
|
||||
int response)
|
||||
@ -575,7 +566,6 @@ static void command_move_clients(client_t *client, source_t *source,
|
||||
admin_send_response(doc, client, response,
|
||||
MOVECLIENTS_TRANSFORMED_REQUEST);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -616,7 +606,6 @@ static void command_move_clients(client_t *client, source_t *source,
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
||||
static void command_show_listeners(client_t *client, source_t *source,
|
||||
@ -670,7 +659,6 @@ static void command_show_listeners(client_t *client, source_t *source,
|
||||
admin_send_response(doc, client, response,
|
||||
LISTCLIENTS_TRANSFORMED_REQUEST);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
||||
static void command_buildm3u(client_t *client, source_t *source,
|
||||
@ -706,6 +694,8 @@ static void command_buildm3u(client_t *client, source_t *source,
|
||||
free(host);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
||||
|
||||
static void command_manageauth(client_t *client, source_t *source,
|
||||
int response)
|
||||
{
|
||||
@ -764,7 +754,6 @@ static void command_manageauth(client_t *client, source_t *source,
|
||||
free(message);
|
||||
}
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
||||
static void command_kill_source(client_t *client, source_t *source,
|
||||
@ -784,7 +773,6 @@ static void command_kill_source(client_t *client, source_t *source,
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
||||
static void command_kill_client(client_t *client, source_t *source,
|
||||
@ -829,7 +817,6 @@ static void command_kill_client(client_t *client, source_t *source,
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
||||
static void command_fallback(client_t *client, source_t *source,
|
||||
@ -876,7 +863,6 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -908,7 +894,6 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -917,7 +902,6 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
admin_send_response(doc, client, response,
|
||||
ADMIN_XSL_RESPONSE);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
||||
static void command_shoutcast_metadata(client_t *client, source_t *source)
|
||||
@ -958,7 +942,6 @@ static void command_stats(client_t *client, int response) {
|
||||
stats_get_xml(&doc, 1);
|
||||
admin_send_response(doc, client, response, STATS_TRANSFORMED_REQUEST);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -969,14 +952,18 @@ static void command_list_mounts(client_t *client, int response)
|
||||
avl_tree_rlock (global.source_tree);
|
||||
if (response == PLAINTEXT)
|
||||
{
|
||||
char buffer [4096], *buf = buffer;
|
||||
unsigned int remaining = sizeof (buffer);
|
||||
int ret = snprintf (buffer, remaining,
|
||||
"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
|
||||
|
||||
char *buf;
|
||||
unsigned int remaining = 4096;
|
||||
int ret;
|
||||
ice_config_t *config = config_get_config ();
|
||||
mount_proxy *mountinfo = config->mounts;
|
||||
while (mountinfo)
|
||||
|
||||
client->refbuf = refbuf_new (remaining);
|
||||
buf = client->refbuf->data;
|
||||
ret = snprintf (buf, remaining,
|
||||
"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
|
||||
|
||||
while (mountinfo && ret > 0 && ret < remaining)
|
||||
{
|
||||
mount_proxy *current = mountinfo;
|
||||
source_t *source;
|
||||
@ -1004,7 +991,8 @@ static void command_list_mounts(client_t *client, int response)
|
||||
remaining -= ret;
|
||||
buf += ret;
|
||||
}
|
||||
sock_write_bytes (client->con->sock, buffer, sizeof (buffer)-remaining);
|
||||
client->refbuf->len = 4096 - remaining;
|
||||
fserve_add_client (client, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1015,9 +1003,6 @@ static void command_list_mounts(client_t *client, int response)
|
||||
LISTMOUNTS_TRANSFORMED_REQUEST);
|
||||
xmlFreeDoc(doc);
|
||||
}
|
||||
client_destroy(client);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void command_updatemetadata(client_t *client, source_t *source,
|
||||
@ -1035,5 +1020,4 @@ static void command_updatemetadata(client_t *client, source_t *source,
|
||||
admin_send_response(doc, client, response,
|
||||
UPDATEMETADATA_TRANSFORMED_REQUEST);
|
||||
xmlFreeDoc(doc);
|
||||
client_destroy(client);
|
||||
}
|
||||
|
@ -19,8 +19,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_POLL
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
@ -760,9 +758,6 @@ static void _handle_stats_request (client_t *client, char *uri)
|
||||
|
||||
static void _handle_get_request (client_t *client, char *passed_uri)
|
||||
{
|
||||
char *fullpath;
|
||||
int bytes;
|
||||
struct stat statbuf;
|
||||
source_t *source;
|
||||
int fileserve;
|
||||
int port;
|
||||
@ -821,33 +816,20 @@ static void _handle_get_request (client_t *client, char *passed_uri)
|
||||
** if the extension is .xsl, if so, then process
|
||||
** this request as an XSLT request
|
||||
*/
|
||||
fullpath = util_get_path_from_normalised_uri(uri);
|
||||
if (util_check_valid_extension(fullpath) == XSLT_CONTENT) {
|
||||
if (util_check_valid_extension (uri) == XSLT_CONTENT)
|
||||
{
|
||||
/* If the file exists, then transform it, otherwise, write a 404 */
|
||||
if (stat(fullpath, &statbuf) == 0) {
|
||||
DEBUG0("Stats request, sending XSL transformed stats");
|
||||
client->respcode = 200;
|
||||
bytes = sock_write(client->con->sock,
|
||||
"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
|
||||
if(bytes > 0) client->con->sent_bytes = bytes;
|
||||
stats_transform_xslt(client, fullpath);
|
||||
client_destroy(client);
|
||||
}
|
||||
else {
|
||||
client_send_404(client, "The file you requested could not be found");
|
||||
}
|
||||
free(fullpath);
|
||||
DEBUG0("Stats request, sending XSL transformed stats");
|
||||
stats_transform_xslt (client, uri);
|
||||
if (uri != passed_uri) free (uri);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fserve_client_create (client, uri))
|
||||
{
|
||||
free(fullpath);
|
||||
if (uri != passed_uri) free (uri);
|
||||
return;
|
||||
}
|
||||
free(fullpath);
|
||||
|
||||
avl_tree_rlock(global.source_tree);
|
||||
source = source_find_mount(uri);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "client.h"
|
||||
#include "stats.h"
|
||||
#include "xslt.h"
|
||||
#include "util.h"
|
||||
#define CATMODULE "stats"
|
||||
#include "logging.h"
|
||||
|
||||
@ -703,7 +704,7 @@ static int _send_event_to_client(stats_event_t *event, client_t *client)
|
||||
(event->source != NULL) ? event->source : "global",
|
||||
event->name ? event->name : "null",
|
||||
event->value ? event->value : "null");
|
||||
if (len > 0 && len < sizeof (buf))
|
||||
if (len > 0 && len < (int)sizeof (buf))
|
||||
ret = client_send_bytes (client, buf, len);
|
||||
|
||||
return (ret == -1) ? 0 : 1;
|
||||
@ -886,9 +887,10 @@ static xmlNodePtr _find_xml_node(char *mount, source_xml_t **list, xmlNodePtr ro
|
||||
return node->node;
|
||||
}
|
||||
|
||||
void stats_transform_xslt(client_t *client, char *xslpath)
|
||||
void stats_transform_xslt(client_t *client, const char *uri)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
char *xslpath = util_get_path_from_normalised_uri (uri);
|
||||
|
||||
stats_get_xml(&doc, 0);
|
||||
|
||||
|
@ -86,7 +86,7 @@ void stats_event_time (const char *mount, const char *name);
|
||||
void *stats_connection(void *arg);
|
||||
void *stats_callback(void *arg);
|
||||
|
||||
void stats_transform_xslt(client_t *client, char *xslpath);
|
||||
void stats_transform_xslt(client_t *client, const char *uri);
|
||||
void stats_sendxml(client_t *client);
|
||||
void stats_get_xml(xmlDocPtr *doc, int show_hidden);
|
||||
char *stats_get_value(char *source, char *name);
|
||||
|
41
src/xslt.c
41
src/xslt.c
@ -46,6 +46,7 @@
|
||||
#include "refbuf.h"
|
||||
#include "client.h"
|
||||
#include "stats.h"
|
||||
#include "fserve.h"
|
||||
|
||||
#define CATMODULE "xslt"
|
||||
|
||||
@ -152,41 +153,37 @@ static xsltStylesheetPtr xslt_get_stylesheet(const char *fn) {
|
||||
|
||||
void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client)
|
||||
{
|
||||
xmlOutputBufferPtr outputBuffer;
|
||||
xmlDocPtr res;
|
||||
xsltStylesheetPtr cur;
|
||||
const char *params[16 + 1];
|
||||
size_t count,bytes;
|
||||
|
||||
params[0] = NULL;
|
||||
xmlChar *string;
|
||||
int len;
|
||||
|
||||
thread_mutex_lock(&xsltlock);
|
||||
cur = xslt_get_stylesheet(xslfilename);
|
||||
|
||||
if (cur == NULL) {
|
||||
if (cur == NULL)
|
||||
{
|
||||
thread_mutex_unlock(&xsltlock);
|
||||
bytes = sock_write_string(client->con->sock,
|
||||
(char *)"Could not parse XSLT file");
|
||||
if(bytes > 0) client->con->sent_bytes += bytes;
|
||||
|
||||
ERROR1 ("problem reading stylesheet \"%s\"", xslfilename);
|
||||
client_send_404 (client, "Could not parse XSLT file");
|
||||
return;
|
||||
}
|
||||
|
||||
res = xsltApplyStylesheet(cur, doc, params);
|
||||
res = xsltApplyStylesheet(cur, doc, NULL);
|
||||
|
||||
outputBuffer = xmlAllocOutputBuffer(NULL);
|
||||
|
||||
count = xsltSaveResultTo(outputBuffer, res, cur);
|
||||
xsltSaveResultToString (&string, &len, res, cur);
|
||||
thread_mutex_unlock(&xsltlock);
|
||||
if (string)
|
||||
{
|
||||
const char *http = "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nContent-Length: ";
|
||||
unsigned buf_len = strlen (http) + 20 + len;
|
||||
|
||||
/* Add null byte to end. */
|
||||
bytes = xmlOutputBufferWrite(outputBuffer, 1, "");
|
||||
|
||||
if(sock_write_string(client->con->sock,
|
||||
(char *)outputBuffer->buffer->content))
|
||||
client->con->sent_bytes += bytes;
|
||||
|
||||
xmlOutputBufferClose(outputBuffer);
|
||||
client->respcode = 200;
|
||||
client->refbuf = refbuf_new (buf_len);
|
||||
snprintf (client->refbuf->data, buf_len, "%s%d\r\n\r\n%s", http, len, string);
|
||||
fserve_add_client (client, NULL);
|
||||
xmlFree (string);
|
||||
}
|
||||
xmlFreeDoc(res);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user