mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 22:31:28 +02:00
MINOR: h1-htx: Update h1_copy_msg_data() to ease the traces in the mux-h1
This function now uses the address of the pointer to the htx message where the copy must be performed. This way, when a zero-copy is performed, there is no need to refresh the caller's htx message. It is a bit easier to do that way, especially to add traces in the mux-h1.
This commit is contained in:
parent
f81ef0344e
commit
af542635f7
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
int h1_parse_msg_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx *dsthtx,
|
int h1_parse_msg_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx *dsthtx,
|
||||||
struct buffer *srcbuf, size_t ofs, size_t max);
|
struct buffer *srcbuf, size_t ofs, size_t max);
|
||||||
int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx,
|
int h1_parse_msg_data(struct h1m *h1m, struct htx **dsthtx,
|
||||||
struct buffer *srcbuf, size_t ofs, size_t max,
|
struct buffer *srcbuf, size_t ofs, size_t max,
|
||||||
struct buffer *htxbuf);
|
struct buffer *htxbuf);
|
||||||
int h1_parse_msg_tlrs(struct h1m *h1m, struct htx *dsthtx,
|
int h1_parse_msg_tlrs(struct h1m *h1m, struct htx *dsthtx,
|
||||||
|
34
src/h1_htx.c
34
src/h1_htx.c
@ -393,9 +393,11 @@ int h1_parse_msg_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx *dsthtx,
|
|||||||
/* Copy data from <srbuf> into an DATA block in <dsthtx>. If possible, a
|
/* Copy data from <srbuf> into an DATA block in <dsthtx>. If possible, a
|
||||||
* zero-copy is performed. It returns the number of bytes copied.
|
* zero-copy is performed. It returns the number of bytes copied.
|
||||||
*/
|
*/
|
||||||
static int h1_copy_msg_data(struct htx *dsthtx, struct buffer *srcbuf, size_t ofs,
|
static int h1_copy_msg_data(struct htx **dsthtx, struct buffer *srcbuf, size_t ofs,
|
||||||
size_t count, struct buffer *htxbuf)
|
size_t count, struct buffer *htxbuf)
|
||||||
{
|
{
|
||||||
|
struct htx *tmp_htx = *dsthtx;
|
||||||
|
|
||||||
/* very often with large files we'll face the following
|
/* very often with large files we'll face the following
|
||||||
* situation :
|
* situation :
|
||||||
* - htx is empty and points to <htxbuf>
|
* - htx is empty and points to <htxbuf>
|
||||||
@ -404,7 +406,7 @@ static int h1_copy_msg_data(struct htx *dsthtx, struct buffer *srcbuf, size_t of
|
|||||||
* => we can swap the buffers and place an htx header into
|
* => we can swap the buffers and place an htx header into
|
||||||
* the target buffer instead
|
* the target buffer instead
|
||||||
*/
|
*/
|
||||||
if (unlikely(htx_is_empty(dsthtx) && count == b_data(srcbuf) &&
|
if (unlikely(htx_is_empty(tmp_htx) && count == b_data(srcbuf) &&
|
||||||
!ofs && b_head_ofs(srcbuf) == sizeof(struct htx))) {
|
!ofs && b_head_ofs(srcbuf) == sizeof(struct htx))) {
|
||||||
void *raw_area = srcbuf->area;
|
void *raw_area = srcbuf->area;
|
||||||
void *htx_area = htxbuf->area;
|
void *htx_area = htxbuf->area;
|
||||||
@ -412,20 +414,22 @@ static int h1_copy_msg_data(struct htx *dsthtx, struct buffer *srcbuf, size_t of
|
|||||||
|
|
||||||
srcbuf->area = htx_area;
|
srcbuf->area = htx_area;
|
||||||
htxbuf->area = raw_area;
|
htxbuf->area = raw_area;
|
||||||
dsthtx = (struct htx *)htxbuf->area;
|
tmp_htx = (struct htx *)htxbuf->area;
|
||||||
dsthtx->size = htxbuf->size - sizeof(*dsthtx);
|
tmp_htx->size = htxbuf->size - sizeof(*tmp_htx);
|
||||||
htx_reset(dsthtx);
|
htx_reset(tmp_htx);
|
||||||
b_set_data(htxbuf, b_size(htxbuf));
|
b_set_data(htxbuf, b_size(htxbuf));
|
||||||
|
|
||||||
blk = htx_add_blk(dsthtx, HTX_BLK_DATA, count);
|
blk = htx_add_blk(tmp_htx, HTX_BLK_DATA, count);
|
||||||
blk->info += count;
|
blk->info += count;
|
||||||
|
|
||||||
|
*dsthtx = tmp_htx;
|
||||||
/* nothing else to do, the old buffer now contains an
|
/* nothing else to do, the old buffer now contains an
|
||||||
* empty pre-initialized HTX header
|
* empty pre-initialized HTX header
|
||||||
*/
|
*/
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return htx_add_data(dsthtx, ist2(b_peek(srcbuf, ofs), count));
|
return htx_add_data(*dsthtx, ist2(b_peek(srcbuf, ofs), count));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse HTTP/1 body. It returns the number of bytes parsed if > 0, or 0 if it
|
/* Parse HTTP/1 body. It returns the number of bytes parsed if > 0, or 0 if it
|
||||||
@ -433,7 +437,7 @@ static int h1_copy_msg_data(struct htx *dsthtx, struct buffer *srcbuf, size_t of
|
|||||||
* HTX_FL_PARSING_ERROR and filling h1m->err_pos and h1m->err_state fields. This
|
* HTX_FL_PARSING_ERROR and filling h1m->err_pos and h1m->err_state fields. This
|
||||||
* functions is responsible to update the parser state <h1m>.
|
* functions is responsible to update the parser state <h1m>.
|
||||||
*/
|
*/
|
||||||
int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx,
|
int h1_parse_msg_data(struct h1m *h1m, struct htx **dsthtx,
|
||||||
struct buffer *srcbuf, size_t ofs, size_t max,
|
struct buffer *srcbuf, size_t ofs, size_t max,
|
||||||
struct buffer *htxbuf)
|
struct buffer *htxbuf)
|
||||||
{
|
{
|
||||||
@ -442,7 +446,7 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx,
|
|||||||
|
|
||||||
if (h1m->flags & H1_MF_CLEN) {
|
if (h1m->flags & H1_MF_CLEN) {
|
||||||
/* content-length: read only h2m->body_len */
|
/* content-length: read only h2m->body_len */
|
||||||
ret = htx_get_max_blksz(dsthtx, max);
|
ret = htx_get_max_blksz(*dsthtx, max);
|
||||||
if ((uint64_t)ret > h1m->curr_len)
|
if ((uint64_t)ret > h1m->curr_len)
|
||||||
ret = h1m->curr_len;
|
ret = h1m->curr_len;
|
||||||
if (ret > b_contig_data(srcbuf, ofs))
|
if (ret > b_contig_data(srcbuf, ofs))
|
||||||
@ -460,7 +464,7 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!h1m->curr_len) {
|
if (!h1m->curr_len) {
|
||||||
if (max < sizeof(struct htx_blk) + 1 || !htx_add_endof(dsthtx, HTX_BLK_EOM))
|
if (max < sizeof(struct htx_blk) + 1 || !htx_add_endof(*dsthtx, HTX_BLK_EOM))
|
||||||
goto end;
|
goto end;
|
||||||
h1m->state = H1_MSG_DONE;
|
h1m->state = H1_MSG_DONE;
|
||||||
}
|
}
|
||||||
@ -491,7 +495,7 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (h1m->state == H1_MSG_DATA) {
|
if (h1m->state == H1_MSG_DATA) {
|
||||||
ret = htx_get_max_blksz(dsthtx, max);
|
ret = htx_get_max_blksz(*dsthtx, max);
|
||||||
if ((uint64_t)ret > h1m->curr_len)
|
if ((uint64_t)ret > h1m->curr_len)
|
||||||
ret = h1m->curr_len;
|
ret = h1m->curr_len;
|
||||||
if (ret > b_contig_data(srcbuf, ofs))
|
if (ret > b_contig_data(srcbuf, ofs))
|
||||||
@ -518,13 +522,13 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx,
|
|||||||
/* XFER_LEN is set but not CLEN nor CHNK, it means there is no
|
/* XFER_LEN is set but not CLEN nor CHNK, it means there is no
|
||||||
* body. Switch the message in DONE state
|
* body. Switch the message in DONE state
|
||||||
*/
|
*/
|
||||||
if (max < sizeof(struct htx_blk) + 1 || !htx_add_endof(dsthtx, HTX_BLK_EOM))
|
if (max < sizeof(struct htx_blk) + 1 || !htx_add_endof(*dsthtx, HTX_BLK_EOM))
|
||||||
goto end;
|
goto end;
|
||||||
h1m->state = H1_MSG_DONE;
|
h1m->state = H1_MSG_DONE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* no content length, read till SHUTW */
|
/* no content length, read till SHUTW */
|
||||||
ret = htx_get_max_blksz(dsthtx, max);
|
ret = htx_get_max_blksz(*dsthtx, max);
|
||||||
if (ret > b_contig_data(srcbuf, ofs))
|
if (ret > b_contig_data(srcbuf, ofs))
|
||||||
ret = b_contig_data(srcbuf, ofs);
|
ret = b_contig_data(srcbuf, ofs);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -533,7 +537,7 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx,
|
|||||||
|
|
||||||
end:
|
end:
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dsthtx->flags |= HTX_FL_PARSING_ERROR;
|
(*dsthtx)->flags |= HTX_FL_PARSING_ERROR;
|
||||||
h1m->err_state = h1m->state;
|
h1m->err_state = h1m->state;
|
||||||
h1m->err_pos = ofs;
|
h1m->err_pos = ofs;
|
||||||
total = 0;
|
total = 0;
|
||||||
@ -541,7 +545,7 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx,
|
|||||||
|
|
||||||
/* update htx->extra, only when the body length is known */
|
/* update htx->extra, only when the body length is known */
|
||||||
if (h1m->flags & H1_MF_XFER_LEN)
|
if (h1m->flags & H1_MF_XFER_LEN)
|
||||||
dsthtx->extra = h1m->curr_len;
|
(*dsthtx)->extra = h1m->curr_len;
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2626,14 +2626,14 @@ static size_t fcgi_strm_parse_headers(struct fcgi_strm *fstrm, struct h1m *h1m,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t fcgi_strm_parse_data(struct fcgi_strm *fstrm, struct h1m *h1m, struct htx *htx,
|
static size_t fcgi_strm_parse_data(struct fcgi_strm *fstrm, struct h1m *h1m, struct htx **htx,
|
||||||
struct buffer *buf, size_t *ofs, size_t max, struct buffer *htxbuf)
|
struct buffer *buf, size_t *ofs, size_t max, struct buffer *htxbuf)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = h1_parse_msg_data(h1m, htx, buf, *ofs, max, htxbuf);
|
ret = h1_parse_msg_data(h1m, htx, buf, *ofs, max, htxbuf);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
if (htx->flags & HTX_FL_PARSING_ERROR) {
|
if ((*htx)->flags & HTX_FL_PARSING_ERROR) {
|
||||||
fcgi_strm_error(fstrm);
|
fcgi_strm_error(fstrm);
|
||||||
fcgi_strm_capture_bad_message(fstrm->fconn, fstrm, h1m, buf);
|
fcgi_strm_capture_bad_message(fstrm->fconn, fstrm, h1m, buf);
|
||||||
}
|
}
|
||||||
@ -2703,8 +2703,7 @@ static size_t fcgi_strm_parse_response(struct fcgi_strm *fstrm, struct buffer *b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (h1m->state < H1_MSG_TRAILERS) {
|
else if (h1m->state < H1_MSG_TRAILERS) {
|
||||||
ret = fcgi_strm_parse_data(fstrm, h1m, htx, &fstrm->rxbuf, &total, count, buf);
|
ret = fcgi_strm_parse_data(fstrm, h1m, &htx, &fstrm->rxbuf, &total, count, buf);
|
||||||
htx = htx_from_buf(buf);
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2725,8 +2724,7 @@ static size_t fcgi_strm_parse_response(struct fcgi_strm *fstrm, struct buffer *b
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (h1m->state == H1_MSG_TUNNEL) {
|
else if (h1m->state == H1_MSG_TUNNEL) {
|
||||||
ret = fcgi_strm_parse_data(fstrm, h1m, htx, &fstrm->rxbuf, &total, count, buf);
|
ret = fcgi_strm_parse_data(fstrm, h1m, &htx, &fstrm->rxbuf, &total, count, buf);
|
||||||
htx = htx_from_buf(buf);
|
|
||||||
if (fstrm->state != FCGI_SS_ERROR &&
|
if (fstrm->state != FCGI_SS_ERROR &&
|
||||||
(fstrm->flags & FCGI_SF_ES_RCVD) && b_data(&fstrm->rxbuf) == total) {
|
(fstrm->flags & FCGI_SF_ES_RCVD) && b_data(&fstrm->rxbuf) == total) {
|
||||||
if ((h1m->flags & (H1_MF_VER_11|H1_MF_XFER_LEN)) == H1_MF_VER_11) {
|
if ((h1m->flags & (H1_MF_VER_11|H1_MF_XFER_LEN)) == H1_MF_VER_11) {
|
||||||
|
@ -944,7 +944,7 @@ static size_t h1_process_headers(struct h1s *h1s, struct h1m *h1m, struct htx *h
|
|||||||
* couldn't proceed. Parsing errors are reported by setting H1S_F_*_ERROR flag.
|
* couldn't proceed. Parsing errors are reported by setting H1S_F_*_ERROR flag.
|
||||||
* If relies on the function http_parse_msg_data() to do the parsing.
|
* If relies on the function http_parse_msg_data() to do the parsing.
|
||||||
*/
|
*/
|
||||||
static size_t h1_process_data(struct h1s *h1s, struct h1m *h1m, struct htx *htx,
|
static size_t h1_process_data(struct h1s *h1s, struct h1m *h1m, struct htx **htx,
|
||||||
struct buffer *buf, size_t *ofs, size_t max,
|
struct buffer *buf, size_t *ofs, size_t max,
|
||||||
struct buffer *htxbuf)
|
struct buffer *htxbuf)
|
||||||
{
|
{
|
||||||
@ -1054,8 +1054,7 @@ static size_t h1_process_input(struct h1c *h1c, struct buffer *buf, size_t count
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (h1m->state < H1_MSG_TRAILERS) {
|
else if (h1m->state < H1_MSG_TRAILERS) {
|
||||||
ret = h1_process_data(h1s, h1m, htx, &h1c->ibuf, &total, count, buf);
|
ret = h1_process_data(h1s, h1m, &htx, &h1c->ibuf, &total, count, buf);
|
||||||
htx = htx_from_buf(buf);
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1074,8 +1073,7 @@ static size_t h1_process_input(struct h1c *h1c, struct buffer *buf, size_t count
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (h1m->state == H1_MSG_TUNNEL) {
|
else if (h1m->state == H1_MSG_TUNNEL) {
|
||||||
ret = h1_process_data(h1s, h1m, htx, &h1c->ibuf, &total, count, buf);
|
ret = h1_process_data(h1s, h1m, &htx, &h1c->ibuf, &total, count, buf);
|
||||||
htx = htx_from_buf(buf);
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user