Le 26/03/2026 à 4:00 PM, Cody Ohlsen a écrit :
Hi,


I'd like to submit a patch for a bug we found in the H1 mux that adds ~200ms of

artificial latency to every HEAD response served over an HTTP/1.1 frontend under many conditions.


We discovered this while debugging elevated latencies in a production proxy 
chain

(S3 client -> HAProxy -> upstream origin) where HEAD requests were consistently

2-3x slower than GET requests despite being functionally simpler. The root cause

turned out to be MSG_MORE being incorrectly asserted on the sendmsg() call for

bodyless responses, causing the Linux kernel to cork the TCP segment for ~200ms

waiting for body data that never arrives.


The details and fix are in the patch below. Happy to answer any questions or

rework the patch as needed.


Hi Cody,

Thanks for the detailed analysis. The fix should be adapted a bit because we cannot systematically remove H1C_F_CO_MSG_MORE flag when H1S_F_BODYLESS_RESP is set. This last flag is also set on the server side, to be able to drop payload for responses to HEAD requests. In attachment, my proposal to fix the issue. You've done all the work. Do you want to adapt your patch ?

In addition, I proposed to flag it as a minor bug because it only concerns bodyless responses with a payload, which should not happen.

On my side, I'm only able to reproduce the issue by changing the HEAD method with an "http-request set-method GET" rule. Otherwise, the payload is ignored on server side. So I'm curious. On your side, how are you able to trigger the issue ?

Regards,
--
Christopher Faulet
diff --git a/src/mux_h1.c b/src/mux_h1.c
index 47cdfff2a..d165b88d6 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -4885,8 +4885,14 @@ static size_t h1_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, in
 
 	/* Inherit some flags from the upper layer */
 	h1c->flags &= ~(H1C_F_CO_MSG_MORE|H1C_F_CO_STREAMER);
-	if (flags & CO_SFL_MSG_MORE)
-		h1c->flags |= H1C_F_CO_MSG_MORE;
+	if (flags & CO_SFL_MSG_MORE) {
+		/* Don't set H1C_F_CO_MSG_MORE when sending a bodyless response to client.
+		 * We must do that if the response is not finished, regardless it a bodyless
+		 * response, to be sure to send it ASAP.
+		 */
+		if ((h1c->flags & H1C_F_IS_BACK) || !(h1s->flags & H1S_F_BODYLESS_RESP))
+			h1c->flags |= H1C_F_CO_MSG_MORE;
+	}
 	if (flags & CO_SFL_STREAMER)
 		h1c->flags |= H1C_F_CO_STREAMER;
 

Reply via email to