]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: mux-h1: Use configured error files if possible for early H1 errors
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 10 Jul 2025 08:10:37 +0000 (10:10 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 10 Jul 2025 08:29:49 +0000 (10:29 +0200)
The H1 multiplexer is able to produce some errors on its own to report early
errors, before the stream is created. In that case, the error files of the
proxy were tested to detect empty files (or /dev/null) but they were not
used to produce the error itself.

But the documentation states that configured error files are used in all
cases. And in fact, it is not really a problem to use these files. We must
just format a full HTX message. Thanks to the previous patch, it is now
possible.

This patch should fix the issue #3032. It should be backported to 3.2. For
older versions, it must be discussed but it should be quite easy to do.

src/mux_h1.c

index 88e288b70ee316663226b53d5056b10ad22b9c5e..9cf3316cbebf8130c48789512a5129cc02d92358 100644 (file)
@@ -3661,20 +3661,23 @@ static void h1_alert(struct h1s *h1s)
 */
 static int h1_send_error(struct h1c *h1c)
 {
+       struct buffer *errmsg = NULL;
        int rc = http_get_status_idx(h1c->errcode);
        int ret = 0;
 
        TRACE_ENTER(H1_EV_H1C_ERR, h1c->conn, 0, 0, (size_t[]){h1c->errcode});
 
-       /* Verify if the error is mapped on /dev/null or any empty file */
-       /// XXX: do a function !
+       /* Get the error file, if any */
        if (h1c->px->replies[rc] &&
            h1c->px->replies[rc]->type == HTTP_REPLY_ERRMSG &&
-           h1c->px->replies[rc]->body.errmsg &&
-           b_is_null(h1c->px->replies[rc]->body.errmsg)) {
-               /* Empty error, so claim a success */
-               ret = 1;
-               goto out_abort;
+           h1c->px->replies[rc]->body.errmsg) {
+               /* Verify if the error is mapped on /dev/null or any empty file */
+               if (b_is_null(h1c->px->replies[rc]->body.errmsg)) {
+                       /* Empty error, so claim a success */
+                       ret = 1;
+                       goto out_abort;
+               }
+               errmsg = h1c->px->replies[rc]->body.errmsg;
        }
 
        if (h1c->flags & (H1C_F_OUT_ALLOC|H1C_F_OUT_FULL)) {
@@ -3687,7 +3690,10 @@ static int h1_send_error(struct h1c *h1c)
                TRACE_STATE("waiting for h1c obuf allocation", H1_EV_H1C_ERR|H1_EV_H1C_BLK, h1c->conn);
                goto out;
        }
-       ret = b_istput(&h1c->obuf, ist(http_err_msgs[rc]));
+       if (errmsg)
+               ret = h1_format_htx_msg(htxbuf(errmsg), &h1c->obuf);
+       else
+               ret = b_istput(&h1c->obuf, ist(http_err_msgs[rc]));
        if (unlikely(ret <= 0)) {
                if (!ret) {
                        h1c->flags |= (H1C_F_OUT_FULL|H1C_F_ABRT_PENDING);