BUG/MINOR: filters: Fix HTTP parsing when a filter loops on data forwarding
authorChristopher Faulet <christopher.faulet@capflam.org>
Tue, 21 Jun 2016 09:04:34 +0000 (11:04 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 21 Jun 2016 16:53:09 +0000 (18:53 +0200)
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.

src/proto_http.c

index 78c1ac3..4a6e6d3 100644 (file)
@@ -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: