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[0] != '\0') ? 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 *fn, *value, *prefix, *addr;
00039 char buf[U_MAX_LOG_LENGTH], ip[128] = { '\0' };
00040 u_config_t *sub;
00041 vhost_t *vhost;
00042 struct timeval tv;
00043 struct tm tm;
00044 time_t now;
00045 int logrq, n;
00046
00047 dbg_err_if(h == NULL);
00048 dbg_err_if(config == NULL);
00049 dbg_err_if(rq == NULL);
00050 dbg_err_if(rs == NULL);
00051
00052 dbg_err_if((vhost = http_get_vhost(h, rq)) == NULL);
00053
00054
00055 dbg_err_if(vhost->klog == NULL);
00056
00057 fn = request_get_filename(rq);
00058 dbg_err_if(fn == NULL);
00059
00060 logrq = 0;
00061
00062
00063 if(u_config_get_child_n(config, "log", 0))
00064 {
00065 for(n = 0; (sub = u_config_get_child_n(config, "log", n)) != NULL; ++n)
00066 {
00067 if((value = u_config_get_value(sub)) == NULL)
00068 continue;
00069 if(!fnmatch(value, fn, 0))
00070 {
00071 logrq++;
00072 break;
00073 }
00074 }
00075 } else {
00076
00077 logrq++;
00078 }
00079
00080 if(!logrq)
00081 return 0;
00082
00083
00084 for(n = 0; (sub = u_config_get_child_n(config, "dontlog", n)) != NULL; ++n)
00085 {
00086 if((value = u_config_get_value(sub)) == NULL)
00087 continue;
00088 if(fnmatch(value, fn, 0) == FNM_NOMATCH)
00089 continue;
00090 else
00091 return 0;
00092 }
00093
00094 gettimeofday(&tv, NULL);
00095
00096 now = tv.tv_sec;
00097 #ifdef HAVE_LOCALTIME_R
00098 localtime_r(&now, &tm);
00099 #else
00100 tm = *localtime(&now);
00101 #endif
00102 tm.tm_year += 1900;
00103
00104 if((sub = u_config_get_child(config, "prefix")) == NULL ||
00105 (prefix = u_config_get_value(sub)) == NULL)
00106 {
00107 prefix = default_prefix;
00108 }
00109
00110 addr = request_get_peer_addr(rq);
00111
00112
00113 dbg_err_if(u_snprintf(buf, sizeof(buf),
00114 "%s %s - - [%02d/%s/%4d:%02d:%02d:%02d %ld]"
00115 " \"%s\" %d %s \"%s\" \"%s\" \"-\"",
00116 prefix,
00117 value_or_dash(u_addr_get_ip(addr, ip, sizeof ip)),
00118
00119 tm.tm_mday, months[tm.tm_mon], tm.tm_year,
00120
00121 tm.tm_hour, tm.tm_min, tm.tm_sec, get_timezone(&tm),
00122
00123 value_or_dash(request_get_client_request(rq)),
00124
00125 response_get_status(rs),
00126
00127 value_or_dash(response_get_field_value(rs, "Content-Length")),
00128
00129 value_or_dash(request_get_field_value(rq, "Referer")),
00130 value_or_dash(request_get_field_value(rq, "User-Agent"))
00131 ));
00132
00133
00134 if(vhost->klog->type == KLOG_TYPE_SYSLOG || ctx->pipc == 0)
00135 {
00136 if(vhost->klog)
00137 dbg_err_if(klog(vhost->klog, KLOG_INFO, "%s", buf));
00138 } else {
00139
00140 dbg_err_if(ctx->server == NULL);
00141 dbg_err_if(ctx->backend == NULL);
00142 dbg_err_if(server_ppc_cmd_access_log(ctx->server, ctx->backend->id,
00143 vhost->id, buf));
00144 }
00145
00146 return 0;
00147 err:
00148 return ~0;
00149 }