Send original headers to the upstream
Kirill A. Korinsky
kirill at korins.ky
Fri Jun 28 00:03:13 UTC 2024
Greetings,
Retesting the patch requires some time.
On Wed, 26 Jun 2024 02:42:01 +0100,
Maxim Dounin <mdounin at 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
More information about the nginx
mailing list