access.c

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     /* exit if access logging is not configured */
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     /* if the user specifies what to log */
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; /* log it */
00073             }
00074         }
00075     } else {
00076         /* no "log" key found, match all filenames */
00077         logrq++;
00078     }
00079     
00080     if(!logrq)
00081         return 0; /* don't log this request */
00082 
00083     /* the user specified what is NOT to be logged */
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; /* a "dontlog" item matches the filename, don't log */
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     /* build the log message */
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             /* date */ 
00119             tm.tm_mday, months[tm.tm_mon], tm.tm_year,
00120             /* time */ 
00121             tm.tm_hour, tm.tm_min, tm.tm_sec, get_timezone(&tm),
00122             /* uri */
00123             value_or_dash(request_get_client_request(rq)),
00124             /* status */
00125             response_get_status(rs),
00126             /* bytes returned */
00127             value_or_dash(response_get_field_value(rs, "Content-Length")),
00128             /* referer and user-agent */
00129             value_or_dash(request_get_field_value(rq, "Referer")),
00130             value_or_dash(request_get_field_value(rq, "User-Agent"))
00131             ));
00132 
00133     /* syslog klog doesn't go through ppc */
00134     if(vhost->klog->type == KLOG_TYPE_SYSLOG || ctx->pipc == 0)
00135     {   /* syslog klog or parent context */
00136         if(vhost->klog)
00137             dbg_err_if(klog(vhost->klog, KLOG_INFO, "%s", buf));
00138     } else {
00139         /* children context */
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 }

←Products
Copyright © 2005-2012 - KoanLogic S.r.l. - All rights reserved