From: Christopher Faulet Date: Fri, 23 Oct 2026 07:23:28 +0000 (+0200) Subject: MINOR: hlua/filters: Add HTTPMessage.closed() to check if input is closed X-Git-Tag: v3.5-dev10~61 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=bd8e3642a613879519fec6ecf9c76a598ce0599a;p=haproxy.git MINOR: hlua/filters: Add HTTPMessage.closed() to check if input is closed There is no way for a Lua filter to know if the input of the HTTP message it is filtering is closed, i.e. if no more data will be received on the corresponding channel because the end of the stream was reached or an error was detected. HTTPMessage.eom() is not suitable to detect that. It relies on the message framing and is only true when the end of the message was properly reported. For instance, when a truncated request is received, no end of message is reported but the input is nonetheless closed. HTTPMessage.may_recv() is not suitable either because, as its name implies, it only tells if more data may still be received at this point. An unfinished message whose input is closed returns false. Conversely, HTTPMessage.closed() returns true as soon as the input is closed, whatever the message framing state. However, as for HTTPMessage.eom(), the result is relative to the data visible by the current filter. It is only true when all data were already exposed to it. So if an earlier filter holds back some data, the function returns false until these data are visible. --- diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst index e2350ff1f..f7f6dd4e6 100644 --- a/doc/lua-api/index.rst +++ b/doc/lua-api/index.rst @@ -4482,6 +4482,24 @@ HTTPMessage class All incoming data by default. May be set to -1 to get a maximum of data. :returns: a string containing the data found or nil. +.. js:function:: HTTPMessage.closed(http_msg) + + This function returns true if the input of the HTTP message **http_msg** is + closed, meaning the underlying channel will not receive data anymore, either + because the end of the stream was reached or an error was detected. When + called by a filter, the result is relative to the data visible by this + filter: if an earlier filter holds back some data, the function always + returns false, even if the input is closed, because the held data may still + be exposed to the current filter. + + Unlike :js:func:`HTTPMessage.eom()`, which relies on the message framing, + this function returns true even if the end of the message was never reached. + For instance, if a truncated request is received, the input is closed but no + end of message was reported. + + :param class_httpmessage http_msg: The manipulated HTTP message. + :returns: a boolean + .. js:function:: HTTPMessage.eom(http_msg) This function returns true if the end of message is reached for the HTTP diff --git a/src/hlua.c b/src/hlua.c index 6e2ab7ccb..f3ad67453 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -7287,6 +7287,21 @@ __LJMP static int hlua_http_msg_may_recv(lua_State *L) return 1; } +/* Returns true if the HTTP message is closed */ +__LJMP static int hlua_http_msg_is_closed(lua_State *L) +{ + struct http_msg *msg; + struct htx *htx; + int closed; + + MAY_LJMP(check_args(L, 1, "closed")); + msg = MAY_LJMP(hlua_checkhttpmsg(L, 1)); + htx = htxbuf(&msg->chn->buf); + closed = hlua_http_msg_fully_visible(L, msg, htx) && channel_input_closed(msg->chn); + lua_pushboolean(L, closed); + return 1; +} + /* Returns true if the HTTP message EOM was received */ __LJMP static int hlua_http_msg_is_eom(lua_State *L) { @@ -14276,6 +14291,7 @@ lua_State *hlua_init_state(int thread_num) hlua_class_function(L, "set_body_len",hlua_http_msg_set_body_len); hlua_class_function(L, "is_full", hlua_http_msg_is_full); hlua_class_function(L, "may_recv", hlua_http_msg_may_recv); + hlua_class_function(L, "closed", hlua_http_msg_is_closed); hlua_class_function(L, "eom", hlua_http_msg_is_eom); hlua_class_function(L, "input", hlua_http_msg_get_in_len); hlua_class_function(L, "output", hlua_http_msg_get_out_len);