int qpack_decode_fs(const unsigned char *buf, uint64_t len, struct buffer *tmp,
struct http_hdr *list, int list_size);
-int qpack_decode_enc(struct buffer *buf, void *ctx);
-int qpack_decode_dec(struct buffer *buf, void *ctx);
+int qpack_decode_enc(struct buffer *buf, int fin, void *ctx);
+int qpack_decode_dec(struct buffer *buf, int fin, void *ctx);
#endif /* _HAPROXY_QPACK_DEC_H */
return len;
}
-/* Parse an uni-stream <qcs> from <rxbuf> which does not contains H3 frames.
- * This may be used for QPACK encoder/decoder streams for example.
+/* Parse a buffer <b> for a <qcs> uni-stream which does not contains H3 frames.
+ * This may be used for QPACK encoder/decoder streams for example. <fin> is set
+ * if this is the last frame of the stream.
*
* Returns the number of consumed bytes or a negative error code.
*/
-static ssize_t h3_parse_uni_stream_no_h3(struct qcs *qcs, struct buffer *b)
+static ssize_t h3_parse_uni_stream_no_h3(struct qcs *qcs, struct buffer *b, int fin)
{
struct h3s *h3s = qcs->ctx;
switch (h3s->type) {
case H3S_T_QPACK_DEC:
- if (qpack_decode_dec(b, NULL))
+ if (qpack_decode_dec(b, fin, qcs))
return -1;
break;
case H3S_T_QPACK_ENC:
- if (qpack_decode_enc(b, NULL))
+ if (qpack_decode_enc(b, fin, qcs))
return -1;
break;
case H3S_T_UNKNOWN:
if (quic_stream_is_uni(qcs->id) && (h3s->flags & H3_SF_UNI_NO_H3)) {
/* For non-h3 STREAM, parse it and return immediately. */
- if ((ret = h3_parse_uni_stream_no_h3(qcs, b)) < 0)
+ if ((ret = h3_parse_uni_stream_no_h3(qcs, b, fin)) < 0)
return -1;
total += ret;
#include <haproxy/buf.h>
#include <haproxy/chunk.h>
#include <haproxy/h3.h>
+#include <haproxy/mux_quic.h>
#include <haproxy/qpack-t.h>
#include <haproxy/qpack-dec.h>
#include <haproxy/qpack-tbl.h>
*
* Returns 0 on success else non-zero.
*/
-int qpack_decode_enc(struct buffer *buf, void *ctx)
+int qpack_decode_enc(struct buffer *buf, int fin, void *ctx)
{
+ struct qcs *qcs = ctx;
size_t len;
unsigned char inst;
+ /* RFC 9204 4.2. Encoder and Decoder Streams
+ *
+ * The sender MUST NOT close either of these streams, and the receiver
+ * MUST NOT request that the sender close either of these streams.
+ * Closure of either unidirectional stream type MUST be treated as a
+ * connection error of type H3_CLOSED_CRITICAL_STREAM.
+ */
+ if (fin) {
+ qcc_emit_cc_app(qcs->qcc, H3_CLOSED_CRITICAL_STREAM, 1);
+ return -1;
+ }
+
len = b_data(buf);
qpack_debug_hexdump(stderr, "[QPACK-DEC-ENC] ", b_head(buf), 0, len);
*
* Returns 0 on success else non-zero.
*/
-int qpack_decode_dec(struct buffer *buf, void *ctx)
+int qpack_decode_dec(struct buffer *buf, int fin, void *ctx)
{
+ struct qcs *qcs = ctx;
size_t len;
unsigned char inst;
+ /* RFC 9204 4.2. Encoder and Decoder Streams
+ *
+ * The sender MUST NOT close either of these streams, and the receiver
+ * MUST NOT request that the sender close either of these streams.
+ * Closure of either unidirectional stream type MUST be treated as a
+ * connection error of type H3_CLOSED_CRITICAL_STREAM.
+ */
+ if (fin) {
+ qcc_emit_cc_app(qcs->qcc, H3_CLOSED_CRITICAL_STREAM, 1);
+ return -1;
+ }
+
len = b_data(buf);
qpack_debug_hexdump(stderr, "[QPACK-DEC-DEC] ", b_head(buf), 0, len);