Check-in [63a88bc1bc]
Overview
Comment:Added ETag
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:63a88bc1bc0116825571d5d5520b4a8ebb73cb4a
User & Date: rkeene on 2014-02-11 08:11:02
Other Links: manifest | tags
Context
2014-02-11
08:12
Updated to provide method earlier to log check-in: 5f36930fec user: rkeene tags: trunk
08:11
Added ETag check-in: 63a88bc1bc user: rkeene tags: trunk
07:43
Updated to support the HEAD HTTP method check-in: 5a054ee091 user: rkeene tags: trunk
Changes

Modified filed.c from [93c05a56c1] to [288fd58a21].

    48     48   	pthread_mutex_t mutex;
    49     49   	char path[FILED_PATH_BUFFER_SIZE];
    50     50   	int fd;
    51     51   	off_t len;
    52     52   	char *lastmod;
    53     53   	char lastmod_b[64];
    54     54   	const char *type;
           55  +	char etag[64];
    55     56   };
    56     57   
    57     58   /* Request variables */
    58     59   struct filed_http_request {
    59     60   	/** Buffers **/
    60     61   	struct filed_fileinfo fileinfo;
    61     62   	char tmpbuf[1010];
................................................................................
   154    155   
   155    156   	return(0);
   156    157   }
   157    158   
   158    159   /* Initialize process */
   159    160   static int filed_init(unsigned int cache_size) {
   160    161   	static int called = 0;
          162  +	unsigned int random_value = 0;
   161    163   	int cache_ret;
          164  +	int random_fd;
   162    165   
   163    166   	if (called) {
   164    167   		return(0);
   165    168   	}
   166    169   
   167    170   	called = 1;
   168    171   
          172  +	/* Attempt to lock all memory to physical RAM (but don't care if we can't) */
   169    173   	mlockall(MCL_CURRENT | MCL_FUTURE);
   170    174   
          175  +	/* Ignore SIGPIPE */
   171    176   	signal(SIGPIPE, SIG_IGN);
   172    177   
          178  +	/* Initialize cache structure */
   173    179   	cache_ret = filed_init_cache(cache_size);
   174    180   	if (cache_ret != 0) {
   175    181   		return(cache_ret);
   176    182   	}
          183  +
          184  +	/* Initialize random number generator */
          185  +	random_fd = open("/dev/urandom", O_RDONLY);
          186  +	if (random_fd >= 0) {
          187  +		read(random_fd, &random_value, sizeof(random_value));
          188  +
          189  +		close(random_fd);
          190  +	}
          191  +
          192  +	random_value ^= getpid();
          193  +	random_value ^= getuid();
          194  +	random_value ^= time(NULL);
          195  +
          196  +	srandom(random_value);
   177    197   
   178    198   	return(0);
   179    199   }
   180    200   
   181    201   /* Listen on a particular address/port */
   182    202   static int filed_listen(const char *address, unsigned int port) {
   183    203   	struct sockaddr_in6 addr_v6;
................................................................................
   497    517   
   498    518   	filed_log_msg_debug("Looking up MIME type for %s (hash = %llu)", p, (unsigned long long) filed_hash((const unsigned char *) p, 16777259));
   499    519   
   500    520   #include "filed-mime-types.h"
   501    521   
   502    522   	return(FILED_DEFAULT_TYPE);
   503    523   }
          524  +
          525  +/* Generate a unique identifier */
          526  +static void filed_generate_etag(char *etag, size_t length) {
          527  +	snprintf(etag, length, "%llx%llx%llx%llx",
          528  +		(unsigned long long) random(),
          529  +		(unsigned long long) random(),
          530  +		(unsigned long long) random(),
          531  +		(unsigned long long) random()
          532  +	);
          533  +}
   504    534   
   505    535   /* Open a file and return file information */
   506    536   static struct filed_fileinfo *filed_open_file(const char *path, struct filed_fileinfo *buffer) {
   507    537   	struct filed_fileinfo *cache;
   508    538   	const char *open_path;
   509    539   	unsigned int cache_idx;
   510    540   	off_t len;
................................................................................
   544    574   		len = lseek(fd, 0, SEEK_END);
   545    575   		lseek(fd, 0, SEEK_SET);
   546    576   
   547    577   		cache->fd = fd;
   548    578   		cache->len = len;
   549    579   		strcpy(cache->path, path);
   550    580   		cache->type = filed_determine_mimetype(open_path);
          581  +		filed_generate_etag(cache->etag, sizeof(cache->etag));
   551    582   
   552    583   		/* XXX:TODO: Determine */
   553    584   		cache->lastmod = filed_format_time(cache->lastmod_b, sizeof(cache->lastmod_b), time(NULL) - 30);
   554    585   	} else {
   555    586   		filed_log_msg_debug("Cache hit for idx: %lu: PATH \"%s\"", (unsigned long) cache_idx, path);
   556    587   	}
   557    588   
................................................................................
   566    597   		return(NULL);
   567    598   	}
   568    599   
   569    600   	buffer->fd = fd;
   570    601   	buffer->len = cache->len;
   571    602   	buffer->type = cache->type;
   572    603   	memcpy(buffer->lastmod_b, cache->lastmod_b, sizeof(buffer->lastmod_b));
          604  +	memcpy(buffer->etag, cache->etag, sizeof(buffer->etag));
   573    605   	buffer->lastmod = buffer->lastmod_b + (cache->lastmod - cache->lastmod_b);
   574    606   
   575    607   	pthread_mutex_unlock(&cache->mutex);
   576    608   
   577    609   	return(buffer);
   578    610   }
   579    611   
................................................................................
   794    826   				http_code = 200;
   795    827   			}
   796    828   			request->headers.range.offset = 0;
   797    829   			request->headers.range.length = fileinfo->len;
   798    830   		}
   799    831   
   800    832   		if (http_code > 0) {
   801         -			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",
          833  +			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",
   802    834   				http_code,
   803    835   				date_current,
   804    836   				fileinfo->lastmod,
   805    837   				(unsigned long long) request->headers.range.length,
   806         -				fileinfo->type
          838  +				fileinfo->type,
          839  +				fileinfo->etag
   807    840   			);
   808    841   			if (http_code == 206) {
   809    842   				fprintf(fp, "Content-Range: bytes %llu-%llu/%llu\r\n",
   810    843   					(unsigned long long) request->headers.range.offset,
   811    844   					(unsigned long long) (request->headers.range.offset + request->headers.range.length - 1),
   812    845   					(unsigned long long) fileinfo->len
   813    846   				);