BUG/MINOR: http-client: Don't forget to commit changes on HTX message

In the http-client I/O handler, HTX request and response are loaded from the
channels buffer. Some changes are preformed in these messages. So, we must
take care to commit changes into the underlying buffer by calling
htx_to_buf().

It is especially important when the HTX message becoms empty to be able to
quickly release the buffer.

This patch should be backported as far as 2.6.
This commit is contained in:
Christopher Faulet 2023-08-04 14:28:23 +02:00
parent b34d353968
commit e827b45821

View File

@ -760,12 +760,11 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
/* call the request callback */ /* call the request callback */
hc->ops.req_payload(hc); hc->ops.req_payload(hc);
hc_htx = htx_from_buf(&hc->req.buf); hc_htx = htxbuf(&hc->req.buf);
htx = htx_from_buf(&req->buf);
if (htx_is_empty(hc_htx)) if (htx_is_empty(hc_htx))
goto out; goto out;
htx = htx_from_buf(&req->buf);
if (htx_is_empty(htx)) { if (htx_is_empty(htx)) {
size_t data = hc_htx->data; size_t data = hc_htx->data;
@ -795,9 +794,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
b_free(&hc->req.buf); b_free(&hc->req.buf);
} }
htx = htx_from_buf(&req->buf); htx = htxbuf(&req->buf);
if (!htx)
goto out;
/* if the request contains the HTX_FL_EOM, we finished the request part. */ /* if the request contains the HTX_FL_EOM, we finished the request part. */
if (htx->flags & HTX_FL_EOM) if (htx->flags & HTX_FL_EOM)
@ -815,7 +812,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
if (!co_data(res)) if (!co_data(res))
goto out; goto out;
htx = htxbuf(&res->buf); htx = htxbuf(&res->buf);
if (!htx) if (htx_is_empty(htx))
goto out; goto out;
blk = htx_get_head_blk(htx); blk = htx_get_head_blk(htx);
if (blk && (htx_get_blk_type(blk) == HTX_BLK_RES_SL)) if (blk && (htx_get_blk_type(blk) == HTX_BLK_RES_SL))
@ -834,12 +831,15 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
if (hc->ops.res_stline) if (hc->ops.res_stline)
hc->ops.res_stline(hc); hc->ops.res_stline(hc);
htx_to_buf(htx, &res->buf);
/* if there is no HTX data anymore and the EOM flag is /* if there is no HTX data anymore and the EOM flag is
* set, leave (no body) */ * set, leave (no body) */
if (htx_is_empty(htx) && htx->flags & HTX_FL_EOM) if (htx_is_empty(htx) && htx->flags & HTX_FL_EOM)
appctx->st0 = HTTPCLIENT_S_RES_END; appctx->st0 = HTTPCLIENT_S_RES_END;
else else
appctx->st0 = HTTPCLIENT_S_RES_HDR; appctx->st0 = HTTPCLIENT_S_RES_HDR;
break; break;
case HTTPCLIENT_S_RES_HDR: case HTTPCLIENT_S_RES_HDR:
@ -854,7 +854,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
if (!co_data(res)) if (!co_data(res))
goto out; goto out;
htx = htxbuf(&res->buf); htx = htxbuf(&res->buf);
if (!htx) if (htx_is_empty(htx))
goto out; goto out;
hdr_num = 0; hdr_num = 0;
@ -879,6 +879,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
} }
blk = htx_remove_blk(htx, blk); blk = htx_remove_blk(htx, blk);
} }
htx_to_buf(htx, &res->buf);
if (hdr_num) { if (hdr_num) {
/* alloc and copy the headers in the httpclient struct */ /* alloc and copy the headers in the httpclient struct */
@ -911,7 +912,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
goto out; goto out;
htx = htxbuf(&res->buf); htx = htxbuf(&res->buf);
if (!htx || htx_is_empty(htx)) if (htx_is_empty(htx))
goto out; goto out;
if (!b_alloc(&hc->res.buf)) if (!b_alloc(&hc->res.buf))
@ -934,8 +935,10 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
vlen = MIN(count, blksz); vlen = MIN(count, blksz);
vlen = MIN(vlen, room); vlen = MIN(vlen, room);
if (vlen == 0) if (vlen == 0) {
htx_to_buf(htx, &res->buf);
goto process_data; goto process_data;
}
if (type == HTX_BLK_DATA) { if (type == HTX_BLK_DATA) {
struct ist v = htx_get_blk_value(htx, blk); struct ist v = htx_get_blk_value(htx, blk);
@ -953,11 +956,15 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
hc->ops.res_payload(hc); hc->ops.res_payload(hc);
/* cannot copy everything, need to process */ /* cannot copy everything, need to process */
if (vlen != blksz) if (vlen != blksz) {
htx_to_buf(htx, &res->buf);
goto process_data; goto process_data;
}
} else { } else {
if (vlen != blksz) if (vlen != blksz) {
htx_to_buf(htx, &res->buf);
goto process_data; goto process_data;
}
/* remove any block which is not a data block */ /* remove any block which is not a data block */
c_rew(res, blksz); c_rew(res, blksz);
@ -965,6 +972,8 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
} }
} }
htx_to_buf(htx, &res->buf);
/* if not finished, should be called again */ /* if not finished, should be called again */
if (!(htx_is_empty(htx) && (htx->flags & HTX_FL_EOM))) if (!(htx_is_empty(htx) && (htx->flags & HTX_FL_EOM)))
goto out; goto out;