]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: http-client: Don't forget to commit changes on HTX message
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 4 Aug 2023 12:28:23 +0000 (14:28 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 4 Aug 2023 12:32:48 +0000 (14:32 +0200)
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.

src/http_client.c

index 2c33c85a27e51a57f9824d5b77cb25dabb9b8353..46cdbdb5d58afbeb0359581e5e6701619af4d3e5 100644 (file)
@@ -760,12 +760,11 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
                                                /* call the request callback */
                                                hc->ops.req_payload(hc);
 
-                                               hc_htx = htx_from_buf(&hc->req.buf);
-                                               htx = htx_from_buf(&req->buf);
-
+                                               hc_htx = htxbuf(&hc->req.buf);
                                                if (htx_is_empty(hc_htx))
                                                        goto out;
 
+                                               htx = htx_from_buf(&req->buf);
                                                if (htx_is_empty(htx)) {
                                                        size_t data = hc_htx->data;
 
@@ -795,9 +794,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
                                                        b_free(&hc->req.buf);
                                        }
 
-                                       htx = htx_from_buf(&req->buf);
-                                       if (!htx)
-                                               goto out;
+                                       htx = htxbuf(&req->buf);
 
                                        /* if the request contains the HTX_FL_EOM, we finished the request part. */
                                        if (htx->flags & HTX_FL_EOM)
@@ -815,7 +812,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
                                if (!co_data(res))
                                        goto out;
                                htx = htxbuf(&res->buf);
-                               if (!htx)
+                               if (htx_is_empty(htx))
                                        goto out;
                                blk = htx_get_head_blk(htx);
                                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)
                                        hc->ops.res_stline(hc);
 
+                               htx_to_buf(htx, &res->buf);
+
                                /* if there is no HTX data anymore and the EOM flag is
                                 * set, leave (no body) */
                                if (htx_is_empty(htx) && htx->flags & HTX_FL_EOM)
                                        appctx->st0 = HTTPCLIENT_S_RES_END;
                                else
                                        appctx->st0 = HTTPCLIENT_S_RES_HDR;
+
                                break;
 
                        case HTTPCLIENT_S_RES_HDR:
@@ -854,7 +854,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
                                        if (!co_data(res))
                                                goto out;
                                        htx = htxbuf(&res->buf);
-                                       if (!htx)
+                                       if (htx_is_empty(htx))
                                                goto out;
 
                                        hdr_num = 0;
@@ -879,6 +879,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
                                                }
                                                blk = htx_remove_blk(htx, blk);
                                        }
+                                       htx_to_buf(htx, &res->buf);
 
                                        if (hdr_num) {
                                                /* alloc and copy the headers in the httpclient struct */
@@ -911,7 +912,7 @@ static void httpclient_applet_io_handler(struct appctx *appctx)
                                        goto out;
 
                                htx = htxbuf(&res->buf);
-                               if (!htx || htx_is_empty(htx))
+                               if (htx_is_empty(htx))
                                        goto out;
 
                                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(vlen, room);
 
-                                       if (vlen == 0)
+                                       if (vlen == 0) {
+                                               htx_to_buf(htx, &res->buf);
                                                goto process_data;
+                                       }
 
                                        if (type == HTX_BLK_DATA) {
                                                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);
 
                                                /* cannot copy everything, need to process */
-                                               if (vlen != blksz)
+                                               if (vlen != blksz) {
+                                                       htx_to_buf(htx, &res->buf);
                                                        goto process_data;
+                                               }
                                        } else {
-                                               if (vlen != blksz)
+                                               if (vlen != blksz) {
+                                                       htx_to_buf(htx, &res->buf);
                                                        goto process_data;
+                                               }
 
                                                /* remove any block which is not a data block */
                                                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 (!(htx_is_empty(htx) && (htx->flags & HTX_FL_EOM)))
                                        goto out;