]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: hlua: Properly enable/disable receives for TCP applets
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 4 Mar 2026 18:15:34 +0000 (19:15 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 5 Mar 2026 14:34:46 +0000 (15:34 +0100)
From a lua TCP applet, in functions used to retrieve data (receive,
try_receive and getline), we must take care to disable receives when data
are returned (or on failure) and to restart receives when these functions
are called again. In addition, when an applet execution is finished, we must
restart receives to properly drain the request.

This patch should be backported to 3.3. On older version, no bug was
reported so we can wait a report first.

src/hlua.c

index 950751b46f0f2daa5e210f2df2b7c2fd01d247e3..604e2d142a8fcc8b44b398269c47ef7a00c7bc04 100644 (file)
@@ -5306,6 +5306,9 @@ __LJMP static int hlua_applet_tcp_getline_yield(lua_State *L, int status, lua_KC
 
        /* End of data: commit the total strings and return. */
        if (ret < 0) {
+               /* Stop to consume */
+               applet_wont_consume(luactx->appctx);
+
                luaL_pushresult(&luactx->b);
                return 1;
        }
@@ -5320,6 +5323,10 @@ __LJMP static int hlua_applet_tcp_getline_yield(lua_State *L, int status, lua_KC
                luaL_addlstring(&luactx->b, blk2, len2);
 
        applet_skip_input(luactx->appctx, len1+len2);
+
+       /* Stop to consume until the next receive */
+       applet_wont_consume(luactx->appctx);
+
        luaL_pushresult(&luactx->b);
        return 1;
 }
@@ -5329,6 +5336,9 @@ __LJMP static int hlua_applet_tcp_getline(lua_State *L)
 {
        struct hlua_appctx *luactx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
 
+       /* Restart to consume - could have been disabled by a previous receive */
+       applet_will_consume(luactx->appctx);
+
        /* Initialise the string catenation. */
        luaL_buffinit(L, &luactx->b);
 
@@ -5355,6 +5365,9 @@ __LJMP static int hlua_applet_tcp_recv_try(lua_State *L)
        /* Data not yet available. return yield. */
        if (ret == 0) {
                if (tick_is_expired(exp_date, now_ms)) {
+                       /* Stop to consume until the next receive */
+                       applet_wont_consume(luactx->appctx);
+
                        /* return the result. */
                        lua_pushnil(L);
                        return 1;
@@ -5366,6 +5379,9 @@ __LJMP static int hlua_applet_tcp_recv_try(lua_State *L)
 
        /* End of data: commit the total strings and return. */
        if (ret < 0) {
+               /* Stop to consume */
+               applet_wont_consume(luactx->appctx);
+
                luaL_pushresult(&luactx->b);
                return 1;
        }
@@ -5386,6 +5402,9 @@ __LJMP static int hlua_applet_tcp_recv_try(lua_State *L)
                applet_skip_input(luactx->appctx, len1+len2);
 
                if (tick_is_expired(exp_date, now_ms)) {
+                       /* Stop to consume until the next receive */
+                       applet_wont_consume(luactx->appctx);
+
                        /* return the result. */
                        luaL_pushresult(&luactx->b);
                        return 1;
@@ -5420,6 +5439,9 @@ __LJMP static int hlua_applet_tcp_recv_try(lua_State *L)
                        return 0;
                }
 
+               /* Stop to consume until the next receive */
+               applet_wont_consume(luactx->appctx);
+
                /* return the result. */
                luaL_pushresult(&luactx->b);
                return 1;
@@ -5474,6 +5496,9 @@ __LJMP static int hlua_applet_tcp_recv(lua_State *L)
        exp_date = delay ? tick_add(now_ms, delay) : TICK_ETERNITY;
        lua_pushinteger(L, exp_date);
 
+       /* Restart to consume - could have been disabled by a previous receive */
+       applet_will_consume(luactx->appctx);
+
        /* Initialise the string catenation. */
        luaL_buffinit(L, &luactx->b);
 
@@ -5495,6 +5520,9 @@ __LJMP static int hlua_applet_tcp_try_recv(lua_State *L)
        /* set the expiration date (mandatory arg but not relevant here) */
        lua_pushinteger(L, now_ms);
 
+       /* Restart to consume - could have been disabled by a previous receive */
+       applet_will_consume(luactx->appctx);
+
        /* Initialise the string catenation. */
        luaL_buffinit(L, &luactx->b);
 
@@ -11094,8 +11122,11 @@ void hlua_applet_tcp_fct(struct appctx *ctx)
                goto out;
 
        /* The applet execution is already done. */
-       if (tcp_ctx->flags & APPLET_DONE)
+       if (tcp_ctx->flags & APPLET_DONE) {
+               /* Restart to consume to drain request data */
+               applet_will_consume(ctx);
                goto out;
+       }
 
        /* Execute the function. */
        switch (hlua_ctx_resume(hlua, 1)) {
@@ -11103,6 +11134,9 @@ void hlua_applet_tcp_fct(struct appctx *ctx)
        case HLUA_E_OK:
                tcp_ctx->flags |= APPLET_DONE;
                applet_set_eos(ctx);
+
+               /* Restart to consume to drain request data */
+               applet_will_consume(ctx);
                break;
 
        /* yield. */