]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
OPTIM: haterm: use chunk builders for generated response headers
authorAleksandar Lazic <al-haproxy@none.at>
Sun, 15 Mar 2026 13:37:57 +0000 (14:37 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 19 Mar 2026 06:42:33 +0000 (07:42 +0100)
hstream_build_http_resp() currently uses snprintf() to build the
status code and the generated X-req/X-rsp header values.

These strings are short and are fully derived from already parsed request
state, so they can be assembled directly in the HAProxy trash buffer using
`chunk_strcat()` and `ultoa_o()`.

This keeps the generated output unchanged while removing the remaining
`snprintf()` calls from the response-building path.

No functional change is expected.

Signed-off-by: Aleksandar Lazic <al-haproxy@none.at>
src/haterm.c

index 98100f83ed9cf4c88d65851c130b4698d5138719..908a471c4facbd7718c8d01d878c25436d9ddaec 100644 (file)
@@ -501,11 +501,14 @@ static int hstream_build_http_resp(struct hstream *hs)
        struct htx *htx;
        unsigned int flags = HTX_SL_F_IS_RESP | HTX_SL_F_XFER_LEN | (!hs->req_chunked ?  HTX_SL_F_CLEN : 0);
        struct htx_sl *sl;
-       char hdrbuf[128];
+       char *end;
 
        TRACE_ENTER(HS_EV_HSTRM_RESP, hs);
 
-       snprintf(hdrbuf, sizeof(hdrbuf), "%d", hs->req_code);
+       chunk_reset(&trash);
+       end = ultoa_o(hs->req_code, trash.area, trash.size);
+       if (!end)
+               goto err;
        buf = hstream_get_buf(hs, &hs->res);
        if (!buf) {
                TRACE_ERROR("could not allocate response buffer", HS_EV_HSTRM_RESP, hs);
@@ -515,7 +518,7 @@ static int hstream_build_http_resp(struct hstream *hs)
        htx = htx_from_buf(buf);
        sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags,
                            !(hs->ka & 4) ? ist("HTTP/1.0") : ist("HTTP/1.1"),
-                           ist(hdrbuf), IST_NULL);
+                           ist2(trash.area, end - trash.area), IST_NULL);
        if (!sl) {
                TRACE_ERROR("could not add HTX start line", HS_EV_HSTRM_RESP, hs);
                goto err;
@@ -550,18 +553,46 @@ static int hstream_build_http_resp(struct hstream *hs)
        }
 
        /* XXX TODO time?  XXX */
-       snprintf(hdrbuf, sizeof(hdrbuf), "time=%ld ms", 0L);
-       if (!htx_add_header(htx, ist("X-req"), ist(hdrbuf))) {
+       chunk_reset(&trash);
+       if (!chunk_strcat(&trash, "time=0 ms") ||
+           !htx_add_header(htx, ist("X-req"), ist2(trash.area, trash.data))) {
                TRACE_ERROR("could not add x-req HTX header", HS_EV_HSTRM_RESP, hs);
            goto err;
        }
 
        /* XXX TODO time? XXX */
-       snprintf(hdrbuf, sizeof(hdrbuf), "id=%s, code=%d, cache=%d,%s size=%lld, time=%d ms (%ld real)",
-                "dummy", hs->req_code, hs->req_cache,
-                        hs->req_chunked ? " chunked," : "",
-                        hs->req_size, 0, 0L);
-       if (!htx_add_header(htx, ist("X-rsp"), ist(hdrbuf))) {
+       chunk_reset(&trash);
+       if (!chunk_strcat(&trash, "id=dummy, code=")) {
+               TRACE_ERROR("could not build x-rsp HTX header", HS_EV_HSTRM_RESP, hs);
+           goto err;
+       }
+       end = ultoa_o(hs->req_code, trash.area + trash.data, trash.size - trash.data);
+       if (!end)
+               goto err;
+       trash.data = end - trash.area;
+       if (!chunk_strcat(&trash, ", cache=")) {
+               TRACE_ERROR("could not build x-rsp HTX header", HS_EV_HSTRM_RESP, hs);
+           goto err;
+       }
+       end = ultoa_o(hs->req_cache, trash.area + trash.data, trash.size - trash.data);
+       if (!end)
+               goto err;
+       trash.data = end - trash.area;
+       if (hs->req_chunked && !chunk_strcat(&trash, ", chunked,")) {
+               TRACE_ERROR("could not build x-rsp HTX header", HS_EV_HSTRM_RESP, hs);
+           goto err;
+       }
+       if (!chunk_strcat(&trash, " size=")) {
+               TRACE_ERROR("could not build x-rsp HTX header", HS_EV_HSTRM_RESP, hs);
+           goto err;
+       }
+       end = ultoa_o(hs->req_size, trash.area + trash.data, trash.size - trash.data);
+       if (!end)
+               goto err;
+       trash.data = end - trash.area;
+
+       if (!chunk_strcat(&trash, ", time=0 ms (0 real)") ||
+           !htx_add_header(htx, ist("X-rsp"), ist2(trash.area, trash.data))) {
                TRACE_ERROR("could not add x-rsp HTX header", HS_EV_HSTRM_RESP, hs);
            goto err;
        }