struct h1s *h1s = __sc_mux_strm(sc);
struct h1c *h1c = h1s->h1c;
struct h1m *h1m = (!(h1c->flags & H1C_F_IS_BACK) ? &h1s->res : &h1s->req);
- size_t ret = 0;
+ size_t sz, offset = 0, ret = 0;
TRACE_ENTER(H1_EV_STRM_SEND, h1c->conn, h1s, 0, (size_t[]){count});
h1m->curr_len = count;
}
else {
- /* XXX: Unsupported for now but will be added soon ! */
- h1s->sd->iobuf.flags |= IOBUF_FL_NO_FF;
- goto out;
+ /* The producer does not know the chunk size, thus this will be emitted at the
+ * end, in done_ff(). So splicing cannot be used (see TODO below).
+ * We will reserve 12 bytes to handle at most 4Go chunk with all CRLFs !
+ * (<8-bytes SIZE><CRLF><CHUNK-DATA><CRLF>)
+ */
+ if (count > MAX_RANGE(unsigned int))
+ count = MAX_RANGE(unsigned int);
+ offset = 12;
+ /* Add 2 more bytes to finish the previous chunk */
+ if (h1m->state == H1_MSG_CHUNK_CRLF)
+ offset += 2;
+ goto no_splicing;
}
}
}
TRACE_DEVEL("Unable to allocate pipe for splicing, fallback to buffer", H1_EV_STRM_SEND, h1c->conn, h1s);
}
+ no_splicing:
if (!h1_get_buf(h1c, &h1c->obuf)) {
h1c->flags |= H1C_F_OUT_ALLOC;
TRACE_STATE("waiting for opposite h1c obuf allocation", H1_EV_STRM_SEND|H1_EV_H1S_BLK, h1c->conn, h1s);
if (b_space_wraps(&h1c->obuf))
b_slow_realign(&h1c->obuf, trash.area, b_data(&h1c->obuf));
- h1s->sd->iobuf.buf = &h1c->obuf;
- h1s->sd->iobuf.offset = 0;
- h1s->sd->iobuf.data = 0;
/* Cannot forward more than available room in output buffer */
- if (count > b_room(&h1c->obuf))
- count = b_room(&h1c->obuf);
+ sz = b_contig_space(&h1c->obuf) - offset;
+ if (count > sz)
+ count = sz;
if (!count) {
h1c->flags |= H1C_F_OUT_FULL;
goto out;
}
+ h1s->sd->iobuf.buf = &h1c->obuf;
+ h1s->sd->iobuf.offset = offset;
+ h1s->sd->iobuf.data = 0;
+
/* forward remaining input data */
if (b_data(input)) {
size_t xfer = count;
if (b_room(&h1c->obuf) == sd->iobuf.offset)
h1c->flags |= H1C_F_OUT_FULL;
+ if (sd->iobuf.offset) {
+ b_add(&h1c->obuf, sd->iobuf.offset);
+ b_del(&h1c->obuf, sd->iobuf.offset);
+ h1_prepend_chunk_size(&h1c->obuf, sd->iobuf.data, sd->iobuf.offset - ((h1m->state == H1_MSG_CHUNK_CRLF) ? 4 : 2));
+ h1_append_chunk_crlf(&h1c->obuf);
+ if (h1m->state == H1_MSG_CHUNK_CRLF)
+ h1_prepend_chunk_crlf(&h1c->obuf);
+ h1m->state = H1_MSG_CHUNK_SIZE;
+ }
+
total = sd->iobuf.data;
sd->iobuf.buf = NULL;
sd->iobuf.offset = 0;