Commit c359faf1 authored by Michael Smith's avatar Michael Smith

More features:

  -- per mountpoint listener maxima
  -- static configuration of mountpoint fallbacks
  -- stream dumping (write incoming stream to disk)

Fixed some warnings that other people introduced.

svn path=/trunk/icecast/; revision=4383
parent d2fbef60
......@@ -69,6 +69,17 @@ void client_send_404(client_t *client, char *message) {
client_destroy(client);
}
void client_send_504(client_t *client, char *message) {
int bytes;
client->respcode = 504;
bytes = sock_write(client->con->sock,
"HTTP/1.0 504 Server Full\r\n"
"Content-Type: text/html\r\n\r\n"
"<b>%s</b>\r\n", message);
if (bytes > 0) client->con->sent_bytes = bytes;
client_destroy(client);
}
void client_send_401(client_t *client) {
int bytes = sock_write(client->con->sock,
"HTTP/1.0 401 Authentication Required\r\n"
......
......@@ -29,6 +29,7 @@ typedef struct _client_tag
client_t *client_create(connection_t *con, http_parser_t *parser);
void client_destroy(client_t *client);
void client_send_504(client_t *client, char *message);
void client_send_404(client_t *client, char *message);
void client_send_401(client_t *client);
void client_send_400(client_t *client, char *message);
......
......@@ -296,6 +296,7 @@ static connection_t *_get_connection(void)
int connection_create_source(client_t *client, connection_t *con, http_parser_t *parser, char *mount) {
source_t *source;
char *contenttype;
mount_proxy *mountproxy, *mountinfo = NULL;
/* check to make sure this source wouldn't
** be over the limit
......@@ -310,6 +311,15 @@ int connection_create_source(client_t *client, connection_t *con, http_parser_t
global_unlock();
stats_event_inc(NULL, "sources");
mountproxy = config_get_config()->mounts;
while(mountproxy) {
if(!strcmp(mountproxy->mountname, mount)) {
mountinfo = mountproxy;
break;
}
mountproxy = mountproxy->next;
}
contenttype = httpp_getvar(parser, "content-type");
......@@ -319,12 +329,13 @@ int connection_create_source(client_t *client, connection_t *con, http_parser_t
WARN1("Content-type \"%s\" not supported, dropping source", contenttype);
goto fail;
} else {
source = source_create(client, con, parser, mount, format);
source = source_create(client, con, parser, mount,
format, mountinfo);
}
} else {
format_type_t format = FORMAT_TYPE_MP3;
ERROR0("No content-type header, falling back to backwards compatibility mode for icecast 1.x relays. Assuming content is mp3.");
source = source_create(client, con, parser, mount, format);
source = source_create(client, con, parser, mount, format, mountinfo);
}
source->send_return = 1;
......@@ -762,13 +773,8 @@ static void _handle_get_request(connection_t *con,
global_lock();
if (global.clients >= config_get_config()->client_limit) {
client->respcode = 504;
bytes = sock_write(client->con->sock,
"HTTP/1.0 504 Server Full\r\n"
"Content-Type: text/html\r\n\r\n"
"<b>The server is already full. Try again later.</b>\r\n");
if (bytes > 0) client->con->sent_bytes = bytes;
client_destroy(client);
client_send_504(client,
"The server is already full. Try again later.");
global_unlock();
return;
}
......@@ -781,18 +787,23 @@ static void _handle_get_request(connection_t *con,
global_lock();
if (global.clients >= config_get_config()->client_limit) {
client->respcode = 504;
bytes = sock_write(client->con->sock,
"HTTP/1.0 504 Server Full\r\n"
"Content-Type: text/html\r\n\r\n"
"<b>The server is already full. Try again later.</b>\r\n");
if (bytes > 0) client->con->sent_bytes = bytes;
client_destroy(client);
client_send_504(client,
"The server is already full. Try again later.");
global_unlock();
avl_tree_unlock(global.source_tree);
return;
}
else if(source->max_listeners != -1 &&
source->listeners >= source->max_listeners)
{
client_send_504(client,
"Too many clients on this mountpoint. Try again later.");
global_unlock();
avl_tree_unlock(global.source_tree);
return;
}
global.clients++;
source->listeners++;
global_unlock();
client->format_data = source->format->create_client_data(
......
......@@ -3,6 +3,7 @@
#include <string.h>
#include <sys/types.h>
#include <ogg/ogg.h>
#include <errno.h>
#ifndef _WIN32
#include <unistd.h>
......@@ -55,7 +56,8 @@ static void _add_yp_info(source_t *source, char *stat_name,
void *info, int type);
source_t *source_create(client_t *client, connection_t *con,
http_parser_t *parser, const char *mount, format_type_t type)
http_parser_t *parser, const char *mount, format_type_t type,
mount_proxy *mountinfo)
{
int i = 0;
source_t *src;
......@@ -73,6 +75,8 @@ source_t *source_create(client_t *client, connection_t *con,
src->num_yp_directories = 0;
src->listeners = 0;
src->send_return = 0;
src->dumpfilename = NULL;
src->dumpfile = NULL;
src->audio_info = util_dict_new();
for (i=0;i<config_get_config()->num_yp_directories;i++) {
if (config_get_config()->yp_url[i]) {
......@@ -86,6 +90,20 @@ source_t *source_create(client_t *client, connection_t *con,
}
}
if(mountinfo != NULL) {
src->fallback_mount = mountinfo->fallback_mount;
src->max_listeners = mountinfo->max_listeners;
src->dumpfilename = mountinfo->dumpfile;
}
if(src->dumpfilename != NULL) {
src->dumpfile = fopen(src->dumpfilename, "ab");
if(src->dumpfile == NULL) {
WARN2("Cannot open dump file \"%s\" for appending: %s, disabling.",
src->dumpfilename, strerror(errno));
}
}
return src;
}
......@@ -170,7 +188,6 @@ void *source_main(void *arg)
int listeners = 0;
int i=0;
int suppress_yp = 0;
util_dict *audio_info;
char *ai;
long queue_limit = config_get_config()->queue_size_limit;
......@@ -378,6 +395,18 @@ void *source_main(void *arg)
** to catch back up if it can
*/
/* First, stream dumping, if enabled */
if(source->dumpfile) {
if(fwrite(refbuf->data, 1, refbuf->len, source->dumpfile) !=
refbuf->len)
{
WARN1("Write to dump file failed, disabling: %s",
strerror(errno));
fclose(source->dumpfile);
source->dumpfile = NULL;
}
}
/* acquire read lock on client_tree */
avl_tree_rlock(source->client_tree);
......@@ -586,6 +615,9 @@ done:
avl_delete(global.source_tree, source, source_free_source);
avl_tree_unlock(global.source_tree);
if(source->dumpfile)
fclose(source->dumpfile);
thread_exit(0);
return NULL;
......
......@@ -6,6 +6,8 @@
#include "util.h"
#include "format.h"
#include <stdio.h>
typedef struct source_tag
{
client_t *client;
......@@ -29,13 +31,19 @@ typedef struct source_tag
rwlock_t *shutdown_rwlock;
ypdata_t *ypdata[MAX_YP_DIRECTORIES];
util_dict *audio_info;
char *dumpfilename; /* Name of a file to dump incoming stream to */
FILE *dumpfile;
int num_yp_directories;
long listeners;
long max_listeners;
int send_return;
} source_t;
source_t *source_create(client_t *client, connection_t *con, http_parser_t *parser, const char *mount, format_type_t type);
source_t *source_create(client_t *client, connection_t *con,
http_parser_t *parser, const char *mount, format_type_t type,
mount_proxy *mountinfo);
source_t *source_find_mount(const char *mount);
int source_compare_sources(void *arg, void *a, void *b);
int source_free_source(void *key);
......
......@@ -414,6 +414,7 @@ const char *util_dict_get(util_dict *dict, const char *key)
return dict->val;
dict = dict->next;
}
return NULL;
}
int util_dict_set(util_dict *dict, const char *key, const char *val)
......@@ -521,3 +522,4 @@ char *util_dict_urlencode(util_dict *dict, char delim)
return 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