[xiph-commits] r9220 - icecast/trunk/icecast/src
karl at motherfish-iii.xiph.org
karl at motherfish-iii.xiph.org
Fri May 6 08:57:19 PDT 2005
Author: karl
Date: 2005-05-06 08:57:15 -0700 (Fri, 06 May 2005)
New Revision: 9220
Modified:
icecast/trunk/icecast/src/client.c
icecast/trunk/icecast/src/connection.c
icecast/trunk/icecast/src/fserve.c
icecast/trunk/icecast/src/source.c
icecast/trunk/icecast/src/stats.c
icecast/trunk/icecast/src/stats.h
Log:
merge from branch. push clients count handling to the client_create/_destroy
functions. call client_create in the general handler and pass client_t to the
specific handler including the stats request handler, which now logs in the
access log.
Modified: icecast/trunk/icecast/src/client.c
===================================================================
--- icecast/trunk/icecast/src/client.c 2005-05-06 13:37:25 UTC (rev 9219)
+++ icecast/trunk/icecast/src/client.c 2005-05-06 15:57:15 UTC (rev 9220)
@@ -27,8 +27,10 @@
#include "avl/avl.h"
#include "httpp/httpp.h"
+#include "cfgfile.h"
#include "connection.h"
#include "refbuf.h"
+#include "stats.h"
#include "client.h"
#include "logging.h"
@@ -38,8 +40,24 @@
client_t *client_create(connection_t *con, http_parser_t *parser)
{
+ ice_config_t *config = config_get_config ();
client_t *client = (client_t *)calloc(1, sizeof(client_t));
+ int client_limit = config->client_limit;
+ config_release_config ();
+ global_lock();
+ if (global.clients >= client_limit || client == NULL)
+ {
+ client_limit = global.clients;
+ global_unlock();
+ free (client);
+ WARN1 ("server client limit reached (%d clients)", client_limit);
+ return NULL;
+ }
+ global.clients++;
+ stats_event_args (NULL, "clients", "%d", global.clients);
+ global_unlock();
+
client->con = con;
client->parser = parser;
client->refbuf = NULL;
@@ -61,6 +79,11 @@
connection_close(client->con);
httpp_destroy(client->parser);
+ global_lock ();
+ global.clients--;
+ stats_event_args (NULL, "clients", "%d", global.clients);
+ global_unlock ();
+
/* drop ref counts if need be */
if (client->refbuf)
refbuf_release (client->refbuf);
Modified: icecast/trunk/icecast/src/connection.c
===================================================================
--- icecast/trunk/icecast/src/connection.c 2005-05-06 13:37:25 UTC (rev 9219)
+++ icecast/trunk/icecast/src/connection.c 2005-05-06 15:57:15 UTC (rev 9220)
@@ -500,7 +500,21 @@
* so we only do this once we know we're going to accept the source.
*/
if (source->client == NULL)
+ {
source->client = client_create (source->con, source->parser);
+ if (source->client == NULL)
+ {
+ config_release_config();
+ global_lock();
+ global.sources--;
+ global_unlock();
+ connection_close (source->con);
+ source->con = NULL;
+ httpp_destroy (source->parser);
+ source->parser = NULL;
+ return -1;
+ }
+ }
while (mountproxy)
{
@@ -686,14 +700,10 @@
}
-static void _handle_source_request(connection_t *con,
- http_parser_t *parser, char *uri, int auth_style)
+static void _handle_source_request (client_t *client, char *uri, int auth_style)
{
- client_t *client;
source_t *source;
- client = client_create(con, parser);
-
INFO1("Source logging in at mountpoint \"%s\"", uri);
if (uri[0] != '/')
@@ -702,9 +712,9 @@
client_send_401 (client);
return;
}
-
if (auth_style == ICECAST_SOURCE_AUTH) {
- if (!connection_check_source_pass(parser, uri)) {
+ if (connection_check_source_pass (client->parser, uri) == 0)
+ {
/* We commonly get this if the source client is using the wrong
* protocol: attempt to diagnose this and return an error
*/
@@ -721,8 +731,8 @@
source->shoutcast_compat = 1;
}
source->client = client;
- source->parser = parser;
- source->con = con;
+ source->parser = client->parser;
+ source->con = client->con;
if (connection_complete_source (source) < 0)
{
source->client = NULL;
@@ -740,35 +750,25 @@
}
-static void _handle_stats_request(connection_t *con,
- http_parser_t *parser, char *uri)
+static void _handle_stats_request (client_t *client, char *uri)
{
- stats_connection_t *stats;
-
stats_event_inc(NULL, "stats_connections");
-
- if (!connection_check_admin_pass(parser)) {
+
+ if (connection_check_admin_pass (client->parser) == 0)
+ {
+ client_send_401 (client);
ERROR0("Bad password for stats connection");
- connection_close(con);
- httpp_destroy(parser);
return;
}
-
+
stats_event_inc(NULL, "stats");
-
- /* create stats connection and create stats handler thread */
- stats = (stats_connection_t *)malloc(sizeof(stats_connection_t));
- stats->parser = parser;
- stats->con = con;
-
- thread_create("Stats Connection", stats_connection, (void *)stats, THREAD_DETACHED);
+
+ thread_create("Stats Connection", stats_connection, (void *)client, THREAD_DETACHED);
}
-static void _handle_get_request(connection_t *con,
- http_parser_t *parser, char *passed_uri)
+static void _handle_get_request (client_t *client, char *passed_uri)
{
char *fullpath;
- client_t *client;
int bytes;
struct stat statbuf;
source_t *source;
@@ -780,7 +780,6 @@
int serverport = 0;
aliases *alias;
ice_config_t *config;
- int client_limit;
int ret;
char *uri = passed_uri;
@@ -790,14 +789,13 @@
host = strdup (config->hostname);
port = config->port;
for(i = 0; i < global.server_sockets; i++) {
- if(global.serversock[i] == con->serversock) {
+ if(global.serversock[i] == client->con->serversock) {
serverhost = config->listeners[i].bind_address;
serverport = config->listeners[i].port;
break;
}
}
alias = config->aliases;
- client_limit = config->client_limit;
/* there are several types of HTTP GET clients
** media clients, which are looking for a source (eg, URI = /stream.ogg)
@@ -820,8 +818,6 @@
}
config_release_config();
- /* make a client */
- client = client_create(con, parser);
stats_event_inc(NULL, "client_connections");
/* Dispatch all admin requests */
@@ -894,16 +890,6 @@
}
free (host);
- global_lock();
- if (global.clients >= client_limit) {
- global_unlock();
- client_send_404(client,
- "The server is already full. Try again later.");
- if (uri != passed_uri) free (uri);
- return;
- }
- global_unlock();
-
avl_tree_rlock(global.source_tree);
source = source_find_mount(uri);
if (source) {
@@ -949,21 +935,12 @@
}
}
- /* And then check that there's actually room in the server... */
global_lock();
- if (global.clients >= client_limit) {
- global_unlock();
- avl_tree_unlock(global.source_tree);
- client_send_404(client,
- "The server is already full. Try again later.");
- if (uri != passed_uri) free (uri);
- return;
- }
/* Early-out for per-source max listeners. This gets checked again
* by the source itself, later. This route gives a useful message to
* the client, also.
*/
- else if(source->max_listeners != -1 &&
+ if (source->max_listeners != -1 &&
source->listeners >= source->max_listeners)
{
global_unlock();
@@ -973,7 +950,6 @@
if (uri != passed_uri) free (uri);
return;
}
- global.clients++;
global_unlock();
source->format->create_client_data (source, client);
@@ -1048,19 +1024,19 @@
"SOURCE %s HTTP/1.0\r\n%s", mount, header);
parser = httpp_create_parser();
httpp_initialize(parser, NULL);
- if (httpp_parse(parser, http_compliant, strlen(http_compliant))) {
- _handle_source_request(con, parser, mount, SHOUTCAST_SOURCE_AUTH);
- free(http_compliant);
- return;
+ if (httpp_parse (parser, http_compliant, strlen(http_compliant)))
+ {
+ client_t *client = client_create (con, parser);
+ if (client)
+ {
+ _handle_source_request (client, mount, SHOUTCAST_SOURCE_AUTH);
+ free (http_compliant);
+ return;
+ }
}
- else {
- ERROR0("Invalid source request");
- connection_close(con);
- free(http_compliant);
- httpp_destroy(parser);
- return;
- }
- return;
+ connection_close (con);
+ httpp_destroy (parser);
+ free (http_compliant);
}
static void *_handle_connection(void *arg)
@@ -1145,25 +1121,36 @@
rawuri = httpp_getvar(parser, HTTPP_VAR_URI);
uri = util_normalise_uri(rawuri);
- if(!uri) {
- client = client_create(con, parser);
- client_send_404(client, "The path you requested was invalid");
+ if (uri == NULL)
+ {
+ sock_write(con->sock, "The path you requested was invalid\r\n");
+ connection_close(con);
+ httpp_destroy(parser);
continue;
}
+ client = client_create (con, parser);
+ if (client == NULL)
+ {
+ sock_write (con->sock, "HTTP/1.0 404 File Not Found\r\n"
+ "Content-Type: text/html\r\n\r\n"
+ "<b>Connection limit reached</b>");
+ connection_close(con);
+ httpp_destroy(parser);
+ continue;
+ }
if (parser->req_type == httpp_req_source) {
- _handle_source_request(con, parser, uri, ICECAST_SOURCE_AUTH);
+ _handle_source_request (client, uri, ICECAST_SOURCE_AUTH);
}
else if (parser->req_type == httpp_req_stats) {
- _handle_stats_request(con, parser, uri);
+ _handle_stats_request (client, uri);
}
else if (parser->req_type == httpp_req_get) {
- _handle_get_request(con, parser, uri);
+ _handle_get_request (client, uri);
}
else {
ERROR0("Wrong request type from client");
- connection_close(con);
- httpp_destroy(parser);
+ client_send_400 (client, "unknown request");
}
free(uri);
Modified: icecast/trunk/icecast/src/fserve.c
===================================================================
--- icecast/trunk/icecast/src/fserve.c 2005-05-06 13:37:25 UTC (rev 9219)
+++ icecast/trunk/icecast/src/fserve.c 2005-05-06 15:57:15 UTC (rev 9220)
@@ -224,7 +224,6 @@
active_list = to_move;
client_tree_changed = 1;
fserve_clients++;
- stats_event_inc(NULL, "clients");
}
pending_list = NULL;
thread_mutex_unlock (&pending_lock);
@@ -303,10 +302,6 @@
fserve_t *to_go = (fserve_t *)pending_list;
pending_list = to_go->next;
- /* Argh! _free_client decrements "clients" in stats, but it hasn't been
- incremented if the client is still on the pending list. So, fix that
- up first. Messy. */
- stats_event_inc(NULL, "clients");
_free_client (to_go);
}
thread_mutex_unlock (&pending_lock);
@@ -395,21 +390,6 @@
client->content_length = (int64_t)file_buf.st_size;
}
- global_lock();
- if(global.clients >= client_limit) {
- global_unlock();
- httpclient->respcode = 504;
- bytes = sock_write(httpclient->con->sock,
- "HTTP/1.0 504 Server Full\r\n"
- "Content-Type: text/html\r\n\r\n"
- "<b>Server is full, try again later.</b>\r\n");
- if(bytes > 0) httpclient->con->sent_bytes = bytes;
- fserve_client_destroy(client);
- return -1;
- }
- global.clients++;
- global_unlock();
-
range = httpp_getvar (client->client->parser, "range");
if (range != NULL) {
@@ -510,11 +490,6 @@
fserve_t *client = (fserve_t *)key;
fserve_client_destroy(client);
- global_lock();
- global.clients--;
- global_unlock();
- stats_event_dec(NULL, "clients");
-
return 1;
}
Modified: icecast/trunk/icecast/src/source.c
===================================================================
--- icecast/trunk/icecast/src/source.c 2005-05-06 13:37:25 UTC (rev 9219)
+++ icecast/trunk/icecast/src/source.c 2005-05-06 15:57:15 UTC (rev 9220)
@@ -219,9 +219,6 @@
avl_tree_rlock (source->pending_tree);
while (avl_get_first (source->pending_tree))
{
- /* _free_client decrements client count, so increment it first... */
- stats_event_inc(NULL, "clients");
-
avl_delete (source->pending_tree,
avl_get_first(source->pending_tree)->key, _free_client);
}
@@ -697,9 +694,6 @@
client_node = avl_get_first(source->pending_tree);
while (client_node) {
- /* We have to do this first, since _free_client decrements it... */
- stats_event_inc(NULL, "clients");
-
if(source->max_listeners != -1 &&
source->listeners >= source->max_listeners)
{
@@ -836,11 +830,6 @@
{
client_t *client = (client_t *)key;
- global_lock();
- global.clients--;
- global_unlock();
- stats_event_dec(NULL, "clients");
-
client_destroy(client);
return 1;
Modified: icecast/trunk/icecast/src/stats.c
===================================================================
--- icecast/trunk/icecast/src/stats.c 2005-05-06 13:37:25 UTC (rev 9219)
+++ icecast/trunk/icecast/src/stats.c 2005-05-06 15:57:15 UTC (rev 9220)
@@ -679,15 +679,18 @@
return event;
}
-static int _send_event_to_client(stats_event_t *event, connection_t *con)
+static int _send_event_to_client(stats_event_t *event, client_t *client)
{
- int ret;
+ int ret = -1, len;
+ char buf [200];
/* send data to the client!!!! */
- ret = sock_write(con->sock, "EVENT %s %s %s\n",
+ len = snprintf (buf, sizeof (buf), "EVENT %s %s %s\n",
(event->source != NULL) ? event->source : "global",
event->name ? event->name : "null",
event->value ? event->value : "null");
+ if (len > 0 && len < sizeof (buf))
+ ret = client_send_bytes (client, buf, len);
return (ret == -1) ? 0 : 1;
}
@@ -775,7 +778,7 @@
void *stats_connection(void *arg)
{
- stats_connection_t *statcon = (stats_connection_t *)arg;
+ client_t *client = (client_t *)arg;
stats_event_t *local_event_queue = NULL;
mutex_t local_event_mutex;
stats_event_t *event;
@@ -785,6 +788,7 @@
/* increment the thread count */
thread_mutex_lock(&_stats_mutex);
_stats_threads++;
+ stats_event_args (NULL, "stats", "%d", _stats_threads);
thread_mutex_unlock(&_stats_mutex);
thread_mutex_create(&local_event_mutex);
@@ -795,7 +799,7 @@
thread_mutex_lock(&local_event_mutex);
event = _get_event_from_queue(&local_event_queue);
if (event != NULL) {
- if (!_send_event_to_client(event, statcon->con)) {
+ if (!_send_event_to_client(event, client)) {
_free_event(event);
thread_mutex_unlock(&local_event_mutex);
break;
@@ -813,9 +817,11 @@
thread_mutex_lock(&_stats_mutex);
_unregister_listener (&local_event_queue);
_stats_threads--;
+ stats_event_args (NULL, "stats", "%d", _stats_threads);
thread_mutex_unlock(&_stats_mutex);
thread_mutex_destroy(&local_event_mutex);
+ client_destroy (client);
INFO0 ("stats client finished");
return NULL;
Modified: icecast/trunk/icecast/src/stats.h
===================================================================
--- icecast/trunk/icecast/src/stats.h 2005-05-06 13:37:25 UTC (rev 9219)
+++ icecast/trunk/icecast/src/stats.h 2005-05-06 15:57:15 UTC (rev 9220)
@@ -21,12 +21,6 @@
#include <libxml/tree.h>
-typedef struct _stats_connection_tag
-{
- connection_t *con;
- http_parser_t *parser;
-} stats_connection_t;
-
typedef struct _stats_node_tag
{
char *name;
More information about the commits
mailing list