mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-06-30 22:18:19 -04:00
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
This commit is contained in:
parent
e06793a7ad
commit
f1c6cf9d4e
@ -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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
} 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
|
|||||||
|
|
||||||
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 @@
|
|||||||
#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)
|
|||||||
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();
|
||||||
|
82
src/fserve.c
82
src/fserve.c
@ -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 {
|
|||||||
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,6 +112,7 @@ 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");
|
||||||
|
if (mimetypes)
|
||||||
avl_tree_free (mimetypes, _delete_mapping);
|
avl_tree_free (mimetypes, _delete_mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
|||||||
((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) {
|
|||||||
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 @@
|
|||||||
#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);
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user