]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: mux-h1: only reset the session's timing info on the frontend side
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 7 Oct 2026 08:58:15 +0000 (10:58 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 16 Oct 2026 17:10:26 +0000 (19:10 +0200)
When an H1 stream is detached, h1s_finish_detach() resets the session's
accept date, handshake and idle times so that the next request on the same
connection reports the right values. But this is also performed for backend
H1 streams, whose <sess> is the client's session. For an H1 frontend it does
not matter because the frontend stream is detached afterwards and resets
these values again. But for H2 and H3 frontends, the session is shared by
all streams of the client connection and the mux sets these values itself
when creating each stream. In this case the backend detach overwrites them,
so the next stream created on the client connection reports a wrong
accept/request date and idle time (%tr, %Ti, %Tt in logs): they are counted
from the end of the previous exchange with the server instead of from the
previous stream as the H2/H3 muxes intend.

For instance, with an H2 frontend and an H1 server, a client sending two
requests on the same connection, the first one taking 1 second, logs
"Ti=0 Tt=0" for the second one, instead of "Ti=1002 Tt=1002" with an H2
server or with this patch.

The timing info are now only reset for frontend H1 streams.

This patch may be backported to all supported versions.

src/mux_h1.c

index 247db32aaa15ebf802f2e032c45386137fdcfe04..9eea1e39fe480297e22f0976f63f6c409e77eca9 100644 (file)
@@ -1177,10 +1177,17 @@ static int h1s_finish_detach(struct h1s *h1s)
        sess = h1s->sess;
        h1c = h1s->h1c;
 
-       sess->accept_date = date;
-       sess->accept_ts   = now_ns;
-       sess->t_handshake = 0;
-       sess->t_idle      = -1;
+       /* Prepare the timing information for the next request on a frontend
+        * connection. On the backend side, <sess> is the client's session,
+        * which may be shared by several streams (H2/H3), it must not be
+        * touched.
+        */
+       if (!(h1c->flags & H1C_F_IS_BACK)) {
+               sess->accept_date = date;
+               sess->accept_ts   = now_ns;
+               sess->t_handshake = 0;
+               sess->t_idle      = -1;
+       }
 
        is_not_first = h1s->flags & H1S_F_NOT_FIRST;
        h1s_destroy(h1s);