Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -11,11 +11,14 @@ all: filed filed: filed.o $(CC) $(CFLAGS) $(LDFLAGS) -o "$@" $^ $(LIBS) -filed.o: filed.c +filed.o: filed.c filed-mime-types.h + +filed-mime-types.h: generate-mime-types + ./generate-mime-types > filed-mime-types.h install: filed filed.1 test -d "$(DESTDIR)$(mandir)/man1" || mkdir -p "$(DESTDIR)$(mandir)/man1" test -d "$(DESTDIR)$(bindir)" || mkdir -p "$(DESTDIR)$(bindir)" cp filed.1 "$(DESTDIR)$(mandir)/man1/" @@ -24,6 +27,9 @@ clean: rm -f filed filed.o distclean: clean -.PHONY: all install clean distclean +mrproper: distclean + rm -f filed-mime-types.h + +.PHONY: all install clean distclean mrproper Index: filed.c ================================================================== --- filed.c +++ filed.c @@ -19,10 +19,11 @@ #include /* Compile time constants */ #define FILED_SENDFILE_MAX 16777215 #define MAX_FAILURE_COUNT 30 +#define FILED_DEFAULT_TYPE "application/octet-stream" /* Default values */ #define PORT 80 #define THREAD_COUNT 5 #define BIND_ADDR "::" @@ -39,11 +40,11 @@ char *path; int fd; off_t len; char *lastmod; char lastmod_b[64]; - char *type; + const char *type; }; /* Request variables */ struct filed_http_request { /** Buffers **/ @@ -220,21 +221,45 @@ if (prev < curr) { diff = curr - prev; } else { diff = prev - curr; } + + prev = curr; retval <<= 3; + retval &= 0xFFFFFFFFLU; retval ^= diff; value++; } retval = retval % modulus; return(retval); } + +/* Find a mime-type based on the filename */ +static const char *filed_determine_mimetype(const char *path) { + const char *p; + + p = strrchr(path, '.'); + if (p == NULL) { + return(FILED_DEFAULT_TYPE); + } + + p++; + if (*p == '\0') { + return(FILED_DEFAULT_TYPE); + } + + filed_log_msg_debug("Looking up MIME type for %s (hash = %llu)", p, (unsigned long long) filed_hash((const unsigned char *) p, 16777259)); + +#include "filed-mime-types.h" + + return(FILED_DEFAULT_TYPE); +} /* Open a file and return file information */ static struct filed_fileinfo *filed_open_file(const char *path, struct filed_fileinfo *buffer) { struct filed_fileinfo *cache; unsigned int cache_idx; @@ -270,13 +295,13 @@ lseek(fd, 0, SEEK_SET); cache->fd = fd; cache->len = len; cache->path = strdup(path); + cache->type = filed_determine_mimetype(path); /* XXX:TODO: Determine */ - cache->type = "video/mp4"; cache->lastmod = filed_format_time(cache->lastmod_b, sizeof(cache->lastmod_b), time(NULL) - 30); } else { filed_log_msg_debug("Cache hit for idx: %lu: PATH \"%s\"", (unsigned long) cache_idx, path); } ADDED generate-mime-types Index: generate-mime-types ================================================================== --- /dev/null +++ generate-mime-types @@ -0,0 +1,81 @@ +#! /usr/bin/env tclsh + +set modulus 16777259 + +proc filed_hash {str mod} { + set retval [expr {$mod - 1}] + set prev [expr {$mod % 255}] + for {set idx 0} {$idx < [string length $str]} {incr idx} { + set curr [string index $str $idx] + binary scan $curr H* curr + set curr [format %u 0x$curr] + + if {$curr < 32} { + set curr [expr {255 - $curr}] + } else { + set curr [expr {$curr - 32}] + } + + if {$prev < $curr} { + set diff [expr {$curr - $prev}] + } else { + set diff [expr {$prev - $curr}] + } + + set prev $curr + + set retval [expr {($retval << 3) & 0xffffffff}] + set retval [expr {$retval ^ $diff}] + } + + set retval [expr {$retval % $mod}] + + return $retval + +} + +set mimeinfofile "/etc/httpd/mime.types" + +set fd [open $mimeinfofile] +set mimeinfo [read $fd] +close $fd + +foreach line [split $mimeinfo "\n"] { + regsub {#.*} $line {} line + set line [string trim $line] + + if {$line == ""} { + continue + } + + set line [split $line] + + set mime [lindex $line 0] + set extensions [lrange $line 1 end] + + foreach extension $extensions { + if {$extension == ""} { + continue + } + + set extensioninfo($extension) $mime + } +} + +foreach extension [array names extensioninfo] { + set hash_id [filed_hash $extension $modulus] + + lappend hashinfo($hash_id) $extension + +} +puts "\tswitch (filed_hash((const unsigned char *) p, $modulus)) \{" +foreach hash [lsort -integer -increasing [array names hashinfo]] { + puts "\t\tcase $hash:" + foreach extension $hashinfo($hash) { + puts "\t\t\tif (strcmp(p, \"$extension\") == 0) \{" + puts "\t\t\t\treturn(\"$extensioninfo($extension)\");" + puts "\t\t\t\}" + } + puts "\t\t\treturn(FILED_DEFAULT_TYPE);" +} +puts "\t\}"