[xiph-cvs] cvs commit: icecast/src connection.c fserve.c fserve.h main.c util.c util.h

Michael Smith msmith at xiph.org
Sun Aug 18 01:49:25 PDT 2002



msmith      02/08/18 04:49:25

  Modified:    src      connection.c fserve.c fserve.h main.c util.c util.h
  Log:
  Fileserving that might actually work for > 1 user.
  cleanups for the base64 decoder.

Revision  Changes    Path
1.28      +1 -7      icecast/src/connection.c

Index: connection.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/connection.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- connection.c	18 Aug 2002 05:06:58 -0000	1.27
+++ connection.c	18 Aug 2002 08:49:25 -0000	1.28
@@ -533,13 +533,7 @@
         }
     else if(config_get_config()->fileserve && 
             stat(fullpath, &statbuf) == 0) {
-        client->respcode = 200;
-        bytes = sock_write(client->con->sock, 
-                "HTTP/1.0 200 OK\r\nContent-Type: %s\r\n\r\n", 
-                fserve_content_type(fullpath));
-        if(bytes > 0) client->con->sent_bytes = bytes;
-        if(fserve_client_create(client, fullpath) < 0)
-            client_destroy(client);
+        fserve_client_create(client, fullpath);
         free(fullpath);
         return;
     }

<p><p>1.2       +91 -3     icecast/src/fserve.c

Index: fserve.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/fserve.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- fserve.c	18 Aug 2002 05:06:58 -0000	1.1
+++ fserve.c	18 Aug 2002 08:49:25 -0000	1.2
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
+#include <sys/poll.h>
 
 #ifndef _WIN32
 #include <unistd.h>
@@ -41,6 +42,11 @@
 static cond_t fserv_cond;
 static thread_t *fserv_thread;
 static int run_fserv;
+static int fserve_clients;
+static int client_tree_changed=0;
+
+static struct pollfd *ufds = NULL;
+static int ufdssize = 0;
 
 /* avl tree helper */
 static int _compare_clients(void *compare_arg, void *a, void *b);
@@ -77,6 +83,42 @@
     avl_tree_free(pending_tree, _free_client);
 }
 
+static void wait_for_fds() {
+    avl_node *client_node;
+    fserve_t *client;
+    int i;
+
+    while(run_fserv) {
+        if(client_tree_changed) {
+            client_tree_changed = 0;
+            i = 0;
+            ufdssize = fserve_clients;
+            ufds = realloc(ufds, ufdssize * sizeof(struct pollfd));
+            avl_tree_rlock(client_tree);
+            client_node = avl_get_first(client_tree);
+            while(client_node) {
+                client = client_node->key;
+                ufds[i].fd = client->client->con->sock;
+                ufds[i].events = POLLOUT;
+                client_node = avl_get_next(client_node);
+            }
+            avl_tree_unlock(client_tree);
+        }
+
+        if(poll(ufds, ufdssize, 200) > 0) {
+            return;
+        }
+        else {
+            avl_tree_rlock(pending_tree);
+            client_node = avl_get_first(pending_tree);
+            avl_tree_unlock(pending_tree);
+            if(client_node)
+                return;
+        }
+    }
+}
+
+
 void *fserv_thread_function(void *arg)
 {
     avl_node *client_node, *pending_node;
@@ -88,15 +130,25 @@
 
         client_node = avl_get_first(client_tree);
         if(!client_node) {
+            avl_tree_rlock(pending_tree);
             pending_node = avl_get_first(pending_tree);
             if(!pending_node) {
                 /* There are no current clients. Wait until there are... */
+                avl_tree_unlock(pending_tree);
                 avl_tree_unlock(client_tree);
                 thread_cond_wait(&fserv_cond);
                 continue;
             }
+            avl_tree_unlock(pending_tree);
         }
 
+        /* This isn't hugely efficient, but it'll do for now */
+        avl_tree_unlock(client_tree);
+        wait_for_fds();
+
+        avl_tree_rlock(client_tree);
+        client_node = avl_get_first(client_tree);
+
         while(client_node) {
             avl_node_wlock(client_node);
 
@@ -145,8 +197,10 @@
         while(client_node) {
             client = (fserve_t *)client_node->key;
             if(client->client->con->error) {
+                fserve_clients--;
                 client_node = avl_get_next(client_node);
                 avl_delete(client_tree, (void *)client, _free_client);
+                client_tree_changed = 1;
                 continue;
             }
             client_node = avl_get_next(client_node);
@@ -159,6 +213,9 @@
         while(client_node) {
             client = (fserve_t *)client_node->key;
             avl_insert(client_tree, client);
+            client_tree_changed = 1;
+            fserve_clients++;
+            stats_event_inc(NULL, "clients");
             client_node = avl_get_next(client_node);
 
         }
@@ -191,7 +248,7 @@
     return NULL;
 }
 
-char *fserve_content_type(char *path)
+static char *fserve_content_type(char *path)
 {
     char *ext = util_get_extension(path);
 
@@ -225,17 +282,43 @@
 int fserve_client_create(client_t *httpclient, char *path)
 {
     fserve_t *client = calloc(1, sizeof(fserve_t));
+    int bytes;
 
-    client->client = httpclient;
     client->file = fopen(path, "rb");
     if(!client->file) {
-        fserve_client_destroy(client);
+        client_send_404(httpclient, "File not readable");
         return -1;
     }
+
+    client->client = httpclient;
     client->offset = 0;
     client->datasize = 0;
     client->buf = malloc(BUFSIZE);
 
+    global_lock();
+    if(global.clients >= config_get_config()->client_limit) {
+        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);
+        global_unlock();
+        return -1;
+    }
+    global.clients++;
+    global_unlock();
+
+    httpclient->respcode = 200;
+    bytes = sock_write(httpclient->con->sock,
+            "HTTP/1.0 200 OK\r\n"
+            "Content-Type: %s\r\n\r\n",
+            fserve_content_type(path));
+    if(bytes > 0) httpclient->con->sent_bytes = bytes;
+
+    sock_set_blocking(client->client->con->sock, SOCK_NONBLOCK);
+
     avl_tree_wlock(pending_tree);
     avl_insert(pending_tree, client);
     avl_tree_unlock(pending_tree);
@@ -266,6 +349,11 @@
         fserve_t *client = (fserve_t *)key;
 
         fserve_client_destroy(client);
+    global_lock();
+    global.clients--;
+    global_unlock();
+    stats_event_dec(NULL, "clients");
+
         
         return 1;
 }

<p><p>1.2       +0 -1      icecast/src/fserve.h

Index: fserve.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/fserve.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- fserve.h	18 Aug 2002 05:06:58 -0000	1.1
+++ fserve.h	18 Aug 2002 08:49:25 -0000	1.2
@@ -15,7 +15,6 @@
 
 void fserve_initialize(void);
 void fserve_shutdown(void);
-char *fserve_content_type(char *path);
 int fserve_client_create(client_t *httpclient, char *path);
 
 

<p><p>1.17      +10 -9     icecast/src/main.c

Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/main.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- main.c	18 Aug 2002 05:06:58 -0000	1.16
+++ main.c	18 Aug 2002 08:49:25 -0000	1.17
@@ -43,6 +43,12 @@
         printf("\n");
 }
 
+static void _stop_logging(void)
+{
+	log_close(errorlog);
+	log_close(accesslog);
+}
+
 static void _initialize_subsystems(void)
 {
         log_initialize();
@@ -54,7 +60,6 @@
         global_initialize();
         refbuf_initialize();
     xslt_initialize();
-    DEBUG0("Calling fserve_initialize()");
     fserve_initialize();
 }
 
@@ -65,6 +70,10 @@
         refbuf_shutdown();
         stats_shutdown();
         slave_shutdown();
+
+    /* Now that these are done, we can stop the loggers. */
+	_stop_logging();
+
         global_shutdown();
         connection_shutdown();
         config_shutdown();
@@ -127,12 +136,6 @@
         return 0;
 }
 
