From e5e36ce09722e63ca4542b0b2ff1a1eb905f8208 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Mon, 1 Jul 2024 14:33:59 +0200 Subject: [PATCH] BUG/MEDIUM: hlua/cli: Fix lua CLI commands to work with applet's buffers In 3.0, the CLI applet was rewritten to use its own buffers. However, the lua part, used to register CLI commands at runtime, was not updated accordingly. It means the lua CLI commands still try to write in the channel buffers. This is of course totally unexepected and not supported. Because of this bug, the applet hangs intead of returning the command result. The registration of lua CLI commands relies on the lua TCP applets. So the send and receive functions were fixed to use the applet's buffer when it is required and still use the channel buffers otherwies. This way, other lua TCP applets can still run on the legacy mode, without the applet's buffers. This patch must be backported to 3.0. --- src/hlua.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/hlua.c b/src/hlua.c index 94a6e49983..30bd34edd5 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -5273,7 +5273,10 @@ __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KCont size_t len2; /* Read the maximum amount of data available. */ - ret = co_getblk_nc(sc_oc(sc), &blk1, &len1, &blk2, &len2); + if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS) + ret = b_getblk_nc(&luactx->appctx->inbuf, &blk1, &len1, &blk2, &len2, 0, b_data(&luactx->appctx->inbuf)); + else + ret = co_getblk_nc(sc_oc(sc), &blk1, &len1, &blk2, &len2); /* Data not yet available. return yield. */ if (ret == 0) { @@ -5299,7 +5302,10 @@ __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KCont */ luaL_addlstring(&luactx->b, blk1, len1); luaL_addlstring(&luactx->b, blk2, len2); - co_skip(sc_oc(sc), len1 + len2); + if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS) + b_del(&luactx->appctx->inbuf, len1 + len2); + else + co_skip(sc_oc(sc), len1 + len2); applet_need_more_data(luactx->appctx); MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0)); @@ -5317,8 +5323,10 @@ __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KCont luaL_addlstring(&luactx->b, blk2, len2); len -= len2; - /* Consume input channel output buffer data. */ - co_skip(sc_oc(sc), len1 + len2); + if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS) + b_del(&luactx->appctx->inbuf, len1 + len2); + else + co_skip(sc_oc(sc), len1 + len2); /* If there is no other data available, yield waiting for new data. */ if (len > 0) { @@ -5376,13 +5384,17 @@ __LJMP static int hlua_applet_tcp_send_yield(lua_State *L, int status, lua_KCont struct channel *chn = sc_ic(sc); int max; - /* Get the max amount of data which can write as input in the channel. */ - max = channel_recv_max(chn); + /* Get the max amount of data which can be written */ + if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS) + max = b_room(&luactx->appctx->outbuf); + else + max = channel_recv_max(chn); + if (max > (len - l)) max = len - l; /* Copy data. */ - ci_putblk(chn, str + l, max); + applet_putblk(luactx->appctx, str + l, max); /* update counters. */ l += max; @@ -5393,7 +5405,10 @@ __LJMP static int hlua_applet_tcp_send_yield(lua_State *L, int status, lua_KCont * applet, and returns a yield. */ if (l < len) { - sc_need_room(sc, channel_recv_max(chn) + 1); + if (luactx->appctx->flags & APPCTX_FL_INOUT_BUFS) + applet_have_more_data(luactx->appctx); + else + sc_need_room(sc, channel_recv_max(chn) + 1); MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_send_yield, TICK_ETERNITY, 0)); } @@ -10927,7 +10942,10 @@ void hlua_applet_tcp_fct(struct appctx *ctx) out: /* eat the whole request */ - co_skip(sc_oc(sc), co_data(sc_oc(sc))); + if (ctx->flags & APPCTX_FL_INOUT_BUFS) + b_reset(&ctx->inbuf); + else + co_skip(sc_oc(sc), co_data(sc_oc(sc))); return; error: -- 2.39.5