diff options
author | Stefan Bühler <stbuehler@web.de> | 2010-08-05 19:53:49 +0000 |
---|---|---|
committer | Stefan Bühler <stbuehler@web.de> | 2010-08-05 19:53:49 +0000 |
commit | 572f738f29d2c9cc038b3085f0651de4db434026 (patch) | |
tree | 3a84af3b07ad36b965abb68a40367719f2af6475 | |
parent | f8ef22c019b9bd0a0647a3603a159aba753c0db6 (diff) | |
download | lighttpd-git-572f738f29d2c9cc038b3085f0651de4db434026.tar.gz |
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
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/mod_accesslog.c | 83 |
2 files changed, 48 insertions, 36 deletions
@@ -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) diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c index e55deca8..420037eb 100644 --- a/src/mod_accesslog.c +++ b/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) { |