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 );