]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: htx: Add a function to append an HTX message to another one
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 23 Jan 2020 10:47:53 +0000 (11:47 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 6 Feb 2020 13:54:47 +0000 (14:54 +0100)
the htx_append_msg() function can now be used to append an HTX message to
another one. All the message is copied or nothing. If an error occurs during the
copy, all changes are rolled back.

This patch is mandatory to fix a bug in http_reply_and_close() function. Be
careful to backport it first.

include/common/htx.h
src/htx.c

index b22da99b4f8e7b2685c8bb0a06fb9888b0caf986..11caa59bff4e17b2a9bacc55a39fcf8f131836a5 100644 (file)
@@ -255,6 +255,7 @@ struct htx_blk *htx_add_data_atonce(struct htx *htx, struct ist data);
 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);
 
 /* Functions and macros to get parts of the start-line or legnth of these
  * parts. Request and response start-lines are both composed of 3 parts.
index 139f3c096b0bca26e433ba3fb12a6451bd370172..41eb47274ecb035528e3ad9340b894c6d1670d8c 100644 (file)
--- a/src/htx.c
+++ b/src/htx.c
@@ -1040,3 +1040,34 @@ void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk *
        *blk = cblk;
        *ref = pblk;
 }
+
+/* Append the HTX message <src> to the HTX message <dst>. It returns 1 on
+ * success and 0 on error.  All the message or nothing is copied. If an error
+ * occurred, all blocks from <src> already appended to <dst> are truncated.
+ */
+int htx_append_msg(struct htx *dst, const struct htx *src)
+{
+       struct htx_blk *blk, *newblk;
+       enum htx_blk_type type;
+       uint32_t blksz, offset = dst->data;
+
+       for (blk = htx_get_head_blk(src); blk; blk = htx_get_next_blk(src, blk)) {
+               type = htx_get_blk_type(blk);
+
+               if (type == HTX_BLK_UNUSED)
+                       continue;
+
+               blksz = htx_get_blksz(blk);
+               newblk = htx_add_blk(dst, type, blksz);
+               if (!newblk)
+                       goto error;
+               newblk->info = blk->info;
+               memcpy(htx_get_blk_ptr(dst, newblk), htx_get_blk_ptr(src, blk), blksz);
+       }
+
+       return 1;
+
+  error:
+       htx_truncate(dst, offset);
+       return 0;
+}