From: Willy Tarreau Date: Thu, 3 Jan 2019 20:27:19 +0000 (+0100) Subject: BUG/MEDIUM: mux-h1: don't enforce chunked encoding on requests X-Git-Tag: v2.0-dev1~274 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=61952370404d1286f77421343682359a8051fb8a;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: mux-h1: don't enforce chunked encoding on requests Recent commit 4710d20 ("BUG/MEDIUM: mux-h1: make HTX chunking consistent with H2") tried to address chunking inconsistencies between H1/HTX/H2 and has enforced it on every outgoing message carrying H1_MF_XFER_LEN without H1_MF_CLEN nor H1_MF_CHNK. But it also does it on requests, which is not appropriate since a request by default doesn't have a message body unless explicitly mentioned. Also make sure we only do this on HTTP/1.1 messages. The problem is to guarantee the highest level of compatibility between H1/H1, H1/H2, H2/H1 in each direction regarding the lack of content- length. We have this truth table (a star '*' indicates which one can pass trailers) : H1 client -> H1 server : request: CL=0 TE=0 XL=1 -> CL=0 TE=0 CL=0 TE=1 XL=1 -> CL=0 TE=1 * CL=1 TE=0 XL=1 -> CL=1 TE=0 CL=1 TE=1 XL=1 -> CL=1 TE=1 * response: CL=0 TE=0 XL=0 -> CL=0 TE=0 CL=0 TE=1 XL=1 -> CL=0 TE=1 * CL=1 TE=0 XL=1 -> CL=1 TE=0 CL=1 TE=1 XL=1 -> CL=1 TE=1 * H2 client -> H1 server : (H2 messages always carry XFER_LEN) request: CL=0 XL=1 -> CL=0 TE=0 CL=1 XL=1 -> CL=1 TE=0 response: CL=0 TE=0 XL=0 -> CL=0 CL=0 TE=1 XL=1 -> CL=0 * CL=1 TE=0 XL=1 -> CL=1 CL=1 TE=1 XL=1 -> CL=1 * H1 client -> H2 server : (H2 messages always carry XFER_LEN) request: CL=0 TE=0 XL=1 -> CL=0 CL=0 TE=1 XL=1 -> CL=0 * CL=1 TE=0 XL=1 -> CL=1 CL=1 TE=1 XL=1 -> CL=1 * response: CL=0 XL=1 -> CL=0 TE=1 * CL=1 XL=1 -> CL=1 TE=0 For H1 client to H2 server, it will be possible to rely on the presence of "TE: trailers" in the H1 request to automatically switch to chunks in the response, and be able to pass trailers at the end. For now this check is not implemented so an H2 response missing a content-length to an H1 request will always have a transfer-encoding header added and trailers will be forwarded if any. This patch depends on previous commit "MINOR: mux-h1: parse the content-length header on output and set H1_MF_CLEN" to work properly. Since the aforementioned commit is scheduled for backport to 1.9 this commit must also be backported to 1.9. --- diff --git a/src/mux_h1.c b/src/mux_h1.c index 56937391f5..bdce6dc7f3 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -1576,7 +1576,8 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun } } - if ((h1m->flags & (H1_MF_CLEN|H1_MF_CHNK|H1_MF_XFER_LEN)) == H1_MF_XFER_LEN) { + if ((h1m->flags & (H1_MF_VER_11|H1_MF_RESP|H1_MF_CLEN|H1_MF_CHNK|H1_MF_XFER_LEN)) == + (H1_MF_VER_11|H1_MF_RESP|H1_MF_XFER_LEN)) { /* chunking needed but header not seen */ if (!chunk_memcat(tmp, "transfer-encoding: chunked\r\n", 28)) goto copy;