BUG/MEDIUM: filters/htx: Fix data forwarding when payload length is unknown

It is only a problem on the response path because the request payload length
it always known. But when a filter is registered to analyze the response
payload, the filtering may hang if the server closes just after the headers.

The root cause of the bug comes from an attempt to allow the filters to not
immediately forward the headers if necessary. A filter may choose to hold
the headers by not forwarding any bytes of the payload. For a message with
no payload but a known payload length, there is always a EOM block to
forward. Thus holding the EOM block for bodyless messages is a good way to
also hold the headers. However, messages with an unknown payload length,
there is no EOM block finishing the message, but only a SHUTR flag on the
channel to mark the end of the stream. If there is no payload when it
happens, there is no payload at all to forward. In the filters API, it is
wrongly detected as a condition to not forward the headers.

Because it is not the most used feature and not the obvious one, this patch
introduces another way to hold the message headers at the begining of the
forwarding. A filter flag is added to explicitly says the headers should be
hold. A filter may choose to set the STRM_FLT_FL_HOLD_HTTP_HDRS flag and not
forwad anything to hold the headers. This flag is removed at each call, thus
it must always be explicitly set by filters. This flag is only evaluated if
no byte has ever been forwarded because the headers are forwarded with the
first byte of the payload.

reg-tests/filters/random-forwarding.vtc reg-test is updated to also test
responses with unknown payload length (with and without payload).

This patch must be backported as far as 2.0.
diff --git a/reg-tests/filters/random-forwarding.vtc b/reg-tests/filters/random-forwarding.vtc
index fdda4e0..2982c88 100644
--- a/reg-tests/filters/random-forwarding.vtc
+++ b/reg-tests/filters/random-forwarding.vtc
@@ -24,6 +24,19 @@
         recv 36000
         send_n 1000 "0123456789abcdefghijklmnopqrstuvwxyz"
         barrier b1 sync
+
+        accept
+        rxreq
+        expect req.url == "/"
+        txresp -nolen \
+          -hdr "Content-Type: text/plain" \
+          -bodylen 20480
+        close
+
+        accept
+        rxreq
+        expect req.url == "/"
+        txresp -nolen
 } -start
 
 haproxy h1 -conf {
@@ -69,3 +82,27 @@
         recv 36000
         barrier b1 sync
 } -run
+
+client c2 -connect ${h1_fe1_sock} {
+        txreq -url "/" \
+          -hdr "Accept-Encoding: gzip" \
+          -hdr "Content-Type: text/plain"
+        rxresp
+        expect resp.status == 200
+        expect resp.http.content-encoding == "<undef>"
+        expect resp.http.transfer-encoding == "<undef>"
+        expect resp.http.content-length == "<undef>"
+        expect resp.bodylen == 20480
+} -run
+
+client c3 -connect ${h1_fe1_sock} {
+        txreq -url "/" \
+          -hdr "Accept-Encoding: gzip" \
+          -hdr "Content-Type: text/plain"
+        rxresp
+        expect resp.status == 200
+        expect resp.http.content-encoding == "<undef>"
+        expect resp.http.transfer-encoding == "<undef>"
+        expect resp.http.content-length == "<undef>"
+        expect resp.bodylen == 0
+} -run