↑ 1 #include <stdio.h>
↑ 2 #include <stdlib.h>
↑ 3 #include <unistd.h>
↑ 4 #include "rh_string.h"
↑ 5 #include "handler.h"
↑ 6 #include "http_request.h"
↑ 7 #include "rh_chunk.h"
↑ 8
↑ 9 enum {
↑ 10 LOG_OFFSET_METHOD = 1,
↑ 11 LOG_OFFSET_URI = 3,
↑ 12 LOG_OFFSET_VERSION = 5,
↑ 13
↑ 14 LOG_OFFSET_MAX = 10
↑ 15 };
↑ 16
↑ 17 struct logfile {
↑ 18 int fd;
↑ 19 struct iovec log[LOG_OFFSET_MAX];
↑ 20 };
↑ 21
↑ 22
↑ 23 #define LOG_CONST(_off,_str) \
↑ 24 { log->log[_off].iov_base = _str; \
↑ 25 log->log[_off].iov_len = CONST_LEN(_str); \
↑ 26 }
↑ 27
↑ 28 #define LOG_BUFFER(_off,_buffer) \
↑ 29 { log->log[_off].iov_base = (_buffer)->data; \
↑ 30 log->log[_off].iov_len = (_buffer)->used; \
↑ 31 }
↑ 32
↑ 33 DECLARE_HANDLER_FUNCTION (accesslog,exec)
↑ 34 {
↑ 35 http_request_t *request;
↑ 36 struct logfile *log;
↑ 37
↑ 38 #ifdef RHTTPD_DUMP_HANDLER_CALL
↑ 39 printf ("%s(%p)\n", __FUNCTION__, (void*)handler);
↑ 40 #endif
↑ 41
↑ 42 request = handler->request;
↑ 43 log = handler->data_global;
↑ 44 #if 1
↑ 45 printf ("%s(): %3d [%.*s] %zu:%zu byte \n", __FUNCTION__,
↑ 46 request->header_out.status,
↑ 47 request->header_in.uri.log.used,
↑ 48 request->header_in.uri.log.data,
↑ 49 request->chunk_header.size_out,
↑ 50 request->chunk_content.size_out );
↑ 51
↑ 52 return HANDLER_SUCCESS;
↑ 53
↑ 54 #endif
↑ 55 switch (request->header_in.method) {
↑ 56 case HTTP_METHOD_GET:
↑ 57 LOG_CONST(LOG_OFFSET_METHOD, "GET"); break;
↑ 58 case HTTP_METHOD_HEAD:
↑ 59 LOG_CONST(LOG_OFFSET_METHOD, "HEAD"); break;
↑ 60 case HTTP_METHOD_POST:
↑ 61 LOG_CONST(LOG_OFFSET_METHOD, "POST"); break;
↑ 62 case HTTP_METHOD_TRACE:
↑ 63 LOG_CONST(LOG_OFFSET_METHOD, "TRACE"); break;
↑ 64 default:
↑ 65 LOG_CONST(LOG_OFFSET_METHOD, "unknown"); break;
↑ 66 }
↑ 67
↑ 68 LOG_BUFFER(LOG_OFFSET_URI, &request->header_in.uri.log);
↑ 69
↑ 70 switch (request->header_in.version) {
↑ 71 case HTTP_VERSION_10:
↑ 72 LOG_CONST(LOG_OFFSET_VERSION, "HTTP/1.0"); break;
↑ 73 case HTTP_VERSION_11:
↑ 74 LOG_CONST(LOG_OFFSET_VERSION, "HTTP/1.1"); break;
↑ 75 default:
↑ 76 LOG_CONST(LOG_OFFSET_VERSION, "HTTP/?.?"); break;
↑ 77 }
↑ 78
↑ 79 writev (log->fd, log->log, LOG_OFFSET_MAX-1);
↑ 80
↑ 81 return HANDLER_SUCCESS;
↑ 82 }
↑ 83
↑ 84 DECLARE_HANDLER_FUNCTION (accesslog,init_global)
↑ 85 {
↑ 86 struct logfile *log;
↑ 87
↑ 88 #ifdef RHTTPD_DUMP_HANDLER_CALL
↑ 89 printf ("%s(%p)\n", __FUNCTION__, (void*)handler);
↑ 90 #endif
↑ 91
↑ 92 log = calloc(1, sizeof(*log));
↑ 93 if (NULL == log)
↑ 94 return HANDLER_FAILURE;
↑ 95
↑ 96 log->fd = STDOUT_FILENO;
↑ 97
↑ 98
↑ 99 LOG_CONST(0, "\"");
↑100 LOG_CONST(LOG_OFFSET_METHOD + 1, " ");
↑101 LOG_CONST(LOG_OFFSET_URI + 1, " ");
↑102 LOG_CONST(LOG_OFFSET_VERSION + 1, "\"");
↑103 LOG_CONST(LOG_OFFSET_VERSION + 2, "\n");
↑104
↑105 handler->data_global = log;
↑106
↑107 return HANDLER_SUCCESS;
↑108 }
↑109
↑110 DECLARE_HANDLER_FUNCTION (accesslog,free_global)
↑111 {
↑112 struct logfile *log;
↑113
↑114 #ifdef RHTTPD_DUMP_HANDLER_CALL
↑115 printf ("%s(%p)\n", __FUNCTION__, (void*)handler);
↑116 #endif
↑117
↑118 log = handler->data_global;
↑119 if (NULL == log)
↑120 return HANDLER_SUCCESS;
↑121
↑122 // close (log->fd);
↑123 free (log);
↑124
↑125 return HANDLER_SUCCESS;
↑126 }
↑127
↑128 #undef LOG_CONST
↑129 #undef LOG_BUFFER
↑130
↑131 DECLARE_HANDLER_BEGIN (accesslog, ACCESSLOG)
↑132 .DECLARE_HANDLER_NULL (accesslog, setup),
↑133 .DECLARE_HANDLER_NULL (accesslog, init),
↑134 .DECLARE_HANDLER_SYMBOL (accesslog, init_global),
↑135 .DECLARE_HANDLER_NULL (accesslog, free),
↑136 .DECLARE_HANDLER_SYMBOL (accesslog, free_global),
↑137 .DECLARE_HANDLER_SYMBOL (accesslog, exec),
↑138 DECLARE_HANDLER_END
syntax highlighted by Code2HTML, v. 0.9.1