MEDIUM: htx: Refactor transfer of htx blocks to merge DATA blocks if possible

When htx_xfer_blks() is called and when HTX DATA blocks are copied, we now
merge them in one block. This will help all payload analysis, if any.
This commit is contained in:
Christopher Faulet 2026-02-03 08:29:51 +01:00
parent a8887e55a0
commit 783db96ccb

View file

@ -704,8 +704,9 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
{
struct htx_blk *blk, *dstblk;
struct htx_blk *srcref, *dstref;
struct ist v;
enum htx_blk_type type;
uint32_t info, max, sz, ret;
uint32_t max, sz, ret;
ret = htx_used_space(dst);
srcref = dstref = dstblk = NULL;
@ -715,38 +716,44 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
*/
for (blk = htx_get_head_blk(src); blk && count; blk = htx_get_next_blk(src, blk)) {
type = htx_get_blk_type(blk);
sz = htx_get_blksz(blk);
/* Ignore unused block */
if (type == HTX_BLK_UNUSED)
continue;
max = htx_get_max_blksz(dst, count);
if (!max)
break;
sz = htx_get_blksz(blk);
info = blk->info;
if (sz > max) {
/* Only DATA blocks can be partially xferred */
if (type != HTX_BLK_DATA)
switch (type) {
case HTX_BLK_DATA:
v = htx_get_blk_value(src, blk);
if (v.len > max)
v.len = max;
v.len = htx_add_data(dst, v);
if (!v.len)
goto stop;
dstblk = htx_get_tail_blk(dst);
count -= sizeof(*dstblk) + v.len;
if (v.len != sz) {
/* Partial xfer: don't remove <blk> from <src> but
* resize its content */
htx_cut_data_blk(src, blk, v.len);
goto stop;
}
break;
default:
/* Only DATA blocks can be partially xferred */
if (sz > max)
goto stop;
dstblk = htx_add_blk(dst, type, sz);
if (!dstblk)
goto stop;
dstblk->info = blk->info;
htx_memcpy(htx_get_blk_ptr(dst, dstblk), htx_get_blk_ptr(src, blk), sz);
count -= sizeof(*dstblk) + sz;
break;
sz = max;
info = (type << 28) + sz;
}
dstblk = htx_reserve_nxblk(dst, sz);
if (!dstblk)
break;
dstblk->info = info;
htx_memcpy(htx_get_blk_ptr(dst, dstblk), htx_get_blk_ptr(src, blk), sz);
count -= sizeof(*dstblk) + sz;
if (blk->info != info) {
/* Partial xfer: don't remove <blk> from <src> but
* resize its content */
htx_cut_data_blk(src, blk, sz);
break;
}
/* Save <blk> to <srcref> and <dstblk> to <dstref> when we start
@ -768,7 +775,7 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
break;
}
}
stop:
if (unlikely(dstref)) {
/* Headers or trailers part was partially xferred, so rollback
* the copy by removing all block between <dstref> and <dstblk>,