BUG/MEDIUM: httpclient: Fix loop consuming HTX blocks from the response channel
When the HTTP client consumes the response, it loops on the HTX message to copy blocks content and it removes blocks by calling htx_remove_blk(). But this function removes a block and returns the next one in the HTX message. The result must be used instead of using htx_get_next(). It is especially important because the block used in htx_get_next() loop was removed. It only works because the message is not defragmented during the loop. In addition, the loop on the response was simplified to iter on blocks instead of positions. This patch must be backported to 2.5.
This commit is contained in:
parent
a6c4a48341
commit
534645d6c0
@ -652,12 +652,10 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
|
||||
struct htx_blk *blk = NULL;
|
||||
struct htx *htx;
|
||||
struct htx_sl *sl = NULL;
|
||||
int32_t pos;
|
||||
uint32_t hdr_num;
|
||||
uint32_t sz;
|
||||
int ret;
|
||||
|
||||
|
||||
while (1) {
|
||||
|
||||
/* required to stop */
|
||||
@ -797,33 +795,25 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
|
||||
goto more;
|
||||
|
||||
hdr_num = 0;
|
||||
|
||||
for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
|
||||
struct htx_blk *blk = htx_get_blk(htx, pos);
|
||||
blk = htx_get_head_blk(htx);
|
||||
while (blk) {
|
||||
enum htx_blk_type type = htx_get_blk_type(blk);
|
||||
uint32_t sz = htx_get_blksz(blk);
|
||||
|
||||
if (type == HTX_BLK_UNUSED) {
|
||||
c_rew(res, sz);
|
||||
htx_remove_blk(htx, blk);
|
||||
}
|
||||
c_rew(res, sz);
|
||||
blk = htx_remove_blk(htx, blk);
|
||||
|
||||
if (type == HTX_BLK_HDR) {
|
||||
if (type == HTX_BLK_UNUSED)
|
||||
continue;
|
||||
else if (type == HTX_BLK_HDR) {
|
||||
hdrs[hdr_num].n = istdup(htx_get_blk_name(htx, blk));
|
||||
hdrs[hdr_num].v = istdup(htx_get_blk_value(htx, blk));
|
||||
if (!isttest(hdrs[hdr_num].v) || !isttest(hdrs[hdr_num].n))
|
||||
goto end;
|
||||
c_rew(res, sz);
|
||||
htx_remove_blk(htx, blk);
|
||||
hdr_num++;
|
||||
}
|
||||
|
||||
/* create a NULL end of array and leave the loop */
|
||||
if (type == HTX_BLK_EOH) {
|
||||
else if (type == HTX_BLK_EOH) {
|
||||
/* create a NULL end of array and leave the loop */
|
||||
hdrs[hdr_num].n = IST_NULL;
|
||||
hdrs[hdr_num].v = IST_NULL;
|
||||
c_rew(res, sz);
|
||||
htx_remove_blk(htx, blk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -869,8 +859,8 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
|
||||
goto process_data;
|
||||
|
||||
/* decapsule the htx data to raw data */
|
||||
for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
|
||||
struct htx_blk *blk = htx_get_blk(htx, pos);
|
||||
blk = htx_get_head_blk(htx);
|
||||
while (blk) {
|
||||
enum htx_blk_type type = htx_get_blk_type(blk);
|
||||
size_t count = co_data(res);
|
||||
uint32_t blksz = htx_get_blksz(blk);
|
||||
@ -892,7 +882,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
|
||||
c_rew(res, vlen);
|
||||
|
||||
if (vlen == blksz)
|
||||
htx_remove_blk(htx, blk);
|
||||
blk = htx_remove_blk(htx, blk);
|
||||
else
|
||||
htx_cut_data_blk(htx, blk, vlen);
|
||||
|
||||
@ -909,7 +899,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
|
||||
|
||||
/* remove any block which is not a data block */
|
||||
c_rew(res, blksz);
|
||||
htx_remove_blk(htx, blk);
|
||||
blk = htx_remove_blk(htx, blk);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user