BUG/MINOR: fix option httplog validation with TCP frontends
Option httplog needs to be checked only once the proxy has been validated,
so that its final mode (tcp/http) can be used. Also we need to check for
httplog before checking the log format, so that we can report a warning
about this specific option and not about the format it implies.
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 622e168..15ed23a 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -344,6 +344,8 @@
int no_options; /* PR_O_REDISP, PR_O_TRANSP, ... */
int no_options2; /* PR_O2_* */
+ char *logformat_string; /* log format string */
+ char *uniqueid_format_string; /* unique-id format string */
struct {
const char *file; /* file where the section appears */
int line; /* line where the section appears */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 5bd2cfc..a45acb1 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1345,7 +1345,6 @@
int err_code = 0;
struct acl_cond *cond = NULL;
struct logsrv *tmplogsrv;
- struct logformat_node *tmplf;
char *errmsg = NULL;
if (!strcmp(args[0], "listen"))
@@ -1564,21 +1563,17 @@
LIST_ADDQ(&curproxy->logsrvs, &node->list);
}
- /* copy default log_format to curproxy */
- list_for_each_entry(tmplf, &defproxy.logformat, list) {
- struct logformat_node *node = malloc(sizeof(struct logformat_node));
- memcpy(node, tmplf, sizeof(struct logformat_node));
- LIST_INIT(&node->list);
- LIST_ADDQ(&curproxy->logformat, &node->list);
- }
+ /* get either a pointer to the logformat string or a copy of it */
+ curproxy->logformat_string = defproxy.logformat_string;
+ if (curproxy->logformat_string &&
+ curproxy->logformat_string != default_http_log_format &&
+ curproxy->logformat_string != default_tcp_log_format &&
+ curproxy->logformat_string != clf_http_log_format)
+ curproxy->logformat_string = strdup(curproxy->logformat_string);
- /* copy default unique_id to curproxy */
- list_for_each_entry(tmplf, &defproxy.format_unique_id, list) {
- struct logformat_node *node = malloc(sizeof(struct logformat_node));
- memcpy(node, tmplf, sizeof(struct logformat_node));
- LIST_INIT(&node->list);
- LIST_ADDQ(&curproxy->format_unique_id, &node->list);
- }
+ curproxy->uniqueid_format_string = defproxy.uniqueid_format_string;
+ if (curproxy->uniqueid_format_string)
+ curproxy->uniqueid_format_string = strdup(curproxy->uniqueid_format_string);
/* copy default header unique id */
if (defproxy.header_unique_id)
@@ -1614,6 +1609,13 @@
free(defproxy.expect_str);
if (defproxy.expect_regex) regfree(defproxy.expect_regex);
+ if (defproxy.logformat_string == default_http_log_format ||
+ defproxy.logformat_string == default_tcp_log_format ||
+ defproxy.logformat_string == clf_http_log_format)
+ free(defproxy.logformat_string);
+
+ free(defproxy.uniqueid_format_string);
+
for (rc = 0; rc < HTTP_ERR_SIZE; rc++)
chunk_destroy(&defproxy.errmsg[rc]);
@@ -3384,13 +3386,19 @@
goto out;
}
}
- parse_logformat_string(logformat, curproxy, &curproxy->logformat, curproxy->mode);
+ if (curproxy->logformat_string != default_http_log_format &&
+ curproxy->logformat_string != default_tcp_log_format &&
+ curproxy->logformat_string != clf_http_log_format)
+ free(curproxy->logformat_string);
+ curproxy->logformat_string = logformat;
}
else if (!strcmp(args[1], "tcplog")) {
- char *logformat;
/* generate a detailed TCP log */
- logformat = default_tcp_log_format;
- parse_logformat_string(logformat, curproxy, &curproxy->logformat, curproxy->mode);
+ if (curproxy->logformat_string != default_http_log_format &&
+ curproxy->logformat_string != default_tcp_log_format &&
+ curproxy->logformat_string != clf_http_log_format)
+ free(curproxy->logformat_string);
+ curproxy->logformat_string = default_tcp_log_format;
}
else if (!strcmp(args[1], "tcpka")) {
/* enable TCP keep-alives on client and server sessions */
@@ -4639,7 +4647,8 @@
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
- parse_logformat_string(args[1], curproxy, &curproxy->format_unique_id, PR_MODE_HTTP);
+ free(curproxy->uniqueid_format_string);
+ curproxy->uniqueid_format_string = strdup(args[1]);
}
else if (strcmp(args[0], "unique-id-header") == 0) {
@@ -4658,7 +4667,12 @@
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
- parse_logformat_string(args[1], curproxy, &curproxy->logformat, curproxy->mode);
+
+ if (curproxy->logformat_string != default_http_log_format &&
+ curproxy->logformat_string != default_tcp_log_format &&
+ curproxy->logformat_string != clf_http_log_format)
+ free(curproxy->logformat_string);
+ curproxy->logformat_string = strdup(args[1]);
}
else if (!strcmp(args[0], "log") && kwm == KWM_NO) {
@@ -6208,6 +6222,13 @@
}
}
+ /* compile the log format */
+ if (curproxy->logformat_string)
+ parse_logformat_string(curproxy->logformat_string, curproxy, &curproxy->logformat, curproxy->mode);
+
+ if (curproxy->uniqueid_format_string)
+ parse_logformat_string(curproxy->uniqueid_format_string, curproxy, &curproxy->format_unique_id, PR_MODE_HTTP);
+
/* first, we will invert the servers list order */
newsrv = NULL;
while (curproxy->srv) {
diff --git a/src/haproxy.c b/src/haproxy.c
index 8d3e6e3..ff962c2 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -831,6 +831,12 @@
free(p->capture_name);
free(p->monitor_uri);
free(p->rdp_cookie_name);
+ if (p->logformat_string == default_http_log_format ||
+ p->logformat_string == default_tcp_log_format ||
+ p->logformat_string == clf_http_log_format)
+ free(p->logformat_string);
+
+ free(p->uniqueid_format_string);
for (i = 0; i < HTTP_ERR_SIZE; i++)
chunk_destroy(&p->errmsg[i]);
diff --git a/src/proxy.c b/src/proxy.c
index bc5779f..3568251 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -406,6 +406,13 @@
Warning("config : 'option httplog' not usable with %s '%s' (needs 'mode http'). Falling back to 'option tcplog'.\n",
proxy_type_str(curproxy), curproxy->id);
}
+ if (curproxy->logformat_string == default_http_log_format ||
+ curproxy->logformat_string == clf_http_log_format) {
+ curproxy->logformat_string = default_tcp_log_format;
+ Warning("config : 'option httplog' not usable with %s '%s' (needs 'mode http'). Falling back to 'option tcplog'.\n",
+ proxy_type_str(curproxy), curproxy->id);
+ }
+
return 0;
}