MEDIUM: quic: detect the stream FIN

Set the QC_SF_FIN_STREAM on the app layers (h3 / hq-interop) when
reaching the HTX EOM. This is used to warn the mux layer to set the FIN
on the QUIC stream.
diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h
index 2e869c6..3bded67 100644
--- a/include/haproxy/mux_quic-t.h
+++ b/include/haproxy/mux_quic-t.h
@@ -54,6 +54,7 @@
 };
 
 #define QC_SF_NONE              0x00000000
+#define QC_SF_FIN_STREAM        0x00000001  // FIN bit must be set for last frame of the stream
 
 struct qcs {
 	struct qcc *qcc;
diff --git a/src/h3.c b/src/h3.c
index af20656..ecaa02d 100644
--- a/src/h3.c
+++ b/src/h3.c
@@ -620,6 +620,9 @@
 		}
 	}
 
+	if ((htx->flags & HTX_FL_EOM) && htx_is_empty(htx))
+		qcs->flags |= QC_SF_FIN_STREAM;
+
  out:
 	if (total) {
 		if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND))
diff --git a/src/hq_interop.c b/src/hq_interop.c
index af59410..3d530f4 100644
--- a/src/hq_interop.c
+++ b/src/hq_interop.c
@@ -116,6 +116,9 @@
 		}
 	}
 
+	if ((htx->flags & HTX_FL_EOM) && htx_is_empty(htx))
+		qcs->flags |= QC_SF_FIN_STREAM;
+
 	b_add(res, b_data(&outbuf));
 
 	if (total) {
diff --git a/src/mux_quic.c b/src/mux_quic.c
index bdf57e5..df58686 100644
--- a/src/mux_quic.c
+++ b/src/mux_quic.c
@@ -143,8 +143,17 @@
 		struct qcs *qcs = container_of(node, struct qcs, by_id);
 		struct buffer *buf = &qcs->tx.buf;
 		if (b_data(buf)) {
-			/* TODO handle the FIN parameter */
-			ret = qcs_push_frame(qcs, buf, 0, qcs->tx.offset);
+			char fin = 0;
+
+			/* if FIN is activated, ensure the buffer to
+			 * send is the last
+			 */
+			if (qcs->flags & QC_SF_FIN_STREAM) {
+				BUG_ON(b_data(&qcs->tx.buf) < b_data(buf));
+				fin = (b_data(&qcs->tx.buf) - b_data(buf) == 0);
+			}
+
+			ret = qcs_push_frame(qcs, buf, fin, qcs->tx.offset);
 			if (ret < 0)
 				ABORT_NOW();