]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: htx: Add helper functions to xfer a message to smaller or larger one
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 10 Mar 2026 07:10:29 +0000 (08:10 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 23 Mar 2026 13:02:42 +0000 (14:02 +0100)
htx_move_to_small_buffer()/htx_move_to_large_buffer() and
htx_copy_to_small_buffer()/htx_copy_to_large_buffer() functions can now be
used to move or copy blocks from a default buffer to a small or large
buffer. The destination buffer is allocated and then each blocks are
transferred into it.

These funtions relies in htx_xfer() function.

include/haproxy/htx.h
src/htx.c

index e22b2c0732656f935e36db0e815efc535a92de2a..deeacd0a93954b36d83af3dfe15f0c39a800a126 100644 (file)
@@ -57,6 +57,10 @@ size_t htx_add_data(struct htx *htx, const struct ist data);
 struct htx_blk *htx_add_last_data(struct htx *htx, struct ist data);
 void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk **ref);
 int htx_append_msg(struct htx *dst, const struct htx *src);
+struct buffer *htx_move_to_small_buffer(struct buffer *dst, struct buffer *src);
+struct buffer *htx_move_to_large_buffer(struct buffer *dst, struct buffer *src);
+struct buffer *htx_copy_to_small_buffer(struct buffer *dst, struct buffer *src);
+struct buffer *htx_copy_to_large_buffer(struct buffer *dst, struct buffer *src);
 
 #define HTX_XFER_DEFAULT           0x00000000 /* Default XFER: no partial xfer / remove blocks from source */
 #define HTX_XFER_KEEP_SRC_BLKS     0x00000001 /* Don't remove xfer blocks from source messages during xfer */
index 695a69aace15063b00710b3cf4257758c31321aa..13b6a0cbc0cb3ea9998389db53f806536648d7d9 100644 (file)
--- a/src/htx.c
+++ b/src/htx.c
@@ -11,6 +11,7 @@
  */
 
 #include <haproxy/chunk.h>
+#include <haproxy/dynbuf.h>
 #include <haproxy/global.h>
 #include <haproxy/htx.h>
 #include <haproxy/net_helper.h>
@@ -1325,3 +1326,68 @@ int htx_append_msg(struct htx *dst, const struct htx *src)
        htx_truncate(dst, offset);
        return 0;
 }
+
+
+/* If possible, trasnfer HTX blocks from <src> to a small buffer. This function
+ * allocate the small buffer and makes <dst> point on it. If <dst> is not empty
+ * or if <src> contains to many data, NULL is returned. If the allocation
+ * failed, NULL is returned. Otherwise <dst> is returned.  <flags> instructs how
+ * the transfer must be performed.
+ */
+struct buffer *__htx_xfer_to_small_buffer(struct buffer *dst, struct buffer *src, unsigned int flags)
+{
+       struct htx *dst_htx;
+       struct htx *src_htx = htxbuf(src);
+       size_t sz = (sizeof(struct htx) + htx_used_space(src_htx));
+
+       if (dst->size || sz > global.tune.bufsize_small  || !b_alloc_small(dst))
+               return NULL;
+       dst_htx = htx_from_buf(dst);
+       htx_xfer(dst_htx, src_htx, src_htx->size, flags);
+       htx_to_buf(dst_htx, dst);
+       return dst;
+}
+
+/* If possible, trasnfer HTX blocks from <src> to a large buffer. This function
+ * allocate the small buffer and makes <dst> point on it. If <dst> is not empty
+ * or if <src> contains to many data, NULL is returned. If the allocation
+ * failed, NULL is returned. Otherwise <dst> is returned.  <flags> instructs how
+ * the transfer must be performed.
+ */
+struct buffer *__htx_xfer_to_large_buffer(struct buffer *dst, struct buffer *src, unsigned int flags)
+{
+       struct htx *dst_htx;
+       struct htx *src_htx = htxbuf(src);
+       size_t sz = (sizeof(struct htx) + htx_used_space(src_htx));
+
+       if (dst->size || sz > global.tune.bufsize_large || !b_alloc_large(dst))
+               return NULL;
+       dst_htx = htx_from_buf(dst);
+       htx_xfer(dst_htx, src_htx, src_htx->size, flags);
+       htx_to_buf(dst_htx, dst);
+       return dst;
+}
+
+/* Move HTX blocks from <src> to <dst>. Relies on __htx_xfer_to_small_buffer() */
+struct buffer *htx_move_to_small_buffer(struct buffer *dst, struct buffer *src)
+{
+       return __htx_xfer_to_small_buffer(dst, src, HTX_XFER_DEFAULT);
+}
+
+/* Move HTX blocks from <src> to <dst>. Relies on __htx_xfer_to_large_buffer() */
+struct buffer *htx_move_to_large_buffer(struct buffer *dst, struct buffer *src)
+{
+       return __htx_xfer_to_large_buffer(dst, src, HTX_XFER_DEFAULT);
+}
+
+/* Copy HTX blocks from <src> to <dst>. Relies on __htx_xfer_to_small_buffer() */
+struct buffer *htx_copy_to_small_buffer(struct buffer *dst, struct buffer *src)
+{
+       return __htx_xfer_to_small_buffer(dst, src, HTX_XFER_KEEP_SRC_BLKS);
+}
+
+/* Copy HTX blocks from <src> to <dst>. Relies on __htx_xfer_to_large_buffer() */
+struct buffer *htx_copy_to_large_buffer(struct buffer *dst, struct buffer *src)
+{
+       return __htx_xfer_to_large_buffer(dst, src, HTX_XFER_KEEP_SRC_BLKS);
+}