Commit e9adc91b authored by Karl Heyes's avatar Karl Heyes

make admin and web root pages use file serving thread to send back responses

svn path=/icecast/trunk/icecast/; revision=9464
parent 4f4e7be9
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "stats.h" #include "stats.h"
#include "os.h" #include "os.h"
#include "xslt.h" #include "xslt.h"
#include "fserve.h"
#include "format.h" #include "format.h"
...@@ -111,6 +112,7 @@ ...@@ -111,6 +112,7 @@
#define RAW 1 #define RAW 1
#define TRANSFORMED 2 #define TRANSFORMED 2
#define PLAINTEXT 3 #define PLAINTEXT 3
int admin_get_command(char *command) int admin_get_command(char *command)
{ {
if(!strcmp(command, FALLBACK_RAW_REQUEST)) if(!strcmp(command, FALLBACK_RAW_REQUEST))
...@@ -195,7 +197,6 @@ static void admin_handle_mount_request(client_t *client, source_t *source, ...@@ -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_handle_general_request(client_t *client, int command);
static void admin_send_response(xmlDocPtr doc, client_t *client, static void admin_send_response(xmlDocPtr doc, client_t *client,
int response, char *xslt_template); int response, char *xslt_template);
static void html_write(client_t *client, char *fmt, ...);
/* build an XML doc containing information about currently running sources. /* 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 * 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) ...@@ -257,42 +258,42 @@ xmlDocPtr admin_build_sourcelist (const char *mount)
void admin_send_response(xmlDocPtr doc, client_t *client, void admin_send_response(xmlDocPtr doc, client_t *client,
int response, char *xslt_template) int response, char *xslt_template)
{ {
xmlChar *buff = NULL; if (response == RAW)
int len = 0; {
ice_config_t *config; xmlChar *buff = NULL;
char *fullpath_xslt_template; int len = 0;
int fullpath_xslt_template_len; unsigned int buf_len;
char *adminwebroot; const char *http = "HTTP/1.0 200 OK\r\n"
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"
"Content-Type: text/xml\r\n" "Content-Type: text/xml\r\n"
"\r\n", len); "Content-Length: ";
html_write(client, "%s", buff); 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) { if (response == TRANSFORMED)
config = config_get_config(); {
adminwebroot = config->adminroot_dir; char *fullpath_xslt_template;
fullpath_xslt_template_len = strlen(adminwebroot) + int fullpath_xslt_template_len;
strlen(xslt_template) + 2; 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); fullpath_xslt_template = malloc(fullpath_xslt_template_len);
snprintf(fullpath_xslt_template, fullpath_xslt_template_len, "%s%s%s", 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(); 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); DEBUG1("Sending XSLT (%s)", fullpath_xslt_template);
xslt_transform(doc, fullpath_xslt_template, client); xslt_transform(doc, fullpath_xslt_template, client);
free(fullpath_xslt_template); free(fullpath_xslt_template);
} }
if (buff) {
xmlFree(buff);
}
} }
void admin_handle_request(client_t *client, char *uri) void admin_handle_request(client_t *client, char *uri)
{ {
char *mount, *command_string; char *mount, *command_string;
...@@ -544,16 +545,6 @@ static void html_success(client_t *client, char *message) ...@@ -544,16 +545,6 @@ static void html_success(client_t *client, char *message)
client_destroy(client); 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, static void command_move_clients(client_t *client, source_t *source,
int response) int response)
...@@ -575,7 +566,6 @@ static void command_move_clients(client_t *client, source_t *source, ...@@ -575,7 +566,6 @@ static void command_move_clients(client_t *client, source_t *source,
admin_send_response(doc, client, response, admin_send_response(doc, client, response,
MOVECLIENTS_TRANSFORMED_REQUEST); MOVECLIENTS_TRANSFORMED_REQUEST);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
return; return;
} }
...@@ -616,7 +606,6 @@ static void command_move_clients(client_t *client, source_t *source, ...@@ -616,7 +606,6 @@ static void command_move_clients(client_t *client, source_t *source,
admin_send_response(doc, client, response, admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE); ADMIN_XSL_RESPONSE);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
} }
static void command_show_listeners(client_t *client, source_t *source, 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, ...@@ -670,7 +659,6 @@ static void command_show_listeners(client_t *client, source_t *source,
admin_send_response(doc, client, response, admin_send_response(doc, client, response,
LISTCLIENTS_TRANSFORMED_REQUEST); LISTCLIENTS_TRANSFORMED_REQUEST);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
} }
static void command_buildm3u(client_t *client, source_t *source, static void command_buildm3u(client_t *client, source_t *source,
...@@ -706,6 +694,8 @@ 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); free(host);
client_destroy(client); client_destroy(client);
} }
static void command_manageauth(client_t *client, source_t *source, static void command_manageauth(client_t *client, source_t *source,
int response) int response)
{ {
...@@ -764,7 +754,6 @@ static void command_manageauth(client_t *client, source_t *source, ...@@ -764,7 +754,6 @@ static void command_manageauth(client_t *client, source_t *source,
free(message); free(message);
} }
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
} }
static void command_kill_source(client_t *client, source_t *source, 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, ...@@ -784,7 +773,6 @@ static void command_kill_source(client_t *client, source_t *source,
admin_send_response(doc, client, response, admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE); ADMIN_XSL_RESPONSE);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
} }
static void command_kill_client(client_t *client, source_t *source, 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, ...@@ -829,7 +817,6 @@ static void command_kill_client(client_t *client, source_t *source,
admin_send_response(doc, client, response, admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE); ADMIN_XSL_RESPONSE);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
} }
static void command_fallback(client_t *client, source_t *source, static void command_fallback(client_t *client, source_t *source,
...@@ -876,7 +863,6 @@ static void command_metadata(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_send_response(doc, client, response,
ADMIN_XSL_RESPONSE); ADMIN_XSL_RESPONSE);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
return; return;
} }
...@@ -908,7 +894,6 @@ static void command_metadata(client_t *client, source_t *source, ...@@ -908,7 +894,6 @@ static void command_metadata(client_t *client, source_t *source,
admin_send_response(doc, client, response, admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE); ADMIN_XSL_RESPONSE);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
return; return;
} }
...@@ -917,7 +902,6 @@ static void command_metadata(client_t *client, source_t *source, ...@@ -917,7 +902,6 @@ static void command_metadata(client_t *client, source_t *source,
admin_send_response(doc, client, response, admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE); ADMIN_XSL_RESPONSE);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
} }
static void command_shoutcast_metadata(client_t *client, source_t *source) static void command_shoutcast_metadata(client_t *client, source_t *source)
...@@ -958,7 +942,6 @@ static void command_stats(client_t *client, int response) { ...@@ -958,7 +942,6 @@ static void command_stats(client_t *client, int response) {
stats_get_xml(&doc, 1); stats_get_xml(&doc, 1);
admin_send_response(doc, client, response, STATS_TRANSFORMED_REQUEST); admin_send_response(doc, client, response, STATS_TRANSFORMED_REQUEST);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
return; return;
} }
...@@ -969,14 +952,18 @@ static void command_list_mounts(client_t *client, int response) ...@@ -969,14 +952,18 @@ static void command_list_mounts(client_t *client, int response)
avl_tree_rlock (global.source_tree); avl_tree_rlock (global.source_tree);
if (response == PLAINTEXT) if (response == PLAINTEXT)
{ {
char buffer [4096], *buf = buffer; char *buf;
unsigned int remaining = sizeof (buffer); unsigned int remaining = 4096;
int ret = snprintf (buffer, remaining, int ret;
"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
ice_config_t *config = config_get_config (); ice_config_t *config = config_get_config ();
mount_proxy *mountinfo = config->mounts; 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; mount_proxy *current = mountinfo;
source_t *source; source_t *source;
...@@ -1004,7 +991,8 @@ static void command_list_mounts(client_t *client, int response) ...@@ -1004,7 +991,8 @@ static void command_list_mounts(client_t *client, int response)
remaining -= ret; remaining -= ret;
buf += ret; buf += ret;
} }
sock_write_bytes (client->con->sock, buffer, sizeof (buffer)-remaining); client->refbuf->len = 4096 - remaining;
fserve_add_client (client, NULL);
} }
else else
{ {
...@@ -1015,9 +1003,6 @@ static void command_list_mounts(client_t *client, int response) ...@@ -1015,9 +1003,6 @@ static void command_list_mounts(client_t *client, int response)
LISTMOUNTS_TRANSFORMED_REQUEST); LISTMOUNTS_TRANSFORMED_REQUEST);
xmlFreeDoc(doc); xmlFreeDoc(doc);
} }
client_destroy(client);
return;
} }
static void command_updatemetadata(client_t *client, source_t *source, static void command_updatemetadata(client_t *client, source_t *source,
...@@ -1035,5 +1020,4 @@ 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, admin_send_response(doc, client, response,
UPDATEMETADATA_TRANSFORMED_REQUEST); UPDATEMETADATA_TRANSFORMED_REQUEST);
xmlFreeDoc(doc); xmlFreeDoc(doc);
client_destroy(client);
} }
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_POLL #ifdef HAVE_POLL
#include <sys/poll.h> #include <sys/poll.h>
#endif #endif
...@@ -760,9 +758,6 @@ static void _handle_stats_request (client_t *client, char *uri) ...@@ -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) static void _handle_get_request (client_t *client, char *passed_uri)
{ {
char *fullpath;
int bytes;
struct stat statbuf;
source_t *source; source_t *source;
int fileserve; int fileserve;
int port; int port;
...@@ -821,33 +816,20 @@ static void _handle_get_request (client_t *client, char *passed_uri) ...@@ -821,33 +816,20 @@ static void _handle_get_request (client_t *client, char *passed_uri)
** if the extension is .xsl, if so, then process ** if the extension is .xsl, if so, then process
** this request as an XSLT request ** this request as an XSLT request
*/ */
fullpath = util_get_path_from_normalised_uri(uri); if (util_check_valid_extension (uri) == XSLT_CONTENT)
if (util_check_valid_extension(fullpath) == XSLT_CONTENT) { {
/* If the file exists, then transform it, otherwise, write a 404 */ /* If the file exists, then transform it, otherwise, write a 404 */
if (stat(fullpath, &statbuf) == 0) { DEBUG0("Stats request, sending XSL transformed stats");
DEBUG0("Stats request, sending XSL transformed stats"); stats_transform_xslt (client, uri);
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);
if (uri != passed_uri) free (uri); if (uri != passed_uri) free (uri);
return; return;
} }
if (fserve_client_create (client, uri)) if (fserve_client_create (client, uri))
{ {
free(fullpath);
if (uri != passed_uri) free (uri); if (uri != passed_uri) free (uri);
return; return;
} }
free(fullpath);
avl_tree_rlock(global.source_tree); avl_tree_rlock(global.source_tree);
source = source_find_mount(uri); source = source_find_mount(uri);
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "client.h" #include "client.h"
#include "stats.h" #include "stats.h"
#include "xslt.h" #include "xslt.h"
#include "util.h"
#define CATMODULE "stats" #define CATMODULE "stats"
#include "logging.h" #include "logging.h"
...@@ -703,7 +704,7 @@ static int _send_event_to_client(stats_event_t *event, client_t *client) ...@@ -703,7 +704,7 @@ static int _send_event_to_client(stats_event_t *event, client_t *client)
(event->source != NULL) ? event->source : "global", (event->source != NULL) ? event->source : "global",
event->name ? event->name : "null", event->name ? event->name : "null",
event->value ? event->value : "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); ret = client_send_bytes (client, buf, len);
return (ret == -1) ? 0 : 1; return (ret == -1) ? 0 : 1;
...@@ -886,9 +887,10 @@ static xmlNodePtr _find_xml_node(char *mount, source_xml_t **list, xmlNodePtr ro ...@@ -886,9 +887,10 @@ static xmlNodePtr _find_xml_node(char *mount, source_xml_t **list, xmlNodePtr ro
return node->node; return node->node;
} }
void stats_transform_xslt(client_t *client, char *xslpath) void stats_transform_xslt(client_t *client, const char *uri)
{ {
xmlDocPtr doc; xmlDocPtr doc;
char *xslpath = util_get_path_from_normalised_uri (uri);
stats_get_xml(&doc, 0); stats_get_xml(&doc, 0);
......
...@@ -86,7 +86,7 @@ void stats_event_time (const char *mount, const char *name); ...@@ -86,7 +86,7 @@ void stats_event_time (const char *mount, const char *name);
void *stats_connection(void *arg); void *stats_connection(void *arg);
void *stats_callback(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_sendxml(client_t *client);
void stats_get_xml(xmlDocPtr *doc, int show_hidden); void stats_get_xml(xmlDocPtr *doc, int show_hidden);
char *stats_get_value(char *source, char *name); char *stats_get_value(char *source, char *name);
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "refbuf.h" #include "refbuf.h"
#include "client.h" #include "client.h"
#include "stats.h" #include "stats.h"
#include "fserve.h"
#define CATMODULE "xslt" #define CATMODULE "xslt"
...@@ -152,41 +153,37 @@ static xsltStylesheetPtr xslt_get_stylesheet(const char *fn) { ...@@ -152,41 +153,37 @@ static xsltStylesheetPtr xslt_get_stylesheet(const char *fn) {
void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client) void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client)
{ {
xmlOutputBufferPtr outputBuffer;
xmlDocPtr res; xmlDocPtr res;
xsltStylesheetPtr cur; xsltStylesheetPtr cur;
const char *params[16 + 1]; xmlChar *string;
size_t count,bytes; int len;
params[0] = NULL;
thread_mutex_lock(&xsltlock); thread_mutex_lock(&xsltlock);
cur = xslt_get_stylesheet(xslfilename); cur = xslt_get_stylesheet(xslfilename);
if (cur == NULL) { if (cur == NULL)
{
thread_mutex_unlock(&xsltlock); thread_mutex_unlock(&xsltlock);
bytes = sock_write_string(client->con->sock, ERROR1 ("problem reading stylesheet \"%s\"", xslfilename);
(char *)"Could not parse XSLT file"); client_send_404 (client, "Could not parse XSLT file");
if(bytes > 0) client->con->sent_bytes += bytes;
return; 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); thread_mutex_unlock(&xsltlock);
if (string)
/* Add null byte to end. */ {
bytes = xmlOutputBufferWrite(outputBuffer, 1, ""); const char *http = "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nContent-Length: ";
unsigned buf_len = strlen (http) + 20 + len;
if(sock_write_string(client->con->sock,
(char *)outputBuffer->buffer->content)) client->respcode = 200;
client->con->sent_bytes += bytes; client->refbuf = refbuf_new (buf_len);
snprintf (client->refbuf->data, buf_len, "%s%d\r\n\r\n%s", http, len, string);
xmlOutputBufferClose(outputBuffer); fserve_add_client (client, NULL);
xmlFree (string);
}
xmlFreeDoc(res); xmlFreeDoc(res);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment