Send original headers to the upstream
Kirill A. Korinsky
kirill at korins.ky
Tue Jun 25 22:22:14 UTC 2024
Greetings,
Here is a patch that adds a string to proxy_pass_request_headers as a
possible value.
Such a string is used as a prefix for headers which is overwritten by Nginx
when it proxies the request to upstream.
As a nice side effect, this feature preserves the original order of HTTP
headers, which might be needed sometimes.
It is only implemented on the proxy module because there is no other way to
deliver the original request without touching it.
diff --git src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_proxy_module.c
index 536482ec5..6a722042b 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"),
@@ -1389,7 +1393,10 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
if (ngx_hash_find(&headers->hash, header[i].hash,
header[i].lowcase_key, header[i].key.len))
{
- continue;
+ if (plcf->request_headers_prefix.len == 0) {
+ continue;
+ }
+ len += plcf->request_headers_prefix.len;
}
len += header[i].key.len + sizeof(": ") - 1
@@ -1525,7 +1532,12 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
if (ngx_hash_find(&headers->hash, header[i].hash,
header[i].lowcase_key, header[i].key.len))
{
- continue;
+ if (plcf->request_headers_prefix.len == 0) {
+ continue;
+ }
+ b->last = ngx_copy(b->last,
+ plcf->request_headers_prefix.data,
+ plcf->request_headers_prefix.len);
}
b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len);
@@ -3349,6 +3361,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 +3740,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 +4788,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.store = 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