-static void _stop_logging(void)
-{
-	log_close(errorlog);
-	log_close(accesslog);
-}
-
 static int _setup_socket(void)
 {
         ice_config_t *config;
@@ -344,8 +347,6 @@
         _server_proc();
 
         INFO0("Shutting down");
-
-	_stop_logging();
 
         _shutdown_subsystems();
 

<p><p>1.13      +24 -23    icecast/src/util.c

Index: util.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/util.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- util.c	17 Aug 2002 04:48:07 -0000	1.12
+++ util.c	18 Aug 2002 08:49:25 -0000	1.13
@@ -275,6 +275,25 @@
     'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
 };
 
+static signed char base64decode[256] = {
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
+     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -1, -2, -2,
+     -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
+     -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+     -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
+};
+
 /* This isn't efficient, but it doesn't need to be */
 char *util_base64_encode(char *data)
 {
@@ -309,25 +328,7 @@
     return result;
 }
 
-static int base64chartoval(char input)
-{
-    if(input >= 'A' && input <= 'Z')
-        return input - 'A';
-    else if(input >= 'a' && input <= 'z')
-        return input - 'a' + 26;
-    else if(input >= '0' && input <= '9')
-        return input - '0' + 52;
-    else if(input == '+')
-        return 62;
-    else if(input == '/')
-        return 63;
-    else if(input == '=')
-        return -1;
-    else
-        return -2;
-}
-
-char *util_base64_decode(char *input)
+char *util_base64_decode(unsigned char *input)
 {
     int len = strlen(input);
     char *out = malloc(len*3/4 + 5);
@@ -341,10 +342,10 @@
             return NULL; /* Invalid Base64 data */
         }
 
-        vals[0] = base64chartoval(*input++);
-        vals[1] = base64chartoval(*input++);
-        vals[2] = base64chartoval(*input++);
-        vals[3] = base64chartoval(*input++);
+        vals[0] = base64decode[*input++];
+        vals[1] = base64decode[*input++];
+        vals[2] = base64decode[*input++];
+        vals[3] = base64decode[*input++];
 
         if(vals[0] < 0 || vals[1] < 0 || vals[2] < -1 || vals[3] < -1) {
             continue;

<p><p>1.8       +1 -1      icecast/src/util.h

Index: util.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/util.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- util.h	16 Aug 2002 14:26:48 -0000	1.7
+++ util.h	18 Aug 2002 08:49:25 -0000	1.8
@@ -12,6 +12,6 @@
 char *util_get_path_from_normalised_uri(char *uri);
 char *util_normalise_uri(char *uri);
 char *util_base64_encode(char *data);
-char *util_base64_decode(char *input);
+char *util_base64_decode(unsigned char *input);
 
 #endif  /* __UTIL_H__ */

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list