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.
This commit is contained in:
Christopher Faulet 2025-07-10 10:06:13 +02:00
parent 378c182192
commit 187ae28cf4
2 changed files with 70 additions and 0 deletions

View File

@ -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_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_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_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 */ #endif /* _HAPROXY_H1_HTX_H */

View File

@ -1117,6 +1117,75 @@ int h1_format_htx_data(const struct ist data, struct buffer *chk, int chunked)
return 0; return 0;
} }
/* Format the htx message into its H1 representation. It returns 1 on success or
* 0 if <outbuf> 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: * Local variables:
* c-indent-level: 8 * c-indent-level: 8