]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: h1-htx: Update h1_copy_msg_data() to ease the traces in the mux-h1
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 1 Oct 2019 19:52:49 +0000 (21:52 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 4 Oct 2019 13:46:59 +0000 (15:46 +0200)
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
src/h1_htx.c
src/mux_fcgi.c
src/mux_h1.c

index da372151c8e85d6e6f1fbf5a84fb1dcb3dfeb04e..51db02c2431db585be246a5e6b628a88f00359b2 100644 (file)
@@ -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,
index 86b4a76173166070878a71e7ae317ba713bcc3be..1252f8a13dc7a9bd27710c7d14cc395a7c431ff6 100644 (file)
@@ -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
  * 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 <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
         *      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 <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 *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;
 }
 
index d0fdde43568ed7f179d02c96b54908531566e820..d66c8af1e8796b38434bb28adc52283a4b5171cb 100644 (file)
@@ -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) {
index 5375ad536373e59a3a3dac9ba2f9e93e4562da6b..2b4be8775908689f4d2580abba30bfaac5d4bd6e 100644 (file)
@@ -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;
                }