Browse Source

mod_accesslog: optimize accesslog_append_escaped (fixes #2236, thx crypt)

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2747 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.27
Stefan Bühler 11 years ago
parent
commit
572f738f29
  1. 1
      NEWS
  2. 83
      src/mod_accesslog.c

1
NEWS

@ -22,6 +22,7 @@ NEWS
* mod_cgi: fix race condition leaving response not forwarded to client (fixes #2217)
* mod_accesslog: Fix var declarations mixed in source (fixes #2233)
* mod_status: Add version to status page (fixes #2219)
* mod_accesslog: optimize accesslog_append_escaped (fixes #2236, thx crypt)
- 1.4.26 - 2010-02-07
* Fix request parser to handle packets with splitted \r\n\r\n (fixes #2105)

83
src/mod_accesslog.c

@ -157,51 +157,62 @@ INIT_FUNC(mod_accesslog_init) {
}
static void accesslog_append_escaped(buffer *dest, buffer *str) {
unsigned int i;
char *ptr, *start, *end;
/* replaces non-printable chars with \xHH where HH is the hex representation of the byte */
/* exceptions: " => \", \ => \\, whitespace chars => \n \t etc. */
if (str->used == 0) return;
buffer_prepare_append(dest, str->used - 1);
for (i = 0; i < str->used - 1; i++) {
if (str->ptr[i] >= ' ' && str->ptr[i] <= '~') {
/* printable chars */
buffer_append_string_len(dest, &str->ptr[i], 1);
} else switch (str->ptr[i]) {
case '"':
BUFFER_APPEND_STRING_CONST(dest, "\\\"");
break;
case '\\':
BUFFER_APPEND_STRING_CONST(dest, "\\\\");
break;
case '\b':
BUFFER_APPEND_STRING_CONST(dest, "\\b");
break;
case '\n':
BUFFER_APPEND_STRING_CONST(dest, "\\n");
break;
case '\r':
BUFFER_APPEND_STRING_CONST(dest, "\\r");
break;
case '\t':
BUFFER_APPEND_STRING_CONST(dest, "\\t");
break;
case '\v':
BUFFER_APPEND_STRING_CONST(dest, "\\v");
break;
default: {
/* non printable char => \xHH */
char hh[5] = {'\\','x',0,0,0};
char h = str->ptr[i] / 16;
hh[2] = (h > 9) ? (h - 10 + 'A') : (h + '0');
h = str->ptr[i] % 16;
hh[3] = (h > 9) ? (h - 10 + 'A') : (h + '0');
buffer_append_string_len(dest, &hh[0], 4);
for (ptr = start = str->ptr, end = str->ptr + str->used - 1; ptr < end; ptr++) {
if (*ptr >= ' ' && *ptr <= '~') {
/* nothing to change, add later as one block */
} else {
/* copy previous part */
if (start < ptr) {
buffer_append_string_len(dest, start, ptr - start);
}
start = ptr + 1;
switch (*ptr) {
case '"':
BUFFER_APPEND_STRING_CONST(dest, "\\\"");
break;
case '\\':
BUFFER_APPEND_STRING_CONST(dest, "\\\\");
break;
case '\b':
BUFFER_APPEND_STRING_CONST(dest, "\\b");
break;
case '\n':
BUFFER_APPEND_STRING_CONST(dest, "\\n");
break;
case '\r':
BUFFER_APPEND_STRING_CONST(dest, "\\r");
break;
case '\t':
BUFFER_APPEND_STRING_CONST(dest, "\\t");
break;
case '\v':
BUFFER_APPEND_STRING_CONST(dest, "\\v");
break;
default: {
/* non printable char => \xHH */
char hh[5] = {'\\','x',0,0,0};
char h = *ptr / 16;
hh[2] = (h > 9) ? (h - 10 + 'A') : (h + '0');
h = *ptr % 16;
hh[3] = (h > 9) ? (h - 10 + 'A') : (h + '0');
buffer_append_string_len(dest, &hh[0], 4);
}
break;
}
break;
}
}
if (start < end) {
buffer_append_string_len(dest, start, end - start);
}
}
static int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {

Loading…
Cancel
Save