BUG/MINOR: htx: Change htx_xfer_blk() to also count metadata

This patch makes the function more accurate. Thanks to the function
htx_get_max_blksz(), the transfer of data has been simplified. Note that now the
total number of bytes copied (metadata + payload) is returned. This slighly
change how the function is used in the H2 multiplexer.
This commit is contained in:
Christopher Faulet 2019-05-16 11:29:13 +02:00 committed by Willy Tarreau
parent 2ae35045e2
commit 156852b613
2 changed files with 20 additions and 26 deletions

View file

@ -480,9 +480,9 @@ struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk,
}
/* Transfer HTX blocks from <src> to <dst>, stopping on the first block of the
* type <mark> (typically EOH, EOD or EOM) or when <count> bytes of data were
* moved. It returns the number of bytes of data moved and the last HTX block
* inserted in <dst>.
* type <mark> (typically EOH, EOD or EOM) or when <count> bytes were moved
* (including payload and meta-data). It returns the number of bytes moved and
* the last HTX block inserted in <dst>.
*/
struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
enum htx_blk_type mark)
@ -491,35 +491,29 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
enum htx_blk_type type;
uint32_t info, max, sz, ret;
ret = 0;
ret = htx_used_space(dst);
blk = htx_get_blk(src, htx_get_head(src));
dstblk = NULL;
while (blk && ret <= count) {
while (blk && count) {
type = htx_get_blk_type(blk);
/* Ingore unused block */
if (type == HTX_BLK_UNUSED)
goto next;
sz = htx_get_blksz(blk);
if (!sz) {
dstblk = htx_reserve_nxblk(dst, 0);
if (!dstblk)
break;
dstblk->info = blk->info;
goto next;
}
sz = htx_get_blksz(blk);
info = blk->info;
max = htx_free_data_space(dst);
if (max > count - ret)
max = count - ret;
max = htx_get_max_blksz(dst, count);
if (!max)
break;
if (sz > max) {
/* Headers and pseudo headers must be fully copied */
if (type != HTX_BLK_DATA)
break;
sz = max;
info = (type << 28) + sz;
/* Headers and pseudo headers must be fully copied */
if (type != HTX_BLK_DATA || !sz)
break;
}
dstblk = htx_reserve_nxblk(dst, sz);
@ -528,13 +522,11 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
dstblk->info = info;
memcpy(htx_get_blk_ptr(dst, dstblk), htx_get_blk_ptr(src, blk), sz);
ret += sz;
count -= sizeof(dstblk) + sz;
if (blk->info != info) {
/* Partial move: don't remove <blk> from <src> but
* resize its content */
blk->addr += sz;
htx_set_blk_value_len(blk, htx_get_blksz(blk) - sz);
src->data -= sz;
htx_cut_data_blk(src, blk, sz);
break;
}
@ -547,6 +539,8 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
}
end:
ret = htx_used_space(dst) - ret;
return (struct htx_ret){.ret = ret, .blk = dstblk};
}

View file

@ -5379,7 +5379,6 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
struct h2c *h2c = h2s->h2c;
struct htx *h2s_htx = NULL;
struct htx *buf_htx = NULL;
struct htx_ret htx_ret;
size_t ret = 0;
/* transfer possibly pending data to the upper layer */
@ -5394,6 +5393,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
goto end;
}
ret = h2s_htx->data;
buf_htx = htx_from_buf(buf);
count = htx_free_data_space(buf_htx);
if (flags & CO_RFL_KEEP_RSV) {
@ -5402,7 +5402,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
count -= global.tune.maxrewrite;
}
htx_ret = htx_xfer_blks(buf_htx, h2s_htx, count, HTX_BLK_EOM);
htx_xfer_blks(buf_htx, h2s_htx, count, HTX_BLK_EOM);
if (h2s_htx->flags & HTX_FL_PARSING_ERROR)
buf_htx->flags |= HTX_FL_PARSING_ERROR;
@ -5410,7 +5410,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
buf_htx->extra = (h2s_htx->extra ? (h2s_htx->data + h2s_htx->extra) : 0);
htx_to_buf(buf_htx, buf);
htx_to_buf(h2s_htx, &h2s->rxbuf);
ret = htx_ret.ret;
ret -= h2s_htx->data;
}
else {
ret = b_xfer(buf, &h2s->rxbuf, count);