]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: filters: Use macros to call filters callbacks to speed-up processing
authorChristopher Faulet <cfaulet@qualys.com>
Tue, 24 Nov 2015 15:24:13 +0000 (16:24 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 9 Feb 2016 13:53:15 +0000 (14:53 +0100)
When no filter is attached to the stream, the CPU footprint due to the calls to
filters_* functions is huge, especially for chunk-encoded messages. Using macros
to check if we have some filters or not is a great improvement.

Furthermore, instead of checking the filter list emptiness, we introduce a flag
to know if filters are attached or not to a stream.

include/proto/filters.h
include/types/stream.h
src/filters.c
src/proto_http.c
src/stream.c

index 2e215778463a0b950dd69477625eca9b7b7270db..0e0eb5f30470d7737a75ee4da91beabc4ee8ee2d 100644 (file)
 #define FLT_NXT(flt, chn) ((flt)->next[CHN_IDX(chn)])
 #define FLT_FWD(flt, chn) ((flt)->fwd[CHN_IDX(chn)])
 
+#define HAS_FILTERS(strm) ((strm)->strm_flt.has_filters)
+
+#define FLT_STRM_CB_IMPL_0(strm, call)                                 \
+       do {                                                            \
+               if (HAS_FILTERS(strm)) { call; }                        \
+       } while (0)
+#define FLT_STRM_CB_IMPL_1(strm, call, default_ret, ...)               \
+       (HAS_FILTERS(strm) ? call : default_ret)
+#define FLT_STRM_CB_IMPL_2(strm, call, default_ret, on_error)          \
+       ({                                                              \
+               int _ret;                                               \
+               if (HAS_FILTERS(strm)) {                                \
+                       _ret = call;                                    \
+                       if (_ret < 0) { on_error; }                     \
+               }                                                       \
+               else                                                    \
+                       _ret = default_ret;                             \
+               _ret;                                                   \
+       })
+#define FLT_STRM_CB_IMPL_3(strm, call, default_ret, on_error, on_wait) \
+       ({                                                              \
+               int _ret;                                               \
+               if (HAS_FILTERS(strm)) {                                \
+                       _ret = call;                                    \
+                       if (_ret < 0) { on_error; }                     \
+                       if (!_ret)    { on_wait;  }                     \
+               }                                                       \
+               else                                                    \
+                       _ret = default_ret;                             \
+               _ret;                                                   \
+       })
+
+#define FLT_STRM_CB_IMPL_X(strm, call, A, B, C, CB_IMPL, ...) CB_IMPL
+
+#define FLT_STRM_CB(strm, call, ...)                                   \
+       FLT_STRM_CB_IMPL_X(strm, call, ##__VA_ARGS__,                   \
+                          FLT_STRM_CB_IMPL_3(strm, call, ##__VA_ARGS__), \
+                          FLT_STRM_CB_IMPL_2(strm, call, ##__VA_ARGS__), \
+                          FLT_STRM_CB_IMPL_1(strm, call, ##__VA_ARGS__), \
+                          FLT_STRM_CB_IMPL_0(strm, call))
+
+#define CALL_FILTER_ANALYZER(analyzer, strm, chn, bit)                 \
+       if (!HAS_FILTERS(strm) || analyzer((strm), (chn), bit)) ; else break
+
 extern struct pool_head *pool2_filter;
 
 int  flt_init(struct proxy *p);
index d6e05e4f74dba9dea4b176a58c4fb92122f7f4df..e2efc930bc669c5fb86768cabf167fdd0e469f9b 100644 (file)
@@ -128,6 +128,7 @@ struct stream {
        struct {
                struct list    filters;
                struct filter *current[2];        /* 0: request, 1: response */
+               char           has_filters;
        } strm_flt;
 
        struct task *task;              /* the task associated with this stream */
index 974c742f496e593ad1ac6cdd45f2d821ca2cb6ad..01dc5fa8e8bdb6a0d51b11e2b02eb5f3d0554004 100644 (file)
@@ -295,6 +295,7 @@ flt_stream_add_filter(struct stream *s, struct filter *filter,
        f->conf  = filter->conf;
        f->is_backend_filter = is_backend;
        LIST_ADDQ(&s->strm_flt.filters, &f->list);
+       s->strm_flt.has_filters = 1;
        return 0;
 }
 
@@ -309,6 +310,7 @@ flt_stream_init(struct stream *s)
 
        LIST_INIT(&s->strm_flt.filters);
        memset(s->strm_flt.current, 0, sizeof(s->strm_flt.current));
+       s->strm_flt.has_filters = 0;
        list_for_each_entry(filter, &strm_fe(s)->filters, list) {
                if (flt_stream_add_filter(s, filter, 0) < 0)
                        return -1;
@@ -333,6 +335,8 @@ flt_stream_release(struct stream *s, int only_backend)
                        pool_free2(pool2_filter, filter);
                }
        }
+       if (LIST_ISEMPTY(&s->strm_flt.filters))
+               s->strm_flt.has_filters = 0;
 }
 
 /*
@@ -393,9 +397,6 @@ flt_http_headers(struct stream *s, struct http_msg *msg)
        struct filter *filter;
        int            ret = 1;
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               goto end;
-
        RESUME_FILTER_LOOP(s, msg->chn) {
                if (filter->ops  && filter->ops->http_headers) {
                        ret = filter->ops->http_headers(s, filter, msg);
@@ -419,9 +420,6 @@ flt_http_start_chunk(struct stream *s, struct http_msg *msg)
 {
        int ret = 1;
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               goto end;
-
        RESUME_FILTER_LOOP(s, msg->chn) {
                if (filter->ops->http_start_chunk) {
                        ret = filter->ops->http_start_chunk(s, filter, msg);
@@ -450,12 +448,6 @@ flt_http_data(struct stream *s, struct http_msg *msg)
        unsigned int   buf_i;
        int            ret = 0;
 
-       /* No filter, consume all available data */
-       if (LIST_ISEMPTY(&s->strm_flt.filters)) {
-               ret = MIN(msg->chunk_len, msg->chn->buf->i - msg->next);
-               goto end;
-       }
-
        /* Save buffer state */
        buf_i = msg->chn->buf->i;
        list_for_each_entry(filter, &s->strm_flt.filters, list) {
@@ -483,7 +475,6 @@ flt_http_data(struct stream *s, struct http_msg *msg)
        }
        /* Restore the original buffer state */
        msg->chn->buf->i = buf_i;
- end:
        return ret;
 }
 
@@ -492,9 +483,6 @@ flt_http_end_chunk(struct stream *s, struct http_msg *msg)
 {
        int ret = 1;
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               goto end;
-
        RESUME_FILTER_LOOP(s, msg->chn) {
                if (filter->ops->http_end_chunk) {
                        ret = filter->ops->http_end_chunk(s, filter, msg);
@@ -513,9 +501,6 @@ flt_http_last_chunk(struct stream *s, struct http_msg *msg)
 {
        int ret = 1;
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               goto end;
-
        RESUME_FILTER_LOOP(s, msg->chn) {
                if (filter->ops->http_last_chunk) {
                        ret = filter->ops->http_last_chunk(s, filter, msg);
@@ -543,9 +528,6 @@ flt_http_chunk_trailers(struct stream *s, struct http_msg *msg)
 {
        int ret = 1;
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               goto end;
-
        RESUME_FILTER_LOOP(s, msg->chn) {
                if (filter->ops->http_chunk_trailers) {
                        ret = filter->ops->http_chunk_trailers(s, filter, msg);
@@ -570,9 +552,6 @@ flt_http_end(struct stream *s, struct http_msg *msg)
 {
        int ret = 1;
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               goto end;
-
        RESUME_FILTER_LOOP(s, msg->chn) {
                if (filter->ops->http_end) {
                        ret = filter->ops->http_end(s, filter, msg);
@@ -594,9 +573,6 @@ flt_http_reset(struct stream *s, struct http_msg *msg)
 {
        struct filter *filter;
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               return;
-
        list_for_each_entry(filter, &s->strm_flt.filters, list) {
                if (filter->ops->http_reset)
                        filter->ops->http_reset(s, filter, msg);
@@ -612,9 +588,6 @@ flt_http_reply(struct stream *s, short status, const struct chunk *msg)
 {
        struct filter *filter;
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               return;
-
        list_for_each_entry(filter, &s->strm_flt.filters, list) {
                if (filter->ops->http_reply)
                        filter->ops->http_reply(s, filter, status, msg);
@@ -636,10 +609,6 @@ flt_http_forward_data(struct stream *s, struct http_msg *msg, unsigned int len)
        struct filter *filter = NULL;
        int            ret = len;
 
-       /* No filter, forward all data */
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               goto end;
-
        list_for_each_entry(filter, &s->strm_flt.filters, list) {
                if (filter->ops->http_forward_data) {
                        /*  Remove bytes that the current filter considered as
@@ -719,9 +688,6 @@ flt_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
 {
        int ret = 1;
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
-               goto end;
-
        RESUME_FILTER_LOOP(s, chn) {
                if (filter->ops->channel_analyze) {
                        ret = filter->ops->channel_analyze(s, filter, chn, an_bit);
@@ -732,7 +698,6 @@ flt_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
 
  check_result:
        ret = handle_analyzer_result(s, chn, 0, ret);
- end:
        return ret;
 }
 
index 48d12f0f6ed40f414b36322fb4e9ba01f205d522..3b39e9cefac54905e6bd6936418c7feada06f1f5 100644 (file)
@@ -935,7 +935,7 @@ int http_remove_header2(struct http_msg *msg, struct hdr_idx *idx, struct hdr_ct
 static void http_server_error(struct stream *s, struct stream_interface *si,
                              int err, int finst, int status, const struct chunk *msg)
 {
-       flt_http_reply(s, status, msg);
+       FLT_STRM_CB(s, flt_http_reply(s, status, msg));
        channel_auto_read(si_oc(si));
        channel_abort(si_oc(si));
        channel_auto_close(si_oc(si));
@@ -970,7 +970,7 @@ void
 http_reply_and_close(struct stream *s, short status, struct chunk *msg)
 {
        s->txn->flags &= ~TX_WAIT_NEXT_RQ;
-       flt_http_reply(s, status, msg);
+       FLT_STRM_CB(s, flt_http_reply(s, status, msg));
        stream_int_retnclose(&s->si[0], msg);
 }
 
@@ -4027,7 +4027,7 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s
                }
                memcpy(trash.str + trash.len, "\r\n\r\n", 4);
                trash.len += 4;
-               flt_http_reply(s, txn->status, &trash);
+               FLT_STRM_CB(s, flt_http_reply(s, txn->status, &trash));
                bo_inject(res->chn, trash.str, trash.len);
                /* "eat" the request */
                bi_fast_delete(req->chn->buf, req->sov);
@@ -5071,14 +5071,14 @@ void http_end_txn_clean_session(struct stream *s)
                        si_idle_conn(&s->si[1], &srv->idle_conns);
        }
 
-       if (LIST_ISEMPTY(&s->strm_flt.filters)) {
-               s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0;
-               s->res.analysers = 0;
-       }
-       else {
+       if (HAS_FILTERS(s)) {
                s->req.analysers &= AN_FLT_END;
                s->res.analysers &= AN_FLT_END;
        }
+       else {
+               s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0;
+               s->res.analysers = 0;
+       }
 }
 
 
@@ -5442,7 +5442,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
        struct session *sess = s->sess;
        struct http_txn *txn = s->txn;
        struct http_msg *msg = &s->txn->req;
-       int ret, ret2;
+       int ret;
 
        if (unlikely(msg->msg_state < HTTP_MSG_BODY))
                return 0;
@@ -5462,25 +5462,16 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
         * decide whether to return 100, 417 or anything else in return of
         * an "Expect: 100-continue" header.
         */
-
        if (msg->msg_state == HTTP_MSG_BODY) {
                /* we have msg->sov which points to the first byte of message
                 * body, and req->buf.p still points to the beginning of the
                 * message. We forward the headers now, as we don't need them
                 * anymore, and we want to flush them.
                 */
-               ret = flt_http_headers(s, msg);
-               if (ret < 0)
-                       goto return_bad_req;
-               if (!ret)
-                       return 0;
-
-               ret = flt_http_forward_data(s, msg, msg->sov);
-               if (ret < 0)
-                       goto return_bad_req;
-               b_adv(req->buf, ret);
-               msg->next -= ret;
-               msg->sov  -= ret;
+               FLT_STRM_CB(s, flt_http_headers(s, msg),
+                           /* default_ret */ 1,
+                           /* on_error    */ goto return_bad_req,
+                           /* on_wait     */ return 0);
 
                /* The previous analysers guarantee that the state is somewhere
                 * between MSG_BODY and the first MSG_DATA. So msg->sol and
@@ -5526,10 +5517,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
                if (msg->msg_state == HTTP_MSG_DATA) {
                        /* must still forward */
                        /* we may have some pending data starting at req->buf->p */
-                       ret = flt_http_data(s, msg);
-                       if (ret < 0)
-                               goto aborted_xfer;
-                       msg->next      += ret;
+                       ret = FLT_STRM_CB(s, flt_http_data(s, msg),
+                                         /* default_ret */ MIN(msg->chunk_len, req->buf->i - msg->next),
+                                         /* on_error    */ goto aborted_xfer);
+                       msg->next     += ret;
                        msg->chunk_len -= ret;
 
                        if (msg->chunk_len) {
@@ -5561,13 +5552,16 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
                                        goto return_bad_req;
                                }
                        }
-                       ret = (msg->chunk_len
-                              ? flt_http_start_chunk(s, msg)
-                              : flt_http_last_chunk(s, msg));
-                       if (ret < 0)
-                               goto return_bad_req;
-                       if (!ret)
-                               goto missing_data;
+                       if (msg->chunk_len)
+                               FLT_STRM_CB(s, flt_http_start_chunk(s, msg),
+                                           /* default_ret */ 1,
+                                           /* on_error    */ goto return_bad_req,
+                                           /* on_wait     */ goto missing_data);
+                       else
+                               FLT_STRM_CB(s, flt_http_last_chunk(s, msg),
+                                           /* default_ret */ 1,
+                                           /* on_error    */ goto return_bad_req,
+                                           /* on_wait     */ goto missing_data);
                        msg->next += msg->sol;
                        msg->sol   = 0;
                        msg->msg_state = msg->chunk_len ? HTTP_MSG_DATA : HTTP_MSG_TRAILERS;
@@ -5586,11 +5580,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
                                        goto return_bad_req;
                                }
                        }
-                       ret = flt_http_end_chunk(s, msg);
-                       if (ret < 0)
-                               goto return_bad_req;
-                       if (!ret)
-                               goto missing_data;
+                       FLT_STRM_CB(s, flt_http_end_chunk(s, msg),
+                                   /* default_ret */ 1,
+                                   /* on_error    */ goto return_bad_req,
+                                   /* on_wait     */ goto missing_data);
                        msg->next += msg->sol;
                        msg->sol   = 0;
                        msg->msg_state = HTTP_MSG_CHUNK_SIZE;
@@ -5607,11 +5600,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
                                        goto return_bad_req;
                                }
                        }
-                       ret2 = flt_http_chunk_trailers(s, msg);
-                       if (ret2 < 0)
-                               goto return_bad_req;
-                       if (!ret2)
-                               goto missing_data;
+                       FLT_STRM_CB(s, flt_http_chunk_trailers(s, msg),
+                                   /* default_ret */ 1,
+                                   /* on_error    */ goto return_bad_req,
+                                   /* on_wait     */ goto missing_data);
                        msg->next += msg->sol;
                        msg->sol   = 0;
                        if (!ret)
@@ -5627,22 +5619,20 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
                        /* we may have some pending data starting at req->buf->p
                         * such as last chunk of data or trailers.
                         */
-                       ret = flt_http_forward_data(s, msg, msg->next);
-                       if (ret < 0)
-                               goto return_bad_req;
+                       ret = FLT_STRM_CB(s, flt_http_forward_data(s, msg, msg->next),
+                                         /* default_ret */ msg->next,
+                                         /* on_error    */ goto return_bad_req);
                        b_adv(req->buf, ret);
                        msg->next -= ret;
                        if (unlikely(!(s->req.flags & CF_WROTE_DATA) || msg->sov > 0))
                                msg->sov -= ret;
-
                        if (msg->next)
                                goto skip_resync_states;
 
-                       ret = flt_http_end(s, msg);
-                       if (ret < 0)
-                               goto return_bad_req;
-                       if (!ret)
-                               goto skip_resync_states;
+                       FLT_STRM_CB(s, flt_http_end(s, msg),
+                                   /* default_ret */ 1,
+                                   /* on_error    */ goto return_bad_req,
+                                   /* on_wait     */ goto skip_resync_states);
                        msg->msg_state = HTTP_MSG_DONE;
                }
                else {
@@ -5703,14 +5693,14 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
 
  missing_data:
        /* we may have some pending data starting at req->buf->p */
-       ret = flt_http_forward_data(s, msg, msg->next);
-       if (ret < 0)
-               goto return_bad_req;
+       ret = FLT_STRM_CB(s, flt_http_forward_data(s, msg, msg->next),
+                         /* default_ret */ msg->next,
+                         /* on_error    */ goto return_bad_req);
        b_adv(req->buf, ret);
        msg->next -= ret;
        if (unlikely(!(s->req.flags & CF_WROTE_DATA) || msg->sov > 0))
                msg->sov -= ret;
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
+       if (!HAS_FILTERS(s))
                msg->chunk_len -= channel_forward(req, msg->chunk_len);
 
        /* stop waiting for data if the input is closed before the end */
@@ -6162,7 +6152,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                msg->msg_state = HTTP_MSG_RPBEFORE;
                txn->status = 0;
                s->logs.t_data = -1; /* was not a response yet */
-               flt_http_reset(s, msg);
+               FLT_STRM_CB(s, flt_http_reset(s, msg));
                goto next_one;
 
        case 200:
@@ -6733,8 +6723,7 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s
        }
 
  skip_header_mangling:
-       if ((msg->flags & HTTP_MSGF_XFER_LEN) ||
-           !LIST_ISEMPTY(&s->strm_flt.filters) ||
+       if ((msg->flags & HTTP_MSGF_XFER_LEN) || HAS_FILTERS(s) ||
            (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_TUN) {
                rep->analysers &= ~AN_FLT_XFER_DATA;
                rep->analysers |= AN_RES_HTTP_XFER_BODY;
@@ -6782,12 +6771,13 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s
  * is performed at once on final states for all bytes parsed, or when leaving
  * on missing data.
  */
+
 int http_response_forward_body(struct stream *s, struct channel *res, int an_bit)
 {
        struct session *sess = s->sess;
        struct http_txn *txn = s->txn;
        struct http_msg *msg = &s->txn->rsp;
-       int ret, ret2;
+       int ret;
 
        if (unlikely(msg->msg_state < HTTP_MSG_BODY))
                return 0;
@@ -6812,18 +6802,10 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
                 * message. We forward the headers now, as we don't need them
                 * anymore, and we want to flush them.
                 */
-               ret = flt_http_headers(s, msg);
-               if (ret < 0)
-                       goto return_bad_res;
-               if (!ret)
-                       return 0;
-
-               ret = flt_http_forward_data(s, msg, msg->sov);
-               if (ret < 0)
-                       goto return_bad_res;
-               b_adv(res->buf, ret);
-               msg->next -= ret;
-               msg->sov  -= ret;
+               FLT_STRM_CB(s, flt_http_headers(s, msg),
+                           /* default_ret */ 1,
+                           /* on_error    */ goto return_bad_res,
+                           /* on_wait     */ return 0);
 
                /* The previous analysers guarantee that the state is somewhere
                 * between MSG_BODY and the first MSG_DATA. So msg->sol and
@@ -6852,11 +6834,14 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
                          * found, so we must read the body until the server
                          * connection is closed. In that case, we eat data as
                          * they come. */
-                       if (!(msg->flags & HTTP_MSGF_XFER_LEN))
-                               msg->chunk_len = (res->buf->i - msg->next);
-                       ret = flt_http_data(s, msg);
-                       if (ret < 0)
-                               goto aborted_xfer;
+                       if (!(msg->flags & HTTP_MSGF_XFER_LEN)) {
+                               unsigned long long len = (res->buf->i - msg->next);
+                               msg->chunk_len += len;
+                               msg->body_len  += len;
+                       }
+                       ret = FLT_STRM_CB(s, flt_http_data(s, msg),
+                                         /* default_ret */ MIN(msg->chunk_len, res->buf->i - msg->next),
+                                         /* on_error    */ goto aborted_xfer);
                        msg->next      += ret;
                        msg->chunk_len -= ret;
                        if (msg->chunk_len) {
@@ -6891,11 +6876,10 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
                                        goto return_bad_res;
                                }
                        }
-                       ret = flt_http_end_chunk(s, msg);
-                       if (ret < 0)
-                               goto return_bad_res;
-                       if (!ret)
-                               goto missing_data;
+                       FLT_STRM_CB(s, flt_http_end_chunk(s, msg),
+                                   /* default_ret */ 1,
+                                   /* on_error    */ goto return_bad_res,
+                                   /* on_wait     */ goto missing_data);
                        msg->next += msg->sol;
                        msg->sol   = 0;
                        msg->msg_state = HTTP_MSG_CHUNK_SIZE;
@@ -6916,13 +6900,16 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
                                        goto return_bad_res;
                                }
                        }
-                       ret = (msg->chunk_len
-                              ? flt_http_start_chunk(s, msg)
-                              : flt_http_last_chunk(s, msg));
-                       if (ret < 0)
-                               goto return_bad_res;
-                       if (!ret)
-                               goto missing_data;
+                       if (msg->chunk_len)
+                               FLT_STRM_CB(s, flt_http_start_chunk(s, msg),
+                                           /* default_ret */ 1,
+                                           /* on_error    */ goto return_bad_res,
+                                           /* on_wait     */ goto missing_data);
+                       else
+                               FLT_STRM_CB(s, flt_http_last_chunk(s, msg),
+                                           /* default_ret */ 1,
+                                           /* on_error    */ goto return_bad_res,
+                                           /* on_wait     */ goto missing_data);
                        msg->next += msg->sol;
                        msg->sol   = 0;
                        msg->msg_state = msg->chunk_len ? HTTP_MSG_DATA : HTTP_MSG_TRAILERS;
@@ -6939,11 +6926,10 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
                                        goto return_bad_res;
                                }
                        }
-                       ret2 = flt_http_chunk_trailers(s, msg);
-                       if (ret2 < 0)
-                               goto return_bad_res;
-                       if (!ret2)
-                               goto missing_data;
+                       FLT_STRM_CB(s, flt_http_chunk_trailers(s, msg),
+                                   /* default_ret */ 1,
+                                   /* on_error    */ goto return_bad_res,
+                                   /* on_wait     */ goto missing_data);
                        msg->next += msg->sol;
                        msg->sol   = 0;
                        if (!ret)
@@ -6960,22 +6946,20 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
                        /* we may have some pending data starting at res->buf->p
                         * such as a last chunk of data or trailers.
                         */
-                       ret = flt_http_forward_data(s, msg, msg->next);
-                       if (ret < 0)
-                               goto return_bad_res;
+                       ret = FLT_STRM_CB(s, flt_http_forward_data(s, msg, msg->next),
+                                         /* default_ret */ msg->next,
+                                         /* on_error    */ goto return_bad_res);
                        b_adv(res->buf, ret);
                        msg->next -= ret;
                        if (msg->sov > 0)
                                msg->sov -= ret;
-
                        if (msg->next)
                                goto skip_resync_states;
 
-                       ret = flt_http_end(s, msg);
-                       if (ret < 0)
-                               goto return_bad_res;
-                       if (!ret)
-                               goto skip_resync_states;
+                       FLT_STRM_CB(s, flt_http_end(s, msg),
+                                   /* default_ret */ 1,
+                                   /* on_error    */ goto return_bad_res,
+                                   /* on_wait     */ goto skip_resync_states);
                        msg->msg_state = HTTP_MSG_DONE;
                        /* fall through */
 
@@ -7013,15 +6997,14 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
 
  missing_data:
        /* we may have some pending data starting at res->buf->p */
-       ret = flt_http_forward_data(s, msg, msg->next);
-       if (ret < 0)
-               goto return_bad_res;
+       ret = FLT_STRM_CB(s, flt_http_forward_data(s, msg, msg->next),
+                         /* default_ret */ msg->next,
+                         /* on_error    */ goto return_bad_res);
        b_adv(res->buf, ret);
        msg->next -= ret;
        if (msg->sov > 0)
                msg->sov -= ret;
-
-       if (LIST_ISEMPTY(&s->strm_flt.filters))
+       if (!HAS_FILTERS(s))
                msg->chunk_len -= channel_forward(res, msg->chunk_len);
 
        if (res->flags & CF_SHUTW)
index c5d6d437b10978542dfa1b02936e9266e3f49b23..a274ea450d095ff431f0aa535fefc419fe85c264 100644 (file)
@@ -1765,107 +1765,95 @@ struct task *process_stream(struct task *t)
                                }
 
                                if (ana_list & AN_REQ_INSPECT_FE) {
-                                       if (!flt_analyze(s, req, AN_REQ_INSPECT_FE))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_INSPECT_FE);
                                        if (!tcp_inspect_request(s, req, AN_REQ_INSPECT_FE))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_INSPECT_FE);
                                }
 
                                if (ana_list & AN_REQ_WAIT_HTTP) {
-                                       if (!flt_analyze(s, req, AN_REQ_WAIT_HTTP))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_WAIT_HTTP);
                                        if (!http_wait_for_request(s, req, AN_REQ_WAIT_HTTP))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_WAIT_HTTP);
                                }
 
                                if (ana_list & AN_REQ_HTTP_BODY) {
-                                       if (!flt_analyze(s, req, AN_REQ_HTTP_BODY))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_BODY);
                                        if (!http_wait_for_request_body(s, req, AN_REQ_HTTP_BODY))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_BODY);
                                }
 
                                if (ana_list & AN_REQ_HTTP_PROCESS_FE) {
-                                       if (!flt_analyze(s, req, AN_REQ_HTTP_PROCESS_FE))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_PROCESS_FE);
                                        if (!http_process_req_common(s, req, AN_REQ_HTTP_PROCESS_FE, sess->fe))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_FE);
                                }
 
                                if (ana_list & AN_REQ_SWITCHING_RULES) {
-                                       if (!flt_analyze(s, req, AN_REQ_SWITCHING_RULES))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_SWITCHING_RULES);
                                        if (!process_switching_rules(s, req, AN_REQ_SWITCHING_RULES))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_SWITCHING_RULES);
                                }
 
-                               if (ana_list & AN_REQ_INSPECT_BE) {
-                                       if (!flt_analyze(s, req, AN_REQ_INSPECT_BE))
+                               if (ana_list & AN_FLT_START_BE) {
+                                       if (!flt_start_analyze(s, req, AN_FLT_START_BE))
                                                break;
+                                       UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_FLT_START_BE);
+                               }
+
+                               if (ana_list & AN_REQ_INSPECT_BE) {
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_INSPECT_BE);
                                        if (!tcp_inspect_request(s, req, AN_REQ_INSPECT_BE))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_INSPECT_BE);
                                }
 
                                if (ana_list & AN_REQ_HTTP_PROCESS_BE) {
-                                       if (!flt_analyze(s, req, AN_REQ_HTTP_PROCESS_BE))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_PROCESS_BE);
                                        if (!http_process_req_common(s, req, AN_REQ_HTTP_PROCESS_BE, s->be))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_BE);
                                }
 
                                if (ana_list & AN_REQ_HTTP_TARPIT) {
-                                       if (!flt_analyze(s, req, AN_REQ_HTTP_TARPIT))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_TARPIT);
                                        if (!http_process_tarpit(s, req, AN_REQ_HTTP_TARPIT))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_TARPIT);
                                }
 
                                if (ana_list & AN_REQ_SRV_RULES) {
-                                       if (!flt_analyze(s, req, AN_REQ_SRV_RULES))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_SRV_RULES);
                                        if (!process_server_rules(s, req, AN_REQ_SRV_RULES))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_SRV_RULES);
                                }
 
                                if (ana_list & AN_REQ_HTTP_INNER) {
-                                       if (!flt_analyze(s, req, AN_REQ_HTTP_INNER))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_HTTP_INNER);
                                        if (!http_process_request(s, req, AN_REQ_HTTP_INNER))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_HTTP_INNER);
                                }
 
                                if (ana_list & AN_REQ_PRST_RDP_COOKIE) {
-                                       if (!flt_analyze(s, req, AN_REQ_PRST_RDP_COOKIE))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_PRST_RDP_COOKIE);
                                        if (!tcp_persist_rdp_cookie(s, req, AN_REQ_PRST_RDP_COOKIE))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_PRST_RDP_COOKIE);
                                }
 
                                if (ana_list & AN_REQ_STICKING_RULES) {
-                                       if (!flt_analyze(s, req, AN_REQ_STICKING_RULES))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, req, AN_REQ_STICKING_RULES);
                                        if (!process_sticking_rules(s, req, AN_REQ_STICKING_RULES))
                                                break;
                                        UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_REQ_STICKING_RULES);
                                }
 
