BUG/MEDIUM: filters: Fix channels synchronization in flt_end_analyze
When a filter is used, there are 2 channel's analyzers to surround all the
others, flt_start_analyze and flt_end_analyze. This is the good place to acquire
and release resources used by filters, when needed. In addition, the last one is
used to synchronize the both channels, especially for HTTP streams. We must wait
that the analyze is finished for the both channels for an HTTP transaction
before restarting it for the next one.
But this part was buggy, leading to unexpected behaviours. First, depending on
which channel ends first, the request or the response can be switch in a
"forward forever" mode. Then, the HTTP transaction can be cleaned up too early,
while a processing is still in progress on a channel.
To fix the bug, the flag CF_FLT_ANALYZE has been added. It is set on channels in
flt_start_analyze and is kept if at least one filter is still analyzing the
channel. So, we can trigger the channel syncrhonization if this flag was removed
on the both channels. In addition, the flag TX_WAIT_CLEANUP has been added on
the transaction to know if the transaction must be cleaned up or not during
channels syncrhonization. This way, we are sure to reset everything once all the
processings are finished.
This patch should be backported in 1.7.
diff --git a/src/proto_http.c b/src/proto_http.c
index c0f57c5..6d55e6a 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -5339,15 +5339,8 @@
else
si_idle_conn(&s->si[1], &srv->idle_conns);
}
-
- if (HAS_FILTERS(s)) {
- s->req.analysers &= AN_REQ_FLT_END;
- s->res.analysers &= AN_RES_FLT_END;
- }
- else {
- s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0;
- s->res.analysers = 0;
- }
+ s->req.analysers = strm_li(s) ? strm_li(s)->analysers : 0;
+ s->res.analysers = 0;
}
@@ -5703,8 +5696,12 @@
s->req.flags |= CF_WAKE_WRITE;
else if (channel_congested(&s->res))
s->res.flags |= CF_WAKE_WRITE;
- else
- http_end_txn_clean_session(s);
+ else {
+ s->req.analysers = AN_REQ_FLT_END;
+ s->res.analysers = AN_RES_FLT_END;
+ txn->flags |= TX_WAIT_CLEANUP;
+ return 1;
+ }
}
return txn->req.msg_state != old_req_state ||