mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-04 12:41:00 +02:00
MINOR: htx: Add function to reserve the max possible size for an HTX DATA block
The function htx_reserve_max_data() should be used to get an HTX DATA block with the max possible size. A current block may be extended or a new one created, depending on the HTX message state. But the idea is to let the caller to copy a bunch of data without requesting many new blocks. It is its responsibility to resize the block at the end, to set the final block size. This function will be used to parse messages with small chunks. Indeed, we can have more than 2700 1-byte chunks in a 16Kb of input data. So it is easy to understand how this function may help to improve the parsing of chunk messages.
This commit is contained in:
parent
2a821684c8
commit
e071f0e6a4
@ -57,6 +57,7 @@ struct htx_blk *htx_add_trailer(struct htx *htx, const struct ist name, const st
|
||||
struct htx_blk *htx_add_all_headers(struct htx *htx, const struct http_hdr *hdrs);
|
||||
struct htx_blk *htx_add_all_trailers(struct htx *htx, const struct http_hdr *hdrs);
|
||||
struct htx_blk *htx_add_endof(struct htx *htx, enum htx_blk_type type);
|
||||
struct htx_ret htx_reserve_max_data(struct htx *htx);
|
||||
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);
|
||||
|
||||
63
src/htx.c
63
src/htx.c
@ -935,6 +935,69 @@ struct htx_blk *htx_add_endof(struct htx *htx, enum htx_blk_type type)
|
||||
return blk;
|
||||
}
|
||||
|
||||
/* Reserves the maximum possible size for an HTX data block, by extending an
|
||||
* existing one or by creating a now one. It returns a compound result with the
|
||||
* HTX block and the position where new data must be inserted (0 for a new
|
||||
* block). If an error occurs or if there is no space left, NULL is returned
|
||||
* instead of a pointer on an HTX block.
|
||||
*/
|
||||
struct htx_ret htx_reserve_max_data(struct htx *htx)
|
||||
{
|
||||
struct htx_blk *blk, *tailblk;
|
||||
uint32_t sz, room;
|
||||
int32_t len = htx_free_data_space(htx);
|
||||
|
||||
if (htx->head == -1)
|
||||
goto rsv_new_block;
|
||||
|
||||
if (!len)
|
||||
return (struct htx_ret){.ret = 0, .blk = NULL};
|
||||
|
||||
/* get the tail and head block */
|
||||
tailblk = htx_get_tail_blk(htx);
|
||||
if (tailblk == NULL)
|
||||
goto rsv_new_block;
|
||||
sz = htx_get_blksz(tailblk);
|
||||
|
||||
/* Don't try to append data if the last inserted block is not of the
|
||||
* same type */
|
||||
if (htx_get_blk_type(tailblk) != HTX_BLK_DATA)
|
||||
goto rsv_new_block;
|
||||
|
||||
/*
|
||||
* Same type and enough space: append data
|
||||
*/
|
||||
if (!htx->head_addr) {
|
||||
if (tailblk->addr+sz != htx->tail_addr)
|
||||
goto rsv_new_block;
|
||||
room = (htx_pos_to_addr(htx, htx->tail) - htx->tail_addr);
|
||||
}
|
||||
else {
|
||||
if (tailblk->addr+sz != htx->head_addr)
|
||||
goto rsv_new_block;
|
||||
room = (htx->end_addr - htx->head_addr);
|
||||
}
|
||||
BUG_ON((int32_t)room < 0);
|
||||
if (room < len)
|
||||
len = room;
|
||||
|
||||
append_data:
|
||||
htx_change_blk_value_len(htx, tailblk, sz+len);
|
||||
|
||||
BUG_ON((int32_t)htx->tail_addr < 0);
|
||||
BUG_ON((int32_t)htx->head_addr < 0);
|
||||
BUG_ON(htx->end_addr > htx->tail_addr);
|
||||
BUG_ON(htx->head_addr > htx->end_addr);
|
||||
return (struct htx_ret){.ret = sz, .blk = tailblk};
|
||||
|
||||
rsv_new_block:
|
||||
/* FIXME: check data.len (< 256MB) */
|
||||
blk = htx_add_blk(htx, HTX_BLK_DATA, len);
|
||||
if (!blk)
|
||||
return (struct htx_ret){.ret = 0, .blk = NULL};
|
||||
blk->info += len;
|
||||
return (struct htx_ret){.ret = 0, .blk = blk};
|
||||
}
|
||||
|
||||
/* Adds an HTX block of type DATA in <htx>. It first tries to append data if
|
||||
* possible. It returns the number of bytes consumed from <data>, which may be
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user