]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: applet: Simplify a bit API to exchange data with applets
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 26 Jan 2024 14:41:46 +0000 (15:41 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 7 Feb 2024 14:04:52 +0000 (15:04 +0100)
Default .rcv_buf and .snd_buf functions that applets can use are now
specialized to manipulate raw buffers or HTX buffers.

Thus a TCP applet should use appctx_raw_rcv_buf() and appctx_raw_snd_buf()
while HTTP applet should use appctx_htx_rcv_buf() and appctx_htx_snd_buf().

Note that the appctx is now directly passed to these functions instead of
the SC.

include/haproxy/applet-t.h
include/haproxy/applet.h
src/applet.c
src/cache.c
src/stats.c
src/stconn.c

index 86e08c319554cf9086705f93685b2381a0fbd5de..9ee8f5d9cf7ec493d3365dc04eb27c1e57b826e9 100644 (file)
@@ -61,8 +61,8 @@ struct applet {
        int (*init)(struct appctx *);      /* callback to init resources, may be NULL.
                                              expect 0 if ok, -1 if an error occurs. */
        void (*fct)(struct appctx *);      /* internal I/O handler, may never be NULL */
-       size_t (*rcv_buf)(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags); /* called from the upper layer to get data */
-       size_t (*snd_buf)(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags); /* Called from the upper layet to put data */
+       size_t (*rcv_buf)(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags); /* called from the upper layer to get data */
+       size_t (*snd_buf)(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags); /* Called from the upper layet to put data */
        size_t (*fastfwd)(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags); /* Callback to fast-forward data */
        void (*release)(struct appctx *);  /* callback to release resources, may be NULL */
        unsigned int timeout;              /* execution timeout. */
index 2f84a1168402773c211f6acd739af29655b96c7b..17222c5244c05b3c10d112e0d15128768ffedcfc 100644 (file)
@@ -49,8 +49,14 @@ int appctx_finalize_startup(struct appctx *appctx, struct proxy *px, struct buff
 void appctx_free_on_early_error(struct appctx *appctx);
 void appctx_free(struct appctx *appctx);
 
+size_t appctx_htx_rcv_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags);
+size_t appctx_raw_rcv_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags);
 size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags);
+
+size_t appctx_htx_snd_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags);
+size_t appctx_raw_snd_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags);
 size_t appctx_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags);
+
 int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags);
 
 static inline struct appctx *appctx_new_here(struct applet *applet, struct sedesc *sedesc)
index 7b302f97683319fa123671bf094cb492a708a8c8..91232cceb5c433ec1e3484c009d0769102dc5704 100644 (file)
@@ -452,6 +452,45 @@ int appctx_buf_available(void *arg)
        return 1;
 }
 
+size_t appctx_htx_rcv_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags)
+{
+       struct htx *appctx_htx = htx_from_buf(&appctx->outbuf);
+       struct htx *buf_htx = NULL;
+       size_t ret = 0;
+
+       if (htx_is_empty(appctx_htx)) {
+               htx_to_buf(appctx_htx, &appctx->outbuf);
+               goto out;
+       }
+
+       ret = appctx_htx->data;
+       buf_htx = htx_from_buf(buf);
+       if (htx_is_empty(buf_htx) && htx_used_space(appctx_htx) <= count) {
+               htx_to_buf(buf_htx, buf);
+               htx_to_buf(appctx_htx, &appctx->outbuf);
+               b_xfer(buf, &appctx->outbuf, b_data(&appctx->outbuf));
+               goto out;
+       }
+
+       htx_xfer_blks(buf_htx, appctx_htx, count, HTX_BLK_UNUSED);
+       buf_htx->flags |= (appctx_htx->flags & (HTX_FL_PARSING_ERROR|HTX_FL_PROCESSING_ERROR));
+       if (htx_is_empty(appctx_htx)) {
+               buf_htx->flags |= (appctx_htx->flags & HTX_FL_EOM);
+       }
+       buf_htx->extra = (appctx_htx->extra ? (appctx_htx->data + appctx_htx->extra) : 0);
+       htx_to_buf(buf_htx, buf);
+       htx_to_buf(appctx_htx, &appctx->inbuf);
+       ret -= appctx_htx->data;
+
+  out:
+       return ret;
+}
+
+size_t appctx_raw_rcv_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags)
+{
+       return b_xfer(buf, &appctx->outbuf, MAX(count, b_data(&appctx->outbuf)));
+}
+
 size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags)
 {
        struct appctx *appctx = __sc_appctx(sc);
@@ -471,38 +510,7 @@ size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsig
                goto end;
        }
 
