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

Reply via email to