From: Christopher Faulet Date: Thu, 10 Jul 2025 08:06:13 +0000 (+0200) Subject: MINOR: h1-htx: Add function to format an HTX message in its H1 representation X-Git-Tag: v3.3-dev3~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=187ae28cf41bc60074d6d80304f625fd52c7030a;p=thirdparty%2Fhaproxy.git MINOR: h1-htx: Add function to format an HTX message in its H1 representation The function h1_format_htx_msg() can now be used to convert a valid HTX message in its H1 representation. No validity test is performed, the HTX message must be valid. Only trailers are silently ignored if the message is not chunked. In addition, the destination buffer must be empty. 1XX interim responses should be supported. But again, there is no validity tests. --- diff --git a/include/haproxy/h1_htx.h b/include/haproxy/h1_htx.h index ae67c8fdf..5be56cdd8 100644 --- a/include/haproxy/h1_htx.h +++ b/include/haproxy/h1_htx.h @@ -65,6 +65,7 @@ int h1_format_htx_reqline(const struct htx_sl *sl, struct buffer *chk); int h1_format_htx_stline(const struct htx_sl *sl, struct buffer *chk); int h1_format_htx_hdr(const struct ist n, const struct ist v, struct buffer *chk); int h1_format_htx_data(const struct ist data, struct buffer *chk, int chunked); +int h1_format_htx_msg(const struct htx *htx, struct buffer *outbuf); #endif /* _HAPROXY_H1_HTX_H */ diff --git a/src/h1_htx.c b/src/h1_htx.c index 5845694ae..142d99199 100644 --- a/src/h1_htx.c +++ b/src/h1_htx.c @@ -1117,6 +1117,75 @@ int h1_format_htx_data(const struct ist data, struct buffer *chk, int chunked) return 0; } +/* Format the htx message into its H1 representation. It returns 1 on success or + * 0 if is full or not emtpy. No check are preformed on the message, it must be + * valid. Trailers are silently ignored if the message is not chunked. + */ +int h1_format_htx_msg(const struct htx *htx, struct buffer *outbuf) +{ + const struct htx_sl *sl; + const struct htx_blk *blk; + struct ist n, v; + enum htx_blk_type type; + uint32_t flags; + int has_eod = 0; + + if (b_data(outbuf)) + return 0; + + for (blk = htx_get_head_blk(htx); blk; blk = htx_get_next_blk(htx, blk)) { + type = htx_get_blk_type(blk); + if (type == HTX_BLK_REQ_SL) { + sl = htx_get_blk_ptr(htx, blk); + flags = sl->flags; + if (!h1_format_htx_reqline(sl, outbuf)) + goto full; + } + else if (type == HTX_BLK_RES_SL) { + sl = htx_get_blk_ptr(htx, blk); + flags = sl->flags; + if (!h1_format_htx_stline(sl, outbuf)) + goto full; + } + else if (type == HTX_BLK_HDR) { + n = htx_get_blk_name(htx, blk); + v = htx_get_blk_value(htx, blk); + + if (!h1_format_htx_hdr(n, v, outbuf)) + goto full; + } + else if (type == HTX_BLK_EOH) { + if (!b_putblk(outbuf, "\r\n", 2)) + goto full; + } + else if (type == HTX_BLK_DATA) { + v = htx_get_blk_value(htx, blk); + if (!h1_format_htx_data(v, outbuf, (flags & HTX_SL_F_CHNK))) + goto full; + } + else if (type == HTX_BLK_TLR) { + if ((flags & HTX_SL_F_CHNK) && has_eod == 0 && !b_putblk(outbuf, "0\r\n", 3)) + goto full; + has_eod = 1; + n = htx_get_blk_name(htx, blk); + v = htx_get_blk_value(htx, blk); + + if (!h1_format_htx_hdr(n, v, outbuf)) + goto full; + } + else if (type == HTX_BLK_EOT) + break; + } + + if ((flags & HTX_SL_F_CHNK) && has_eod == 0 && !b_putblk(outbuf, "0\r\n\r\n", 5)) + goto full; + + return 1; + full: + b_reset(outbuf); + return 0; +} + /* * Local variables: * c-indent-level: 8