From: Alex Rousskov Date: Tue, 6 Sep 2011 18:28:11 +0000 (-0600) Subject: Support maximum field width for string access.log fields. X-Git-Tag: take08~24^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c32c6db7e28a12379ccb01aa07261d233137ac47;p=thirdparty%2Fsquid.git Support maximum field width for string access.log fields. Some standard command-line and some log processing tools have trouble handling URLs or other logged fields exceeding 8KB in length. Moreover, Squid violates its own log line format and truncates the entire log line if, for example, the URL is 8KB long. By supporting .precision format argument, we allow the administrator to specify logged URL size and avoid these problems. Limiting logged field width has no effect on traffic on the wire, with the exception of log records if they are sent over the network, of course. TODO: The name comes from the printf(3) "precision" format part. It may be a good idea to rename our "precision" into max_width or similar, especially if we do not support floating point precision logging. TODO: Old code used chars to store user-configured field width and precision. That does not work for URLs, headers, and other entries longer than 256 characters. This patch changes the storage type to int. The code should probably be polished further to remove unsigned->signed conversions. --- diff --git a/src/cf.data.pre b/src/cf.data.pre index 307885dbeb..6737e056eb 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -2876,8 +2876,12 @@ DOC_START ' output as-is - left aligned - width field width. If starting with 0 the - output is zero padded + + width minimum and/or maximum field width: + [width_min][.width_max] + When minimum starts with 0, the field is zero-padded. + String values exceeding maximum width are truncated. + {arg} argument such as header name etc Format codes: diff --git a/src/format/Format.cc b/src/format/Format.cc index e39861b4c6..18ab080072 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -1034,11 +1034,18 @@ Format::Format::assemble(MemBuf &mb, AccessLogEntry *al, int logSequenceNumber) } } - if (fmt->width) { + // enforce width limits if configured + const bool haveMaxWidth = fmt->precision && !doint && !dooff; + if (haveMaxWidth || fmt->width) { + const int minWidth = fmt->width ? + static_cast(fmt->width) : 0; + const int maxWidth = haveMaxWidth ? + static_cast(fmt->precision) : strlen(out); + if (fmt->left) - mb.Printf("%-*s", (int) fmt->width, out); + mb.Printf("%-*.*s", minWidth, maxWidth, out); else - mb.Printf("%*s", (int) fmt->width, out); + mb.Printf("%*.*s", minWidth, maxWidth, out); } else mb.append(out, strlen(out)); } else { diff --git a/src/format/Tokens.h b/src/format/Tokens.h index a609718e5b..aff0212f11 100644 --- a/src/format/Tokens.h +++ b/src/format/Tokens.h @@ -215,8 +215,8 @@ public: } header; char *timespec; } data; - unsigned char width; - unsigned char precision; + unsigned int width; + unsigned int precision; enum Quoting quote; unsigned int left:1; unsigned int space:1;