]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: cli: Use the sedesc to report and detect end of processing
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 31 Mar 2023 08:25:07 +0000 (10:25 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 5 Apr 2023 06:57:05 +0000 (08:57 +0200)
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.

src/cli.c

index 32b1c2c0199ffb80aa83baf553220def9f3a9709..1c942e1b2fc0a5e3c1a07ef96306044832ad6f03 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -893,14 +893,12 @@ static void cli_io_handler(struct appctx *appctx)
        int reql;
        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;
 
        /* Check if the input buffer is available. */
-       if (res->buf.size == 0) {
-               /* buf.size==0 means we failed to get a buffer and were
-                * already subscribed to a wait list to get a buffer.
-                */
+       if (!b_size(&res->buf)) {
+               sc_need_room(sc);
                goto out;
        }
 
@@ -913,10 +911,7 @@ static void cli_io_handler(struct appctx *appctx)
                        appctx->cli_level = bind_conf->level;
                }
                else if (appctx->st0 == CLI_ST_END) {
-                       /* Let's close for real now. We just close the request
-                        * side, the conditions below will complete if needed.
-                        */
-                       sc_shutw(sc);
+                       se_fl_set(appctx->sedesc, SE_FL_EOS);
                        free_trash_chunk(appctx->chunk);
                        appctx->chunk = NULL;
                        break;
@@ -928,6 +923,7 @@ static void cli_io_handler(struct appctx *appctx)
                        if (!appctx->chunk) {
                                appctx->chunk = alloc_trash_chunk();
                                if (!appctx->chunk) {
+                                       se_fl_set(appctx->sedesc, SE_FL_ERROR);
                                        appctx->st0 = CLI_ST_END;
                                        continue;
                                }
@@ -960,6 +956,7 @@ static void cli_io_handler(struct appctx *appctx)
                        if (reql <= 0) { /* closed or EOL not found */
                                if (reql == 0)
                                        break;
+                               se_fl_set(appctx->sedesc, SE_FL_ERROR);
                                appctx->st0 = CLI_ST_END;
                                continue;
                        }
@@ -987,6 +984,7 @@ static void cli_io_handler(struct appctx *appctx)
                         */
                        len = reql - 1;
                        if (str[len] != '\n') {
+                               se_fl_set(appctx->sedesc, SE_FL_ERROR);
                                appctx->st0 = CLI_ST_END;
                                continue;
                        }
@@ -1143,13 +1141,13 @@ static void cli_io_handler(struct appctx *appctx)
                                break;
                        }
 
-                       /* Now we close the output if one of the writers did so,
-                        * or if we're not in interactive mode and the request
-                        * buffer is empty. This still allows pipelined requests
-                        * to be sent in non-interactive mode.
+                       /* Now we close the output if we're not in interactive
+                        * mode and the request buffer is empty. This still
+                        * allows pipelined requests to be sent in
+                        * non-interactive mode.
                         */
-                       if (((res->flags & (CF_SHUTW|CF_SHUTW_NOW))) ||
-                          (!(appctx->st1 & APPCTX_CLI_ST1_PROMPT) && !co_data(req) && (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD)))) {
+                       if (!(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;
                                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:
        DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rqh=%lu, rqs=%lu, rh=%lu, rs=%lu\n",
                __FUNCTION__, __LINE__,