From dd92232012d6184bbb76a7f419cdf4a434822229 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Fri, 24 Apr 2026 11:35:08 +0200 Subject: [PATCH] MEDIUM: http-htx: Make authority update optional when adding a header This patch is similar to the previous one but for header addtion. It is now possible to skip the authority updated. An extra argument was added to http_add_header() function for this purpose. --- addons/ot/src/http.c | 2 +- addons/otel/src/http.c | 2 +- include/haproxy/http_htx.h | 2 +- src/cache.c | 2 +- src/fcgi-app.c | 6 +++--- src/flt_http_comp.c | 6 +++--- src/hlua.c | 6 +++--- src/http_act.c | 6 +++--- src/http_ana.c | 8 ++++---- src/http_ext.c | 10 +++++----- src/http_htx.c | 12 +++++++----- 11 files changed, 32 insertions(+), 30 deletions(-) diff --git a/addons/ot/src/http.c b/addons/ot/src/http.c index 0a3572af4..5e8ed0705 100644 --- a/addons/ot/src/http.c +++ b/addons/ot/src/http.c @@ -261,7 +261,7 @@ int flt_ot_http_header_set(struct channel *chn, const char *prefix, const char * if (value == NULL) { /* Do nothing. */ } - else if (http_add_header(htx, ist_name, ist(value)) == 1) { + else if (http_add_header(htx, ist_name, ist(value), 1) == 1) { retval = 0; FLT_OT_DBG(3, "HTTP header '%s: %s' added", ist_name.ptr, value); diff --git a/addons/otel/src/http.c b/addons/otel/src/http.c index 48962ad48..511747c80 100644 --- a/addons/otel/src/http.c +++ b/addons/otel/src/http.c @@ -268,7 +268,7 @@ int flt_otel_http_header_set(struct channel *chn, const char *prefix, const char if (value == NULL) { retval = 0; } - else if (http_add_header(htx, ist_name, ist(value)) == 1) { + else if (http_add_header(htx, ist_name, ist(value), 1) == 1) { retval = 0; OTELC_DBG(DEBUG, "HTTP header '%s: %s' added", ist_name.ptr, value); diff --git a/include/haproxy/http_htx.h b/include/haproxy/http_htx.h index 7259d29d7..6a5b91e1a 100644 --- a/include/haproxy/http_htx.h +++ b/include/haproxy/http_htx.h @@ -42,7 +42,7 @@ int http_find_pfx_header(const struct htx *htx, const struct ist prefix, struct int http_find_sfx_header(const struct htx *htx, const struct ist suffix, struct http_hdr_ctx *ctx, int full); int http_find_sub_header(const struct htx *htx, const struct ist sub, struct http_hdr_ctx *ctx, int full); int http_match_header(const struct htx *htx, const struct my_regex *re, struct http_hdr_ctx *ctx, int full); -int http_add_header(struct htx *htx, const struct ist n, const struct ist v); +int http_add_header(struct htx *htx, const struct ist n, const struct ist v, int update_authority); int http_replace_stline(struct htx *htx, const struct ist p1, const struct ist p2, const struct ist p3); int http_replace_req_meth(struct htx *htx, const struct ist meth); int http_replace_req_uri(struct htx *htx, const struct ist uri); diff --git a/src/cache.c b/src/cache.c index 58ecd620b..9bed02004 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1738,7 +1738,7 @@ static int htx_cache_add_age_hdr(struct appctx *appctx, struct htx *htx) age = CACHE_ENTRY_MAX_AGE; end = ultoa_o(age, b_head(&trash), b_size(&trash)); b_set_data(&trash, end - b_head(&trash)); - if (!http_add_header(htx, ist("Age"), ist2(b_head(&trash), b_data(&trash)))) + if (!http_add_header(htx, ist("Age"), ist2(b_head(&trash), b_data(&trash)), 0)) return 0; return 1; } diff --git a/src/fcgi-app.c b/src/fcgi-app.c index eafbe28ab..58b257e30 100644 --- a/src/fcgi-app.c +++ b/src/fcgi-app.c @@ -331,7 +331,7 @@ static int fcgi_flt_http_headers(struct stream *s, struct filter *filter, struct get_gmtime(date.tv_sec, &tm); trash.data = strftime(trash.area, trash.size, "%a, %d %b %Y %T %Z", &tm); if (trash.data) - http_add_header(htx, ist("date"), ist2(trash.area, trash.data)); + http_add_header(htx, ist("date"), ist2(trash.area, trash.data), 0); } /* Add the header "Content-Length:" if possible */ @@ -352,7 +352,7 @@ static int fcgi_flt_http_headers(struct stream *s, struct filter *filter, struct len += htx_get_blksz(blk); } end = ultoa_o(len, trash.area, trash.size); - if (http_add_header(htx, ist("content-length"), ist2(trash.area, end-trash.area))) { + if (http_add_header(htx, ist("content-length"), ist2(trash.area, end-trash.area), 0)) { sl->flags |= HTX_SL_F_CLEN; msg->flags |= HTTP_MSGF_CNT_LEN; } @@ -424,7 +424,7 @@ static int fcgi_flt_http_headers(struct stream *s, struct filter *filter, struct pool_free(pool_head_fcgi_param_rule, param_rule); continue; } - if (!http_add_header(htx, param_rule->name, ist2(value->area, value->data))) + if (!http_add_header(htx, param_rule->name, ist2(value->area, value->data), 1)) goto rewrite_err; pool_free(pool_head_fcgi_param_rule, param_rule); } diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c index bbcb083ff..8de0305a0 100644 --- a/src/flt_http_comp.c +++ b/src/flt_http_comp.c @@ -453,7 +453,7 @@ set_compression_header(struct comp_state *st, struct stream *s, struct http_msg /* add "Transfer-Encoding: chunked" header */ if (!(msg->flags & HTTP_MSGF_TE_CHNK)) { - if (!http_add_header(htx, ist("Transfer-Encoding"), ist("chunked"))) + if (!http_add_header(htx, ist("Transfer-Encoding"), ist("chunked"), 0)) goto error; msg->flags |= HTTP_MSGF_TE_CHNK; sl->flags |= (HTX_SL_F_XFER_ENC|HTX_SL_F_CHNK); @@ -494,7 +494,7 @@ set_compression_header(struct comp_state *st, struct stream *s, struct http_msg if (ctx.blk == NULL) { if (last_vary.blk == NULL) { /* No Vary header found at all. Add our header */ - if (!http_add_header(htx, ist("Vary"), ist("Accept-Encoding"))) + if (!http_add_header(htx, ist("Vary"), ist("Accept-Encoding"), 0)) goto error; } else { @@ -515,7 +515,7 @@ set_compression_header(struct comp_state *st, struct stream *s, struct http_msg if (comp_algo->cfg_name_len != 8 || memcmp(comp_algo->cfg_name, "identity", 8) != 0) { struct ist v = ist2(comp_algo->ua_name, comp_algo->ua_name_len); - if (!http_add_header(htx, ist("Content-Encoding"), v)) + if (!http_add_header(htx, ist("Content-Encoding"), v, 0)) goto error; } diff --git a/src/hlua.c b/src/hlua.c index 92a15a97d..97c290ec5 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -6711,7 +6711,7 @@ __LJMP static inline int hlua_http_add_hdr(lua_State *L, struct http_msg *msg) struct htx *htx = htxbuf(&msg->chn->buf); lua_pushboolean(L, http_add_header(htx, ist2(name, name_len), - ist2(value, value_len))); + ist2(value, value_len), 1)); return 0; } @@ -7193,7 +7193,7 @@ __LJMP static int hlua_http_msg_set_body_len(lua_State *L) goto success; /* add "Transfer-Encoding: chunked" header */ - if (!http_add_header(htx, ist("Transfer-Encoding"), ist("chunked"))) + if (!http_add_header(htx, ist("Transfer-Encoding"), ist("chunked"), 0)) goto failure; msg->flags |= (HTTP_MSGF_VER_11|HTTP_MSGF_XFER_LEN|HTTP_MSGF_TE_CHNK); sl->flags |= (HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN|HTX_SL_F_XFER_ENC|HTX_SL_F_CHNK); @@ -7225,7 +7225,7 @@ __LJMP static int hlua_http_msg_set_body_len(lua_State *L) } /* Now add Content-Length header */ - if (!http_add_header(htx, ist("Content-Length"), ist(clen))) + if (!http_add_header(htx, ist("Content-Length"), ist(clen), 0)) goto failure; msg->flags |= (HTTP_MSGF_VER_11|HTTP_MSGF_XFER_LEN|HTTP_MSGF_CNT_LEN); sl->flags |= (HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN|HTX_SL_F_CLEN); diff --git a/src/http_act.c b/src/http_act.c index b93b8419b..2dcbe89d2 100644 --- a/src/http_act.c +++ b/src/http_act.c @@ -1282,7 +1282,7 @@ static enum act_return http_action_auth(struct act_rule *rule, struct proxy *px, http_remove_header(htx, &ctx); /* Now a the right XXX-Authenticate header */ - if (!http_add_header(htx, hdr, ist2(b_orig(&trash), b_data(&trash)))) + if (!http_add_header(htx, hdr, ist2(b_orig(&trash), b_data(&trash)), 0)) goto fail; /* Finally forward the reply */ @@ -1450,7 +1450,7 @@ static enum act_return http_action_set_header(struct act_rule *rule, struct prox } /* Now add header */ - if (!http_add_header(htx, n, v)) + if (!http_add_header(htx, n, v, 1)) goto fail_rewrite; leave: @@ -1538,7 +1538,7 @@ static enum act_return http_action_set_headers_bin(struct act_rule *rule, struct } /* Now add header */ - if (!http_add_header(htx, n, v)) + if (!http_add_header(htx, n, v, 1)) goto fail_rewrite; } diff --git a/src/http_ana.c b/src/http_ana.c index f0a21554a..0201253b1 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -460,7 +460,7 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s ctx.blk = NULL; if (!http_find_header(htx, ist("Early-Data"), &ctx, 0)) { - if (unlikely(!http_add_header(htx, ist("Early-Data"), ist("1")))) + if (unlikely(!http_add_header(htx, ist("Early-Data"), ist("1"), 0))) goto return_fail_rewrite; } } @@ -705,7 +705,7 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit) /* send unique ID if a "unique-id-header" is defined */ if (isttest(sess->fe->header_unique_id) && - unlikely(!http_add_header(htx, sess->fe->header_unique_id, unique_id))) + unlikely(!http_add_header(htx, sess->fe->header_unique_id, unique_id, 1))) goto return_fail_rewrite; } @@ -1950,7 +1950,7 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s if (s->be->cookie_attrs) chunk_appendf(&trash, "; %s", s->be->cookie_attrs); - if (unlikely(!http_add_header(htx, ist("Set-Cookie"), ist2(trash.area, trash.data)))) + if (unlikely(!http_add_header(htx, ist("Set-Cookie"), ist2(trash.area, trash.data), 0))) goto return_fail_rewrite; txn->flags &= ~TX_SCK_MASK; @@ -1969,7 +1969,7 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s txn->flags &= ~TX_CACHEABLE & ~TX_CACHE_COOK; - if (unlikely(!http_add_header(htx, ist("Cache-control"), ist("private")))) + if (unlikely(!http_add_header(htx, ist("Cache-control"), ist("private"), 0))) goto return_fail_rewrite; } } diff --git a/src/http_ext.c b/src/http_ext.c index 32399bfdf..a5e862d30 100644 --- a/src/http_ext.c +++ b/src/http_ext.c @@ -769,7 +769,7 @@ int http_handle_7239_header(struct stream *s, struct channel *req) return 0; /* htx error */ } else { - if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data)))) + if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data), 0))) return 0; /* htx error */ } } @@ -823,7 +823,7 @@ int http_handle_xff_header(struct stream *s, struct channel *req) * on the frontend's header name. */ chunk_printf(&trash, "%d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]); - if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data)))) + if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data), 0))) return 0; } } @@ -845,7 +845,7 @@ int http_handle_xff_header(struct stream *s, struct channel *req) * on the frontend's header name. */ chunk_printf(&trash, "%s", pn); - if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data)))) + if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data), 0))) return 0; } } @@ -892,7 +892,7 @@ int http_handle_xot_header(struct stream *s, struct channel *req) * on the frontend's header name. */ chunk_printf(&trash, "%d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]); - if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data)))) + if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data), 0))) return 0; } } @@ -914,7 +914,7 @@ int http_handle_xot_header(struct stream *s, struct channel *req) * on the frontend's header name. */ chunk_printf(&trash, "%s", pn); - if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data)))) + if (unlikely(!http_add_header(htx, hdr, ist2(trash.area, trash.data), 0))) return 0; } } diff --git a/src/http_htx.c b/src/http_htx.c index aced3f5e4..a0f7fc318 100644 --- a/src/http_htx.c +++ b/src/http_htx.c @@ -283,7 +283,7 @@ int http_match_header(const struct htx *htx, const struct my_regex *re, struct h /* Adds a header block int the HTX message , just before the EOH block. It * returns 1 on success, otherwise it returns 0. */ -int http_add_header(struct htx *htx, const struct ist n, const struct ist v) +int http_add_header(struct htx *htx, const struct ist n, const struct ist v, int update_authority) { struct htx_blk *blk; struct htx_sl *sl; @@ -318,10 +318,12 @@ int http_add_header(struct htx *htx, const struct ist n, const struct ist v) } end: - sl = http_get_stline(htx); - if (sl && (sl->flags & HTX_SL_F_HAS_AUTHORITY) && isteqi(n, ist("host"))) { - if (!http_update_authority(htx, sl, v)) - goto fail; + if (update_authority) { + sl = http_get_stline(htx); + if (sl && (sl->flags & HTX_SL_F_HAS_AUTHORITY) && isteqi(n, ist("host"))) { + if (!http_update_authority(htx, sl, v)) + goto fail; + } } return 1;