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.
This commit is contained in:
Christopher Faulet 2026-04-24 11:35:08 +02:00
parent 9368f4eaa2
commit dd92232012
11 changed files with 32 additions and 30 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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 <htx>, 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;