MINOR: htx: Add a function to append an HTX message to another one

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.
diff --git a/include/common/htx.h b/include/common/htx.h
index b22da99..11caa59 100644
--- a/include/common/htx.h
+++ b/include/common/htx.h
@@ -255,6 +255,7 @@
 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.
diff --git a/src/htx.c b/src/htx.c
index 139f3c0..41eb472 100644
--- a/src/htx.c
+++ b/src/htx.c
@@ -1040,3 +1040,34 @@
 	*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;
+}