diff --git a/include/common/htx.h b/include/common/htx.h index df75e3397..e7d8b80f6 100644 --- a/include/common/htx.h +++ b/include/common/htx.h @@ -194,6 +194,7 @@ struct htx_blk *htx_add_endof(struct htx *htx, enum htx_blk_type type); struct htx_blk *htx_add_data_atonce(struct htx *htx, struct ist data); 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_reqline_to_h1(const struct htx_sl *sl, struct buffer *chk); int htx_stline_to_h1(const struct htx_sl *sl, struct buffer *chk); diff --git a/src/htx.c b/src/htx.c index 24d3ed4c9..e83271cb3 100644 --- a/src/htx.c +++ b/src/htx.c @@ -1037,6 +1037,29 @@ struct htx_blk *htx_add_last_data(struct htx *htx, struct ist data) return blk; } +/* Moves the block just before the block . Both blocks must be in the + * HTX message and must be placed after . pointer to these + * blocks are updated to remain valid after the move. */ +void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk **ref) +{ + struct htx_blk *cblk, *pblk; + + cblk = *blk; + for (pblk = htx_get_prev_blk(htx, cblk); pblk; pblk = htx_get_prev_blk(htx, pblk)) { + /* Swap .addr and .info fields */ + cblk->addr ^= pblk->addr; pblk->addr ^= cblk->addr; cblk->addr ^= pblk->addr; + cblk->info ^= pblk->info; pblk->info ^= cblk->info; cblk->info ^= pblk->info; + + if (cblk->addr == pblk->addr) + cblk->addr += htx_get_blksz(pblk); + if (pblk == *ref) + break; + cblk = pblk; + } + *blk = cblk; + *ref = pblk; +} + /* Appends the H1 representation of the request line block to the * chunk . It returns 1 if data are successfully appended, otherwise it * returns 0.