diff --git a/include/proto/channel.h b/include/proto/channel.h index 73288584b..c072c661f 100644 --- a/include/proto/channel.h +++ b/include/proto/channel.h @@ -915,9 +915,10 @@ static inline void channel_slow_realign(struct channel *chn, char *swap) /* Forward all headers of an HTX message, starting from the SL to the EOH. This - * function also updates the first block position. + * function returns the position of the block after the EOH, if + * found. Otherwise, it returns -1. */ -static inline void channel_htx_fwd_headers(struct channel *chn, struct htx *htx) +static inline int32_t channel_htx_fwd_headers(struct channel *chn, struct htx *htx) { int32_t pos; size_t data = 0; @@ -926,11 +927,12 @@ static inline void channel_htx_fwd_headers(struct channel *chn, struct htx *htx) struct htx_blk *blk = htx_get_blk(htx, pos); data += htx_get_blksz(blk); if (htx_get_blk_type(blk) == HTX_BLK_EOH) { - htx->first = htx_get_next(htx, pos); + pos = htx_get_next(htx, pos); break; } } c_adv(chn, data); + return pos; } /* Forward bytes of payload of an HTX message. This function also updates diff --git a/src/filters.c b/src/filters.c index f0cf9b6c2..ff7807565 100644 --- a/src/filters.c +++ b/src/filters.c @@ -782,7 +782,8 @@ 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); - int ret = len - co_data(msg->chn); + unsigned int out = co_data(msg->chn); + int ret = len - out; list_for_each_entry(filter, &strm_flt(s)->filters, list) { /* Call "data" filters only */ @@ -792,7 +793,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, offset, ret - offset); + ret = FLT_OPS(filter)->http_payload(s, filter, msg, out + offset, ret - offset); if (ret < 0) goto end; *flt_off += ret; diff --git a/src/proto_htx.c b/src/proto_htx.c index 7a1f9c516..64595a3c4 100644 --- a/src/proto_htx.c +++ b/src/proto_htx.c @@ -1220,12 +1220,12 @@ 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; - channel_htx_fwd_payload(req, htx, ret); + c_adv(req, ret); if (htx->data != co_data(req) || htx->extra) goto missing_data_or_waiting; } else { - channel_htx_fwd_all(req, htx); + c_adv(req, htx->data - co_data(req)); if (msg->flags & HTTP_MSGF_XFER_LEN) channel_htx_forward_forever(req, htx); } @@ -1698,7 +1698,7 @@ int htx_wait_for_response(struct stream *s, struct channel *rep, int an_bit) if (txn->status < 200 && (txn->status == 100 || txn->status >= 102)) { FLT_STRM_CB(s, flt_http_reset(s, msg)); - channel_htx_fwd_headers(rep, htx); + htx->first = channel_htx_fwd_headers(rep, htx); msg->msg_state = HTTP_MSG_RPBEFORE; txn->status = 0; s->logs.t_data = -1; /* was not a response yet */ @@ -2219,12 +2219,12 @@ 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; - channel_htx_fwd_payload(res, htx, ret); + c_adv(res, ret); if (htx->data != co_data(res) || htx->extra) goto missing_data_or_waiting; } else { - channel_htx_fwd_all(res, htx); + c_adv(res, htx->data - co_data(res)); if (msg->flags & HTTP_MSGF_XFER_LEN) channel_htx_forward_forever(res, htx); }