[xiph-cvs] cvs commit: icecast/src fserve.c

Michael Smith msmith at xiph.org
Sun Aug 18 06:38:51 PDT 2002



msmith      02/08/18 09:38:51

  Modified:    src      fserve.c
  Log:
  Build an extension->mimetype mapping table from /etc/mime.types, use this
  for sending content-type when file serving.

Revision  Changes    Path
1.4       +107 -13   icecast/src/fserve.c

Index: fserve.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/fserve.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- fserve.c	18 Aug 2002 09:38:45 -0000	1.3
+++ fserve.c	18 Aug 2002 13:38:51 -0000	1.4
@@ -39,8 +39,15 @@
 
 #define BUFSIZE 4096
 
+#ifdef _WIN32
+#define MIMETYPESFILE ".\\mime.types"
+#else
+#define MIMETYPESFILE "/etc/mime.types"
+#endif
+
 static avl_tree *client_tree;
 static avl_tree *pending_tree;
+static avl_tree *mimetypes;
 
 static cond_t fserv_cond;
 static thread_t *fserv_thread;
@@ -56,17 +63,26 @@
 static int fd_max = 0;
 #endif
 
+typedef struct {
+    char *ext;
+    char *type;
+} mime_type;
+
 /* avl tree helper */
 static int _compare_clients(void *compare_arg, void *a, void *b);
 static int _remove_client(void *key);
 static int _free_client(void *key);
-void *fserv_thread_function(void *arg);
+static int _delete_mapping(void *mapping);
+static void *fserv_thread_function(void *arg);
+static void create_mime_mappings(char *fn);
 
 void fserve_initialize(void)
 {
     if(!config_get_config()->fileserve)
         return;
 
+    create_mime_mappings(MIMETYPESFILE);
+
         client_tree = avl_tree_new(_compare_clients, NULL);
         pending_tree = avl_tree_new(_compare_clients, NULL);
     thread_cond_create(&fserv_cond);
@@ -82,6 +98,8 @@
     if(!config_get_config()->fileserve)
         return;
 
+    avl_tree_free(mimetypes, _delete_mapping);
+
     run_fserv = 0;
     thread_cond_signal(&fserv_cond);
     thread_join(fserv_thread);
@@ -150,7 +168,7 @@
     }
 }
 
-void *fserv_thread_function(void *arg)
+static void *fserv_thread_function(void *arg)
 {
     avl_node *client_node, *pending_node;
     fserve_t *client;
@@ -282,18 +300,24 @@
 static char *fserve_content_type(char *path)
 {
     char *ext = util_get_extension(path);
+    mime_type exttype = {ext, NULL};
+    mime_type *result;
 
-    if(!strcmp(ext, "ogg"))
-        return "application/x-ogg";
-    else if(!strcmp(ext, "mp3"))
-        return "audio/mpeg";
-    else if(!strcmp(ext, "html"))
-        return "text/html";
-    else if(!strcmp(ext, "txt"))
-        return "text/plain";
-    else
-        return "application/octet-stream";
-    /* TODO Add more types */
+    if(!avl_get_by_key(mimetypes, &exttype, (void **)(&result)))
+        return result->type;
+    else {
+        /* Fallbacks for a few basic ones */
+        if(!strcmp(ext, "ogg"))
+            return "application/x-ogg";
+        else if(!strcmp(ext, "mp3"))
+            return "audio/mpeg";
+        else if(!strcmp(ext, "html"))
+            return "text/html";
+        else if(!strcmp(ext, "txt"))
+            return "text/plain";
+        else
+            return "application/octet-stream";
+    }
 }
 
 static void fserve_client_destroy(fserve_t *client)
@@ -387,5 +411,75 @@
 
         
         return 1;
+}
+
+static int _delete_mapping(void *mapping) {
+    mime_type *map = mapping;
+    free(map->ext);
+    free(map->type);
+    free(map);
+
+    return 1;
+}
+
+static int _compare_mappings(void *arg, void *a, void *b)
+{
+    return strcmp(
+            ((mime_type *)a)->ext,
+            ((mime_type *)b)->ext);
+}
+
+static void create_mime_mappings(char *fn) {
+    FILE *mimefile = fopen(fn, "r");
+    char line[4096];
+    char *type, *ext, *cur;
+    mime_type *mapping, *tmp;
+
+    mimetypes = avl_tree_new(_compare_mappings, NULL);
+
+    if(!mimefile)
+        return;
+
+    while(fgets(line, 4096, mimefile))
+    {
+        line[4095] = 0;
+
+        if(*line == 0 || *line == '#')
+            continue;
+
+        type = line;
+
+        cur = line;
+
+        while(*cur != ' ' && *cur != '\t' && *cur)
+            cur++;
+        if(*cur == 0)
+            continue;
+
+        *cur++ = 0;
+
+        while(1) {
+            while(*cur == ' ' || *cur == '\t')
+                cur++;
+            if(*cur == 0)
+                break;
+
+            ext = cur;
+            while(*cur != ' ' && *cur != '\t' && *cur != '\n' && *cur)
+                cur++;
+            *cur++ = 0;
+            if(*ext) {
+                /* Add a new extension->type mapping */
+                mapping = malloc(sizeof(mime_type));
+                mapping->ext = strdup(ext);
+                mapping->type = strdup(type);
+                if(!avl_get_by_key(mimetypes, mapping, (void **)(&tmp)))
+                    avl_delete(mimetypes, mapping, _delete_mapping);
+                avl_insert(mimetypes, mapping);
+            }
+        }
+    }
+
+    fclose(mimefile);
 }
 

<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