BUG/MEDIUM: mux_h2: Handle others remaining read0 cases on partial frames

We've found others places where the read0 is ignored because of an
incomplete frame parsing. This time, it happens during parsing of
CONTINUATION frames.

When frames are parsed, incomplete frames are properly handled and
H2_CF_DEM_SHORT_READ flag is set. It is also true for HEADERS
frames. However, for CONTINUATION frames, there is an exception. Besides
parsing the current frame, we try to peek header of the next one to merge
payload of both frames, the current one and the next one. Idea is to create
a sole HEADERS frame before parsing the payload. However, in this case, it
is possible to have an incomplete frame too, not the current one but the
next one. From the demux point of view, the current frame is complete. We
must go to the internal function h2c_decode_headers() to detect an
incomplete frame. And this case was not identified and fixed when
H2_CF_DEM_SHORT_READ flag was introduced in the commit b5f7b5296
("BUG/MEDIUM: mux-h2: Handle remaining read0 cases on partial frames")

This bug was reported in a comment of the issue #1362. The patch must be
backported as far as 2.0.

(cherry picked from commit 485da0b0535cc575ed8d4f3bf407e9101dbb80aa)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/mux_h2.c b/src/mux_h2.c
index dfe0b37..b343be7 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -2667,8 +2667,12 @@
 			if (h2c->st0 >= H2_CS_ERROR)
 				goto out;
 
-			if (error == 0)
+			if (error == 0) {
+				/* Demux not blocked because of the stream, it is an incomplete frame */
+				if (!(h2c->flags &H2_CF_DEM_BLOCK_ANY))
+					h2c->flags |= H2_CF_DEM_SHORT_READ;
 				goto out; // missing data
+			}
 
 			if (error < 0) {
 				/* Failed to decode this frame (e.g. too large request)
@@ -2705,8 +2709,12 @@
 		goto out;
 
 	if (error <= 0) {
-		if (error == 0)
+		if (error == 0) {
+			/* Demux not blocked because of the stream, it is an incomplete frame */
+			if (!(h2c->flags &H2_CF_DEM_BLOCK_ANY))
+				h2c->flags |= H2_CF_DEM_SHORT_READ;
 			goto out; // missing data
+		}
 
 		/* Failed to decode this stream (e.g. too large request)
 		 * but the HPACK decompressor is still synchronized.
@@ -2824,8 +2832,12 @@
 	}
 
 	if (error <= 0) {
-		if (error == 0)
+		if (error == 0) {
+			/* Demux not blocked because of the stream, it is an incomplete frame */
+			if (!(h2c->flags &H2_CF_DEM_BLOCK_ANY))
+				h2c->flags |= H2_CF_DEM_SHORT_READ;
 			goto fail; // missing data
+		}
 
 		/* stream error : send RST_STREAM */
 		TRACE_ERROR("couldn't decode response HEADERS", H2_EV_RX_FRAME|H2_EV_RX_HDR, h2c->conn, h2s);