diff options
Diffstat (limited to 'src/mod_accesslog.c')
-rw-r--r-- | src/mod_accesslog.c | 911 |
1 files changed, 0 insertions, 911 deletions
diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c deleted file mode 100644 index 419fc463..00000000 --- a/src/mod_accesslog.c +++ /dev/null @@ -1,911 +0,0 @@ -/* - * make sure _GNU_SOURCE is defined - */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <sys/types.h> -#include <sys/stat.h> - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> /* only the defines on windows */ -#include <errno.h> -#include <time.h> - -#include <stdio.h> - -#include "base.h" -#include "log.h" -#include "buffer.h" - -#include "plugin.h" - -#include "inet_ntop_cache.h" - -#include "sys-socket.h" -#include "sys-files.h" - -#ifdef HAVE_SYSLOG_H -# include <syslog.h> -#endif - -typedef struct { - char key; - enum { - FORMAT_UNSET, - FORMAT_UNSUPPORTED, - FORMAT_PERCENT, - FORMAT_REMOTE_HOST, - FORMAT_REMOTE_IDENT, - FORMAT_REMOTE_USER, - FORMAT_TIMESTAMP, - FORMAT_REQUEST_LINE, - FORMAT_STATUS, - FORMAT_BYTES_OUT_NO_HEADER, - FORMAT_HEADER, - - FORMAT_REMOTE_ADDR, - FORMAT_LOCAL_ADDR, - FORMAT_COOKIE, - FORMAT_TIME_USED_MS, - FORMAT_ENV, - FORMAT_FILENAME, - FORMAT_REQUEST_PROTOCOL, - FORMAT_REQUEST_METHOD, - FORMAT_SERVER_PORT, - FORMAT_QUERY_STRING, - FORMAT_TIME_USED, - FORMAT_URL, - FORMAT_SERVER_NAME, - FORMAT_HTTP_HOST, - FORMAT_CONNECTION_STATUS, - FORMAT_BYTES_IN, - FORMAT_BYTES_OUT, - - FORMAT_RESPONSE_HEADER - } type; -} format_mapping; - -/** - * - * - * "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" - * - */ - -const format_mapping fmap[] = -{ - { '%', FORMAT_PERCENT }, - { 'h', FORMAT_REMOTE_HOST }, - { 'l', FORMAT_REMOTE_IDENT }, - { 'u', FORMAT_REMOTE_USER }, - { 't', FORMAT_TIMESTAMP }, - { 'r', FORMAT_REQUEST_LINE }, - { 's', FORMAT_STATUS }, - { 'b', FORMAT_BYTES_OUT_NO_HEADER }, - { 'i', FORMAT_HEADER }, - - { 'a', FORMAT_REMOTE_ADDR }, - { 'A', FORMAT_LOCAL_ADDR }, - { 'B', FORMAT_BYTES_OUT_NO_HEADER }, - { 'C', FORMAT_COOKIE }, - { 'D', FORMAT_TIME_USED_MS }, - { 'e', FORMAT_ENV }, - { 'f', FORMAT_FILENAME }, - { 'H', FORMAT_REQUEST_PROTOCOL }, - { 'm', FORMAT_REQUEST_METHOD }, - { 'n', FORMAT_UNSUPPORTED }, /* we have no notes */ - { 'p', FORMAT_SERVER_PORT }, - { 'P', FORMAT_UNSUPPORTED }, /* we are only one process */ - { 'q', FORMAT_QUERY_STRING }, - { 'T', FORMAT_TIME_USED }, - { 'U', FORMAT_URL }, /* w/o querystring */ - { 'v', FORMAT_SERVER_NAME }, - { 'V', FORMAT_HTTP_HOST }, - { 'X', FORMAT_CONNECTION_STATUS }, - { 'I', FORMAT_BYTES_IN }, - { 'O', FORMAT_BYTES_OUT }, - - { 'o', FORMAT_RESPONSE_HEADER }, - - { '\0', FORMAT_UNSET } -}; - - -typedef struct { - enum { FIELD_UNSET, FIELD_STRING, FIELD_FORMAT } type; - - buffer *string; - int field; -} format_field; - -typedef struct { - format_field **ptr; - - size_t used; - size_t size; -} format_fields; - -typedef struct { - buffer *access_logfile; - buffer *format; - unsigned short use_syslog; - - - int log_access_fd; - time_t last_generated_accesslog_ts; - time_t *last_generated_accesslog_ts_ptr; - - - buffer *access_logbuffer; - buffer *ts_accesslog_str; - - format_fields *parsed_format; -} plugin_config; - -typedef struct { - PLUGIN_DATA; - - plugin_config **config_storage; - plugin_config conf; -} plugin_data; - -INIT_FUNC(mod_accesslog_init) { - plugin_data *p; - - UNUSED(srv); - - p = calloc(1, sizeof(*p)); - - return p; -} - -static void accesslog_append_escaped(buffer *dest, buffer *str) { - /* replaces non-printable chars with \xHH where HH is the hex representation of the byte */ - /* exceptions: " => \", \ => \\, whitespace chars => \n \t etc. */ - if (str->used == 0) return; - buffer_prepare_append(dest, str->used - 1); - - for (unsigned int i = 0; i < str->used - 1; i++) { - if (str->ptr[i] >= ' ' && str->ptr[i] <= '~') { - /* printable chars */ - buffer_append_string_len(dest, &str->ptr[i], 1); - } else switch (str->ptr[i]) { - case '"': - BUFFER_APPEND_STRING_CONST(dest, "\\\""); - break; - case '\\': - BUFFER_APPEND_STRING_CONST(dest, "\\\\"); - break; - case '\b': - BUFFER_APPEND_STRING_CONST(dest, "\\b"); - break; - case '\n': - BUFFER_APPEND_STRING_CONST(dest, "\\n"); - break; - case '\r': - BUFFER_APPEND_STRING_CONST(dest, "\\r"); - break; - case '\t': - BUFFER_APPEND_STRING_CONST(dest, "\\t"); - break; - case '\v': - BUFFER_APPEND_STRING_CONST(dest, "\\v"); - break; - default: { - /* non printable char => \xHH */ - char hh[5] = {'\\','x',0,0,0}; - char h = str->ptr[i] / 16; - hh[2] = (h > 9) ? (h - 10 + 'A') : (h + '0'); - h = str->ptr[i] % 16; - hh[3] = (h > 9) ? (h - 10 + 'A') : (h + '0'); - buffer_append_string_len(dest, &hh[0], 4); - } - break; - } - } -} - -static int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) { - size_t i, j, k = 0, start = 0; - - for (i = 0; i < format->used - 1; i++) { - - switch(format->ptr[i]) { - case '%': - if (start != i) { - /* copy the string */ - if (fields->size == 0) { - fields->size = 16; - fields->used = 0; - fields->ptr = malloc(fields->size * sizeof(format_field * )); - } else if (fields->used == fields->size) { - fields->size += 16; - fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_field * )); - } - - fields->ptr[fields->used] = malloc(sizeof(format_field)); - fields->ptr[fields->used]->type = FIELD_STRING; - fields->ptr[fields->used]->string = buffer_init(); - - buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start); - - fields->used++; - } - - - /* we need a new field */ - - if (fields->size == 0) { - fields->size = 16; - fields->used = 0; - fields->ptr = malloc(fields->size * sizeof(format_field * )); - } else if (fields->used == fields->size) { - fields->size += 16; - fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_field * )); - } - - /* search for the terminating command */ - switch (format->ptr[i+1]) { - case '>': - case '<': - /* only for s */ - - for (j = 0; fmap[j].key != '\0'; j++) { - if (fmap[j].key != format->ptr[i+2]) continue; - - /* found key */ - - fields->ptr[fields->used] = malloc(sizeof(format_field)); - fields->ptr[fields->used]->type = FIELD_FORMAT; - fields->ptr[fields->used]->field = fmap[j].type; - fields->ptr[fields->used]->string = NULL; - - fields->used++; - - break; - } - - if (fmap[j].key == '\0') { - log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); - return -1; - } - - start = i + 3; - - break; - case '{': - /* go forward to } */ - - for (k = i+2; k < format->used - 1; k++) { - if (format->ptr[k] == '}') break; - } - - if (k == format->used - 1) { - log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); - return -1; - } - if (format->ptr[k+1] == '\0') { - log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); - return -1; - } - - for (j = 0; fmap[j].key != '\0'; j++) { - if (fmap[j].key != format->ptr[k+1]) continue; - - /* found key */ - - fields->ptr[fields->used] = malloc(sizeof(format_field)); - fields->ptr[fields->used]->type = FIELD_FORMAT; - fields->ptr[fields->used]->field = fmap[j].type; - fields->ptr[fields->used]->string = buffer_init(); - - buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + i + 2, k - (i + 2)); - - fields->used++; - - break; - } - - if (fmap[j].key == '\0') { - log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); - return -1; - } - - start = k + 2; - - break; - default: - for (j = 0; fmap[j].key != '\0'; j++) { - if (fmap[j].key != format->ptr[i+1]) continue; - - /* found key */ - - fields->ptr[fields->used] = malloc(sizeof(format_field)); - fields->ptr[fields->used]->type = FIELD_FORMAT; - fields->ptr[fields->used]->field = fmap[j].type; - fields->ptr[fields->used]->string = NULL; - - fields->used++; - - break; - } - - if (fmap[j].key == '\0') { - log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed"); - return -1; - } - - start = i + 2; - - break; - } - - break; - } - } - - if (start < i) { - /* copy the string */ - if (fields->size == 0) { - fields->size = 16; - fields->used = 0; - fields->ptr = malloc(fields->size * sizeof(format_field * )); - } else if (fields->used == fields->size) { - fields->size += 16; - fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_field * )); - } - - fields->ptr[fields->used] = malloc(sizeof(format_field)); - fields->ptr[fields->used]->type = FIELD_STRING; - fields->ptr[fields->used]->string = buffer_init(); - - buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start); - - fields->used++; - } - - return 0; -} - -FREE_FUNC(mod_accesslog_free) { - plugin_data *p = p_d; - size_t i; - - if (!p) return HANDLER_GO_ON; - - if (p->config_storage) { - - for (i = 0; i < srv->config_context->used; i++) { - plugin_config *s = p->config_storage[i]; - - if (!s) continue; - - if (s->access_logbuffer->used) { - if (s->use_syslog) { -# ifdef HAVE_SYSLOG_H - if (s->access_logbuffer->used > 2) { - syslog(LOG_INFO, "%*s", (int) s->access_logbuffer->used - 2, s->access_logbuffer->ptr); - } -# endif - } else if (s->log_access_fd != -1) { - write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1); - } - } - - if (s->log_access_fd != -1) close(s->log_access_fd); - - buffer_free(s->ts_accesslog_str); - buffer_free(s->access_logbuffer); - buffer_free(s->format); - buffer_free(s->access_logfile); - - if (s->parsed_format) { - size_t j; - for (j = 0; j < s->parsed_format->used; j++) { - if (s->parsed_format->ptr[j]->string) buffer_free(s->parsed_format->ptr[j]->string); - free(s->parsed_format->ptr[j]); - } - free(s->parsed_format->ptr); - free(s->parsed_format); - } - - free(s); - } - - free(p->config_storage); - } - - free(p); - - return HANDLER_GO_ON; -} - -SETDEFAULTS_FUNC(log_access_open) { - plugin_data *p = p_d; - size_t i = 0; - - config_values_t cv[] = { - { "accesslog.filename", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, - { "accesslog.use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, - { "accesslog.format", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, - { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } - }; - - if (!p) return HANDLER_ERROR; - - p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); - - for (i = 0; i < srv->config_context->used; i++) { - plugin_config *s; - - s = calloc(1, sizeof(plugin_config)); - s->access_logfile = buffer_init(); - s->format = buffer_init(); - s->access_logbuffer = buffer_init(); - s->ts_accesslog_str = buffer_init(); - s->log_access_fd = -1; - s->last_generated_accesslog_ts = 0; - s->last_generated_accesslog_ts_ptr = &(s->last_generated_accesslog_ts); - - - cv[0].destination = s->access_logfile; - cv[1].destination = &(s->use_syslog); - cv[2].destination = s->format; - - p->config_storage[i] = s; - - if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { - return HANDLER_ERROR; - } - - if (i == 0 && buffer_is_empty(s->format)) { - /* set a default logfile string */ - - buffer_copy_string_len(s->format, CONST_STR_LEN("%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"")); - } - - /* parse */ - - if (s->format->used) { - s->parsed_format = calloc(1, sizeof(*(s->parsed_format))); - - if (-1 == accesslog_parse_format(srv, s->parsed_format, s->format)) { - - log_error_write(srv, __FILE__, __LINE__, "sb", - "parsing accesslog-definition failed:", s->format); - - return HANDLER_ERROR; - } -#if 0 - /* debugging */ - for (j = 0; j < s->parsed_format->used; j++) { - switch (s->parsed_format->ptr[j]->type) { - case FIELD_FORMAT: - log_error_write(srv, __FILE__, __LINE__, "ssds", - "config:", "format", s->parsed_format->ptr[j]->field, - s->parsed_format->ptr[j]->string ? - s->parsed_format->ptr[j]->string->ptr : "" ); - break; - case FIELD_STRING: - log_error_write(srv, __FILE__, __LINE__, "ssbs", "config:", "string '", s->parsed_format->ptr[j]->string, "'"); - break; - default: - break; - } - } -#endif - } - - if (s->use_syslog) { - /* ignore the next checks */ - continue; - } - - if (buffer_is_empty(s->access_logfile)) continue; - - if (s->access_logfile->ptr[0] == '|') { -#ifdef HAVE_FORK - /* create write pipe and spawn process */ - - int to_log_fds[2]; - pid_t pid; - - if (pipe(to_log_fds)) { - log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno)); - return HANDLER_ERROR; - } - - /* fork, execve */ - switch (pid = fork()) { - case 0: - /* child */ - - close(STDIN_FILENO); - dup2(to_log_fds[0], STDIN_FILENO); - close(to_log_fds[0]); - /* not needed */ - close(to_log_fds[1]); - - /* we don't need the client socket */ - for (i = 3; i < 256; i++) { - close(i); - } - - /* exec the log-process (skip the | ) - * - */ - - execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, (char *)NULL); - - log_error_write(srv, __FILE__, __LINE__, "sss", - "spawning log-process failed: ", strerror(errno), - s->access_logfile->ptr + 1); - - exit(-1); - break; - case -1: - /* error */ - log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed: ", strerror(errno)); - break; - default: - close(to_log_fds[0]); - - s->log_access_fd = to_log_fds[1]; - - break; - } -#else - return -1; -#endif - } else if (-1 == (s->log_access_fd = - open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) { - - log_error_write(srv, __FILE__, __LINE__, "ssb", - "opening access-log failed:", - strerror(errno), s->access_logfile); - - return HANDLER_ERROR; - } -#ifndef _WIN32 - fcntl(s->log_access_fd, F_SETFD, FD_CLOEXEC); -#endif - } - - return HANDLER_GO_ON; -} - -SIGHUP_FUNC(log_access_cycle) { - plugin_data *p = p_d; - size_t i; - - if (!p->config_storage) return HANDLER_GO_ON; - - for (i = 0; i < srv->config_context->used; i++) { - plugin_config *s = p->config_storage[i]; - - if (s->access_logbuffer->used) { - if (s->use_syslog) { -#ifdef HAVE_SYSLOG_H - if (s->access_logbuffer->used > 2) { - /* syslog appends a \n on its own */ - syslog(LOG_INFO, "%*s", (int) s->access_logbuffer->used - 2, s->access_logbuffer->ptr); - } -#endif - } else if (s->log_access_fd != -1) { - write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1); - } - - buffer_reset(s->access_logbuffer); - } - - if (s->use_syslog == 0 && - !buffer_is_empty(s->access_logfile) && - s->access_logfile->ptr[0] != '|') { - - close(s->log_access_fd); - - if (-1 == (s->log_access_fd = - open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) { - - log_error_write(srv, __FILE__, __LINE__, "ss", "cycling access-log failed:", strerror(errno)); - - return HANDLER_ERROR; - } - } - } - - return HANDLER_GO_ON; -} - -static int mod_accesslog_patch_connection(server *srv, connection *con, plugin_data *p) { - size_t i, j; - plugin_config *s = p->config_storage[0]; - - PATCH_OPTION(access_logfile); - PATCH_OPTION(format); - PATCH_OPTION(log_access_fd); - PATCH_OPTION(last_generated_accesslog_ts_ptr); - PATCH_OPTION(access_logbuffer); - PATCH_OPTION(ts_accesslog_str); - PATCH_OPTION(parsed_format); - PATCH_OPTION(use_syslog); - - /* skip the first, the global context */ - for (i = 1; i < srv->config_context->used; i++) { - data_config *dc = (data_config *)srv->config_context->data[i]; - s = p->config_storage[i]; - - /* condition didn't match */ - if (!config_check_cond(srv, con, dc)) continue; - - /* merge config */ - for (j = 0; j < dc->value->used; j++) { - data_unset *du = dc->value->data[j]; - - if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.filename"))) { - PATCH_OPTION(access_logfile); - PATCH_OPTION(log_access_fd); - PATCH_OPTION(last_generated_accesslog_ts_ptr); - PATCH_OPTION(access_logbuffer); - PATCH_OPTION(ts_accesslog_str); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.format"))) { - PATCH_OPTION(format); - PATCH_OPTION(parsed_format); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.use-syslog"))) { - PATCH_OPTION(use_syslog); - } - } - } - - return 0; -} - -REQUESTDONE_FUNC(log_access_write) { - plugin_data *p = p_d; - buffer *b; - size_t j; - - int newts = 0; - data_string *ds; - - mod_accesslog_patch_connection(srv, con, p); - - b = p->conf.access_logbuffer; - if (b->used == 0) { - buffer_copy_string_len(b, CONST_STR_LEN("")); - } - - for (j = 0; j < p->conf.parsed_format->used; j++) { - switch(p->conf.parsed_format->ptr[j]->type) { - case FIELD_STRING: - buffer_append_string_buffer(b, p->conf.parsed_format->ptr[j]->string); - break; - case FIELD_FORMAT: - switch(p->conf.parsed_format->ptr[j]->field) { - case FORMAT_TIMESTAMP: - - /* cache the generated timestamp */ - if (srv->cur_ts != *(p->conf.last_generated_accesslog_ts_ptr)) { - struct tm tm; -#if defined(HAVE_STRUCT_TM_GMTOFF) - long scd, hrs, min; -#endif - - buffer_prepare_copy(p->conf.ts_accesslog_str, 255); -#if defined(HAVE_STRUCT_TM_GMTOFF) -# ifdef HAVE_LOCALTIME_R - localtime_r(&(srv->cur_ts), &tm); - strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", &tm); -# else - strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime(&(srv->cur_ts))); -# endif - p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1; - - buffer_append_string(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-"); - - scd = abs(tm.tm_gmtoff); - hrs = scd / 3600; - min = (scd % 3600) / 60; - - /* hours */ - if (hrs < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0")); - buffer_append_long(p->conf.ts_accesslog_str, hrs); - - if (min < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0")); - buffer_append_long(p->conf.ts_accesslog_str, min); - buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("]")); -#else -#ifdef HAVE_GMTIME_R - gmtime_r(&(srv->cur_ts), &tm); - strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S +0000]", &tm); -#else - strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S +0000]", gmtime(&(srv->cur_ts))); -#endif - p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1; -#endif - - *(p->conf.last_generated_accesslog_ts_ptr) = srv->cur_ts; - newts = 1; - } - - buffer_append_string_buffer(b, p->conf.ts_accesslog_str); - - break; - case FORMAT_REMOTE_HOST: - - /* handle inet_ntop cache */ - - buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(con->dst_addr))); - - break; - case FORMAT_REMOTE_IDENT: - /* ident */ - buffer_append_string_len(b, CONST_STR_LEN("-")); - break; - case FORMAT_REMOTE_USER: - if (con->authed_user->used > 1) { - buffer_append_string_buffer(b, con->authed_user); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_REQUEST_LINE: - buffer_append_string(b, get_http_method_name(con->request.http_method)); - buffer_append_string_len(b, CONST_STR_LEN(" ")); - accesslog_append_escaped(b, con->request.orig_uri); - buffer_append_string_len(b, CONST_STR_LEN(" ")); - buffer_append_string(b, get_http_version_name(con->request.http_version)); - - break; - case FORMAT_STATUS: - buffer_append_long(b, con->http_status); - break; - - case FORMAT_BYTES_OUT_NO_HEADER: - if (con->bytes_written > 0) { - buffer_append_off_t(b, - con->bytes_written - con->bytes_header <= 0 ? 0 : con->bytes_written - con->bytes_header); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_HEADER: - if (NULL != (ds = (data_string *)array_get_element(con->request.headers, CONST_BUF_LEN(p->conf.parsed_format->ptr[j]->string)))) { - accesslog_append_escaped(b, ds->value); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_RESPONSE_HEADER: - if (NULL != (ds = (data_string *)array_get_element(con->response.headers, CONST_BUF_LEN(p->conf.parsed_format->ptr[j]->string)))) { - accesslog_append_escaped(b, ds->value); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_ENV: - if (NULL != (ds = (data_string *)array_get_element(con->environment, CONST_BUF_LEN(p->conf.parsed_format->ptr[j]->string)))) { - accesslog_append_escaped(b, ds->value); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_FILENAME: - if (con->physical.path->used > 1) { - buffer_append_string_buffer(b, con->physical.path); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_BYTES_OUT: - if (con->bytes_written > 0) { - buffer_append_off_t(b, con->bytes_written); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_BYTES_IN: - if (con->bytes_read > 0) { - buffer_append_off_t(b, con->bytes_read); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_TIME_USED: - buffer_append_long(b, srv->cur_ts - con->request_start); - break; - case FORMAT_SERVER_NAME: - if (con->server_name->used > 1) { - buffer_append_string_buffer(b, con->server_name); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_HTTP_HOST: - if (con->uri.authority->used > 1) { - accesslog_append_escaped(b, con->uri.authority); - } else { - buffer_append_string_len(b, CONST_STR_LEN("-")); - } - break; - case FORMAT_REQUEST_PROTOCOL: - buffer_append_string(b, - con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0"); - break; - case FORMAT_REQUEST_METHOD: - buffer_append_string(b, get_http_method_name(con->request.http_method)); - break; - case FORMAT_SERVER_PORT: - buffer_append_long(b, srv->srvconf.port); - break; - case FORMAT_QUERY_STRING: - accesslog_append_escaped(b, con->uri.query); - break; - case FORMAT_URL: - accesslog_append_escaped(b, con->uri.path_raw); - break; - case FORMAT_CONNECTION_STATUS: - switch(con->keep_alive) { - case 0: buffer_append_string_len(b, CONST_STR_LEN("-")); break; - default: buffer_append_string_len(b, CONST_STR_LEN("+")); break; - } - break; - default: - /* - { 'a', FORMAT_REMOTE_ADDR }, - { 'A', FORMAT_LOCAL_ADDR }, - { 'C', FORMAT_COOKIE }, - { 'D', FORMAT_TIME_USED_MS }, - */ - - break; - } - break; - default: - break; - } - } - - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - if (p->conf.use_syslog || /* syslog doesn't cache */ - (p->conf.access_logfile->used && p->conf.access_logfile->ptr[0] != '|') || /* pipes don't cache */ - newts || - b->used > BUFFER_MAX_REUSE_SIZE) { - if (p->conf.use_syslog) { -#ifdef HAVE_SYSLOG_H - if (b->used > 2) { - /* syslog appends a \n on its own */ - syslog(LOG_INFO, "%*s", (int) b->used - 2, b->ptr); - } -#endif - } else if (p->conf.log_access_fd != -1) { - write(p->conf.log_access_fd, b->ptr, b->used - 1); - } - buffer_reset(b); - } - - return HANDLER_GO_ON; -} - - -LI_EXPORT int mod_accesslog_plugin_init(plugin *p); -LI_EXPORT int mod_accesslog_plugin_init(plugin *p) { - p->version = LIGHTTPD_VERSION_ID; - p->name = buffer_init_string("accesslog"); - - p->init = mod_accesslog_init; - p->set_defaults= log_access_open; - p->cleanup = mod_accesslog_free; - - p->handle_response_done = log_access_write; - p->handle_sighup = log_access_cycle; - - p->data = NULL; - - return 0; -} |