]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: filters: Forward data only if the last filter forwards something
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 7 Feb 2020 15:40:33 +0000 (16:40 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 18 Feb 2020 10:19:57 +0000 (11:19 +0100)
In flt_tcp_payload() and flt_http_payload(), if the last filter does not
forwarding anything, nothing is forwarded, not even the already filtered
data. For now, this patch is useless because the last filter is always sync with
the stream's offset. But it will be mandatory for a bugfix.

src/filters.c

index 090146e68d0f06f0e807dd66e32807258f7b7d2d..ce6a78e05acfef7d80c07e9b1ff9c5211a846977 100644 (file)
@@ -611,7 +611,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 = 0, data = len - out;
 
        DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg);
        list_for_each_entry(filter, &strm_flt(s)->filters, list) {
@@ -623,14 +623,19 @@ flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len)
                        unsigned int offset = *flt_off - *strm_off;
 
                        DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
-                       ret = FLT_OPS(filter)->http_payload(s, filter, msg, out + offset, ret - offset);
+                       ret = FLT_OPS(filter)->http_payload(s, filter, msg, out + offset, data - offset);
                        if (ret < 0)
                                goto end;
                        *flt_off += ret;
-                       ret += offset;
+                       data = ret + offset;
                }
        }
-       *strm_off += ret;
+
+       /* Only forward data if the last filter decides to forward something */
+       if (ret > 0) {
+               ret = data;
+               *strm_off += ret;
+       }
  end:
        DBG_TRACE_LEAVE(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
        return ret;
@@ -861,7 +866,7 @@ flt_tcp_payload(struct stream *s, struct channel *chn, unsigned int len)
        struct filter *filter;
        unsigned long long *strm_off = &FLT_STRM_OFF(s, chn);
        unsigned int out = co_data(chn);
-       int ret = len - out;
+       int ret = 0, data = len - out;
 
        DBG_TRACE_ENTER(STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
        list_for_each_entry(filter, &strm_flt(s)->filters, list) {
@@ -873,14 +878,19 @@ flt_tcp_payload(struct stream *s, struct channel *chn, unsigned int len)
                        unsigned int offset = *flt_off - *strm_off;
 
                        DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
-                       ret = FLT_OPS(filter)->tcp_payload(s, filter, chn, out + offset, ret - offset);
+                       ret = FLT_OPS(filter)->tcp_payload(s, filter, chn, out + offset, data - offset);
                        if (ret < 0)
                                goto end;
                        *flt_off += ret;
-                       ret += offset;
+                       data = ret + offset;
                }
        }
-       *strm_off += ret;
+
+       /* Only forward data if the last filter decides to forward something */
+       if (ret > 0) {
+               ret = data;
+               *strm_off += ret;
+       }
  end:
        DBG_TRACE_LEAVE(STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
        return ret;