[xiph-commits] r9140 - icecast/branches/kh/icecast/src

karl at motherfish-iii.xiph.org karl at motherfish-iii.xiph.org
Fri Apr 15 03:58:54 PDT 2005


Author: karl
Date: 2005-04-15 03:58:47 -0700 (Fri, 15 Apr 2005)
New Revision: 9140

Modified:
   icecast/branches/kh/icecast/src/admin.c
   icecast/branches/kh/icecast/src/auth.c
   icecast/branches/kh/icecast/src/client.c
   icecast/branches/kh/icecast/src/connection.c
   icecast/branches/kh/icecast/src/format.c
   icecast/branches/kh/icecast/src/format_mp3.c
   icecast/branches/kh/icecast/src/format_ogg.c
   icecast/branches/kh/icecast/src/fserve.c
   icecast/branches/kh/icecast/src/slave.c
   icecast/branches/kh/icecast/src/source.c
   icecast/branches/kh/icecast/src/source.h
   icecast/branches/kh/icecast/src/stats.c
Log:
push global clients count handling to client_create/destroy. call the create in the main
connection handler code and pass that to the specific request handlers. 
drop references to parser/con in source


Modified: icecast/branches/kh/icecast/src/admin.c
===================================================================
--- icecast/branches/kh/icecast/src/admin.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/admin.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -264,7 +264,7 @@
             if (source->running)
             {
                 snprintf (buf, sizeof(buf), "%lu",
-                        (unsigned long)(now - source->con->con_time));
+                        (unsigned long)(now - source->client->con->con_time));
                 xmlNewChild (srcnode, NULL, "Connected", buf);
                 xmlNewChild (srcnode, NULL, "content-type", 
                         source->format->contenttype);

Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/auth.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -121,10 +121,6 @@
     {
         client_t *client = auth_user->client;
 
-        /* failed client, drop global count */
-        global_lock();
-        global.clients--;
-        global_unlock();
         if (client->respcode)
             client_destroy (client);
         else
@@ -264,7 +260,6 @@
         slave_rescan();
     }
     DEBUG1 ("Added client to pending on %s", source->mount);
-    stats_event_inc (NULL, "clients");
     return 0;
 }
 

Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/client.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -27,9 +27,11 @@
 #include "avl/avl.h"
 #include "httpp/httpp.h"
 
+#include "cfgfile.h"
 #include "connection.h"
 #include "refbuf.h"
 #include "format.h"
+#include "stats.h"
 
 #include "client.h"
 #include "logging.h"
@@ -43,8 +45,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;
@@ -67,6 +85,7 @@
      */
     if(client->con->ip)
         logging_access(client);
+
 #ifdef HAVE_AIO
     if (aio_cancel (client->con->sock, NULL) == AIO_NOTCANCELED)
     {
@@ -82,6 +101,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/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/connection.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -671,14 +671,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] != '/')
@@ -688,7 +684,7 @@
         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
@@ -706,8 +702,6 @@
             source->shoutcast_compat = 1;
         }
         source->client = client;
-        source->parser = parser;
-        source->con = con;
         if (connection_complete_source (source, NULL, NULL) < 0)
         {
             source->client = NULL;
@@ -725,35 +719,24 @@
 }
 
 
-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)
 {
-    client_t *client;
     int fileserve;
     char *host = NULL;
     int port;
@@ -772,7 +755,7 @@
         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;
@@ -802,8 +785,6 @@
     }
     config_release_config();
 
-    /* make a client */
-    client = client_create(con, parser);
     stats_event_inc(NULL, "client_connections");
 
     /* Dispatch all admin requests */
@@ -816,21 +797,6 @@
     }
     free (host);
 
-    global_lock();
-    if (global.clients >= client_limit)
-    {
-        global_unlock();
-        if (slave_redirect (uri, client) == 0)
-        {
-            client_send_404(client,
-                    "The server is already full. Try again later.");
-        }
-        if (uri != passed_uri) free (uri);
-        return;
-    }
-    global.clients++;
-    global_unlock();
-
     add_client (uri, client);
 
     if (uri != passed_uri) free (uri);
