From: Willy Tarreau Date: Tue, 27 Feb 2024 14:50:55 +0000 (+0100) Subject: MINOR: applet: add new function applet_append_line() X-Git-Tag: v3.0-dev6~59 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6ae41dc510a5bb8d2c94f093b255a4b8e46763d5;p=thirdparty%2Fhaproxy.git MINOR: applet: add new function applet_append_line() This function takes a buffer on input, and offset and a length, and consumes the block from that buffer to send it to the appctx's output buffer. This will be used to simplify the ring reader code. --- diff --git a/include/haproxy/applet.h b/include/haproxy/applet.h index 22c68fbd98..1c88c128d4 100644 --- a/include/haproxy/applet.h +++ b/include/haproxy/applet.h @@ -58,6 +58,7 @@ size_t appctx_raw_snd_buf(struct appctx *appctx, struct buffer *buf, size_t coun 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); +ssize_t applet_append_line(void *ctx, const struct buffer *buf, size_t ofs, size_t len); static inline struct appctx *appctx_new_here(struct applet *applet, struct sedesc *sedesc) { diff --git a/src/applet.c b/src/applet.c index 21f61b0436..6ab092b76b 100644 --- a/src/applet.c +++ b/src/applet.c @@ -725,6 +725,32 @@ end: return ret; } +/* Atomically append a line to applet 's output, appending a trailing 'LF'. + * The line is read from at offset relative to the buffer's head, + * for bytes. It returns the number of bytes consumed from the input + * buffer on success, -1 if it temporarily cannot (buffer full), -2 if it will + * never be able to (too large msg). The input buffer is not modified. The + * caller is responsible for making sure that there are at least ofs+len bytes + * in the input buffer. + */ +ssize_t applet_append_line(void *ctx, const struct buffer *buf, size_t ofs, size_t len) +{ + struct appctx *appctx = ctx; + + if (unlikely(len + 1 > b_size(&trash))) { + /* too large a message to ever fit, let's skip it */ + return -2; + } + + chunk_reset(&trash); + b_getblk(buf, trash.area, len, ofs); + trash.data += len; + trash.area[trash.data++] = '\n'; + if (applet_putchk(appctx, &trash) == -1) + return -1; + return len; +} + /* Default applet handler */ struct task *task_run_applet(struct task *t, void *context, unsigned int state) {