When using QUIC on the backend side, transcoding of a large HTTP
response may cause the rxbuf to wrap. This patch introduces buffer
wrapping support for the HTTP/0.9 transcoder. This is similar to what is
already implemented in HTTP/3 layer.
This should be backported up to 3.3.
struct htx_sl *sl;
struct buffer *htx_buf;
const unsigned int flags = HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN;
struct htx_sl *sl;
struct buffer *htx_buf;
const unsigned int flags = HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN;
- size_t to_copy = b_data(b);
+ size_t to_copy = b_contig_data(b, 0);
size_t htx_sent = 0;
uint32_t htx_space;
size_t htx_sent = 0;
uint32_t htx_space;
htx_buf = qcc_get_stream_rxbuf(qcs);
BUG_ON(!htx_buf);
htx_buf = qcc_get_stream_rxbuf(qcs);
BUG_ON(!htx_buf);
- BUG_ON(b_head(b) + to_copy > b_wrap(b)); /* TODO */
-
+ head = b_head(b);
+ retry:
htx_space = htx_free_data_space(htx);
if (!htx_space) {
qcs->flags |= QC_SF_DEM_FULL;
htx_space = htx_free_data_space(htx);
if (!htx_space) {
qcs->flags |= QC_SF_DEM_FULL;
+ if (b_head(b) + to_copy > b_wrap(b)) {
+ size_t contig = b_wrap(b) - head;
+ htx_sent = htx_add_data(htx, ist2(b_head(b), contig));
+ if (htx_sent < contig) {
+ qcs->flags |= QC_SF_DEM_FULL;
+ goto out;
+ }
+
+ to_copy -= contig;
+ head = b_orig(b);
+ goto retry;
+ }
+
htx_sent = htx_add_data(htx, ist2(b_head(b), to_copy));
if (htx_sent < to_copy) {
qcs->flags |= QC_SF_DEM_FULL;
htx_sent = htx_add_data(htx, ist2(b_head(b), to_copy));
if (htx_sent < to_copy) {
qcs->flags |= QC_SF_DEM_FULL;
/* Returns the amount of decoded bytes from <b> or a negative error code. */
static ssize_t hq_interop_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
{
/* Returns the amount of decoded bytes from <b> or a negative error code. */
static ssize_t hq_interop_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
{
- /* hq-interop parser does not support buffer wrapping. */
- BUG_ON(b_data(b) != b_contig_data(b, 0));
-
return !(qcs->qcc->flags & QC_CF_IS_BACK) ?
hq_interop_rcv_buf_req(qcs, b, fin) :
hq_interop_rcv_buf_res(qcs, b, fin);
return !(qcs->qcc->flags & QC_CF_IS_BACK) ?
hq_interop_rcv_buf_req(qcs, b, fin) :
hq_interop_rcv_buf_res(qcs, b, fin);