@@ -842,6 +808,7 @@
     int http_compliant_len = 0;
     char header[4096];
     http_parser_t *parser;
+    client_t *client;
 
     memset(shoutcast_password, 0, sizeof (shoutcast_password));
     /* Step one of shoutcast auth protocol, read encoder password (1 line) */
@@ -884,8 +851,15 @@
             "SOURCE %s HTTP/1.0\r\n%s", mount, header);
     parser = httpp_create_parser();
     httpp_initialize(parser, NULL);
+    client = client_create (con, parser);
+    if (client == NULL)
+    {
+        connection_close (con);
+        httpp_destroy (parser);
+        return;
+    }
     if (httpp_parse(parser, http_compliant, strlen(http_compliant))) {
-        _handle_source_request(con, parser, mount, SHOUTCAST_SOURCE_AUTH);
+        _handle_source_request (client, mount, SHOUTCAST_SOURCE_AUTH);
         free(http_compliant);
         return;
     }
@@ -981,20 +955,29 @@
                 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)
+                {
+                    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");

Modified: icecast/branches/kh/icecast/src/format.c
===================================================================
--- icecast/branches/kh/icecast/src/format.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/format.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -240,8 +240,8 @@
     ptr += bytes;
 
     /* iterate through source http headers and send to client */
-    avl_tree_rlock (source->parser->vars);
-    node = avl_get_first (source->parser->vars);
+    avl_tree_rlock (source->client->parser->vars);
+    node = avl_get_first (source->client->parser->vars);
     while (node)
     {
         int next = 1;
@@ -295,7 +295,7 @@
         if (next)
             node = avl_get_next (node);
     }
-    avl_tree_unlock (source->parser->vars);
+    avl_tree_unlock (source->client->parser->vars);
 
     bytes = snprintf (ptr, remaining, "Server: %s\r\n", ICECAST_VERSION_STRING);
     remaining -= bytes;

Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/format_mp3.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -91,7 +91,7 @@
     plugin->set_tag = mp3_set_tag;
     plugin->apply_settings = format_mp3_apply_settings;
 
-    plugin->contenttype = httpp_getvar (source->parser, "content-type");
+    plugin->contenttype = httpp_getvar (source->client->parser, "content-type");
     if (plugin->contenttype == NULL) {
         /* We default to MP3 audio for old clients without content types */
         plugin->contenttype = "audio/mpeg";
@@ -107,7 +107,7 @@
     state->metadata = meta;
     state->interval = -1;
 
-    metadata = httpp_getvar (source->parser, "icy-metaint");
+    metadata = httpp_getvar (source->client->parser, "icy-metaint");
     if (metadata)
     {
         state->inline_metadata_interval = atoi (metadata);
@@ -417,7 +417,7 @@
 
     if ((refbuf = refbuf_new (2048)) == NULL)
         return NULL;
-    bytes = sock_read_bytes (source->con->sock, refbuf->data, 2048);
+    bytes = sock_read_bytes (source->client->con->sock, refbuf->data, 2048);
 
     if (bytes == 0)
     {
@@ -464,7 +464,7 @@
     refbuf = refbuf_new (2048);
     src = refbuf->data;
 
-    ret = sock_read_bytes (source->con->sock, refbuf->data, 2048);
+    ret = sock_read_bytes (source->client->con->sock, refbuf->data, 2048);
 
     if (ret == 0)
     {

Modified: icecast/branches/kh/icecast/src/format_ogg.c
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/format_ogg.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -409,7 +409,7 @@
         /* we need more data to continue getting pages */
         data = ogg_sync_buffer (&ogg_info->oy, 4096);
 
-        bytes = sock_read_bytes (source->con->sock, data, 4096);
+        bytes = sock_read_bytes (source->client->con->sock, data, 4096);
         if (bytes < 0)
         {
             if (sock_recoverable (sock_error()))

Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/fserve.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -225,7 +225,6 @@
                 active_list = to_move;
                 client_tree_changed = 1;
                 fserve_clients++;
-                stats_event_inc(NULL, "clients");
             }
             pending_list = NULL;
             thread_mutex_unlock (&pending_lock);
@@ -301,10 +300,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);
@@ -468,21 +463,6 @@
     httpclient->pos = BUFSIZE;
     client->content_length = (int64_t)file_buf.st_size;
 
-    global_lock();
-    if(global.clients >= client_limit) {
-        global_unlock();
-        httpclient->respcode = 503;
-        bytes = sock_write(httpclient->con->sock,
-                "HTTP/1.0 503 Service Unavailable\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 0;
-    }
-    global.clients++;
-    global_unlock();
-
     range = httpp_getvar (client->client->parser, "range");
 
     do
@@ -565,11 +545,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/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/slave.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -298,8 +298,6 @@
             ERROR1("Error from relay request: %s", httpp_getvar(parser, HTTPP_VAR_ERROR_MESSAGE));
             break;
         }
-        src->parser = parser;
-        src->con = con;
         if (connection_complete_source (src, con, parser) < 0)
         {
             DEBUG0("Failed to complete source initialisation");
@@ -340,10 +338,8 @@
         sock_close (streamsock);
     if (con)
         connection_close (con);
-    src->con = NULL;
     if (parser)
         httpp_destroy (parser);
-    src->parser = NULL;
     source_clear_source (relay->source);
 
     /* initiate an immediate relay cleanup run */

Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/source.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -206,8 +206,6 @@
     DEBUG1 ("clearing source \"%s\"", source->mount);
     client_destroy(source->client);
     source->client = NULL;
-    source->parser = NULL;
-    source->con = NULL;
 
     if (source->dumpfile)
     {
@@ -478,8 +476,8 @@
 
         thread_mutex_unlock (&source->lock);
 
-        if (source->con)
-            fds = util_timed_wait_for_fd (source->con->sock, delay);
+        if (source->client->con)
+            fds = util_timed_wait_for_fd (source->client->con->sock, delay);
         else
         {
             thread_sleep (delay*1000);
@@ -739,12 +737,14 @@
         str = "0";
         if (source->yp_prevent)
             break;
-        if ((str = httpp_getvar (source->parser, "ice-public")))
+        if ((str = httpp_getvar (source->client->parser, "ice-public")))
             break;
-        if ((str = httpp_getvar (source->parser, "icy-pub")))
+        if ((str = httpp_getvar (source->client->parser, "icy-pub")))
             break;
+        if ((str = httpp_getvar (source->client->parser, "x-audiocast-public")))
+            break;
         /* handle header from icecast v2 release */
-        if ((str = httpp_getvar (source->parser, "icy-public")))
+        if ((str = httpp_getvar (source->client->parser, "icy-public")))
             break;
         str = "0";
     } while (0);
@@ -770,15 +770,15 @@
     stats_event_inc (NULL, "sources");
     stats_event_inc (NULL, "source_total_connections");
 
-    if (source->con)
-        sock_set_blocking (source->con->sock, SOCK_NONBLOCK);
+    if (source->client->con)
+        sock_set_blocking (source->client->con->sock, SOCK_NONBLOCK);
 
     DEBUG0("Source creation complete");
     source->last_read = time (NULL);
     source->running = 1;
 
     source->audio_info = util_dict_new();
-    str = httpp_getvar(source->parser, "ice-audio-info");
+    str = httpp_getvar(source->client->parser, "ice-audio-info");
     if (str)
     {
         _parse_audio_info (source, str);
@@ -939,11 +939,6 @@
 
 int source_free_client (source_t *source, client_t *client)
 {
-    global_lock();
-    global.clients--;
-    global_unlock();
-    stats_event_dec(NULL, "clients");
-
     client_set_queue (client, NULL);
 
     /* if no response has been sent then send a 404 */
@@ -1087,6 +1082,7 @@
 {
     mount_proxy *mountinfo = config_find_mount (config, source->mount);
     char *str;
+    http_parser_t *parser = source->client->parser;
 
     /* set global settings first */
     source->queue_size_limit = config->queue_size_limit;
@@ -1095,47 +1091,47 @@
     source->dumpfilename = NULL;
     
     do {
-        str = httpp_getvar(source->parser, "ice-name");
+        str = httpp_getvar(parser, "ice-name");
         if (str) break;
-        str = httpp_getvar(source->parser, "icy-name");
+        str = httpp_getvar(parser, "icy-name");
         if (str) break;
-        str = httpp_getvar(source->parser, "x-audiocast-name");
+        str = httpp_getvar(parser, "x-audiocast-name");
     } while (0);
     stats_event (source->mount, "server_name", str);
 
     do {
-        str = httpp_getvar(source->parser, "ice-description");
+        str = httpp_getvar(parser, "ice-description");
         if (str) break;
-        str = httpp_getvar(source->parser, "icy-description");
+        str = httpp_getvar(parser, "icy-description");
         if (str) break;
-        str = httpp_getvar(source->parser, "x-audiocast-description");
+        str = httpp_getvar(parser, "x-audiocast-description");
     } while (0);
     stats_event (source->mount, "server_description", str);
 
     do {
-        str = httpp_getvar(source->parser, "ice-genre");
+        str = httpp_getvar(parser, "ice-genre");
         if (str) break;
-        str = httpp_getvar(source->parser, "icy-genre");
+        str = httpp_getvar(parser, "icy-genre");
         if (str) break;
-        str = httpp_getvar(source->parser, "x-audiocast-genre");
+        str = httpp_getvar(parser, "x-audiocast-genre");
     } while (0);
     stats_event (source->mount, "genre", str);
 
     do {
-        str = httpp_getvar(source->parser, "ice-url");
+        str = httpp_getvar(parser, "ice-url");
         if (str) break;
-        str = httpp_getvar(source->parser, "icy-url");
+        str = httpp_getvar(parser, "icy-url");
         if (str) break;
-        str = httpp_getvar(source->parser, "x-audiocast-url");
+        str = httpp_getvar(parser, "x-audiocast-url");
     } while (0);
     stats_event (source->mount, "server_url", str);
 
     do {
-        str = httpp_getvar(source->parser, "ice-bitrate");
+        str = httpp_getvar(parser, "ice-bitrate");
         if (str) break;
-        str = httpp_getvar(source->parser, "icy-br");
+        str = httpp_getvar(parser, "icy-br");
         if (str) break;
-        str = httpp_getvar(source->parser, "x-audiocast-bitrate");
+        str = httpp_getvar(parser, "x-audiocast-bitrate");
     } while (0);
     stats_event (source->mount, "bitrate", str);
 
@@ -1322,9 +1318,9 @@
             break;
         }
         type = fserve_content_type (mount);
-        source->parser = httpp_create_parser();
-        httpp_initialize (source->parser, NULL);
-        httpp_setvar (source->parser, "content-type", type);
+        source->client->parser = httpp_create_parser();
+        httpp_initialize (source->client->parser, NULL);
+        httpp_setvar (source->client->parser, "content-type", type);
         source->hidden = 1;
         source->file_only = 1;
         source->yp_prevent = 1;

Modified: icecast/branches/kh/icecast/src/source.h
===================================================================
--- icecast/branches/kh/icecast/src/source.h	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/source.h	2005-04-15 10:58:47 UTC (rev 9140)
@@ -23,8 +23,6 @@
 typedef struct source_tag
 {
     client_t *client;
-    connection_t *con;
-    http_parser_t *parser;
     
     char *mount;
 

Modified: icecast/branches/kh/icecast/src/stats.c
===================================================================
--- icecast/branches/kh/icecast/src/stats.c	2005-04-15 02:07:29 UTC (rev 9139)
+++ icecast/branches/kh/icecast/src/stats.c	2005-04-15 10:58:47 UTC (rev 9140)
@@ -756,7 +756,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;
@@ -774,7 +774,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->con)) {
                 _free_event(event);
                 thread_mutex_unlock(&local_event_mutex);
                 break;



More information about the commits mailing list