Le 18/09/2020 à 01:33, James Brown a écrit :
git bisect says that this regression was caused
by commit c89077713915f605eb5d716545f182c8d0bf5581
This makes little sense to me, since that commit doesn't touch anything even
slightly related.
As far as I can tell, the proximate issue is that PATCH is not a "well-known
method" to HAproxy, despite being in RFC 5789. find_http_meth is returning
HTTP_METH_OTHER (silently) for it, and there's something hinky with how the
method ACL matcher handles HTTP_METH_OTHER.
I tried to poke the pat_match_meth function with a debugger, but it's not even
being called in v2.2.3 (it /is/ being called in v2.2.2). Did something break in
how custom matchers are called?
I'm able to reproduce the bug. In fact, it was introduced by the commit
05f3910f5 ("BUG/MEDIUM: htx: smp_prefetch_htx() must always validate the
direction"). I attached a patch to fix the bug.
Thanks,
--
Christopher Faulet
>From 6ad22f6b3610628eae275918464d2e9386299e1f Mon Sep 17 00:00:00 2001
From: Christopher Faulet <[email protected]>
Date: Fri, 20 Mar 2020 08:21:55 +0100
Subject: [PATCH] WIP: Add flag to explicitly add a connection header
---
src/mux_h1.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/mux_h1.c b/src/mux_h1.c
index b3c954e0e..0b8e6b120 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -79,6 +79,7 @@
/* 0x00000800 .. 0x00001000 unused */
#define H1S_F_HAVE_SRV_NAME 0x00002000 /* Set during output process if the server name header was added to the request */
#define H1S_F_HAVE_O_CONN 0x00004000 /* Set during output process to know connection mode was processed */
+#define H1S_F_EXPLICIT_CONN 0x00008000 /* Explicitly set connection header during output processing */
/* H1 connection descriptor */
struct h1c {
@@ -942,13 +943,13 @@ static void h1_update_req_conn_value(struct h1s *h1s, struct h1m *h1m, struct is
return;
if (h1s->flags & H1S_F_WANT_KAL || px->options2 & PR_O2_FAKE_KA) {
- if (!(h1m->flags & H1_MF_VER_11)) {
+ if (!(h1m->flags & H1_MF_VER_11) || (h1s->flags & H1S_F_EXPLICIT_CONN)) {
TRACE_STATE("add \"Connection: keep-alive\"", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s);
*conn_val = ist("keep-alive");
}
}
else { /* H1S_F_WANT_CLO && !PR_O2_FAKE_KA */
- if (h1m->flags & H1_MF_VER_11) {
+ if ((h1m->flags & H1_MF_VER_11) || (h1s->flags & H1S_F_EXPLICIT_CONN)) {
TRACE_STATE("add \"Connection: close\"", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s);
*conn_val = ist("close");
}
@@ -965,13 +966,14 @@ static void h1_update_res_conn_value(struct h1s *h1s, struct h1m *h1m, struct is
if (h1s->flags & H1S_F_WANT_KAL) {
if (!(h1m->flags & H1_MF_VER_11) ||
- !((h1m->flags & h1s->req.flags) & H1_MF_VER_11)) {
+ !((h1m->flags & h1s->req.flags) & H1_MF_VER_11) ||
+ (h1s->flags & H1S_F_EXPLICIT_CONN)) {
TRACE_STATE("add \"Connection: keep-alive\"", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s);
*conn_val = ist("keep-alive");
}
}
else { /* H1S_F_WANT_CLO */
- if (h1m->flags & H1_MF_VER_11) {
+ if ((h1m->flags & H1_MF_VER_11) || (h1s->flags & H1S_F_EXPLICIT_CONN)) {
TRACE_STATE("add \"Connection: close\"", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s);
*conn_val = ist("close");
}
@@ -1684,10 +1686,13 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
goto skip_hdr;
}
else if (isteq(n, ist("connection"))) {
+ h1s->flags |= H1S_F_EXPLICIT_CONN;
h1_parse_connection_header(h1m, &v);
if (!v.len)
goto skip_hdr;
}
+ else if (isteq(n, ist("keep-alive")))
+ h1s->flags |= H1S_F_EXPLICIT_CONN;
/* Skip header if same name is used to add the server name */
if (!(h1m->flags & H1_MF_RESP) && h1c->px->server_id_hdr_name &&
--
2.24.1