diff --git a/include/haproxy/stconn-t.h b/include/haproxy/stconn-t.h index 223956058..f55472398 100644 --- a/include/haproxy/stconn-t.h +++ b/include/haproxy/stconn-t.h @@ -44,6 +44,7 @@ enum iobuf_flags { enum nego_ff_flags { NEGO_FF_FL_NONE = 0x00000000, /* For initialization purposes */ NEGO_FF_FL_MAY_SPLICE = 0x00000001, /* Consumer may choose to use kernel splicing if it supports it */ + NEGO_FF_FL_EXACT_SIZE = 0x00000002, /* Size passed for the nego is the expected exact size to forwarded */ }; struct iobuf { diff --git a/src/applet.c b/src/applet.c index ba3af6a5f..7b302f976 100644 --- a/src/applet.c +++ b/src/applet.c @@ -619,8 +619,10 @@ int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags) sdo = container_of(peer, struct sedesc, xref); xref_unlock(&appctx->sedesc->xref, peer); - if (appctx->to_forward && count > appctx->to_forward) + if (appctx->to_forward && count > appctx->to_forward) { count = appctx->to_forward; + nego_flags |= NEGO_FF_FL_EXACT_SIZE; + } len = se_nego_ff(sdo, &BUF_NULL, count, nego_flags); if (sdo->iobuf.flags & IOBUF_FL_NO_FF) { diff --git a/src/mux_h1.c b/src/mux_h1.c index 0db232934..a08d08520 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -4470,9 +4470,16 @@ static size_t h1_nego_ff(struct stconn *sc, struct buffer *input, size_t count, } else { BUG_ON(h1m->state != H1_MSG_CHUNK_CRLF && h1m->state != H1_MSG_CHUNK_SIZE); - if (!h1_make_chunk(h1s, h1m, count)) + if (flags & NEGO_FF_FL_EXACT_SIZE) { + if (!h1_make_chunk(h1s, h1m, count)) + goto out; + h1m->curr_len = count; + } + else { + /* XXX: Unsupported for now but will be added soon ! */ + h1s->sd->iobuf.flags |= IOBUF_FL_NO_FF; goto out; - h1m->curr_len = count; + } } } @@ -4655,8 +4662,10 @@ static int h1_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags) retry: ret = 0; - if (h1m->state == H1_MSG_DATA && (h1m->flags & (H1_MF_CHNK|H1_MF_CLEN)) && count > h1m->curr_len) + if (h1m->state == H1_MSG_DATA && (h1m->flags & (H1_MF_CHNK|H1_MF_CLEN)) && count > h1m->curr_len) { + flags |= NEGO_FF_FL_EXACT_SIZE; count = h1m->curr_len; + } if (h1c->conn->xprt->rcv_pipe && !!(flags & CO_RFL_MAY_SPLICE) && !(sdo->iobuf.flags & IOBUF_FL_NO_SPLICING)) nego_flags |= NEGO_FF_FL_MAY_SPLICE;