From: Christopher Faulet Date: Thu, 23 May 2019 09:55:33 +0000 (+0200) Subject: MEDIUM: filters/htx: Filter body relatively to the first block X-Git-Tag: v2.0-dev5~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee847d45d02d7daa75aaee512fff8aa928972964;p=thirdparty%2Fhaproxy.git MEDIUM: filters/htx: Filter body relatively to the first block 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. --- diff --git a/src/cache.c b/src/cache.c index 4371910fc8..83aacd136d 100644 --- a/src/cache.c +++ b/src/cache.c @@ -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; diff --git a/src/filters.c b/src/filters.c index 354aa6a3a0..f0cf9b6c24 100644 --- a/src/filters.c +++ b/src/filters.c @@ -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; } diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c index 63873d092a..f756b20127 100644 --- a/src/flt_http_comp.c +++ b/src/flt_http_comp.c @@ -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: diff --git a/src/flt_trace.c b/src/flt_trace.c index 3a14244892..96a19a1ce5 100644 --- a/src/flt_trace.c +++ b/src/flt_trace.c @@ -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); } } diff --git a/src/proto_htx.c b/src/proto_htx.c index f596294d9c..0bb1eb2fd3 100644 --- a/src/proto_htx.c +++ b/src/proto_htx.c @@ -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; }