]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: http-act: restore the response buffer state in the early-hint action
authorWilly Tarreau <w@1wt.eu>
Mon, 27 Jul 2026 09:42:31 +0000 (11:42 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 27 Jul 2026 13:31:10 +0000 (15:31 +0200)
http_action_early_hint() starts with:

struct htx *htx = htx_from_buf(&res->buf);

htx_from_buf() marks the underlying buffer as full (b_data = b_size) and, as
documented, it is the caller's responsibility to call htx_to_buf() to update it
back. The function never does it. On the success path this is harmless because
the HTX message is not empty, which is exactly what a full buffer represents,
and on the error path channel_htx_truncate() takes care of it. But the very
first test of the function is:

if (!(s->txn.http->req.flags & HTTP_MSGF_VER_11))
goto leave;

so for an HTTP/1.0 client, where no 103 response may be emitted, the response
buffer is left flagged as containing b_size bytes of data while the HTX message
is empty, until some other code path happens to call htx_to_buf() on it. Any
code looking at b_data(&res->buf) in between sees a full response buffer.

No misbehaviour could be observed (the HTX-aware helpers all work on the HTX
message, not on b_data), but leaving the buffer in a state that contradicts its
contents is an accident waiting to happen.

Let's simply call htx_to_buf() on the leave path. It is a no-op for the other
two paths since the message is either non-empty or was already truncated.

This should be backported to all supported versions.

src/http_act.c

index d4c68e2236cec5b415fee24441ad630a9317a46e..0bb7b05f7ad1cc7463251c8671f0e035cf495e5d 100644 (file)
@@ -1389,6 +1389,11 @@ static enum act_return http_action_early_hint(struct act_rule *rule, struct prox
        }
 
   leave:
+       /* the buffer was marked as full by htx_from_buf() above, it must be
+        * updated back, especially on the HTTP/1.0 path where the HTX message
+        * was left untouched and empty.
+        */
+       htx_to_buf(htx, &res->buf);
        free_trash_chunk(value);
        return ret;