[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