MINOR: htx: Add a function to return a block at a specific offset

The htx_find_offset() function may be used to look for a block at a specific
offset in an HTX message, starting from the message head. A compound result is
returned, an htx_ret structure, with the found block and the position of the
offset in the block. If the offset is ouside of the HTX message, the returned
block is NULL.

(cherry picked from commit 1cdceb936521ca4dc06d4f57af909310ec374a5e)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 607e84e30fefb84823c6c30958770aedab5cca02)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/include/common/htx.h b/include/common/htx.h
index 27f0e5e..0522c83 100644
--- a/include/common/htx.h
+++ b/include/common/htx.h
@@ -225,6 +225,7 @@
 struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk);
 struct htx_blk *htx_add_blk(struct htx *htx, enum htx_blk_type type, uint32_t blksz);
 struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk);
+struct htx_ret htx_find_offset(struct htx *htx, uint32_t offset);
 void htx_truncate(struct htx *htx, uint32_t offset);
 struct htx_ret htx_drain(struct htx *htx, uint32_t max);
 
diff --git a/src/htx.c b/src/htx.c
index ed28deb..cb389c2 100644
--- a/src/htx.c
+++ b/src/htx.c
@@ -397,6 +397,31 @@
 	return blk;
 }
 
+/* Looks for the HTX block containing the offset <offset>, starting at the HTX
+ * message's head. The function returns an htx_ret with the found HTX block and
+ * the position inside this block where the offset is. If the offset <offset> is
+ * ouside of the HTX message, htx_ret.blk is set to NULL.
+ */
+struct htx_ret htx_find_offset(struct htx *htx, uint32_t offset)
+{
+	struct htx_blk *blk;
+	struct htx_ret htxret = { .blk = NULL, .ret = 0 };
+
+	if (offset >= htx->data)
+		return htxret;
+
+	for (blk = htx_get_head_blk(htx); blk && offset; blk = htx_get_next_blk(htx, blk)) {
+		uint32_t sz = htx_get_blksz(blk);
+
+		if (offset < sz)
+			break;
+		offset -= sz;
+	}
+	htxret.blk = blk;
+	htxret.ret = offset;
+	return htxret;
+}
+
 /* Removes all blocks after the one containing the offset <offset>. This last
  * one may be truncated if it is a DATA block.
  */