From: Willy Tarreau Date: Sat, 18 Nov 2017 14:39:10 +0000 (+0100) Subject: BUG/MEDIUM: stream: don't automatically forward connect nor close X-Git-Tag: v1.8.0~96 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e223e3bc85393b36cbfe9057450adf2b9a3b7ca8;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: stream: don't automatically forward connect nor close Upon stream instanciation, we used to enable channel auto connect and auto close to ease TCP processing. But commit 9aaf778 ("MAJOR: connection : Split struct connection into struct connection and struct conn_stream.") has revealed that it was a bad idea because this commit enables reading of the trailing shutdown that may follow a small requests, resulting in a read and a shutr turned into shutw before the stream even has a chance to apply the filters. This causes an issue with impossible situations where the backend stream interface is still in SI_ST_INI with a closed output, which blocks some streams for example when performing a redirect with filters enabled. Let's change this so that we only enable these two flags if there is no analyser on the stream. This way process_stream() has a chance to let the analysers decide whether or not to allow the shutdown event to be transferred to the other side. It doesn't seem possible to trigger this issue before 1.8, so for now it is preferable not to backport this fix. --- diff --git a/src/stream.c b/src/stream.c index f8db1554a6..3833983b1d 100644 --- a/src/stream.c +++ b/src/stream.c @@ -224,8 +224,11 @@ struct stream *stream_new(struct session *sess, enum obj_type *origin) channel_init(&s->req); s->req.flags |= CF_READ_ATTACHED; /* the producer is already connected */ s->req.analysers = sess->listener ? sess->listener->analysers : 0; - channel_auto_connect(&s->req); /* don't wait to establish connection */ - channel_auto_close(&s->req); /* let the producer forward close requests */ + + if (!sess->fe->fe_req_ana) { + channel_auto_connect(&s->req); /* don't wait to establish connection */ + channel_auto_close(&s->req); /* let the producer forward close requests */ + } s->req.rto = sess->fe->timeout.client; s->req.wto = TICK_ETERNITY;