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