BUG/MINOR: mux-h1: Don't set CS_FL_EOI too early for protocol upgrade requests

When a protocol upgrade request is received, once parsed, it is waiting for
the response in the DONE state. But we must not set the flag CS_FL_EOI
because we don't know if a protocol upgrade will be performed or not.

Now, it is set on the response path, if both sides reached the DONE
state. If a protocol upgrade is finally performed, both side are switched in
TUNNEL state. Thus the CS_FL_EOI flag is not set.

If backported, this patch must be adapted because for now it relies on last
2.4-dev changes. It may be backported as far as 2.0.

(cherry picked from commit 3e1748bbf30bc06407bda36517c00c0b97bfeb50)
[cf: context adjustment]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/mux_h1.c b/src/mux_h1.c
index cc34bba..c6c15c2 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -1410,7 +1410,11 @@
 	}
 
 	h1s->flags |= H1S_F_PARSING_DONE;
-	h1s->cs->flags |= CS_FL_EOI;
+	/* Don't set EOI on the conn-stream for protocol upgrade requests, wait
+	 * the response to do so or not depending on the status code.
+	 */
+	if (!(h1m->flags & H1_MF_CONN_UPG))
+		h1s->cs->flags |= CS_FL_EOI;
   end:
 	TRACE_LEAVE(H1_EV_RX_DATA|H1_EV_RX_EOI, h1s->h1c->conn, h1s, 0, (size_t[]){ret});
 	return ret;
@@ -1543,7 +1547,7 @@
 		h1s->cs->flags |= CS_FL_RCV_MORE | CS_FL_WANT_ROOM;
 	else if (h1s->flags & H1S_F_REOS) {
 		h1s->cs->flags |= CS_FL_EOS;
-		if (h1m->state == H1_MSG_TUNNEL)
+		if (h1m->state >= H1_MSG_DONE)
 			h1s->cs->flags |= CS_FL_EOI;
 		else if (h1m->state > H1_MSG_LAST_LF && h1m->state < H1_MSG_DONE)
 			h1s->cs->flags |= CS_FL_ERROR;
@@ -1989,6 +1993,13 @@
 
 	htx_to_buf(chn_htx, buf);
   out:
+	/* Both the request and the response reached the DONE state. So set EOI
+	 * flag on the conn-stream. Most of time, the flag will already be set,
+	 * except for protocol upgrades.
+	 */
+	if (h1s->cs && h1s->req.state == H1_MSG_DONE && h1s->res.state == H1_MSG_DONE)
+			h1s->cs->flags |= CS_FL_EOI;
+
 	if (!buf_room_for_htx_data(&h1c->obuf)) {
 		TRACE_STATE("h1c obuf full", H1_EV_TX_DATA|H1_EV_H1S_BLK, h1c->conn, h1s);
 		h1c->flags |= H1C_F_OUT_FULL;