00001 #include <time.h>
00002 #include <u/libu.h>
00003 #include <klone/klone.h>
00004 #include <klone/context.h>
00005 #include <klone/klog.h>
00006 #include <klone/access.h>
00007 #include <klone/server_ppc_cmd.h>
00008
00009 static inline const char *value_or_dash(const char *v)
00010 {
00011 static const char dash[] = "-";
00012
00013 return (v ? v : dash);
00014 }
00015
00016 static long get_timezone(struct tm *tm)
00017 {
00018 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
00019 long int h, m, sign;
00020
00021 sign = (tm->tm_gmtoff > 0 ? 1 : -1);
00022 h = abs(tm->tm_gmtoff) / 3600;
00023 m = (h % 3600) / 60;
00024
00025 return sign * (h * 100 + m);
00026 #else
00027 return 0;
00028 #endif
00029 }
00030
00031 int access_log(http_t *h, u_config_t *config, request_t *rq, response_t *rs)
00032 {
00033 static const char *months[] = {
00034 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00035 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
00036 };
00037 static const char default_prefix[] = "[access]";
00038 const char *ip, *fn, *value, *prefix;
00039 char buf[U_MAX_LOG_LENGTH];
00040 u_config_t *sub;
00041 vhost_t *vhost;
00042 addr_t *addr;
00043 struct timeval tv;
00044 struct tm tm;
00045 time_t now;
00046 int logrq, n;
00047
00048 dbg_err_if(h == NULL);
00049 dbg_err_if(config == NULL);
00050 dbg_err_if(rq == NULL);
00051 dbg_err_if(rs == NULL);
00052
00053 dbg_err_if((vhost = http_get_vhost(h, rq)) == NULL);
00054
00055
00056 dbg_err_if(vhost->klog == NULL);
00057
00058 fn = request_get_filename(rq);
00059 dbg_err_if(fn == NULL);
00060
00061 logrq = 0;
00062
00063
00064 if(u_config_get_child_n(config, "log", 0))
00065 {
00066 for(n = 0; (sub = u_config_get_child_n(config, "log", n)) != NULL; ++n)
00067 {
00068 if((value = u_config_get_value(sub)) == NULL)
00069 continue;
00070 if(!fnmatch(value, fn, 0))
00071 {
00072 logrq++;
00073 break;
00074 }
00075 }
00076 } else {
00077
00078 logrq++;
00079 }
00080
00081 if(!logrq)
00082 return 0;
00083
00084
00085 for(n = 0; (sub = u_config_get_child_n(config, "dontlog", n)) != NULL; ++n)
00086 {
00087 if((value = u_config_get_value(sub)) == NULL)
00088 continue;
00089 if(fnmatch(value, fn, 0) == FNM_NOMATCH)
00090 continue;
00091 else
00092 return 0;
00093 }
00094
00095 gettimeofday(&tv, NULL);
00096
00097 addr = request_get_peer_addr(rq);
00098 ip = inet_ntoa(addr->sa.sin.sin_addr);
00099
00100 now = tv.tv_sec;
00101 #ifdef HAVE_LOCALTIME_R
00102 localtime_r(&now, &tm);
00103 #else
00104 tm = *localtime(&now);
00105 #endif
00106 tm.tm_year += 1900;
00107
00108 if((sub = u_config_get_child(config, "prefix")) == NULL ||
00109 (prefix = u_config_get_value(sub)) == NULL)
00110 {
00111 prefix = default_prefix;
00112 }
00113
00114
00115 dbg_err_if(u_snprintf(buf, sizeof(buf),
00116 "%s %s - - [%02d/%s/%4d:%02d:%02d:%02d %ld]"
00117 " \"%s\" %d %s \"%s\" \"%s\" \"-\"",
00118 prefix,
00119 value_or_dash(ip),
00120
00121 tm.tm_mday, months[tm.tm_mon], tm.tm_year,
00122
00123 tm.tm_hour, tm.tm_min, tm.tm_sec, get_timezone(&tm),
00124
00125 value_or_dash(request_get_client_request(rq)),
00126
00127 response_get_status(rs),
00128
00129 value_or_dash(response_get_field_value(rs, "Content-Length")),
00130
00131 value_or_dash(request_get_field_value(rq, "Referer")),
00132 value_or_dash(request_get_field_value(rq, "User-Agent"))
00133 ));
00134
00135
00136 if(vhost->klog->type == KLOG_TYPE_SYSLOG || ctx->pipc == 0)
00137 {
00138 if(vhost->klog)
00139 dbg_err_if(klog(vhost->klog, KLOG_INFO, "%s", buf));
00140 } else {
00141
00142 dbg_err_if(ctx->server == NULL);
00143 dbg_err_if(ctx->backend == NULL);
00144 dbg_err_if(server_ppc_cmd_access_log(ctx->server, ctx->backend->id,
00145 vhost->id, buf));
00146 }
00147
00148 return 0;
00149 err:
00150 return ~0;
00151 }