BUG/MEDIUM: lua: HTTP services must take care of body-less status codes
The following Lua code causes emission of a final chunk after the body,
which is wrong :
core.register_service("send204", "http", function(applet)
applet:set_status(204)
applet:start_response()
end)
Indeed, responses with status codes 1xx, 204 and 304 do not contain any
body and the message ends immediately after the empty header (cf RFC7230)
so by emitting a 0<CR><LF> we're disturbing keep-alive responses. There's
a workaround against this for now which consists in always emitting
"Content-length: 0" but it may not be cool with 304 when clients use
the headers to update their cache.
This fix must be backported to stable versions back to 1.6.
diff --git a/src/hlua.c b/src/hlua.c
index bd3674a..d12c80b 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -4307,12 +4307,17 @@
if (appctx->appctx->ctx.hlua_apphttp.flags & APPLET_HTTP11 && !hdr_connection)
chunk_appendf(tmp, "Connection: close\r\n");
- /* If we dont have a content-length set, we must announce a transfer enconding
- * chunked. This is required by haproxy for the keepalive compliance.
- * If the applet annouce a transfer-encoding chunked itslef, don't
- * do anything.
+ /* If we dont have a content-length set, and the HTTP version is 1.1
+ * and the status code implies the presence of a message body, we must
+ * announce a transfer encoding chunked. This is required by haproxy
+ * for the keepalive compliance. If the applet annouces a transfer-encoding
+ * chunked itslef, don't do anything.
*/
- if (hdr_contentlength == -1 && hdr_chunked == 0) {
+ if (hdr_contentlength == -1 && hdr_chunked == 0 &&
+ (appctx->appctx->ctx.hlua_apphttp.flags & APPLET_HTTP11) &&
+ appctx->appctx->ctx.hlua_apphttp.status >= 200 &&
+ appctx->appctx->ctx.hlua_apphttp.status != 204 &&
+ appctx->appctx->ctx.hlua_apphttp.status != 304) {
chunk_appendf(tmp, "Transfer-encoding: chunked\r\n");
appctx->appctx->ctx.hlua_apphttp.flags |= APPLET_CHUNKED;
}