-       if (IS_HTX_SC(sc)) {
-               struct htx *appctx_htx = htx_from_buf(&appctx->outbuf);
-               struct htx *buf_htx = NULL;
-
-               if (htx_is_empty(appctx_htx)) {
-                       htx_to_buf(appctx_htx, &appctx->outbuf);
-                       goto done;
-               }
-
-               ret = appctx_htx->data;
-               buf_htx = htx_from_buf(buf);
-               if (htx_is_empty(buf_htx) && htx_used_space(appctx_htx) <= count) {
-                       htx_to_buf(buf_htx, buf);
-                       htx_to_buf(appctx_htx, &appctx->outbuf);
-                       b_xfer(buf, &appctx->outbuf, b_data(&appctx->outbuf));
-                       goto done;
-               }
-
-               htx_xfer_blks(buf_htx, appctx_htx, count, HTX_BLK_UNUSED);
-               buf_htx->flags |= (appctx_htx->flags & (HTX_FL_PARSING_ERROR|HTX_FL_PROCESSING_ERROR));
-               if (htx_is_empty(appctx_htx)) {
-                       buf_htx->flags |= (appctx_htx->flags & HTX_FL_EOM);
-               }
-               buf_htx->extra = (appctx_htx->extra ? (appctx_htx->data + appctx_htx->extra) : 0);
-               htx_to_buf(buf_htx, buf);
-               htx_to_buf(appctx_htx, &appctx->inbuf);
-               ret -= appctx_htx->data;
-       }
-       else
-               ret = b_xfer(buf, &appctx->outbuf, MAX(count, b_data(&appctx->outbuf)));
-
-  done:
+       ret = appctx->applet->rcv_buf(appctx, buf, count, flags);
        if (ret)
                applet_fl_clr(appctx, APPCTX_FL_OUTBLK_FULL);
 
@@ -531,6 +539,39 @@ size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsig
        return ret;
 }
 
