]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: filters/htx: Filter body relatively to the first block
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 23 May 2019 09:55:33 +0000 (11:55 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 28 May 2019 05:42:33 +0000 (07:42 +0200)
The filters filtering HTX body, in the callback http_payload, must now loop on
an HTX message starting from the first block position. The offset passed as
parameter is relative to this position and not the head one. It is mandatory
because once filtered, data are now forwarded using the function
channel_htx_fwd_payload(). So the first block position is always updated.

src/cache.c
src/filters.c
src/flt_http_comp.c
src/flt_trace.c
src/proto_htx.c

index 4371910fc87ccb606913ca499be4a1b1c62fd7e7..83aacd136d1eb79599f7e7b8027270282c9c1c9c 100644 (file)
@@ -336,7 +336,6 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms
        struct cache_st *st = filter->ctx;
        struct htx *htx = htxbuf(&msg->chn->buf);
        struct htx_blk *blk;
-       struct htx_ret htx_ret;
        struct cache_entry *object;
        int ret, to_forward = 0;
 
@@ -349,16 +348,17 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms
        }
        object = (struct cache_entry *)st->first_block->data;
 
-       htx_ret = htx_find_blk(htx, offset);
-       blk = htx_ret.blk;
-       offset = htx_ret.ret;
-
-       while (blk && len) {
+       for (blk = htx_get_first_blk(htx); blk && len; blk = htx_get_next_blk(htx, blk)) {
                struct shared_block *fb;
                enum htx_blk_type type = htx_get_blk_type(blk);
                uint32_t sz = htx_get_blksz(blk);
                struct ist v;
 
+               if (offset >= sz) {
+                       offset -= sz;
+                       continue;
+               }
+
                switch (type) {
                        case HTX_BLK_UNUSED:
                                break;
@@ -400,7 +400,6 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms
                }
 
                offset = 0;
-               blk  = htx_get_next_blk(htx, blk);
        }
 
        return to_forward;
index 354aa6a3a020f44e5312b459efc1bcf526015c6f..f0cf9b6c244590707ed6c75ef5eaac6d133e8ac8 100644 (file)
@@ -782,8 +782,7 @@ flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len)
 {
        struct filter *filter;
        unsigned long long *strm_off = &FLT_STRM_OFF(s, msg->chn);
-       unsigned int out = co_data(msg->chn);
-       int ret = len - out;
+       int ret = len - co_data(msg->chn);
 
        list_for_each_entry(filter, &strm_flt(s)->filters, list) {
                /* Call "data" filters only */
@@ -793,7 +792,7 @@ flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len)
                        unsigned long long *flt_off = &FLT_OFF(filter, msg->chn);
                        unsigned int offset = *flt_off - *strm_off;
 
-                       ret = FLT_OPS(filter)->http_payload(s, filter, msg, out + offset, ret - offset);
+                       ret = FLT_OPS(filter)->http_payload(s, filter, msg, offset, ret - offset);
                        if (ret < 0)
                                goto end;
                        *flt_off += ret;
@@ -801,7 +800,6 @@ flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len)
                }
        }
        *strm_off += ret;
-
  end:
        return ret;
 }
index 63873d092a6b7df4140d838bb62c31f12e07a866..f756b20127ddf13382af64bed9053f09dbbf67d1 100644 (file)
@@ -202,18 +202,18 @@ comp_http_payload(struct stream *s, struct filter *filter, struct http_msg *msg,
        struct comp_state *st = filter->ctx;
        struct htx *htx = htxbuf(&msg->chn->buf);
        struct htx_blk *blk;
-       struct htx_ret htx_ret;
        int ret, consumed = 0, to_forward = 0;
 
-       htx_ret = htx_find_blk(htx, offset);
-       blk = htx_ret.blk;
-       offset = htx_ret.ret;
-
-       while (blk && len) {
+       for (blk = htx_get_first_blk(htx); blk && len; blk = htx_get_next_blk(htx, blk)) {
                enum htx_blk_type type = htx_get_blk_type(blk);
                uint32_t sz = htx_get_blksz(blk);
                struct ist v;
 
+               if (offset >= sz) {
+                       offset -= sz;
+                       continue;
+               }
+
                switch (type) {
                        case HTX_BLK_UNUSED:
                                break;
@@ -277,7 +277,6 @@ comp_http_payload(struct stream *s, struct filter *filter, struct http_msg *msg,
                }
 
                offset = 0;
-               blk  = htx_get_next_blk(htx, blk);
        }
 
   end:
index 3a142448920a181608cb2848ddc9aea905e443c4..96a19a1ce533c887833993900b9d881c5a53240d 100644 (file)
@@ -131,17 +131,18 @@ trace_raw_hexdump(struct buffer *buf, int len, int out)
 static void
 trace_htx_hexdump(struct htx *htx, unsigned int offset, unsigned int len)
 {
-       struct htx_ret htx_ret;
        struct htx_blk *blk;
 
-       htx_ret = htx_find_blk(htx, offset);
-       blk = htx_ret.blk;
-       offset = htx_ret.ret;
-
-       while (blk) {
+       for (blk = htx_get_first_blk(htx); blk && len; blk = htx_get_next_blk(htx, blk)) {
                enum htx_blk_type type = htx_get_blk_type(blk);
+               uint32_t sz = htx_get_blksz(blk);
                struct ist v;
 
+               if (offset >= sz) {
+                       offset -= sz;
+                       continue;
+               }
+
                v = htx_get_blk_value(htx, blk);
                v.ptr += offset;
                v.len -= offset;
@@ -152,7 +153,6 @@ trace_htx_hexdump(struct htx *htx, unsigned int offset, unsigned int len)
                len -= v.len;
                if (type == HTX_BLK_DATA || type == HTX_BLK_TLR)
                        trace_hexdump(v);
-               blk = htx_get_next_blk(htx, blk);
        }
 }
 
index f596294d9c82128a101b4b78c4e09347ae828147..0bb1eb2fd3f98509c2a5e6c447324f40d937cdd4 100644 (file)
@@ -1220,7 +1220,7 @@ int htx_request_forward_body(struct stream *s, struct channel *req, int an_bit)
                ret  = flt_http_payload(s, msg, htx->data);
                if (ret < 0)
                        goto return_bad_req;
-               c_adv(req, ret);
+               channel_htx_fwd_payload(req, htx, ret);
                if (htx->data != co_data(req) || htx->extra)
                        goto missing_data_or_waiting;
        }
@@ -2217,7 +2217,7 @@ int htx_response_forward_body(struct stream *s, struct channel *res, int an_bit)
                ret  = flt_http_payload(s, msg, htx->data);
                if (ret < 0)
                        goto return_bad_res;
-               c_adv(res, ret);
+               channel_htx_fwd_payload(res, htx, ret);
                if (htx->data != co_data(res) || htx->extra)
                        goto missing_data_or_waiting;
        }