]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR:: mux-h1: Never handle error at mux level for running connection
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 16 Dec 2022 10:13:00 +0000 (11:13 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 19 Dec 2022 10:01:26 +0000 (11:01 +0100)
During the request parsing, we must be sure to never handle errors at the
mux level if the connection is running (or closing). The error must be
handled by the upper layer.

It should never happen. But there is an edge case that was not properly
handled. If all data are received on the first packet with the read0 and the
request is truncated on the payload, in this case the stream-connector is
created, so the H1C is in RUNNING state. But an error is reported because
the request is truncated. In this specific case, the error is handled by the
mux while it should not.

This patch is related to #1966. It must be backported to 2.7.

src/mux_h1.c

index bade6e2018a8ba4834716f69e0eed1ce152f697f..ce51f43a7091a159964dce6aa4b6fd92e07b9e61 100644 (file)
@@ -2992,22 +2992,23 @@ static int h1_process(struct h1c * h1c)
                h1_process_demux(h1c, buf, count);
                h1_release_buf(h1c, &h1s->rxbuf);
                h1_set_idle_expiration(h1c);
-
-               if (h1s->flags & H1S_F_INTERNAL_ERROR) {
-                       h1_handle_internal_err(h1c);
-                       TRACE_ERROR("internal error detected", H1_EV_H1C_WAKE|H1_EV_H1C_ERR);
-               }
-               else if (h1s->flags & H1S_F_NOT_IMPL_ERROR) {
-                       h1_handle_not_impl_err(h1c);
-                       TRACE_ERROR("not-implemented error detected", H1_EV_H1C_WAKE|H1_EV_H1C_ERR);
-               }
-               else if (h1s->flags & H1S_F_PARSING_ERROR || se_fl_test(h1s->sd, SE_FL_ERROR)) {
-                       h1_handle_parsing_error(h1c);
-                       TRACE_ERROR("parsing error detected", H1_EV_H1C_WAKE|H1_EV_H1C_ERR);
-               }
-               else if (h1c->state < H1_CS_RUNNING) {
-                       TRACE_STATE("Incomplete message, subscribing", H1_EV_RX_DATA|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn, h1s);
-                       h1c->conn->xprt->subscribe(h1c->conn, h1c->conn->xprt_ctx, SUB_RETRY_RECV, &h1c->wait_event);
+               if (h1c->state < H1_CS_RUNNING) {
+                       if (h1s->flags & H1S_F_INTERNAL_ERROR) {
+                               h1_handle_internal_err(h1c);
+                               TRACE_ERROR("internal error detected", H1_EV_H1C_WAKE|H1_EV_H1C_ERR);
+                       }
+                       else if (h1s->flags & H1S_F_NOT_IMPL_ERROR) {
+                               h1_handle_not_impl_err(h1c);
+                               TRACE_ERROR("not-implemented error detected", H1_EV_H1C_WAKE|H1_EV_H1C_ERR);
+                       }
+                       else if (h1s->flags & H1S_F_PARSING_ERROR || se_fl_test(h1s->sd, SE_FL_ERROR)) {
+                               h1_handle_parsing_error(h1c);
+                               TRACE_ERROR("parsing error detected", H1_EV_H1C_WAKE|H1_EV_H1C_ERR);
+                       }
+                       else {
+                               TRACE_STATE("Incomplete message, subscribing", H1_EV_RX_DATA|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn, h1s);
+                               h1c->conn->xprt->subscribe(h1c->conn, h1c->conn->xprt_ctx, SUB_RETRY_RECV, &h1c->wait_event);
+                       }
                }
        }