↑ 1 #include <stdio.h>
↑ 2 #include <stdlib.h>
↑ 3 #include <fcntl.h>
↑ 4 #include <errno.h>
↑ 5 #include <unistd.h>
↑ 6 #include "config.h"
↑ 7 #include "client.h"
↑ 8 #include "server.h"
↑ 9 #include "rh_string.h"
↑ 10 #include "handler.h"
↑ 11 #include "http_request.h"
↑ 12 #include "rh_chunk.h"
↑ 13 #include "http_range.h"
↑ 14
↑ 15 /*
↑ 16 *
↑ 17 * etag
↑ 18 *
↑ 19 *
↑ 20 *
↑ 21 * based on the ideas of apache 2.2.3
↑ 22 *
↑ 23 *
↑ 24 * XXX: the hex decoding is from end to begin of the number
↑ 25 *
↑ 26 */
↑ 27
↑ 28
↑ 29 DECLARE_HANDLER_FUNCTION (etag,exec)
↑ 30 {
↑ 31 http_request_t *request;
↑ 32 rh_stat_t *st;
↑ 33 char *dst;
↑ 34 off_t size;
↑ 35
↑ 36 #ifdef RHTTPD_DUMP_HANDLER_CALL
↑ 37 printf ("%s(%p)\n", __FUNCTION__, (void*)handler);
↑ 38 #endif
↑ 39
↑ 40 request = handler->request;
↑ 41
↑ 42 if (0 != request->header_out.status)
↑ 43 return HANDLER_SUCCESS;
↑ 44
↑ 45 if (NULL == request->st)
↑ 46 return HANDLER_SUCCESS;
↑ 47
↑ 48 if (request->st->error)
↑ 49 return HANDLER_SUCCESS;
↑ 50
↑ 51 st = request->st;
↑ 52
↑ 53 dst = request->header_out.etag.data;
↑ 54
↑ 55 /* file is younger then 1 second, make this etag weak */
↑ 56 if (HTTP_REQUEST_TIME(request) - st->stbuf.st_mtime < 2) {
↑ 57 *dst++ = 'W';
↑ 58 *dst++ = '/';
↑ 59 }
↑ 60
↑ 61 *dst++ = '"';
↑ 62
↑ 63 #define HEX "0123456789abcdef"
↑ 64 if (0 == (size = st->stbuf.st_ino)) {
↑ 65 *dst++ = '0';
↑ 66 } else {
↑ 67 do { *dst++ = *( HEX + (size % 16) ); } while ( (size/=16) );
↑ 68 }
↑ 69
↑ 70 *dst++ = '-';
↑ 71
↑ 72 if (0 == (size = st->stbuf.st_size)) {
↑ 73 *dst++ = '0';
↑ 74 } else {
↑ 75 do { *dst++ = *( HEX + (size % 16) ); } while ( (size/=16) );
↑ 76 }
↑ 77
↑ 78 *dst++ = '-';
↑ 79
↑ 80 if (0 == (size = st->stbuf.st_mtime)) {
↑ 81 *dst++ = '0';
↑ 82 } else {
↑ 83 do { *dst++ = *( HEX + (size % 16) ); } while ( (size/=16) );
↑ 84 }
↑ 85 #undef HEX
↑ 86
↑ 87 *dst++ = '"';
↑ 88
↑ 89 request->header_out.etag.used = (dst - request->header_out.etag.data);
↑ 90
↑ 91
↑ 92 HTTP_HEADER_KEY_SET_CONST(
↑ 93 &request->header_out,
↑ 94 ETAG,
↑ 95 request->header_out.etag.data,
↑ 96 request->header_out.etag.used );
↑ 97
↑ 98
↑ 99 return HANDLER_SUCCESS;
↑100 }
↑101
↑102 DECLARE_HANDLER_BEGIN (etag, CONTENT)
↑103 .DECLARE_HANDLER_NULL (etag, setup),
↑104 .DECLARE_HANDLER_NULL (etag, init),
↑105 .DECLARE_HANDLER_NULL (etag, init_global),
↑106 .DECLARE_HANDLER_NULL (etag, free),
↑107 .DECLARE_HANDLER_NULL (etag, free_global),
↑108 .DECLARE_HANDLER_SYMBOL (etag, exec),
↑109 DECLARE_HANDLER_END
syntax highlighted by Code2HTML, v. 0.9.1