size_t qcs_http_rcv_buf(struct qcs *qcs, struct buffer *buf, size_t count,
char *fin);
+
+int qcs_http_handle_standalone_fin(struct qcs *qcs);
+
size_t qcs_http_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count,
char *fin);
}
if (!b_data(b) && fin && quic_stream_is_bidi(qcs->id)) {
- struct buffer *appbuf;
- struct htx *htx;
- int eom;
-
TRACE_PROTO("received FIN without data", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
- if (!(appbuf = qcc_get_stream_rxbuf(qcs))) {
- TRACE_ERROR("data buffer alloc failure", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
- qcc_set_error(qcs->qcc, H3_ERR_INTERNAL_ERROR, 1);
- goto err;
- }
-
- htx = htx_from_buf(appbuf);
- eom = htx_set_eom(htx);
- htx_to_buf(htx, appbuf);
- if (!eom) {
+ if (qcs_http_handle_standalone_fin(qcs)) {
TRACE_ERROR("cannot set EOM", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
qcc_set_error(qcs->qcc, H3_ERR_INTERNAL_ERROR, 1);
goto err;
/* hq-interop parser does not support buffer wrapping. */
BUG_ON(b_data(b) != b_contig_data(b, 0));
+ if (!b_data(b) && fin && quic_stream_is_bidi(qcs->id)) {
+ if (qcs_http_handle_standalone_fin(qcs))
+ return -1;
+ return 0;
+ }
+
/* skip method */
while (data && HTTP_IS_TOKEN(*ptr)) {
ptr++;
return ret;
}
+int qcs_http_handle_standalone_fin(struct qcs *qcs)
+{
+ struct buffer *appbuf;
+ struct htx *htx;
+ int eom;
+
+ if (!(appbuf = qcc_get_stream_rxbuf(qcs)))
+ goto err;
+
+ htx = htx_from_buf(appbuf);
+ eom = htx_set_eom(htx);
+ htx_to_buf(htx, appbuf);
+ if (!eom)
+ goto err;
+
+ return 0;
+
+ err:
+ return -1;
+}
+
/* QUIC MUX snd_buf operation using HTX data. HTX data will be transferred from
* <buf> to <qcs> stream buffer. Input buffer is expected to be of length
* <count>. <fin> will be set to signal the last data to send for this stream.