diff --git a/src/admin.c b/src/admin.c index 88ee2950..51104f34 100644 --- a/src/admin.c +++ b/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); } diff --git a/src/connection.c b/src/connection.c index 6238ccbc..0c36dd1d 100644 --- a/src/connection.c +++ b/src/connection.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #ifdef HAVE_POLL #include #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); diff --git a/src/stats.c b/src/stats.c index a37afcff..d6453ef3 100644 --- a/src/stats.c +++ b/src/stats.c @@ -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); diff --git a/src/stats.h b/src/stats.h index 484962e4..59025198 100644 --- a/src/stats.h +++ b/src/stats.h @@ -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); diff --git a/src/xslt.c b/src/xslt.c index ecd33dab..22b58fab 100644 --- a/src/xslt.c +++ b/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); }