+size_t appctx_htx_snd_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags)
+{
+       struct htx *appctx_htx = htx_from_buf(&appctx->inbuf);
+       struct htx *buf_htx = htx_from_buf(buf);
+       size_t ret = 0;
+
+       ret = buf_htx->data;
+       if (htx_is_empty(appctx_htx) && buf_htx->data == count) {
+               htx_to_buf(appctx_htx, &appctx->inbuf);
+               htx_to_buf(buf_htx, buf);
+               b_xfer(&appctx->inbuf, buf, b_data(buf));
+               goto end;
+       }
+
+       htx_xfer_blks(appctx_htx, buf_htx, count, HTX_BLK_UNUSED);
+       if (htx_is_empty(buf_htx)) {
+               appctx_htx->flags |= (buf_htx->flags & HTX_FL_EOM);
+       }
+
+       appctx_htx->extra = (buf_htx->extra ? (buf_htx->data + buf_htx->extra) : 0);
+       htx_to_buf(appctx_htx, &appctx->outbuf);
+       htx_to_buf(buf_htx, buf);
+       ret -= buf_htx->data;
+
+end:
+       return ret;
+}
+
+size_t appctx_raw_snd_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned flags)
+{
+       return b_xfer(&appctx->inbuf, buf, MIN(b_room(&appctx->inbuf), count));
+}
+
 size_t appctx_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags)
 {
        struct appctx *appctx = __sc_appctx(sc);
@@ -553,32 +594,7 @@ size_t appctx_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, unsig
        if (!count)
                goto end;
 
-       if (IS_HTX_SC(sc)) {
-               struct htx *appctx_htx = htx_from_buf(&appctx->inbuf);
-               struct htx *buf_htx = htx_from_buf(buf);
-
-               ret = buf_htx->data;
-               if (htx_is_empty(appctx_htx) && buf_htx->data == count) {
-                       htx_to_buf(appctx_htx, &appctx->inbuf);
-                       htx_to_buf(buf_htx, buf);
-                       b_xfer(&appctx->inbuf, buf, b_data(buf));
-                       goto done;
-               }
-
-               htx_xfer_blks(appctx_htx, buf_htx, count, HTX_BLK_UNUSED);
-               if (htx_is_empty(buf_htx)) {
-                       appctx_htx->flags |= (buf_htx->flags & HTX_FL_EOM);
-               }
-
-               appctx_htx->extra = (buf_htx->extra ? (buf_htx->data + buf_htx->extra) : 0);
-               htx_to_buf(appctx_htx, &appctx->outbuf);
-               htx_to_buf(buf_htx, buf);
-               ret -= buf_htx->data;
-       }
-       else
-               ret = b_xfer(&appctx->inbuf, buf, MIN(b_room(&appctx->inbuf), count));
-
-  done:
+       ret = appctx->applet->snd_buf(appctx, buf, count, flags);
        if (ret < count) {
                applet_fl_set(appctx, APPCTX_FL_INBLK_FULL);
                appctx_wakeup(appctx);
index 43df8a6b57f105452d5447576fd77d13656d32a3..385fcefadb7d99528b7c75f3eb8905d19c8f1e53 100644 (file)
@@ -3159,8 +3159,8 @@ struct applet http_cache_applet = {
        .obj_type = OBJ_TYPE_APPLET,
        .name = "<CACHE>", /* used for logging */
        .fct = http_cache_io_handler,
-       .rcv_buf = appctx_rcv_buf,
-       .snd_buf = appctx_snd_buf,
+       .rcv_buf = appctx_htx_rcv_buf,
+       .snd_buf = appctx_htx_snd_buf,
        .fastfwd = http_cache_fastfwd,
        .release = http_cache_applet_release,
 };
index 65a54f6b2e83dd0393aa61e98cb497a76c5304d4..d2e56ec6981ff910f85cba0875d0eb0f67e04f28 100644 (file)
@@ -5539,8 +5539,8 @@ struct applet http_stats_applet = {
        .obj_type = OBJ_TYPE_APPLET,
        .name = "<STATS>", /* used for logging */
        .fct = http_stats_io_handler,
-       .rcv_buf = appctx_rcv_buf,
-       .snd_buf = appctx_snd_buf,
+       .rcv_buf = appctx_htx_rcv_buf,
+       .snd_buf = appctx_htx_snd_buf,
        .fastfwd = http_stats_fastfwd,
        .release = NULL,
 };
index 3817e7b4d25cb92396ddf442f7366333f8cd379d..70f27db81670c5f6dd3b3c51117a18d6f893ef30 100644 (file)
@@ -1968,7 +1968,7 @@ int sc_applet_recv(struct stconn *sc)
         * SE_FL_RCV_MORE on the SC if more space is needed.
         */
        max = channel_recv_max(ic);
-       ret = appctx->applet->rcv_buf(sc, &ic->buf, max, flags);
+       ret = appctx_rcv_buf(sc, &ic->buf, max, flags);
        if (sc_ep_test(sc, SE_FL_WANT_ROOM)) {
                /* SE_FL_WANT_ROOM must not be reported if the channel's
                 * buffer is empty.
@@ -2120,7 +2120,6 @@ int sc_applet_sync_recv(struct stconn *sc)
  */
 int sc_applet_send(struct stconn *sc)
 {
-       struct appctx *appctx = __sc_appctx(sc);
        struct stconn *sco = sc_opposite(sc);
        struct channel *oc = sc_oc(sc);
        size_t ret;
@@ -2146,7 +2145,7 @@ int sc_applet_send(struct stconn *sc)
        BUG_ON(sc_ep_have_ff_data(sc));
 
        if (co_data(oc)) {
-               ret = appctx->applet->snd_buf(sc, &oc->buf, co_data(oc), 0);
+               ret = appctx_snd_buf(sc, &oc->buf, co_data(oc), 0);
                if (ret > 0) {
                        did_send = 1;
                        c_rew(oc, ret);