-                               if (ana_list & AN_FLT_START_BE) {
-                                       if (!flt_start_analyze(s, req, AN_FLT_START_BE))
-                                               break;
-                                       UPDATE_ANALYSERS(req->analysers, ana_list, ana_back, AN_FLT_START_BE);
-                               }
-
                                if (ana_list & AN_FLT_XFER_DATA) {
                                        if (!flt_xfer_data(s, req, AN_FLT_XFER_DATA))
                                                break;
@@ -1958,44 +1946,40 @@ struct task *process_stream(struct task *t)
                                        UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_FLT_START_FE);
                                }
 
-                               if (ana_list & AN_RES_INSPECT) {
-                                       if (!flt_analyze(s, res, AN_RES_INSPECT))
+                               if (ana_list & AN_FLT_START_BE) {
+                                       if (!flt_start_analyze(s, res, AN_FLT_START_BE))
                                                break;
+                                       UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_FLT_START_BE);
+                               }
+
+                               if (ana_list & AN_RES_INSPECT) {
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, res, AN_RES_INSPECT);
                                        if (!tcp_inspect_response(s, res, AN_RES_INSPECT))
                                                break;
                                        UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_RES_INSPECT);
                                }
 
                                if (ana_list & AN_RES_WAIT_HTTP) {
-                                       if (!flt_analyze(s, res, AN_RES_WAIT_HTTP))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, res, AN_RES_WAIT_HTTP);
                                        if (!http_wait_for_response(s, res, AN_RES_WAIT_HTTP))
                                                break;
                                        UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_RES_WAIT_HTTP);
                                }
 
                                if (ana_list & AN_RES_STORE_RULES) {
-                                       if (!flt_analyze(s, res, AN_RES_STORE_RULES))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, res, AN_RES_STORE_RULES);
                                        if (!process_store_rules(s, res, AN_RES_STORE_RULES))
                                                break;
                                        UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_RES_STORE_RULES);
                                }
 
                                if (ana_list & AN_RES_HTTP_PROCESS_BE) {
-                                       if (!flt_analyze(s, res, AN_RES_HTTP_PROCESS_BE))
-                                               break;
+                                       CALL_FILTER_ANALYZER(flt_analyze, s, res, AN_RES_HTTP_PROCESS_BE);
                                        if (!http_process_res_common(s, res, AN_RES_HTTP_PROCESS_BE, s->be))
                                                break;
                                        UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_RES_HTTP_PROCESS_BE);
                                }
 
-                               if (ana_list & AN_FLT_START_BE) {
-                                       if (!flt_start_analyze(s, res, AN_FLT_START_BE))
-                                               break;
-                                       UPDATE_ANALYSERS(res->analysers, ana_list, ana_back, AN_FLT_START_BE);
-                               }
-
                                if (ana_list & AN_FLT_XFER_DATA) {
                                        if (!flt_xfer_data(s, res, AN_FLT_XFER_DATA))
                                                break;