On Feb 26, 2014, at 7:39 PM, Yunkai Zhang <yunkai...@gmail.com> wrote:
> Updated. thanks a lot :) > On Thu, Feb 27, 2014 at 9:04 AM, James Peach <jpe...@apache.org> wrote: > >> 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; } >>> >> >> > > > -- > Yunkai Zhang > Work at Taobao