ssize_t (*rcv_buf)(struct qcs *qcs, struct buffer *b, int fin);
/* Convert HTX to HTTP payload for sending. */
- size_t (*snd_buf)(struct qcs *qcs, struct buffer *b, size_t count);
+ size_t (*snd_buf)(struct qcs *qcs, struct buffer *b, size_t count, char *fin);
/* Negotiate and commit fast-forward data from opposite MUX. */
size_t (*nego_ff)(struct qcs *qcs, size_t count);
* stream instance. Successfully transcoded HTX blocks are removed from input
* buffer.
*
+ * <fin> is used as an output boolean. It will be set if the last blocks of the
+ * HTX message were encoded, which should trigger a FIN STREAM emission.
+ *
* Returns the amount of consumed bytes from <buf>. In case of error,
* connection is flagged and transcoding is interrupted. The returned value is
* unchanged though.
*/
-static size_t h3_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count)
+static size_t h3_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, char *fin)
{
size_t total = 0;
enum htx_blk_type btype;
struct htx_blk *blk;
uint32_t bsize;
int32_t idx;
+ char eom;
int ret = 0;
TRACE_ENTER(H3_EV_STRM_SEND, qcs->qcc->conn, qcs);
+ *fin = 0;
htx = htx_from_buf(buf);
+ /* EOM is saved here, useful if 0-copy is performed with HTX buf. */
+ eom = htx->flags & HTX_FL_EOM;
while (count && !htx_is_empty(htx) && qcc_stream_can_send(qcs) && ret >= 0) {
idx = htx_get_head(htx);
#endif
out:
+ if (eom && htx_is_empty(htx)) {
+ TRACE_USER("transcoding last HTX message", H3_EV_STRM_SEND, qcs->qcc->conn, qcs);
+ *fin = 1;
+ }
htx_to_buf(htx, buf);
TRACE_LEAVE(H3_EV_STRM_SEND, qcs->qcc->conn, qcs);
/* Returns the amount of consumed bytes from <buf>. */
static size_t hq_interop_snd_buf(struct qcs *qcs, struct buffer *buf,
- size_t count)
+ size_t count, char *fin)
{
enum htx_blk_type btype;
struct htx *htx = NULL;
size_t total = 0;
int err;
+ *fin = 0;
htx = htx_from_buf(buf);
while (count && !htx_is_empty(htx) && qcc_stream_can_send(qcs)) {
}
end:
+ if (htx->flags & HTX_FL_EOM && htx_is_empty(htx))
+ *fin = 1;
htx_to_buf(htx, buf);
return total;
{
struct htx *htx;
size_t ret;
- int eom = 0;
TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
if (htx->extra && htx->extra == HTX_UNKOWN_PAYLOAD_LENGTH)
qcs->flags |= QC_SF_UNKNOWN_PL_LENGTH;
- eom = (htx->flags & HTX_FL_EOM);
- ret = qcs->qcc->app_ops->snd_buf(qcs, buf, count);
- *fin = (eom && !b_data(buf));
+ ret = qcs->qcc->app_ops->snd_buf(qcs, buf, count, fin);
TRACE_LEAVE(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);