MEDIUM: cli: Use the sedesc to report and detect end of processing

It is the same kind of change than for the cache applet. Idea is to use the SE
desc instead of the channel or the SC to report end-of-input, end-of-stream and
errors.

Truncated commands are now reported on error. Other changes are the same than
for the cache applet. We now set SE_FL_EOS flag instead of calling cf_shutr()
and calls to cf_shutw are removed.
This commit is contained in:
Christopher Faulet 2023-03-31 10:25:07 +02:00
parent f8130b2de2
commit 2fd0c7669d

View File

@ -893,14 +893,12 @@ static void cli_io_handler(struct appctx *appctx)
int reql; int reql;
int len; int len;
if (unlikely(sc->state == SC_ST_DIS || sc->state == SC_ST_CLO)) if (unlikely(se_fl_test(appctx->sedesc, (SE_FL_EOS|SE_FL_ERROR|SE_FL_SHR|SE_FL_SHW))))
goto out; goto out;
/* Check if the input buffer is available. */ /* Check if the input buffer is available. */
if (res->buf.size == 0) { if (!b_size(&res->buf)) {
/* buf.size==0 means we failed to get a buffer and were sc_need_room(sc);
* already subscribed to a wait list to get a buffer.
*/
goto out; goto out;
} }
@ -913,10 +911,7 @@ static void cli_io_handler(struct appctx *appctx)
appctx->cli_level = bind_conf->level; appctx->cli_level = bind_conf->level;
} }
else if (appctx->st0 == CLI_ST_END) { else if (appctx->st0 == CLI_ST_END) {
/* Let's close for real now. We just close the request se_fl_set(appctx->sedesc, SE_FL_EOS);
* side, the conditions below will complete if needed.
*/
sc_shutw(sc);
free_trash_chunk(appctx->chunk); free_trash_chunk(appctx->chunk);
appctx->chunk = NULL; appctx->chunk = NULL;
break; break;
@ -928,6 +923,7 @@ static void cli_io_handler(struct appctx *appctx)
if (!appctx->chunk) { if (!appctx->chunk) {
appctx->chunk = alloc_trash_chunk(); appctx->chunk = alloc_trash_chunk();
if (!appctx->chunk) { if (!appctx->chunk) {
se_fl_set(appctx->sedesc, SE_FL_ERROR);
appctx->st0 = CLI_ST_END; appctx->st0 = CLI_ST_END;
continue; continue;
} }
@ -960,6 +956,7 @@ static void cli_io_handler(struct appctx *appctx)
if (reql <= 0) { /* closed or EOL not found */ if (reql <= 0) { /* closed or EOL not found */
if (reql == 0) if (reql == 0)
break; break;
se_fl_set(appctx->sedesc, SE_FL_ERROR);
appctx->st0 = CLI_ST_END; appctx->st0 = CLI_ST_END;
continue; continue;
} }
@ -987,6 +984,7 @@ static void cli_io_handler(struct appctx *appctx)
*/ */
len = reql - 1; len = reql - 1;
if (str[len] != '\n') { if (str[len] != '\n') {
se_fl_set(appctx->sedesc, SE_FL_ERROR);
appctx->st0 = CLI_ST_END; appctx->st0 = CLI_ST_END;
continue; continue;
} }
@ -1143,13 +1141,13 @@ static void cli_io_handler(struct appctx *appctx)
break; break;
} }
/* Now we close the output if one of the writers did so, /* Now we close the output if we're not in interactive
* or if we're not in interactive mode and the request * mode and the request buffer is empty. This still
* buffer is empty. This still allows pipelined requests * allows pipelined requests to be sent in
* to be sent in non-interactive mode. * non-interactive mode.
*/ */
if (((res->flags & (CF_SHUTW|CF_SHUTW_NOW))) || if (!(appctx->st1 & APPCTX_CLI_ST1_PROMPT) && !co_data(req) && (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD))) {
(!(appctx->st1 & APPCTX_CLI_ST1_PROMPT) && !co_data(req) && (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD)))) { se_fl_set(appctx->sedesc, SE_FL_EOI);
appctx->st0 = CLI_ST_END; appctx->st0 = CLI_ST_END;
continue; continue;
} }
@ -1175,27 +1173,6 @@ static void cli_io_handler(struct appctx *appctx)
} }
} }
if ((res->flags & CF_SHUTR) && (sc->state == SC_ST_EST)) {
DPRINTF(stderr, "%s@%d: sc to buf closed. req=%08x, res=%08x, st=%d\n",
__FUNCTION__, __LINE__, req->flags, res->flags, sc->state);
/* Other side has closed, let's abort if we have no more processing to do
* and nothing more to consume. This is comparable to a broken pipe, so
* we forward the close to the request side so that it flows upstream to
* the client.
*/
sc_shutw(sc);
}
if ((req->flags & CF_SHUTW) && (sc->state == SC_ST_EST) && (appctx->st0 < CLI_ST_OUTPUT)) {
DPRINTF(stderr, "%s@%d: buf to sc closed. req=%08x, res=%08x, st=%d\n",
__FUNCTION__, __LINE__, req->flags, res->flags, sc->state);
/* We have no more processing to do, and nothing more to send, and
* the client side has closed. So we'll forward this state downstream
* on the response buffer.
*/
sc_shutr(sc);
}
out: out:
DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rqh=%lu, rqs=%lu, rh=%lu, rs=%lu\n", DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rqh=%lu, rqs=%lu, rh=%lu, rs=%lu\n",
__FUNCTION__, __LINE__, __FUNCTION__, __LINE__,