From af542635f7f49589c9917acf35baf0a833e958dc Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 1 Oct 2019 21:52:49 +0200 Subject: [PATCH] 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. --- include/proto/h1_htx.h | 2 +- src/h1_htx.c | 34 +++++++++++++++++++--------------- src/mux_fcgi.c | 10 ++++------ src/mux_h1.c | 8 +++----- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/proto/h1_htx.h b/include/proto/h1_htx.h index da372151c..51db02c24 100644 --- a/include/proto/h1_htx.h +++ b/include/proto/h1_htx.h @@ -29,7 +29,7 @@ int h1_parse_msg_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx *dsthtx, 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 *htxbuf); int h1_parse_msg_tlrs(struct h1m *h1m, struct htx *dsthtx, diff --git a/src/h1_htx.c b/src/h1_htx.c index 86b4a7617..1252f8a13 100644 --- a/src/h1_htx.c +++ b/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 into an DATA block in . If possible, a * 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) { + struct htx *tmp_htx = *dsthtx; + /* very often with large files we'll face the following * situation : * - htx is empty and points to @@ -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 * 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))) { void *raw_area = srcbuf->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; htxbuf->area = raw_area; - dsthtx = (struct htx *)htxbuf->area; - dsthtx->size = htxbuf->size - sizeof(*dsthtx); - htx_reset(dsthtx); + tmp_htx = (struct htx *)htxbuf->area; + tmp_htx->size = htxbuf->size - sizeof(*tmp_htx); + htx_reset(tmp_htx); 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; + + *dsthtx = tmp_htx; /* nothing else to do, the old buffer now contains an * empty pre-initialized HTX header */ 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 @@ -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 * functions is responsible to update the parser state . */ -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 *htxbuf) { @@ -442,7 +446,7 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx, if (h1m->flags & H1_MF_CLEN) { /* 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) ret = h1m->curr_len; 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 (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; h1m->state = H1_MSG_DONE; } @@ -491,7 +495,7 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx, goto end; } 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) ret = h1m->curr_len; 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 * 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; h1m->state = H1_MSG_DONE; } else { /* 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)) ret = b_contig_data(srcbuf, ofs); if (ret) @@ -533,7 +537,7 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx *dsthtx, end: if (ret < 0) { - dsthtx->flags |= HTX_FL_PARSING_ERROR; + (*dsthtx)->flags |= HTX_FL_PARSING_ERROR; h1m->err_state = h1m->state; h1m->err_pos = ofs; 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 */ if (h1m->flags & H1_MF_XFER_LEN) - dsthtx->extra = h1m->curr_len; + (*dsthtx)->extra = h1m->curr_len; return total; } diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c index d0fdde435..d66c8af1e 100644 --- a/src/mux_fcgi.c +++ b/src/mux_fcgi.c @@ -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) { int ret; ret = h1_parse_msg_data(h1m, htx, buf, *ofs, max, htxbuf); if (ret <= 0) { - if (htx->flags & HTX_FL_PARSING_ERROR) { + if ((*htx)->flags & HTX_FL_PARSING_ERROR) { fcgi_strm_error(fstrm); 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) { - ret = fcgi_strm_parse_data(fstrm, h1m, htx, &fstrm->rxbuf, &total, count, buf); - htx = htx_from_buf(buf); + ret = fcgi_strm_parse_data(fstrm, h1m, &htx, &fstrm->rxbuf, &total, count, buf); if (!ret) break; } @@ -2725,8 +2724,7 @@ static size_t fcgi_strm_parse_response(struct fcgi_strm *fstrm, struct buffer *b break; } else if (h1m->state == H1_MSG_TUNNEL) { - ret = fcgi_strm_parse_data(fstrm, h1m, htx, &fstrm->rxbuf, &total, count, buf); - htx = htx_from_buf(buf); + ret = fcgi_strm_parse_data(fstrm, h1m, &htx, &fstrm->rxbuf, &total, count, buf); if (fstrm->state != FCGI_SS_ERROR && (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) { diff --git a/src/mux_h1.c b/src/mux_h1.c index 5375ad536..2b4be8775 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -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. * 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 *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) { - ret = h1_process_data(h1s, h1m, htx, &h1c->ibuf, &total, count, buf); - htx = htx_from_buf(buf); + ret = h1_process_data(h1s, h1m, &htx, &h1c->ibuf, &total, count, buf); if (!ret) break; } @@ -1074,8 +1073,7 @@ static size_t h1_process_input(struct h1c *h1c, struct buffer *buf, size_t count break; } else if (h1m->state == H1_MSG_TUNNEL) { - ret = h1_process_data(h1s, h1m, htx, &h1c->ibuf, &total, count, buf); - htx = htx_from_buf(buf); + ret = h1_process_data(h1s, h1m, &htx, &h1c->ibuf, &total, count, buf); if (!ret) break; }