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").
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 89b985f..6e5649b 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -18767,9 +18767,10 @@
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
diff --git a/include/haproxy/log-t.h b/include/haproxy/log-t.h
index 2fcce43..8be5f09 100644
--- a/include/haproxy/log-t.h
+++ b/include/haproxy/log-t.h
@@ -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
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 443c406..63483cf 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2927,7 +2927,8 @@
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 @@
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 @@
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);
diff --git a/src/log.c b/src/log.c
index f2480b4..192525e 100644
--- a/src/log.c
+++ b/src/log.c
@@ -700,8 +700,13 @@
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;
}
}