On Feb 26, 2014, at 4:30 AM, yun...@apache.org wrote: > Repository: trafficserver > Updated Branches: > refs/heads/master 6d4005f8b -> 38996681d > > > TS-2576: Add Oct/Hex escape representation into LogFormat > > Introudce two escape representations into LogFormat: > * Oct escape sequence: > '\abc': a,b,c should be one of [0-9], and > (a*8^2 + b*8 + c) should be greater than 0 and less than 255. > > * Hex escape sequence: > '\xab': a,b should be one of [0-9, a-f, A-F], and > (a*16 + b) should be greater than 0 and less than 255. > > Signed-off-by: Yunkai Zhang <qiushu....@taobao.com>
Nice! We should add these notes to doc/reference/configuration/logs_xml.config.en.rst > > > Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo > Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/38996681 > Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/38996681 > Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/38996681 > > Branch: refs/heads/master > Commit: 38996681d870249f923e07e5311f983372307316 > Parents: 6d4005f > Author: Yunkai Zhang <qiushu....@taobao.com> > Authored: Tue Feb 18 18:26:20 2014 +0800 > Committer: Yunkai Zhang <qiushu....@taobao.com> > Committed: Wed Feb 26 20:29:21 2014 +0800 > > ---------------------------------------------------------------------- > CHANGES | 2 + > proxy/logging/LogFormat.cc | 108 +++++++++++++++++++++++++++++++++++++--- > proxy/logging/LogFormat.h | 1 + > 3 files changed, 103 insertions(+), 8 deletions(-) > ---------------------------------------------------------------------- > > > http://git-wip-us.apache.org/repos/asf/trafficserver/blob/38996681/CHANGES > ---------------------------------------------------------------------- > diff --git a/CHANGES b/CHANGES > index 150a243..5b374ec 100644 > --- a/CHANGES > +++ b/CHANGES > @@ -1,6 +1,8 @@ > -*- coding: utf-8 -*- > Changes with Apache Traffic Server 5.0.0 > > + *) [TS-2576] Add Oct/Hex escape representation into LogFormat > + > *) [TS-2494] fix the crash that return the stale cached document > when os is down, even if it`s status is not 200 (ok). > *) [TS-2590] Translate documentation into Japanese. > > http://git-wip-us.apache.org/repos/asf/trafficserver/blob/38996681/proxy/logging/LogFormat.cc > ---------------------------------------------------------------------- > diff --git a/proxy/logging/LogFormat.cc b/proxy/logging/LogFormat.cc > index 80e46f4..b5c50f3 100644 > --- a/proxy/logging/LogFormat.cc > +++ b/proxy/logging/LogFormat.cc > @@ -555,6 +555,77 @@ LogFormat::parse_symbol_string(const char > *symbol_string, LogFieldList *field_li > return field_count; > } > > +// > +// Parse escape string, supports two forms: > +// > +// 1) Octal representation: '\abc', for example: '\060' > +// 0 < (a*8^2 + b*8 + c) < 255 > +// > +// 2) Hex representation: '\xab', for exampe: '\x3A' > +// 0 < (a*16 + b) < 255 > +// > +// Return -1 if the beginning four characters are not valid > +// escape sequence, otherwise reutrn unsigned char value of the > +// escape sequence in the string. > +// > +// NOTE: The value of escape sequence should be greater than 0 > +// and less than 255, since: > +// - 0 is terminator of string, and > +// - 255('\377') has been used as LOG_FIELD_MARKER. > +// > +int > +LogFormat::parse_escape_string(const char *str, int len) > +{ > + int sum, start = 0; > + unsigned char a, b, c; > + > + if (str[start] != '\\' || len < 2) > + return -1; > + > + if (str[start + 1] == '\\') > + return '\\'; > + > + if (len < 4) > + return -1; > + > + a = (unsigned char)str[start + 1]; > + b = (unsigned char)str[start + 2]; > + c = (unsigned char)str[start + 3]; > + > + if (isdigit(a) && isdigit(b) && isdigit(b)) { > + > + sum = (a - '0')*64 + (b - '0')*8 + (c - '0'); > + > + if (sum == 0 || sum >= 255) { > + Warning("Octal escape sequence out of range: \\%c%c%c, treat it as > normal string\n", a, b, c); > + return -1; > + } else > + return sum; > + > + } else if (tolower(a) == 'x' && isxdigit(b) && isxdigit(c)) { > + int i, j; > + if (isdigit(b)) > + i = b - '0'; > + else > + i = toupper(b) - 'A' + 10; > + > + if (isdigit(c)) > + j = c - '0'; > + else > + j = toupper(c) - 'A' + 10; > + > + sum = i*16 + j; > + > + if (sum == 0 || sum >= 255) { > + Warning("Hex escape sequence out of range: \\%c%c%c, treat it as > normal string\n", a, b, c); > + return -1; > + } else > + return sum; > + } > + > + return -1; > +} > + > /*------------------------------------------------------------------------- > LogFormat::parse_format_string > > @@ -594,6 +665,7 @@ LogFormat::parse_format_string(const char *format_str, > char **printf_str, char * > unsigned field_count = 0; > unsigned field_len; > unsigned start, stop; > + int escape_char; > > for (start = 0; start < len; start++) { > // > @@ -623,21 +695,41 @@ LogFormat::parse_format_string(const char *format_str, > char **printf_str, char * > fields_pos += field_len; > (*printf_str)[printf_pos++] = LOG_FIELD_MARKER; > ++field_count; > + start = stop; > } else { > // > - // This was not a logging field spec after all, so copy it > - // over to the printf string as is. > + // This was not a logging field spec after all, > + // then try to detect and parse escape string. > // > - memcpy(&(*printf_str)[printf_pos], &format_str[start], stop - start > + 1); > - printf_pos += stop - start + 1; > + escape_char = parse_escape_string(&format_str[start], (len - start)); > + > + if (escape_char == '\\') { > + start += 1; > + (*printf_str)[printf_pos++] = (char)escape_char; > + } else if (escape_char >= 0) { > + start += 3; > + (*printf_str)[printf_pos++] = (char)escape_char; > + } else { > + memcpy(&(*printf_str)[printf_pos], &format_str[start], stop - > start + 1); > + printf_pos += stop - start + 1; > + } > } > - start = stop; > } else { > // > - // This was not the start of a logging field spec, so simply > - // put this char into the printf_str. > + // This was not the start of a logging field spec, > + // then try to detect and parse escape string. > // > - (*printf_str)[printf_pos++] = format_str[start]; > + escape_char = parse_escape_string(&format_str[start], (len - start)); > + > + if (escape_char == '\\') { > + start += 1; > + (*printf_str)[printf_pos++] = (char)escape_char; > + } else if (escape_char >= 0) { > + start += 3; > + (*printf_str)[printf_pos++] = (char)escape_char; > + } else { > + (*printf_str)[printf_pos++] = format_str[start]; > + } > } > } > > > http://git-wip-us.apache.org/repos/asf/trafficserver/blob/38996681/proxy/logging/LogFormat.h > ---------------------------------------------------------------------- > diff --git a/proxy/logging/LogFormat.h b/proxy/logging/LogFormat.h > index da32018..fcc2cef 100644 > --- a/proxy/logging/LogFormat.h > +++ b/proxy/logging/LogFormat.h > @@ -83,6 +83,7 @@ public: > char **file_name, char > **file_header, LogFileFormat * file_type); > static int parse_symbol_string(const char *symbol_string, LogFieldList > *field_list, bool *contains_aggregates); > static int parse_format_string(const char *format_str, char **printf_str, > char **fields_str); > + static int parse_escape_string(const char *str, int len); > > // these are static because m_tagging_on is a class variable > static void turn_tagging_on() { m_tagging_on = true; } >