From: Christopher Faulet Date: Tue, 21 Jun 2016 09:04:34 +0000 (+0200) Subject: BUG/MINOR: filters: Fix HTTP parsing when a filter loops on data forwarding X-Git-Tag: v1.7-dev4~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1eea6d7ba89ad0ed0584478cfc806f3ed7856319;p=thirdparty%2Fhaproxy.git BUG/MINOR: filters: Fix HTTP parsing when a filter loops on data forwarding A filter can choose to loop on data forwarding. When this loop occurs in HTTP_MSG_ENDING state, http_foward_data callbacks are called twice because of a goto on the wrong label. A filter can also choose to loop at the end of a HTTP message, in http_end callback. Here the goto is good but the label is not at the right place. We must be sure to upate msg->sov value. --- diff --git a/src/proto_http.c b/src/proto_http.c index 78c1ac3cee..4a6e6d34b6 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -6851,7 +6851,7 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg) b_adv(chn->buf, ret); msg->next -= ret; if (msg->next) - goto missing_data_or_waiting; + goto waiting; FLT_STRM_DATA_CB(s, chn, flt_http_end(s, msg), /* default_ret */ 1, @@ -6867,11 +6867,12 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg) /* on_error */ goto error); b_adv(chn->buf, ret); msg->next -= ret; + + waiting: if (!(chn->flags & CF_WROTE_DATA) || msg->sov > 0) msg->sov -= ret; if (!HAS_DATA_FILTERS(s, chn)) msg->chunk_len -= channel_forward(chn, msg->chunk_len); - waiting: return 0; error: return -1; @@ -6965,7 +6966,7 @@ http_msg_forward_chunked_body(struct stream *s, struct http_msg *msg) b_adv(chn->buf, ret); msg->next -= ret; if (msg->next) - goto missing_data_or_waiting; + goto waiting; FLT_STRM_DATA_CB(s, chn, flt_http_end(s, msg), /* default_ret */ 1, @@ -6981,11 +6982,12 @@ http_msg_forward_chunked_body(struct stream *s, struct http_msg *msg) /* on_error */ goto error); b_adv(chn->buf, ret); msg->next -= ret; + + waiting: if (!(chn->flags & CF_WROTE_DATA) || msg->sov > 0) msg->sov -= ret; if (!HAS_DATA_FILTERS(s, chn)) msg->chunk_len -= channel_forward(chn, msg->chunk_len); - waiting: return 0; chunk_parsing_error: