Greetings, Retesting the patch requires some time.
On Wed, 26 Jun 2024 02:42:01 +0100, Maxim Dounin <mdou...@mdounin.ru> wrote: > > Note that as implemented, you won't be able to distinguish > original requests headers from the ones with prefix added. E.g., > assuming prefix "X-Original-", and original request headers: > > Host: foo > X-Original-Host: bar > > you'll get > > X-Original-Host: foo > X-Original-Host: bar > > in the upstream request, and you won't be able to tell which one > is real. > > Following the exiting proxy_set_header behaviour, I would rather > suggests that such a feature, if implemented, should drop all the > headers with the configured prefix. > [...] > > Not sure if reusing "proxy_pass_request_headers" for such a > feature is a good idea. From the behaviour of > "proxy_pass_request_headers off;", I would rather assume that > "proxy_pass_request_headers X-Original-;" will pass all the > headers with the specified prefix, and not just the headers which > were modified. > I agree that design when "proxy_pass_request_headers X-Original-;" simple maps all original headers into X-Original-BlaBla is cleaner. It also allows to avoid need to drop any header as well. So, here the updated patch which address all minor remarks as well: https://freenginx.org/pipermail/nginx/2024-June/000238.html diff --git src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_proxy_module.c index 536482ec5..7622360d2 100644 --- src/http/modules/ngx_http_proxy_module.c +++ src/http/modules/ngx_http_proxy_module.c @@ -117,6 +117,8 @@ typedef struct { ngx_uint_t headers_hash_max_size; ngx_uint_t headers_hash_bucket_size; + ngx_str_t request_headers_prefix; + #if (NGX_HTTP_SSL) ngx_uint_t ssl; ngx_uint_t ssl_protocols; @@ -215,6 +217,8 @@ static char *ngx_http_proxy_cookie_flags(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_proxy_pass_request_headers(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); #if (NGX_HTTP_CACHE) static char *ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -445,9 +449,9 @@ static ngx_command_t ngx_http_proxy_commands[] = { { ngx_string("proxy_pass_request_headers"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, + ngx_http_proxy_pass_request_headers, NGX_HTTP_LOC_CONF_OFFSET, - offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_request_headers), + 0, NULL }, { ngx_string("proxy_pass_request_body"), @@ -1386,9 +1390,11 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) i = 0; } - if (ngx_hash_find(&headers->hash, header[i].hash, - header[i].lowcase_key, header[i].key.len)) - { + if (plcf->request_headers_prefix.len > 0) { + len += plcf->request_headers_prefix.len; + } else if (ngx_hash_find(&headers->hash, header[i].hash, + header[i].lowcase_key, + header[i].key.len)) { continue; } @@ -1522,9 +1528,13 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) i = 0; } - if (ngx_hash_find(&headers->hash, header[i].hash, - header[i].lowcase_key, header[i].key.len)) - { + if (plcf->request_headers_prefix.len > 0) { + b->last = ngx_copy(b->last, + plcf->request_headers_prefix.data, + plcf->request_headers_prefix.len); + } else if (ngx_hash_find(&headers->hash, header[i].hash, + header[i].lowcase_key, + header[i].key.len)) { continue; } @@ -3349,6 +3359,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) * conf->body_values = NULL; * conf->body_source = { 0, NULL }; * conf->redirects = NULL; + * conf->request_headers_prefix = { NULL, 0 }; * conf->ssl = 0; * conf->ssl_protocols = 0; * conf->ssl_ciphers = { 0, NULL }; @@ -3727,6 +3738,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->upstream.intercept_errors, prev->upstream.intercept_errors, 0); + ngx_conf_merge_str_value(conf->request_headers_prefix, + prev->request_headers_prefix, ""); + #if (NGX_HTTP_SSL) if (ngx_http_proxy_merge_ssl(cf, conf, prev) != NGX_OK) { @@ -4772,6 +4786,36 @@ ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } +static char * +ngx_http_proxy_pass_request_headers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_proxy_loc_conf_t *plcf = conf; + + ngx_str_t *value; + + if (plcf->upstream.pass_request_headers != NGX_CONF_UNSET) { + return "is duplicate"; + } + + value = cf->args->elts; + + if (ngx_strcmp(value[1].data, "off") == 0) { + plcf->upstream.pass_request_headers = 0; + return NGX_CONF_OK; + } + + plcf->upstream.pass_request_headers = 1; + + if (ngx_strcmp(value[1].data, "on") == 0) { + return NGX_CONF_OK; + } + + plcf->request_headers_prefix = value[1]; + + return NGX_CONF_OK; +} + + #if (NGX_HTTP_CACHE) static char * -- wbr, Kirill