From 85cb0aecf5b29d09d151086858bdcbe0e6f183fc Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 23 Aug 2017 10:52:20 +0200 Subject: [PATCH] BUG/MEDIUM: stream: properly set the required HTTP analysers on use-service Commit 4850e51 ("BUG/MAJOR: lua: Do not force the HTTP analysers in use-services") fixed a bug in how services are used in Lua, but this fix broke the ability for Lua services to support keep-alive. The cause is that we branch to a service while we have not yet set the body analysers on the request nor the response, and when we start to deal with the response we don't have any request analyser anymore. This leads the response forward engine to detect an error and abort. It's very likely that this also causes some random truncation of responses though this has not been observed during the tests. The root cause is not the Lua part in fact, the commit above was correct, the problem is the implementation of the "use-service" action. When done in an HTTP request, it bypasses the load balancing decisions and the connect() phase. These ones are normally the ones preparing the request analysers to parse the body when keep-alive is set. This should be dealt with in the main process_use_service() function in fact. That's what this patch does. If process_use_service() is called from the http-request rule set, it enables the XFER_BODY analyser on the request (since the same is always set on the response). Note that it's exactly what is being done on the stats page which properly supports keep-alive and compression. This fix must be backported to 1.7 and 1.6 as the breakage appeared in 1.6.3. --- src/stream.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/stream.c b/src/stream.c index 43196675b..d9bbe53dd 100644 --- a/src/stream.c +++ b/src/stream.c @@ -1079,6 +1079,15 @@ enum act_return process_use_service(struct act_rule *rule, struct proxy *px, appctx = si_appctx(&s->si[1]); memset(&appctx->ctx, 0, sizeof(appctx->ctx)); appctx->rule = rule; + + /* enable the minimally required analyzers in case of HTTP + * keep-alive to properly handle keep-alive and compression + * on the HTTP response. + */ + if (rule->from == ACT_F_HTTP_REQ) { + s->req.analysers &= AN_REQ_FLT_HTTP_HDRS | AN_REQ_FLT_END; + s->req.analysers |= AN_REQ_HTTP_XFER_BODY; + } } else appctx = si_appctx(&s->si[1]);