Hi all,

Finally I reworked my previous patch. This one should fix the bug, without side effect (AFAIK). It fixes slowdowns experienced on 1.7.9 for HTTP responses with undefined body length when the compression is enabled.

--
Christopher Faulet
>From c42035858a58786c296ae3cf3c2420e4fe82aad0 Mon Sep 17 00:00:00 2001
From: Christopher Faulet <cfau...@haproxy.com>
Date: Tue, 29 Aug 2017 16:06:38 +0200
Subject: [PATCH] BUG/MEDIUM: http: Fix a regression bug when a HTTP response
 is in TUNNEL mode

Unfortunatly, a regression bug was introduced in the commit 1486b0ab
("BUG/MEDIUM: http: Switch HTTP responses in TUNNEL mode when body length is
undefined"). HTTP responses with undefined body length are blocked until timeout
when the compression is enabled. This bug was fixed in commit 69744d92
("BUG/MEDIUM: http: Fix blocked HTTP/1.0 responses when compression is
enabled").

The bug is still the same. We do not forward response data because we are
waiting for the synchronization between the HTTP request and the response.

To fix the bug, conditions to infinitly forward channel data has been slightly
relaxed. Now, it is done if there is no more analyzer registered on the channel
or if _FLT_END analyzer is still there but without the flag CF_FLT_ANALYZE. This
last condition is only possible when a channel is waiting the end of the other
side. So, fundamentally, it means that no one is analyzing the channel
anymore. This is a transitional state during a sync phase.

This patch must be backported in 1.7.
---
 src/stream.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/stream.c b/src/stream.c
index 1985ed98a..d6c12299b 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -2046,7 +2046,7 @@ struct task *process_stream(struct task *t)
 	 * Note that we're checking CF_SHUTR_NOW as an indication of a possible
 	 * recent call to channel_abort().
 	 */
-	if (unlikely(!req->analysers &&
+	if (unlikely((!req->analysers || (req->analysers == AN_REQ_FLT_END && !(req->flags & CF_FLT_ANALYZE))) &&
 	    !(req->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
 	    (si_f->state >= SI_ST_EST) &&
 	    (req->to_forward != CHN_INFINITE_FORWARD))) {
@@ -2205,7 +2205,7 @@ struct task *process_stream(struct task *t)
 	 * Note that we're checking CF_SHUTR_NOW as an indication of a possible
 	 * recent call to channel_abort().
 	 */
-	if (unlikely(!res->analysers &&
+	if (unlikely((!res->analysers || (res->analysers == AN_RES_FLT_END && !(res->flags & CF_FLT_ANALYZE))) &&
 	    !(res->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
 	    (si_b->state >= SI_ST_EST) &&
 	    (res->to_forward != CHN_INFINITE_FORWARD))) {
-- 
2.13.5

Reply via email to