From: William Lallemand Date: Thu, 4 Nov 2021 08:45:58 +0000 (+0100) Subject: BUG/MINOR: httpclient/lua: rcv freeze when no request payload X-Git-Tag: v2.5-dev14~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=933fe394bb11490d45fd231b43b7cd93a0cf21e4;p=thirdparty%2Fhaproxy.git BUG/MINOR: httpclient/lua: rcv freeze when no request payload This patch fixes the receive part of the lua httpclient when no payload was sent. The lua task was not awoken once it jumped into hlua_httpclient_rcv_yield(), which caused the lua client to freeze. It works with a payload because the payload push is doing the wakeup. A change in the state machine of the IO handler is also require to achieve correctly the change from the REQ state to the RES state, it has to detect if there is the right EOM flag in the request. --- diff --git a/src/hlua.c b/src/hlua.c index 94f6562349..08735374af 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -7201,6 +7201,7 @@ rcv: lua_pushstring(L, "body"); luaL_buffinit(L, &hlua_hc->b); + task_wakeup(hlua->task, TASK_WOKEN_MSG); MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_httpclient_rcv_yield, TICK_ETERNITY, 0)); return 1; diff --git a/src/http_client.c b/src/http_client.c index 35de71af76..a289206eb4 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -557,6 +557,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx) struct htx_sl *sl = NULL; int32_t pos; uint32_t hdr_num; + int ret; while (1) { @@ -569,19 +570,27 @@ static void httpclient_applet_io_handler(struct appctx *appctx) case HTTPCLIENT_S_REQ: /* copy the request from the hc->req.buf buffer */ - htx = htx_from_buf(&req->buf); /* We now that it fits the content of a buffer so can * just push this entirely */ - b_xfer(&req->buf, &hc->req.buf, b_data(&hc->req.buf)); - channel_add_input(req, b_data(&req->buf)); - appctx->st0 = HTTPCLIENT_S_REQ_BODY; + ret = b_xfer(&req->buf, &hc->req.buf, b_data(&hc->req.buf)); + if (ret) + channel_add_input(req, b_data(&req->buf)); + + htx = htxbuf(&req->buf); + if (!htx) + goto more; + + if (htx->flags & HTX_FL_EOM) /* check if a body need to be added */ + appctx->st0 = HTTPCLIENT_S_RES_STLINE; + else + appctx->st0 = HTTPCLIENT_S_REQ_BODY; + goto more; /* we need to leave the IO handler once we wrote the request */ break; case HTTPCLIENT_S_REQ_BODY: /* call the payload callback */ { if (hc->ops.req_payload) { - int ret; ret = b_xfer(&req->buf, &hc->req.buf, b_data(&hc->req.buf)); if (ret)