summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bühler <stbuehler@web.de>2010-08-05 19:53:49 +0000
committerStefan Bühler <stbuehler@web.de>2010-08-05 19:53:49 +0000
commit572f738f29d2c9cc038b3085f0651de4db434026 (patch)
tree3a84af3b07ad36b965abb68a40367719f2af6475
parentf8ef22c019b9bd0a0647a3603a159aba753c0db6 (diff)
downloadlighttpd-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--NEWS1
-rw-r--r--src/mod_accesslog.c83
2 files changed, 48 insertions, 36 deletions
diff --git a/NEWS b/NEWS
index 177249ea..fbde14f2 100644
--- a/NEWS
+++ b/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)
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) {