Previous patches have fixes interim response encoding via
h3_resp_headers_send(). However, it is still necessary to adjust h3
layer state-machine so that several successive HTTP responses are
accepted for a single stream.
Prior to this, QMUX was responsible to decree that the final HTX message
was encoded so that FIN stream can be emitted. However, with interim
response, MUX is in fact unable to properly determine this. As such,
this is the responsibility of the application protocol layer. To reflect
this, app_ops snd_buf callback is modified so that a new output argument
<fin> is added to it.
Note that for now this commit does not bring any functional change.
However, it will be necessary for the following patch. As such, it
should be backported prior to it to every versions as necessary.
(cherry picked from commit
f349df44b4e21d8bf9b575a0aa869056a2ebaa58)
[ad: fix context due to mising comment on h3_snd_buf]
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit
96896b408d0fb0b45e5ebf59cc74a5a5c2b03dc9)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit
ea3cf3af3554c31213e0b72e99e3b9bf3bd4803e)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
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);
return -1;
}
-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);
}
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);