MINOR: log-format: allow to preserve spacing in log format strings

Now it's possible to preserve spacing everywhere except in "log-format",
"log-format-sd" and "unique-id-format" directives, where spaces are
delimiters and are merged. That may be useful when the response payload
is specified as a log format string by "lf-file" or "lf-string", or even
for headers or anything else.

In order to merge spaces, a new option LOG_OPT_MERGE_SPACES is applied
exclusively on options passed to function parse_logformat_string().

This patch fixes an issue #701 ("http-request return log-format file
evaluation altering spacing of ASCII output/art").
This commit is contained in:
Dragan Dosen 2020-06-23 18:16:44 +02:00 committed by Willy Tarreau
parent a6026a0c92
commit 1e3b16f74f
4 changed files with 20 additions and 8 deletions

View File

@ -18767,9 +18767,10 @@ as a sample expression rule (see section 7.3). This it useful to add some
less common information such as the client's SSL certificate's DN, or to log
the key that would be used to store an entry into a stick table.
Note: spaces must be escaped. A space character is considered as a separator.
In order to emit a verbatim '%', it must be preceded by another '%' resulting
in '%%'. HAProxy will automatically merge consecutive separators.
Note: spaces must be escaped. In configuration directives "log-format",
"log-format-sd" and "unique-id-format", spaces are considered as
delimiters and are merged. In order to emit a verbatim '%', it must be
preceded by another '%' resulting in '%%'.
Note: when using the RFC5424 syslog message format, the characters '"',
'\' and ']' inside PARAM-VALUE should be escaped with '\' as prefix (see

View File

@ -45,6 +45,7 @@
#define LOG_OPT_RES_CAP 0x00000010
#define LOG_OPT_HTTP 0x00000020
#define LOG_OPT_ESC 0x00000040
#define LOG_OPT_MERGE_SPACES 0x00000080
/* Fields that need to be extracted from the incoming connection or request for

View File

@ -2927,7 +2927,8 @@ out_uri_auth_compat:
curproxy->conf.args.file = curproxy->conf.lfs_file;
curproxy->conf.args.line = curproxy->conf.lfs_line;
err = NULL;
if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, LOG_OPT_MANDATORY,
if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat,
LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES,
SMP_VAL_FE_LOG_END, &err)) {
ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
@ -2943,7 +2944,8 @@ out_uri_auth_compat:
curproxy->conf.args.file = curproxy->conf.lfsd_file;
curproxy->conf.args.line = curproxy->conf.lfsd_line;
err = NULL;
if (!parse_logformat_string(curproxy->conf.logformat_sd_string, curproxy, &curproxy->logformat_sd, LOG_OPT_MANDATORY,
if (!parse_logformat_string(curproxy->conf.logformat_sd_string, curproxy, &curproxy->logformat_sd,
LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES,
SMP_VAL_FE_LOG_END, &err)) {
ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
@ -2964,8 +2966,11 @@ out_uri_auth_compat:
curproxy->conf.args.file = curproxy->conf.uif_file;
curproxy->conf.args.line = curproxy->conf.uif_line;
err = NULL;
if (!parse_logformat_string(curproxy->conf.uniqueid_format_string, curproxy, &curproxy->format_unique_id, LOG_OPT_HTTP,
(curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_BE_HRQ_HDR, &err)) {
if (!parse_logformat_string(curproxy->conf.uniqueid_format_string, curproxy, &curproxy->format_unique_id,
LOG_OPT_HTTP|LOG_OPT_MERGE_SPACES,
(curproxy->cap & PR_CAP_FE) ? SMP_VAL_FE_HRQ_HDR
: SMP_VAL_BE_HRQ_HDR,
&err)) {
ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
curproxy->conf.uif_file, curproxy->conf.uif_line, err);
free(err);

View File

@ -700,8 +700,13 @@ int parse_logformat_string(const char *fmt, struct proxy *curproxy, struct list
if (cformat == LF_INIT) { /* resynchronize state to text/sep/startvar */
switch (*str) {
case '%': cformat = LF_STARTVAR; break;
case ' ': cformat = LF_SEPARATOR; break;
case 0 : cformat = LF_END; break;
case ' ':
if (options & LOG_OPT_MERGE_SPACES) {
cformat = LF_SEPARATOR;
break;
}
/* fall through */
default : cformat = LF_TEXT; break;
}
}