BUG/MEDIUM: mux-h2: Emit an error if the response chunk formatting is incomplete

In legacy HTTP mode, when an chunked H1 response is parsed before sending it to
the client, if a chunk size or a chunk CRLF is incomplete, an error is now
triggered and an RST_STREAM is sent to the client with the ROTOCOL_ERROR error
code. Most of time, it doesn't happen because the HTTP analyzers only forward
properly/fully parsed elements. Thus incomplete chunk size, CRLF and trailers
are not forwarded, waiting for more data. But if the server closes the
connection at this step, the remaining incomplete data are unconditionally
forwarded. When it happens, without this patch, in the H2 multiplexer, nothing
is parsed, leading to a infinite loop in the h2_snd_buf() function.

The HTTP trailers are not supported in legacy mode, but for completeness, the
same is done for incomplete trailers.

This patch should fix the issue #768. It must be backported as far as 1.8. On
the 1.9, an infinite loop may also be experienced. But on the 1.8, the stream is
just finished with an empty DATA frame and the server error is ignored. There is
no mainline commit ID because, on the 2.1 and above, the legacy HTTP mode no
longer exists.
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 679a23f..9e2746d 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -4323,11 +4323,8 @@
 	default:          /* te:chunked : parse chunks */
 		if (h1m->state == H1_MSG_CHUNK_CRLF) {
 			ret = h1_skip_chunk_crlf(buf, ofs, ofs + max);
-			if (!ret)
-				goto end;
-
-			if (ret < 0) {
-				/* FIXME: bad contents. how to proceed here when we're in H2 ? */
+			if (ret <= 0) {
+				/* FIXME: bad contents or truncated response. how to proceed here when we're in H2 ? */
 				h1m->err_pos = ofs + max + ret;
 				h2s_error(h2s, H2_ERR_INTERNAL_ERROR);
 				goto end;
@@ -4341,11 +4338,8 @@
 		if (h1m->state == H1_MSG_CHUNK_SIZE) {
 			unsigned int chunk;
 			ret = h1_parse_chunk_size(buf, ofs, ofs + max, &chunk);
-			if (!ret)
-				goto end;
-
-			if (ret < 0) {
-				/* FIXME: bad contents. how to proceed here when we're in H2 ? */
+			if (ret <= 0) {
+				/* FIXME: bad contents or truncated response. how to proceed here when we're in H2 ? */
 				h1m->err_pos = ofs + max + ret;
 				h2s_error(h2s, H2_ERR_INTERNAL_ERROR);
 				goto end;
@@ -5732,10 +5726,10 @@
 			ret = h1_measure_trailers(buf, total, count);
 
 			if (unlikely((int)ret <= 0)) {
-				if ((int)ret < 0)
-					h2s_error(h2s, H2_ERR_INTERNAL_ERROR);
+				h2s_error(h2s, H2_ERR_INTERNAL_ERROR);
 				break;
 			}
+
 			// trim any possibly pending data (eg: extra CR-LF, ...)
 			total += count;
 			count  = 0;