]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-h1: don't enforce chunked encoding on requests
authorWilly Tarreau <w@1wt.eu>
Thu, 3 Jan 2019 20:27:19 +0000 (21:27 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 3 Jan 2019 21:27:45 +0000 (22:27 +0100)
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.

src/mux_h1.c

index 56937391f539cb307b512eeedabc0323f27869a6..bdce6dc7f3459758ecb9642012fd013c25c99bb4 100644 (file)
@@ -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;