diff options
author | Yann Ylavic <ylavic@apache.org> | 2023-03-14 11:11:24 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2023-03-14 11:11:24 +0000 |
commit | e5fa6ee46ec1d32aa4c85edce752905a21e0cfad (patch) | |
tree | 1b67ca84f7ff26a50da4f7f1e209676d384238db /server | |
parent | 05202ceceacf1cc448ba7e84601871b39879eea1 (diff) | |
download | httpd-e5fa6ee46ec1d32aa4c85edce752905a21e0cfad.tar.gz |
core: Add formats %{z} and %{strftime-format} to ErrorLogFormat. PR 62161.
%{z} prints the timezone offset (i.e. "[+-]nnnn") and %{strftime-format} allows
any %-format handled by [apr_]strftime().
* include/util_time.h():
Define new AP_CTIME_OPTION_GMTOFF option for ap_recent_ctime_ex().
* server/util_time.c(ap_recent_ctime_ex):
Handle AP_CTIME_OPTION_GMTOFF to print "[+-]nnnn" timezone.
* server/log.c(log_ctime):
If the format contains a '%' it's for strftime(), otherwise it's builtin
with new 'z' as AP_CTIME_OPTION_GMTOFF.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908380 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server')
-rw-r--r-- | server/log.c | 32 | ||||
-rw-r--r-- | server/util_time.c | 26 |
2 files changed, 48 insertions, 10 deletions
diff --git a/server/log.c b/server/log.c index 6295f1a89c..f3347d9834 100644 --- a/server/log.c +++ b/server/log.c @@ -573,14 +573,32 @@ static int log_ctime(const ap_errorlog_info *info, const char *arg, int time_len = buflen; int option = AP_CTIME_OPTION_NONE; - while (arg && *arg) { - switch (*arg) { - case 'u': option |= AP_CTIME_OPTION_USEC; - break; - case 'c': option |= AP_CTIME_OPTION_COMPACT; - break; + if (arg) { + if (arg[0] == 'u' && !arg[1]) { /* no ErrorLogFormat (fast path) */ + option |= AP_CTIME_OPTION_USEC; + } + else if (!ap_strchr_c(arg, '%')) { /* special "%{cuz}t" formats */ + while (*arg) { + switch (*arg++) { + case 'u': + option |= AP_CTIME_OPTION_USEC; + break; + case 'c': + option |= AP_CTIME_OPTION_COMPACT; + break; + case 'z': + option |= AP_CTIME_OPTION_GMTOFF; + break; + } + } + } + else { /* "%{strftime %-format}t" */ + apr_size_t len = 0; + apr_time_exp_t expt; + ap_explode_recent_localtime(&expt, apr_time_now()); + apr_strftime(buf, &len, buflen, arg, &expt); + return (int)len; } - arg++; } ap_recent_ctime_ex(buf, apr_time_now(), option, &time_len); diff --git a/server/util_time.c b/server/util_time.c index 995716b318..95df38d8b9 100644 --- a/server/util_time.c +++ b/server/util_time.c @@ -16,6 +16,7 @@ #include "util_time.h" #include "apr_env.h" +#include "apr_strings.h" @@ -27,6 +28,8 @@ /* Length of ISO 8601 date/time */ #define AP_CTIME_COMPACT_LEN 20 +/* Length of timezone offset from GMT ([+-]hhmm) plus leading space */ +#define AP_CTIME_GMTOFF_LEN 6 /* Cache for exploded values of recent timestamps */ @@ -183,6 +186,10 @@ AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t, needed += AP_CTIME_USEC_LENGTH; } + if (option & AP_CTIME_OPTION_GMTOFF) { + needed += AP_CTIME_GMTOFF_LEN; + } + /* Check the provided buffer length */ if (len && *len >= needed) { *len = needed; @@ -195,9 +202,10 @@ AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t, } /* example without options: "Wed Jun 30 21:49:08 1993" */ - /* 123456789012345678901234 */ /* example for compact format: "1993-06-30 21:49:08" */ - /* 1234567890123456789 */ + /* example for compact+usec+gmtoff format: + * "1993-06-30 22:49:08.123456 +0100" + */ ap_explode_recent_localtime(&xt, t); real_year = 1900 + xt.tm_year; @@ -251,7 +259,19 @@ AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t, *date_str++ = real_year % 100 / 10 + '0'; *date_str++ = real_year % 10 + '0'; } - *date_str++ = 0; + if (option & AP_CTIME_OPTION_GMTOFF) { + int off = xt.tm_gmtoff; + char sign = '+'; + if (off < 0) { + off = -off; + sign = '-'; + } + apr_snprintf(date_str, AP_CTIME_GMTOFF_LEN + 1, " %c%.2d%.2d", + sign, off / 3600, (off % 3600) / 60); + } + else { + *date_str = 0; + } return APR_SUCCESS; } |