159
static void accesslog_append_escaped(buffer *dest, buffer *str) {
160
/* replaces non-printable chars with \xHH where HH is the hex representation of the byte */
161
/* exceptions: " => \", \ => \\, whitespace chars => \n \t etc. */
162
if (str->used == 0) return;
163
buffer_prepare_append(dest, str->used - 1);
165
for (unsigned int i = 0; i < str->used - 1; i++) {
166
if (str->ptr[i] >= ' ' && str->ptr[i] <= '~') {
167
/* printable chars */
168
buffer_append_string_len(dest, &str->ptr[i], 1);
169
} else switch (str->ptr[i]) {
171
BUFFER_APPEND_STRING_CONST(dest, "\\\"");
174
BUFFER_APPEND_STRING_CONST(dest, "\\\\");
177
BUFFER_APPEND_STRING_CONST(dest, "\\b");
180
BUFFER_APPEND_STRING_CONST(dest, "\\n");
183
BUFFER_APPEND_STRING_CONST(dest, "\\r");
186
BUFFER_APPEND_STRING_CONST(dest, "\\t");
189
BUFFER_APPEND_STRING_CONST(dest, "\\v");
192
/* non printable char => \xHH */
193
char hh[5] = {'\\','x',0,0,0};
194
char h = str->ptr[i] / 16;
195
hh[2] = (h > 9) ? (h - 10 + 'A') : (h + '0');
196
h = str->ptr[i] % 16;
197
hh[3] = (h > 9) ? (h - 10 + 'A') : (h + '0');
198
buffer_append_string_len(dest, &hh[0], 4);
159
205
static int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
160
206
size_t i, j, k = 0, start = 0;
449
499
return HANDLER_ERROR;
502
/* make sure they didn't try to send the timestamp in twice...
503
* also, save the format string in a different variable (this
504
* will save a few conditionals later)
507
for (j = 0; j < s->parsed_format->used; j++) {
508
if (FIELD_FORMAT == s->parsed_format->ptr[j]->type) {
509
if (FORMAT_TIMESTAMP == s->parsed_format->ptr[j]->field) {
510
if (!buffer_is_empty(s->parsed_format->ptr[j]->string)) {
511
buffer_copy_string(s->ts_accesslog_fmt_str, s->parsed_format->ptr[j]->string->ptr);
515
log_error_write(srv, __FILE__, __LINE__, "sb",
516
"you may not use the timestamp twice in the same access log:", s->format);
518
return HANDLER_ERROR;
453
526
for (j = 0; j < s->parsed_format->used; j++) {
559
644
if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.filename"))) {
560
645
PATCH(access_logfile);
561
646
PATCH(log_access_fd);
562
PATCH(last_generated_accesslog_ts_ptr);
563
647
PATCH(access_logbuffer);
564
PATCH(ts_accesslog_str);
565
648
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.format"))) {
567
650
PATCH(parsed_format);
651
PATCH(last_generated_accesslog_ts_ptr);
652
PATCH(ts_accesslog_str);
653
PATCH(ts_accesslog_fmt_str);
654
PATCH(append_tz_offset);
568
655
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.use-syslog"))) {
569
656
PATCH(use_syslog);
570
PATCH(last_generated_accesslog_ts_ptr);
571
657
PATCH(access_logbuffer);
572
PATCH(ts_accesslog_str);
616
701
#if defined(HAVE_STRUCT_TM_GMTOFF)
617
702
# ifdef HAVE_LOCALTIME_R
618
703
localtime_r(&(srv->cur_ts), &tm);
619
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", &tm);
621
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime(&(srv->cur_ts)));
704
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, &tm);
705
# else /* HAVE_LOCALTIME_R */
706
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, localtime_r(&(srv->cur_ts)));
707
# endif /* HAVE_LOCALTIME_R */
623
708
p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
625
buffer_append_string_len(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-", 1);
627
scd = abs(tm.tm_gmtoff);
629
min = (scd % 3600) / 60;
632
if (hrs < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
633
buffer_append_long(p->conf.ts_accesslog_str, hrs);
635
if (min < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
636
buffer_append_long(p->conf.ts_accesslog_str, min);
637
buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("]"));
710
if (p->conf.append_tz_offset) {
711
buffer_append_string_len(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-", 1);
713
scd = abs(tm.tm_gmtoff);
715
min = (scd % 3600) / 60;
718
if (hrs < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
719
buffer_append_long(p->conf.ts_accesslog_str, hrs);
721
if (min < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
722
buffer_append_long(p->conf.ts_accesslog_str, min);
723
buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("]"));
725
#else /* HAVE_STRUCT_TM_GMTOFF */
726
# ifdef HAVE_GMTIME_R
640
727
gmtime_r(&(srv->cur_ts), &tm);
641
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S +0000]", &tm);
643
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)));
728
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, &tm);
729
# else /* HAVE_GMTIME_R */
730
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, gmtime(&(srv->cur_ts)));
731
# endif /* HAVE_GMTIME_R */
645
732
p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
733
#endif /* HAVE_STRUCT_TM_GMTOFF */
648
735
*(p->conf.last_generated_accesslog_ts_ptr) = srv->cur_ts;
690
777
case FORMAT_HEADER:
691
778
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, p->conf.parsed_format->ptr[j]->string->ptr))) {
692
buffer_append_string_buffer(b, ds->value);
779
accesslog_append_escaped(b, ds->value);
694
781
buffer_append_string_len(b, CONST_STR_LEN("-"));
697
784
case FORMAT_RESPONSE_HEADER:
698
785
if (NULL != (ds = (data_string *)array_get_element(con->response.headers, p->conf.parsed_format->ptr[j]->string->ptr))) {
699
buffer_append_string_buffer(b, ds->value);
786
accesslog_append_escaped(b, ds->value);
701
788
buffer_append_string_len(b, CONST_STR_LEN("-"));
762
849
case FORMAT_QUERY_STRING:
763
buffer_append_string_buffer(b, con->uri.query);
850
accesslog_append_escaped(b, con->uri.query);
766
buffer_append_string_buffer(b, con->uri.path_raw);
853
accesslog_append_escaped(b, con->uri.path_raw);
768
855
case FORMAT_CONNECTION_STATUS:
769
856
switch(con->keep_alive) {