]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: mux-h1: don't truncate responses on soft-stop
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 7 Oct 2026 08:55:51 +0000 (10:55 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 16 Oct 2026 17:10:26 +0000 (19:10 +0200)
During a soft-stop, h1_process() releases the idle frontend connections,
i.e. those flagged with H1C_F_WAIT_NEXT_REQ. But this flag is set by
h1s_destroy() as soon as both the request and the response reached the DONE
state, which only means that the response was entirely formatted into the
output buffer, not that it was sent. So when the client is still downloading
the end of a response, the connection is released and the remaining data are
lost, the client receiving a truncated response.

The connection is now only released if its output buffer is empty.
Otherwise it is kept until everything was sent: h1_send() then wakes
h1_process() up which performs the release.

This was introduced by commit efc6e9564 ("MEDIUM: mux_h1: release idling
frontend conns on soft-stop") in 2.4. It must be backported to all supported
versions.

src/mux_h1.c

index 86ded66a768f8fb2a67d1c18a03c32dfd7389e1b..247db32aaa15ebf802f2e032c45386137fdcfe04 100644 (file)
@@ -4402,8 +4402,11 @@ static int h1_process(struct h1c * h1c)
         */
        if (!(h1c->flags & H1C_F_IS_BACK)) {
                if (unlikely(h1c->px->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) {
+                       /* Note: an idle connection may still have the end of
+                        * the previous response to send.
+                        */
                        if (!(h1c->px->options & PR_O_IDLE_CLOSE_RESP) &&
-                               h1c->flags & H1C_F_WAIT_NEXT_REQ) {
+                           (h1c->flags & H1C_F_WAIT_NEXT_REQ) && !b_data(&h1c->obuf)) {
 
                                int send_close = 1;
                                /* If a close-spread-time option is set, we want to avoid