char *fin);
size_t qcs_http_reset_buf(struct qcs *qcs, struct buffer *buf, size_t count);
+void qcs_http_handle_standalone_fin(struct qcs *qcs);
+
#endif /* USE_QUIC */
#endif /* _HAPROXY_MUX_QUIC_HTTP_H */
#include <haproxy/istbuf.h>
#include <haproxy/mux_quic.h>
#include <haproxy/pool.h>
+#include <haproxy/qmux_http.h>
#include <haproxy/qpack-dec.h>
#include <haproxy/qpack-enc.h>
#include <haproxy/quic_conn-t.h>
ssize_t total = 0, ret;
h3_debug_printf(stderr, "%s: STREAM ID: %lu\n", __func__, qcs->id);
- if (!b_data(b))
- return 0;
if (quic_stream_is_uni(qcs->id) && !(h3s->flags & H3_SF_UNI_INIT)) {
if ((ret = h3_init_uni_stream(h3c, qcs, b)) < 0)
return -1;
}
+ if (!b_data(b) && fin && quic_stream_is_bidi(qcs->id)) {
+ qcs_http_handle_standalone_fin(qcs);
+ return 0;
+ }
+
while (b_data(b) && !(qcs->flags & QC_SF_DEM_FULL) && !h3c->err && !h3s->err) {
uint64_t ftype, flen;
char last_stream_frame = 0;
#include <haproxy/htx.h>
#include <haproxy/http.h>
#include <haproxy/mux_quic.h>
+#include <haproxy/qmux_http.h>
static ssize_t hq_interop_decode_qcs(struct qcs *qcs, struct buffer *b, int fin)
{
size_t size = b_size(b);
size_t data = b_data(b);
+ if (!data && fin) {
+ /* FIN is notified with an empty STREAM frame. */
+ BUG_ON(!qcs->sd); /* sd must already be attached here */
+ qcs_http_handle_standalone_fin(qcs);
+ return 0;
+ }
+
b_alloc(&htx_buf);
htx = htx_from_buf(&htx_buf);
ret = b_data(&b);
}
- if (ret) {
+ if (ret)
qcs_consume(qcs, ret);
+ if (ret || (!b_data(&b) && fin))
qcs_notify_recv(qcs);
- }
TRACE_LEAVE(QMUX_EV_QCS_RECV, qcc->conn, qcs);
return 0;
return count;
}
+
+/* Utility function which can be used by app layer an empty STREAM frame is
+ * received with FIN bit set for <qcs> stream. It will ensure that HTX EOM is
+ * properly inserted in <qcs> app_buf.
+ */
+void qcs_http_handle_standalone_fin(struct qcs *qcs)
+{
+ struct buffer *appbuf;
+ struct htx *htx = NULL;
+
+ appbuf = qc_get_buf(qcs, &qcs->rx.app_buf);
+ BUG_ON(!appbuf);
+
+ htx = htx_from_buf(appbuf);
+ if (htx_is_empty(htx)) {
+ if (!htx_add_endof(htx, HTX_BLK_EOT)) {
+ ABORT_NOW(); /* cannot happen for empty HTX message. */
+ }
+ }
+ htx->flags |= HTX_FL_EOM;
+ htx_to_buf(htx, appbuf);
+}