From e223e3bc85393b36cbfe9057450adf2b9a3b7ca8 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sat, 18 Nov 2017 15:39:10 +0100 Subject: [PATCH] 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. --- src/stream.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/stream.c b/src/stream.c index f8db1554a..3833983b1 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;