mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-19 01:54:37 +00:00
BUG/MEDIUM: log: fix lf_expr_postcheck() behavior with default section
Since7a21c3a4ef
("MAJOR: log: implement proper postparsing for logformat expressions"), logformat expressions stored in a default section are not postchecked anymore. This is because the REGISTER_POST_PROXY_CHECK() only evaluates regular proxies. Because of this, proxy options which are automatically enabled on the proxy depending on the logformat expression features in use are not set on the default proxy, which means such options are not passed to the regular proxies that inherit from it (proxies that and will actually be running the logformat expression during runtime). Because of that, a logformat expression stored inside a default section and executed by a regular proxy may not behave properly. Also, since03ca16f38b
("OPTIM: log: resolve logformat options during postparsing"), it's even worse because logformat node options postresoving is also skipped, which may also alter logformat expression encoding feature. To fix the issue, let's add a special case for default proxies in parse_logformat_string() and lf_expr_postcheck() so that default proxies are postchecked on the fly during parsing time in a "relaxed" way as we cannot assume that the features involved in the logformat expression won't be compatible with the proxy actually running it since we may have different types of proxies inheriting from the same default section. This bug was discovered while trying to address GH #2597. It should be backported to 3.0 with7a21c3a4ef
and03ca16f38b
. (cherry picked from commite4f122f3f4
) Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
This commit is contained in:
parent
310c0dd14e
commit
d1a7330086
19
src/log.c
19
src/log.c
@ -870,15 +870,17 @@ int parse_logformat_string(const char *fmt, struct proxy *curproxy,
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!(curproxy->flags & PR_FL_CHECKED)) {
|
if (!(curproxy->cap & PR_CAP_DEF) &&
|
||||||
|
!(curproxy->flags & PR_FL_CHECKED)) {
|
||||||
/* add the lf_expr to the proxy checks to delay postparsing
|
/* add the lf_expr to the proxy checks to delay postparsing
|
||||||
* since config-related proxy properties are not stable yet
|
* since config-related proxy properties are not stable yet
|
||||||
*/
|
*/
|
||||||
LIST_APPEND(&curproxy->conf.lf_checks, &lf_expr->list);
|
LIST_APPEND(&curproxy->conf.lf_checks, &lf_expr->list);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* probably called during runtime or with proxy already checked,
|
/* default proxy, or regular proxy and probably called during
|
||||||
* perform the postcheck right away
|
* runtime or with proxy already checked, perform the postcheck
|
||||||
|
* right away
|
||||||
*/
|
*/
|
||||||
if (!lf_expr_postcheck(lf_expr, curproxy, err))
|
if (!lf_expr_postcheck(lf_expr, curproxy, err))
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -948,11 +950,17 @@ static int lf_expr_postcheck_node_opt(struct lf_expr *lf_expr, struct logformat_
|
|||||||
* compatible with logformat expression, but once the proxy is checked, we fail
|
* compatible with logformat expression, but once the proxy is checked, we fail
|
||||||
* as soon as we face incompatibilities)
|
* as soon as we face incompatibilities)
|
||||||
*
|
*
|
||||||
|
* If the proxy is a default section, then allow the postcheck to succeed:
|
||||||
|
* the logformat expression may or may not work properly depending on the
|
||||||
|
* actual proxy that effectively runs it during runtime, but we have to stay
|
||||||
|
* permissive since we cannot assume it won't work.
|
||||||
|
*
|
||||||
* It returns 1 on success and 0 on error, <err> will be set in case of error.
|
* It returns 1 on success and 0 on error, <err> will be set in case of error.
|
||||||
*/
|
*/
|
||||||
int lf_expr_postcheck(struct lf_expr *lf_expr, struct proxy *px, char **err)
|
int lf_expr_postcheck(struct lf_expr *lf_expr, struct proxy *px, char **err)
|
||||||
{
|
{
|
||||||
struct logformat_node *lf;
|
struct logformat_node *lf;
|
||||||
|
int default_px = (px->cap & PR_CAP_DEF);
|
||||||
|
|
||||||
if (!(px->flags & PR_FL_CHECKED))
|
if (!(px->flags & PR_FL_CHECKED))
|
||||||
px->to_log |= LW_INIT;
|
px->to_log |= LW_INIT;
|
||||||
@ -987,7 +995,8 @@ int lf_expr_postcheck(struct lf_expr *lf_expr, struct proxy *px, char **err)
|
|||||||
px->to_log |= LW_REQ;
|
px->to_log |= LW_REQ;
|
||||||
}
|
}
|
||||||
else if (lf->type == LOG_FMT_ALIAS) {
|
else if (lf->type == LOG_FMT_ALIAS) {
|
||||||
if (lf->alias->mode == PR_MODE_HTTP && px->mode != PR_MODE_HTTP) {
|
if (lf->alias->mode == PR_MODE_HTTP &&
|
||||||
|
!default_px && px->mode != PR_MODE_HTTP) {
|
||||||
memprintf(err, "format alias '%s' is reserved for HTTP mode",
|
memprintf(err, "format alias '%s' is reserved for HTTP mode",
|
||||||
lf->alias->name);
|
lf->alias->name);
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -1006,7 +1015,7 @@ int lf_expr_postcheck(struct lf_expr *lf_expr, struct proxy *px, char **err)
|
|||||||
if (!lf_expr_postcheck_node_opt(lf_expr, lf, err))
|
if (!lf_expr_postcheck_node_opt(lf_expr, lf, err))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if ((px->to_log & (LW_REQ | LW_RESP)) &&
|
if (!default_px && (px->to_log & (LW_REQ | LW_RESP)) &&
|
||||||
(px->mode != PR_MODE_HTTP && !(px->options & PR_O_HTTP_UPG))) {
|
(px->mode != PR_MODE_HTTP && !(px->options & PR_O_HTTP_UPG))) {
|
||||||
memprintf(err, "logformat expression not usable here (at least one node depends on HTTP mode)");
|
memprintf(err, "logformat expression not usable here (at least one node depends on HTTP mode)");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
Loading…
Reference in New Issue
Block a user