diff --git a/include/haproxy/http_htx.h b/include/haproxy/http_htx.h index 784596dd1..7259d29d7 100644 --- a/include/haproxy/http_htx.h +++ b/include/haproxy/http_htx.h @@ -52,8 +52,8 @@ int http_replace_res_status(struct htx *htx, const struct ist status, const stru int http_replace_res_reason(struct htx *htx, const struct ist reason); int http_append_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data); int http_prepend_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data); -int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data); -int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist name, const struct ist value); +int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data, int update_authority); +int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist name, const struct ist value, int update_authority); int http_remove_header(struct htx *htx, struct http_hdr_ctx *ctx); int http_update_authority(struct htx *htx, struct htx_sl *sl, const struct ist host); int http_update_host(struct htx *htx, struct htx_sl *sl, const struct ist uri); diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c index bd5117097..bbcb083ff 100644 --- a/src/flt_http_comp.c +++ b/src/flt_http_comp.c @@ -477,7 +477,7 @@ set_compression_header(struct comp_state *st, struct stream *s, struct http_msg if (istcat(&v, ist("W/"), trash.size) == -1 || istcat(&v, ctx.value, trash.size) == -1) goto error; - if (!http_replace_header_value(htx, &ctx, v)) + if (!http_replace_header_value(htx, &ctx, v, 0)) goto error; } } diff --git a/src/http_ana.c b/src/http_ana.c index 533613fd4..f0a21554a 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -2728,7 +2728,7 @@ int http_replace_hdrs(struct stream* s, struct htx *htx, struct ist name, output->data = exp_replace(output->area, output->size, ctx.value.ptr, str, pmatch); if (output->data == -1) return -1; - if (!http_replace_header_value(htx, &ctx, ist2(output->area, output->data))) + if (!http_replace_header_value(htx, &ctx, ist2(output->area, output->data), 1)) return -1; } return 0; @@ -3849,7 +3849,7 @@ static void http_manage_server_side_cookies(struct stream *s, struct channel *re ctx.value = ist2(val_beg, val_end - val_beg); ctx.lws_before = ctx.lws_after = 0; - http_replace_header_value(htx, &ctx, ist2(srv->cookie, srv->cklen)); + http_replace_header_value(htx, &ctx, ist2(srv->cookie, srv->cklen), 0); delta = srv->cklen - (val_end - val_beg); sliding = (ctx.value.ptr - val_beg); hdr_beg += sliding; @@ -3867,7 +3867,7 @@ static void http_manage_server_side_cookies(struct stream *s, struct channel *re int sliding, delta; ctx.value = ist2(val_beg, 0); ctx.lws_before = ctx.lws_after = 0; - http_replace_header_value(htx, &ctx, ist2(srv->cookie, srv->cklen + 1)); + http_replace_header_value(htx, &ctx, ist2(srv->cookie, srv->cklen + 1), 0); delta = srv->cklen + 1; sliding = (ctx.value.ptr - val_beg); hdr_beg += sliding; diff --git a/src/http_htx.c b/src/http_htx.c index cc5e4ecad..aced3f5e4 100644 --- a/src/http_htx.c +++ b/src/http_htx.c @@ -650,7 +650,8 @@ int http_prepend_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const s * . It returns 1 on success, otherwise it returns 0. The context is * updated if necessary. */ -int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data) +int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data, + int update_authority) { struct htx_blk *blk = ctx->blk; struct htx_sl *sl; @@ -671,6 +672,9 @@ int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const s goto fail; v = htx_get_blk_value(htx, blk); + if (!update_authority) + goto out; + sl = http_get_stline(htx); if (sl && (sl->flags & HTX_SL_F_HAS_AUTHORITY)) { struct ist n = htx_get_blk_name(htx, blk); @@ -684,7 +688,7 @@ int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const s v = htx_get_blk_value(htx, blk); } } - + out: ctx->blk = blk; ctx->value = ist2(v.ptr + off, data.len); ctx->lws_before = ctx->lws_after = 0; @@ -699,7 +703,8 @@ int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const s * context is updated if necessary. */ int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, - const struct ist name, const struct ist value) + const struct ist name, const struct ist value, + int update_authority) { struct htx_blk *blk = ctx->blk; struct htx_sl *sl; @@ -711,6 +716,9 @@ int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, if (!blk) goto fail; + if (!update_authority) + goto out; + sl = http_get_stline(htx); if (sl && (sl->flags & HTX_SL_F_HAS_AUTHORITY) && isteqi(name, ist("host"))) { if (!http_update_authority(htx, sl, value)) @@ -720,6 +728,7 @@ int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, blk = ctx->blk; } + out: ctx->blk = blk; ctx->value = ist(NULL); ctx->lws_before = ctx->lws_after = 0; @@ -867,7 +876,7 @@ int http_update_host(struct htx *htx, struct htx_sl *sl, const struct ist uri) /* Replace header host value */ ctx.blk = NULL; while (http_find_header(htx, ist("host"), &ctx, 1)) { - if (!http_replace_header_value(htx, &ctx, authority)) + if (!http_replace_header_value(htx, &ctx, authority, 0)) goto fail; } @@ -1889,7 +1898,7 @@ int http_scheme_based_normalize(struct htx *htx) /* replace every host headers by the normalized host */ ctx.blk = NULL; while (http_find_header(htx, ist("host"), &ctx, 1)) { - if (!http_replace_header_value(htx, &ctx, host)) { + if (!http_replace_header_value(htx, &ctx, host, 0)) { free_trash_chunk(temp); goto fail; }