Commit f1c6cf9d authored by Karl Heyes's avatar Karl Heyes

Allow rereading of the mime types file on xml reload. Also allow for specifying

an alternative filename in the xml.

svn path=/icecast/trunk/icecast/; revision=13541
parent e06793a7
...@@ -61,11 +61,13 @@ ...@@ -61,11 +61,13 @@
#define CONFIG_DEFAULT_LOG_DIR "/usr/local/icecast/logs" #define CONFIG_DEFAULT_LOG_DIR "/usr/local/icecast/logs"
#define CONFIG_DEFAULT_WEBROOT_DIR "/usr/local/icecast/webroot" #define CONFIG_DEFAULT_WEBROOT_DIR "/usr/local/icecast/webroot"
#define CONFIG_DEFAULT_ADMINROOT_DIR "/usr/local/icecast/admin" #define CONFIG_DEFAULT_ADMINROOT_DIR "/usr/local/icecast/admin"
#define MIMETYPESFILE "/etc/mime.types"
#else #else
#define CONFIG_DEFAULT_BASE_DIR ".\\" #define CONFIG_DEFAULT_BASE_DIR ".\\"
#define CONFIG_DEFAULT_LOG_DIR ".\\logs" #define CONFIG_DEFAULT_LOG_DIR ".\\logs"
#define CONFIG_DEFAULT_WEBROOT_DIR ".\\webroot" #define CONFIG_DEFAULT_WEBROOT_DIR ".\\webroot"
#define CONFIG_DEFAULT_ADMINROOT_DIR ".\\admin" #define CONFIG_DEFAULT_ADMINROOT_DIR ".\\admin"
#define MIMETYPESFILE ".\\mime.types"
#endif #endif
static ice_config_t _current_configuration; static ice_config_t _current_configuration;
...@@ -201,6 +203,7 @@ void config_clear(ice_config_t *c) ...@@ -201,6 +203,7 @@ void config_clear(ice_config_t *c)
if (c->master_password) xmlFree(c->master_password); if (c->master_password) xmlFree(c->master_password);
if (c->user) xmlFree(c->user); if (c->user) xmlFree(c->user);
if (c->group) xmlFree(c->group); if (c->group) xmlFree(c->group);
xmlFree (c->mimetypes_fn);
thread_mutex_lock(&(_locks.relay_lock)); thread_mutex_lock(&(_locks.relay_lock));
relay = c->relay; relay = c->relay;
...@@ -349,6 +352,7 @@ static void _set_defaults(ice_config_t *configuration) ...@@ -349,6 +352,7 @@ static void _set_defaults(ice_config_t *configuration)
configuration->on_demand = 0; configuration->on_demand = 0;
configuration->dir_list = NULL; configuration->dir_list = NULL;
configuration->hostname = CONFIG_DEFAULT_HOSTNAME; configuration->hostname = CONFIG_DEFAULT_HOSTNAME;
configuration->mimetypes_fn = xmlCharStrdup (MIMETYPESFILE);
configuration->port = 0; configuration->port = 0;
configuration->listeners[0].port = 0; configuration->listeners[0].port = 0;
configuration->listeners[0].bind_address = NULL; configuration->listeners[0].bind_address = NULL;
...@@ -420,6 +424,9 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ...@@ -420,6 +424,9 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
} else if (strcmp(node->name, "hostname") == 0) { } else if (strcmp(node->name, "hostname") == 0) {
if (configuration->hostname && configuration->hostname != CONFIG_DEFAULT_HOSTNAME) xmlFree(configuration->hostname); if (configuration->hostname && configuration->hostname != CONFIG_DEFAULT_HOSTNAME) xmlFree(configuration->hostname);
configuration->hostname = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); configuration->hostname = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "mime-types") == 0) {
if (configuration->mimetypes_fn) xmlFree(configuration->mimetypes_fn);
configuration->mimetypes_fn = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "listen-socket") == 0) { } else if (strcmp(node->name, "listen-socket") == 0) {
_parse_listen_socket(doc, node->xmlChildrenNode, configuration); _parse_listen_socket(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "port") == 0) { } else if (strcmp(node->name, "port") == 0) {
......
...@@ -131,6 +131,7 @@ typedef struct ice_config_tag ...@@ -131,6 +131,7 @@ typedef struct ice_config_tag
char *hostname; char *hostname;
int port; int port;
char *mimetypes_fn;
listener_t listeners[MAX_LISTEN_SOCKETS]; listener_t listeners[MAX_LISTEN_SOCKETS];
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "client.h" #include "client.h"
#include "logging.h" #include "logging.h"
#include "slave.h" #include "slave.h"
#include "fserve.h"
#define CATMODULE "event" #define CATMODULE "event"
...@@ -61,6 +62,7 @@ void event_config_read(void *arg) ...@@ -61,6 +62,7 @@ void event_config_read(void *arg)
config_set_config(&new_config); config_set_config(&new_config);
restart_logging (config_get_config_unlocked()); restart_logging (config_get_config_unlocked());
yp_recheck_config (config_get_config_unlocked()); yp_recheck_config (config_get_config_unlocked());
fserve_recheck_mime_types (config_get_config_unlocked());
config_release_config(); config_release_config();
slave_recheck_all(); slave_recheck_all();
......
...@@ -60,12 +60,6 @@ ...@@ -60,12 +60,6 @@
#define BUFSIZE 4096 #define BUFSIZE 4096
#ifdef _WIN32
#define MIMETYPESFILE ".\\mime.types"
#else
#define MIMETYPESFILE "/etc/mime.types"
#endif
static fserve_t *active_list = NULL; static fserve_t *active_list = NULL;
static volatile fserve_t *pending_list = NULL; static volatile fserve_t *pending_list = NULL;
...@@ -92,14 +86,17 @@ typedef struct { ...@@ -92,14 +86,17 @@ typedef struct {
static void fserve_client_destroy(fserve_t *fclient); static void fserve_client_destroy(fserve_t *fclient);
static int _delete_mapping(void *mapping); static int _delete_mapping(void *mapping);
static void *fserv_thread_function(void *arg); static void *fserv_thread_function(void *arg);
static void create_mime_mappings(const char *fn);
void fserve_initialize(void) void fserve_initialize(void)
{ {
create_mime_mappings(MIMETYPESFILE); ice_config_t *config = config_get_config();
mimetypes = NULL;
thread_mutex_create (&pending_lock); thread_mutex_create (&pending_lock);
fserve_recheck_mime_types (config);
config_release_config();
run_fserv = 1; run_fserv = 1;
stats_event (NULL, "file_connections", "0"); stats_event (NULL, "file_connections", "0");
...@@ -115,7 +112,8 @@ void fserve_shutdown(void) ...@@ -115,7 +112,8 @@ void fserve_shutdown(void)
run_fserv = 0; run_fserv = 0;
thread_join(fserv_thread); thread_join(fserv_thread);
INFO0("file serving thread stopped"); INFO0("file serving thread stopped");
avl_tree_free(mimetypes, _delete_mapping); if (mimetypes)
avl_tree_free (mimetypes, _delete_mapping);
} }
#ifdef HAVE_POLL #ifdef HAVE_POLL
...@@ -312,38 +310,45 @@ static void *fserv_thread_function(void *arg) ...@@ -312,38 +310,45 @@ static void *fserv_thread_function(void *arg)
return NULL; return NULL;
} }
/* string returned needs to be free'd */
char *fserve_content_type (const char *path) char *fserve_content_type (const char *path)
{ {
char *ext = util_get_extension(path); char *ext = util_get_extension(path);
mime_type exttype = {ext, NULL}; mime_type exttype = {ext, NULL};
void *result; void *result;
char *type;
if (!avl_get_by_key (mimetypes, &exttype, &result)) thread_mutex_lock (&pending_lock);
if (mimetypes && !avl_get_by_key (mimetypes, &exttype, &result))
{ {
mime_type *mime = result; mime_type *mime = result;
return mime->type; type = strdup (mime->type);
} }
else { else {
/* Fallbacks for a few basic ones */ /* Fallbacks for a few basic ones */
if(!strcmp(ext, "ogg")) if(!strcmp(ext, "ogg"))
return "application/ogg"; type = strdup ("application/ogg");
else if(!strcmp(ext, "mp3")) else if(!strcmp(ext, "mp3"))
return "audio/mpeg"; type = strdup ("audio/mpeg");
else if(!strcmp(ext, "html")) else if(!strcmp(ext, "html"))
return "text/html"; type = strdup ("text/html");
else if(!strcmp(ext, "css")) else if(!strcmp(ext, "css"))
return "text/css"; type = strdup ("text/css");
else if(!strcmp(ext, "txt")) else if(!strcmp(ext, "txt"))
return "text/plain"; type = strdup ("text/plain");
else if(!strcmp(ext, "jpg")) else if(!strcmp(ext, "jpg"))
return "image/jpeg"; type = strdup ("image/jpeg");
else if(!strcmp(ext, "png")) else if(!strcmp(ext, "png"))
return "image/png"; type = strdup ("image/png");
else if(!strcmp(ext, "m3u")) else if(!strcmp(ext, "m3u"))
return "audio/x-mpegurl"; type = strdup ("audio/x-mpegurl");
else if(!strcmp(ext, "aac"))
type = strdup ("audio/aac");
else else
return "application/octet-stream"; type = strdup ("application/octet-stream");
} }
thread_mutex_unlock (&pending_lock);
return type;
} }
static void fserve_client_destroy(fserve_t *fclient) static void fserve_client_destroy(fserve_t *fclient)
...@@ -524,6 +529,8 @@ int fserve_client_create (client_t *httpclient, const char *path) ...@@ -524,6 +529,8 @@ int fserve_client_create (client_t *httpclient, const char *path)
int strflen; int strflen;
struct tm result; struct tm result;
int64_t endpos = rangenumber+new_content_len-1; int64_t endpos = rangenumber+new_content_len-1;
char *type;
if (endpos < 0) { if (endpos < 0) {
endpos = 0; endpos = 0;
} }
...@@ -531,6 +538,7 @@ int fserve_client_create (client_t *httpclient, const char *path) ...@@ -531,6 +538,7 @@ int fserve_client_create (client_t *httpclient, const char *path)
strflen = strftime(currenttime, 50, "%a, %d-%b-%Y %X GMT", strflen = strftime(currenttime, 50, "%a, %d-%b-%Y %X GMT",
gmtime_r(&now, &result)); gmtime_r(&now, &result));
httpclient->respcode = 206; httpclient->respcode = 206;
type = fserve_content_type (path);
bytes = snprintf (httpclient->refbuf->data, BUFSIZE, bytes = snprintf (httpclient->refbuf->data, BUFSIZE,
"HTTP/1.1 206 Partial Content\r\n" "HTTP/1.1 206 Partial Content\r\n"
"Date: %s\r\n" "Date: %s\r\n"
...@@ -543,7 +551,8 @@ int fserve_client_create (client_t *httpclient, const char *path) ...@@ -543,7 +551,8 @@ int fserve_client_create (client_t *httpclient, const char *path)
rangenumber, rangenumber,
endpos, endpos,
content_length, content_length,
fserve_content_type(path)); type);
free (type);
} }
else { else {
goto fail; goto fail;
...@@ -554,14 +563,15 @@ int fserve_client_create (client_t *httpclient, const char *path) ...@@ -554,14 +563,15 @@ int fserve_client_create (client_t *httpclient, const char *path)
} }
} }
else { else {
char *type = fserve_content_type(path);
httpclient->respcode = 200; httpclient->respcode = 200;
bytes = snprintf (httpclient->refbuf->data, BUFSIZE, bytes = snprintf (httpclient->refbuf->data, BUFSIZE,
"HTTP/1.0 200 OK\r\n" "HTTP/1.0 200 OK\r\n"
"Content-Length: " FORMAT_INT64 "\r\n" "Content-Length: " FORMAT_INT64 "\r\n"
"Content-Type: %s\r\n\r\n", "Content-Type: %s\r\n\r\n",
content_length, content_length,
fserve_content_type(path)); type);
free (type);
} }
httpclient->refbuf->len = bytes; httpclient->refbuf->len = bytes;
httpclient->pos = 0; httpclient->pos = 0;
...@@ -649,20 +659,25 @@ static int _compare_mappings(void *arg, void *a, void *b) ...@@ -649,20 +659,25 @@ static int _compare_mappings(void *arg, void *a, void *b)
((mime_type *)b)->ext); ((mime_type *)b)->ext);
} }
static void create_mime_mappings(const char *fn) { void fserve_recheck_mime_types (ice_config_t *config)
FILE *mimefile = fopen(fn, "r"); {
FILE *mimefile;
char line[4096]; char line[4096];
char *type, *ext, *cur; char *type, *ext, *cur;
mime_type *mapping; mime_type *mapping;
avl_tree *new_mimetypes;
mimetypes = avl_tree_new(_compare_mappings, NULL); if (config->mimetypes_fn == NULL)
return;
mimefile = fopen (config->mimetypes_fn, "r");
if (mimefile == NULL) if (mimefile == NULL)
{ {
WARN1 ("Cannot open mime type file %s", fn); WARN1 ("Cannot open mime types file %s", config->mimetypes_fn);
return; return;
} }
new_mimetypes = avl_tree_new(_compare_mappings, NULL);
while(fgets(line, 4096, mimefile)) while(fgets(line, 4096, mimefile))
{ {
line[4095] = 0; line[4095] = 0;
...@@ -698,13 +713,18 @@ static void create_mime_mappings(const char *fn) { ...@@ -698,13 +713,18 @@ static void create_mime_mappings(const char *fn) {
mapping = malloc(sizeof(mime_type)); mapping = malloc(sizeof(mime_type));
mapping->ext = strdup(ext); mapping->ext = strdup(ext);
mapping->type = strdup(type); mapping->type = strdup(type);
if(!avl_get_by_key(mimetypes, mapping, &tmp)) if (!avl_get_by_key (new_mimetypes, mapping, &tmp))
avl_delete(mimetypes, mapping, _delete_mapping); avl_delete (new_mimetypes, mapping, _delete_mapping);
avl_insert(mimetypes, mapping); avl_insert (new_mimetypes, mapping);
} }
} }
} }
fclose(mimefile); fclose(mimefile);
thread_mutex_lock (&pending_lock);
if (mimetypes)
avl_tree_free (mimetypes, _delete_mapping);
mimetypes = new_mimetypes;
thread_mutex_unlock (&pending_lock);
} }
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#define __FSERVE_H__ #define __FSERVE_H__
#include <stdio.h> #include <stdio.h>
#include "cfgfile.h"
typedef void (*fserve_callback_t)(client_t *, void *); typedef void (*fserve_callback_t)(client_t *, void *);
...@@ -34,6 +35,7 @@ int fserve_client_create(client_t *httpclient, const char *path); ...@@ -34,6 +35,7 @@ int fserve_client_create(client_t *httpclient, const char *path);
int fserve_add_client (client_t *client, FILE *file); int fserve_add_client (client_t *client, FILE *file);
void fserve_add_client_callback (client_t *client, fserve_callback_t callback, void *arg); void fserve_add_client_callback (client_t *client, fserve_callback_t callback, void *arg);
char *fserve_content_type (const char *path); char *fserve_content_type (const char *path);
void fserve_recheck_mime_types (ice_config_t *config);
#endif #endif
......
...@@ -1320,6 +1320,7 @@ static void *source_fallback_file (void *arg) ...@@ -1320,6 +1320,7 @@ static void *source_fallback_file (void *arg)
parser = httpp_create_parser(); parser = httpp_create_parser();
httpp_initialize (parser, NULL); httpp_initialize (parser, NULL);
httpp_setvar (parser, "content-type", type); httpp_setvar (parser, "content-type", type);
free (type);
source->hidden = 1; source->hidden = 1;
source->yp_public = 0; source->yp_public = 0;
......
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