]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: hlua/filters: Add HTTPMessage.closed() to check if input is closed
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 23 Oct 2026 07:23:28 +0000 (09:23 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 23 Oct 2026 17:43:23 +0000 (19:43 +0200)
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.

doc/lua-api/index.rst
src/hlua.c

index e2350ff1f3c37edfb60ef73c532d528dab784d4d..f7f6dd4e64a6aa6c85fc35257e74c44be9444d58 100644 (file)
@@ -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
index 6e2ab7ccb3f0d4dddbe6731b540617b619c672e9..f3ad674532a52ed280ecc3377500d2381103c118 100644 (file)
@@ -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);