MINOR: htx: Add function to drain data from an HTX message

The function htx_drain() can now be used to drain data from an HTX message.

It will be used by other commits to fix bugs, so it must be backported to 1.9.
This commit is contained in:
Christopher Faulet 2019-02-25 10:23:19 +01:00
parent 729b5b308c
commit 549822f0a1
2 changed files with 38 additions and 0 deletions

View File

@ -171,6 +171,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);
void htx_truncate(struct htx *htx, uint32_t offset);
struct htx_ret htx_drain(struct htx *htx, uint32_t max);
struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk,
const struct ist old, const struct ist new);

View File

@ -307,6 +307,43 @@ void htx_truncate(struct htx *htx, uint32_t offset)
blk = htx_remove_blk(htx, blk);
}
/* Drain <count> bytes from the HTX message <htx>. DATA blocks will be cut if
* necessary. Others blocks will be removed at once if <count> is large
* enough. The function returns an htx_ret with the first block remaing in the
* messsage and the amount of data drained. If everything is removed,
* htx_ret.blk is set to NULL.
*/
struct htx_ret htx_drain(struct htx *htx, uint32_t count)
{
struct htx_blk *blk;
struct htx_ret htxret = { .blk = NULL, .ret = 0 };
blk = htx_get_head_blk(htx);
while (count && blk) {
uint32_t sz = htx_get_blksz(blk);
enum htx_blk_type type = htx_get_blk_type(blk);
/* Ingore unused block */
if (type == HTX_BLK_UNUSED)
goto next;
if (sz > count) {
if (type == HTX_BLK_DATA) {
htx_cut_data_blk(htx, blk, count);
htxret.ret += count;
}
break;
}
count -= sz;
htxret.ret += sz;
next:
blk = htx_remove_blk(htx, blk);
}
htxret.blk = blk;
return htxret;
}
/* Tries to append data to the last inserted block, if the type matches and if
* there is enough non-wrapping space. Only DATA and TRAILERS content can be
* appended. If the append fails, a new block is inserted. If an error occurred,