Index: filed.c ================================================================== --- filed.c +++ filed.c @@ -50,10 +50,11 @@ int fd; off_t len; char *lastmod; char lastmod_b[64]; const char *type; + char etag[64]; }; /* Request variables */ struct filed_http_request { /** Buffers **/ @@ -156,26 +157,45 @@ } /* Initialize process */ static int filed_init(unsigned int cache_size) { static int called = 0; + unsigned int random_value = 0; int cache_ret; + int random_fd; if (called) { return(0); } called = 1; + /* Attempt to lock all memory to physical RAM (but don't care if we can't) */ mlockall(MCL_CURRENT | MCL_FUTURE); + /* Ignore SIGPIPE */ signal(SIGPIPE, SIG_IGN); + /* Initialize cache structure */ cache_ret = filed_init_cache(cache_size); if (cache_ret != 0) { return(cache_ret); } + + /* Initialize random number generator */ + random_fd = open("/dev/urandom", O_RDONLY); + if (random_fd >= 0) { + read(random_fd, &random_value, sizeof(random_value)); + + close(random_fd); + } + + random_value ^= getpid(); + random_value ^= getuid(); + random_value ^= time(NULL); + + srandom(random_value); return(0); } /* Listen on a particular address/port */ @@ -499,10 +519,20 @@ #include "filed-mime-types.h" return(FILED_DEFAULT_TYPE); } + +/* Generate a unique identifier */ +static void filed_generate_etag(char *etag, size_t length) { + snprintf(etag, length, "%llx%llx%llx%llx", + (unsigned long long) random(), + (unsigned long long) random(), + (unsigned long long) random(), + (unsigned long long) random() + ); +} /* 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; const char *open_path; @@ -546,10 +576,11 @@ cache->fd = fd; cache->len = len; strcpy(cache->path, path); cache->type = filed_determine_mimetype(open_path); + filed_generate_etag(cache->etag, sizeof(cache->etag)); /* XXX:TODO: Determine */ 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); @@ -568,10 +599,11 @@ buffer->fd = fd; buffer->len = cache->len; buffer->type = cache->type; memcpy(buffer->lastmod_b, cache->lastmod_b, sizeof(buffer->lastmod_b)); + memcpy(buffer->etag, cache->etag, sizeof(buffer->etag)); buffer->lastmod = buffer->lastmod_b + (cache->lastmod - cache->lastmod_b); pthread_mutex_unlock(&cache->mutex); return(buffer); @@ -796,16 +828,17 @@ request->headers.range.offset = 0; request->headers.range.length = fileinfo->len; } if (http_code > 0) { - fprintf(fp, "HTTP/1.1 %i OK\r\nDate: %s\r\nServer: filed\r\nLast-Modified: %s\r\nContent-Length: %llu\r\nAccept-Ranges: bytes\r\nContent-Type: %s\r\nConnection: close\r\n", + fprintf(fp, "HTTP/1.1 %i OK\r\nDate: %s\r\nServer: filed\r\nLast-Modified: %s\r\nContent-Length: %llu\r\nAccept-Ranges: bytes\r\nContent-Type: %s\r\nConnection: close\r\nETag: \"%s\"\r\n", http_code, date_current, fileinfo->lastmod, (unsigned long long) request->headers.range.length, - fileinfo->type + fileinfo->type, + fileinfo->etag ); if (http_code == 206) { fprintf(fp, "Content-Range: bytes %llu-%llu/%llu\r\n", (unsigned long long) request->headers.range.offset, (unsigned long long) (request->headers.range.offset + request->headers.range.length - 1),