diff --git a/src/cfgfile.c b/src/cfgfile.c index f78095ee..2dd2e547 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -49,11 +49,13 @@ #define CONFIG_DEFAULT_CLIENT_LIMIT 256 #define CONFIG_DEFAULT_SOURCE_LIMIT 16 #define CONFIG_DEFAULT_QUEUE_SIZE_LIMIT (500*1024) +#define CONFIG_DEFAULT_BODY_SIZE_LIMIT (4*1024) #define CONFIG_DEFAULT_BURST_SIZE (64*1024) #define CONFIG_DEFAULT_THREADPOOL_SIZE 4 #define CONFIG_DEFAULT_CLIENT_TIMEOUT 30 #define CONFIG_DEFAULT_HEADER_TIMEOUT 15 #define CONFIG_DEFAULT_SOURCE_TIMEOUT 10 +#define CONFIG_DEFAULT_BODY_TIMEOUT (10 + CONFIG_DEFAULT_HEADER_TIMEOUT) #define CONFIG_DEFAULT_MASTER_USERNAME "relay" #define CONFIG_DEFAULT_SHOUTCAST_MOUNT "/stream" #define CONFIG_DEFAULT_SHOUTCAST_USER "source" @@ -801,12 +803,16 @@ static void _set_defaults(ice_config_t *configuration) ->source_limit = CONFIG_DEFAULT_SOURCE_LIMIT; configuration ->queue_size_limit = CONFIG_DEFAULT_QUEUE_SIZE_LIMIT; + configuration + ->body_size_limit = CONFIG_DEFAULT_BODY_SIZE_LIMIT; configuration ->client_timeout = CONFIG_DEFAULT_CLIENT_TIMEOUT; configuration ->header_timeout = CONFIG_DEFAULT_HEADER_TIMEOUT; configuration ->source_timeout = CONFIG_DEFAULT_SOURCE_TIMEOUT; + configuration + ->source_timeout = CONFIG_DEFAULT_BODY_TIMEOUT; configuration ->shoutcast_mount = (char *) xmlCharStrdup(CONFIG_DEFAULT_SHOUTCAST_MOUNT); configuration @@ -1123,6 +1129,8 @@ static void _parse_limits(xmlDocPtr doc, __read_int(doc, node, &configuration->client_limit, " must not be empty."); } else if (xmlStrcmp(node->name, XMLSTR("sources")) == 0) { __read_int(doc, node, &configuration->source_limit, " must not be empty."); + } else if (xmlStrcmp(node->name, XMLSTR("bodysize")) == 0) { + __read_int(doc, node, &configuration->body_size_limit, " must not be empty."); } else if (xmlStrcmp(node->name, XMLSTR("queue-size")) == 0) { __read_unsigned_int(doc, node, &configuration->queue_size_limit, " must not be empty."); } else if (xmlStrcmp(node->name, XMLSTR("threadpool")) == 0) { @@ -1134,6 +1142,8 @@ static void _parse_limits(xmlDocPtr doc, __read_int(doc, node, &configuration->header_timeout, " must not be empty."); } else if (xmlStrcmp(node->name, XMLSTR("source-timeout")) == 0) { __read_int(doc, node, &configuration->source_timeout, " must not be empty."); + } else if (xmlStrcmp(node->name, XMLSTR("body-timeout")) == 0) { + __read_int(doc, node, &configuration->body_timeout, " must not be empty."); } else if (xmlStrcmp(node->name, XMLSTR("burst-on-connect")) == 0) { ICECAST_LOG_WARN(" is deprecated, use instead."); tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); diff --git a/src/cfgfile.h b/src/cfgfile.h index 25fbfbbb..55ab1d98 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -26,6 +26,7 @@ #include "common/thread/thread.h" #include "common/avl/avl.h" #include "icecasttypes.h" +#include "compat.h" #define XMLSTR(str) ((xmlChar *)(str)) @@ -170,11 +171,13 @@ struct ice_config_tag { int client_limit; int source_limit; + int body_size_limit; unsigned int queue_size_limit; unsigned int burst_size; int client_timeout; int header_timeout; int source_timeout; + int body_timeout; int fileserve; int on_demand; /* global setting for all relays */ diff --git a/src/connection.c b/src/connection.c index e3bb9890..33022ebe 100644 --- a/src/connection.c +++ b/src/connection.c @@ -611,11 +611,19 @@ static void _add_body_client(client_queue_t *node) static void process_request_body_queue (void) { client_queue_t **node_ref = (client_queue_t **)&_body_queue; + ice_config_t *config; + time_t timeout; + size_t body_size_limit; ICECAST_LOG_DEBUG("Processing body queue."); ICECAST_LOG_DEBUG("_body_queue=%p, &_body_queue=%p, _body_queue_tail=%p", _body_queue, &_body_queue, _body_queue_tail); + config = config_get_config(); + timeout = time(NULL) - config->body_timeout; + body_size_limit = config->body_size_limit; + config_release_config(); + while (*node_ref) { client_queue_t *node = *node_ref; client_t *client = node->client; @@ -625,7 +633,7 @@ static void process_request_body_queue (void) res = client_body_skip(client); - if (res != CLIENT_SLURP_NEEDS_MORE_DATA) { + if (res != CLIENT_SLURP_NEEDS_MORE_DATA || client->con->con_time <= timeout || client->request_body_read >= body_size_limit) { ICECAST_LOG_DEBUG("Putting client %p back in connection queue.", client); if ((client_queue_t **)_body_queue_tail == &(node->next))