*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
this fixes fastcgi_catch_stderr segfault introduced in r1453
*) ngx_http_upstream_hide_headers_hash()
*) proxy/fastcgi pass_header/hide_header use
ngx_http_upstream_hide_headers_hash()
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index acd5c90..8cfef63 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -1643,8 +1643,6 @@
* conf->upstream.next_upstream = 0;
* conf->upstream.temp_path = NULL;
* conf->upstream.hide_headers_hash = { NULL, 0 };
- * conf->upstream.hide_headers = NULL;
- * conf->upstream.pass_headers = NULL;
* conf->upstream.schema = { 0, NULL };
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
@@ -1674,6 +1672,9 @@
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
conf->upstream.pass_request_body = NGX_CONF_UNSET;
+ conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
+ conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
+
conf->upstream.intercept_errors = NGX_CONF_UNSET;
/* "fastcgi_cyclic_temp_file" is disabled */
@@ -1694,11 +1695,8 @@
u_char *p;
size_t size;
uintptr_t *code;
- ngx_str_t *header;
- ngx_uint_t i, j;
- ngx_array_t hide_headers;
+ ngx_uint_t i;
ngx_keyval_t *src;
- ngx_hash_key_t *hk;
ngx_hash_init_t hash;
ngx_http_script_compile_t sc;
ngx_http_script_copy_code_t *copy;
@@ -1860,108 +1858,19 @@
ngx_conf_merge_str_value(conf->index, prev->index, "");
- if (conf->upstream.hide_headers == NULL
- && conf->upstream.pass_headers == NULL)
- {
- conf->upstream.hide_headers = prev->upstream.hide_headers;
- conf->upstream.pass_headers = prev->upstream.pass_headers;
- conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
+ hash.max_size = 512;
+ hash.bucket_size = ngx_align(64, ngx_cacheline_size);
+ hash.name = "fastcgi_hide_headers_hash";
- if (conf->upstream.hide_headers_hash.buckets) {
- goto peers;
- }
-
- } else {
- if (conf->upstream.hide_headers == NULL) {
- conf->upstream.hide_headers = prev->upstream.hide_headers;
- }
-
- if (conf->upstream.pass_headers == NULL) {
- conf->upstream.pass_headers = prev->upstream.pass_headers;
- }
- }
-
- if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
+ if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
+ &prev->upstream,
+ ngx_http_fastcgi_hide_headers,
+ &hash)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
- for (header = ngx_http_fastcgi_hide_headers; header->len; header++) {
- hk = ngx_array_push(&hide_headers);
- if (hk == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hk->key = *header;
- hk->key_hash = ngx_hash_key_lc(header->data, header->len);
- hk->value = (void *) 1;
- }
-
- if (conf->upstream.hide_headers) {
-
- header = conf->upstream.hide_headers->elts;
-
- for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
-
- hk = hide_headers.elts;
-
- for (j = 0; j < hide_headers.nelts; j++) {
- if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
- goto exist;
- }
- }
-
- hk = ngx_array_push(&hide_headers);
- if (hk == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hk->key = header[i];
- hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
- hk->value = (void *) 1;
-
- exist:
-
- continue;
- }
- }
-
- if (conf->upstream.pass_headers) {
-
- hk = hide_headers.elts;
- header = conf->upstream.pass_headers->elts;
-
- for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
-
- for (j = 0; j < hide_headers.nelts; j++) {
-
- if (hk[j].key.data == NULL) {
- continue;
- }
-
- if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
- hk[j].key.data = NULL;
- break;
- }
- }
- }
- }
-
- hash.hash = &conf->upstream.hide_headers_hash;
- hash.key = ngx_hash_key_lc;
- hash.max_size = 512;
- hash.bucket_size = ngx_align(64, ngx_cacheline_size);
- hash.name = "fastcgi_hide_headers_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
-peers:
-
if (conf->upstream.upstream == NULL) {
conf->upstream.upstream = prev->upstream.upstream;
conf->upstream.schema = prev->upstream.schema;
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 24da70d..ec31673 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -1634,8 +1634,6 @@
* conf->upstream.next_upstream = 0;
* conf->upstream.temp_path = NULL;
* conf->upstream.hide_headers_hash = { NULL, 0 };
- * conf->upstream.hide_headers = NULL;
- * conf->upstream.pass_headers = NULL;
* conf->upstream.schema = { 0, NULL };
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
@@ -1672,6 +1670,9 @@
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
conf->upstream.pass_request_body = NGX_CONF_UNSET;
+ conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
+ conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
+
conf->upstream.intercept_errors = NGX_CONF_UNSET;
/* "proxy_cyclic_temp_file" is disabled */
@@ -1696,9 +1697,7 @@
u_char *p;
size_t size;
uintptr_t *code;
- ngx_str_t *header;
- ngx_uint_t i, j;
- ngx_array_t hide_headers;
+ ngx_uint_t i;
ngx_keyval_t *src, *s, *h;
ngx_hash_key_t *hk;
ngx_hash_init_t hash;
@@ -1913,107 +1912,18 @@
conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size,
ngx_cacheline_size);
- if (conf->upstream.hide_headers == NULL
- && conf->upstream.pass_headers == NULL)
- {
- conf->upstream.hide_headers = prev->upstream.hide_headers;
- conf->upstream.pass_headers = prev->upstream.pass_headers;
- conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
+ hash.max_size = conf->headers_hash_max_size;
+ hash.bucket_size = conf->headers_hash_bucket_size;
+ hash.name = "proxy_headers_hash";
- if (conf->upstream.hide_headers_hash.buckets) {
- goto peers;
- }
-
- } else {
- if (conf->upstream.hide_headers == NULL) {
- conf->upstream.hide_headers = prev->upstream.hide_headers;
- }
-
- if (conf->upstream.pass_headers == NULL) {
- conf->upstream.pass_headers = prev->upstream.pass_headers;
- }
- }
-
- if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
+ if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
+ &prev->upstream,
+ ngx_http_proxy_hide_headers, &hash)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
- for (header = ngx_http_proxy_hide_headers; header->len; header++) {
- hk = ngx_array_push(&hide_headers);
- if (hk == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hk->key = *header;
- hk->key_hash = ngx_hash_key_lc(header->data, header->len);
- hk->value = (void *) 1;
- }
-
- if (conf->upstream.hide_headers) {
-
- header = conf->upstream.hide_headers->elts;
-
- for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
-
- hk = hide_headers.elts;
-
- for (j = 0; j < hide_headers.nelts; j++) {
- if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
- goto exist;
- }
- }
-
- hk = ngx_array_push(&hide_headers);
- if (hk == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hk->key = header[i];
- hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
- hk->value = (void *) 1;
-
- exist:
-
- continue;
- }
- }
-
- if (conf->upstream.pass_headers) {
-
- hk = hide_headers.elts;
- header = conf->upstream.pass_headers->elts;
-
- for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
- for (j = 0; j < hide_headers.nelts; j++) {
-
- if (hk[j].key.data == NULL) {
- continue;
- }
-
- if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
- hk[j].key.data = NULL;
- break;
- }
- }
- }
- }
-
- hash.hash = &conf->upstream.hide_headers_hash;
- hash.key = ngx_hash_key_lc;
- hash.max_size = conf->headers_hash_max_size;
- hash.bucket_size = conf->headers_hash_bucket_size;
- hash.name = "proxy_headers_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
-peers:
-
if (conf->upstream.upstream == NULL) {
conf->upstream.upstream = prev->upstream.upstream;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 48158a4..3cab8ef 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -3408,6 +3408,113 @@
}
+ngx_int_t
+ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
+ ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
+ ngx_str_t *default_hide_headers, ngx_hash_init_t *hash)
+{
+ ngx_str_t *h;
+ ngx_uint_t i, j;
+ ngx_array_t hide_headers;
+ ngx_hash_key_t *hk;
+
+ if (conf->hide_headers == NGX_CONF_UNSET_PTR
+ && conf->pass_headers == NGX_CONF_UNSET_PTR)
+ {
+ conf->hide_headers_hash = prev->hide_headers_hash;
+
+ if (conf->hide_headers_hash.buckets) {
+ return NGX_OK;
+ }
+
+ conf->hide_headers = prev->hide_headers;
+ conf->pass_headers = prev->pass_headers;
+
+ } else {
+ if (conf->hide_headers == NGX_CONF_UNSET_PTR) {
+ conf->hide_headers = prev->hide_headers;
+ }
+
+ if (conf->pass_headers == NGX_CONF_UNSET_PTR) {
+ conf->pass_headers = prev->pass_headers;
+ }
+ }
+
+ if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ for (h = default_hide_headers; h->len; h++) {
+ hk = ngx_array_push(&hide_headers);
+ if (hk == NULL) {
+ return NGX_ERROR;
+ }
+
+ hk->key = *h;
+ hk->key_hash = ngx_hash_key_lc(h->data, h->len);
+ hk->value = (void *) 1;
+ }
+
+ if (conf->hide_headers != NGX_CONF_UNSET_PTR) {
+
+ h = conf->hide_headers->elts;
+
+ for (i = 0; i < conf->hide_headers->nelts; i++) {
+
+ hk = hide_headers.elts;
+
+ for (j = 0; j < hide_headers.nelts; j++) {
+ if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
+ goto exist;
+ }
+ }
+
+ hk = ngx_array_push(&hide_headers);
+ if (hk == NULL) {
+ return NGX_ERROR;
+ }
+
+ hk->key = h[i];
+ hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len);
+ hk->value = (void *) 1;
+
+ exist:
+
+ continue;
+ }
+ }
+
+ if (conf->pass_headers != NGX_CONF_UNSET_PTR) {
+
+ h = conf->pass_headers->elts;
+ hk = hide_headers.elts;
+
+ for (i = 0; i < conf->pass_headers->nelts; i++) {
+ for (j = 0; j < hide_headers.nelts; j++) {
+
+ if (hk[j].key.data == NULL) {
+ continue;
+ }
+
+ if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
+ hk[j].key.data = NULL;
+ break;
+ }
+ }
+ }
+ }
+
+ hash->hash = &conf->hide_headers_hash;
+ hash->key = ngx_hash_key_lc;
+ hash->pool = cf->pool;
+ hash->temp_pool = NULL;
+
+ return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts);
+}
+
+
static void *
ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
{
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index 8395362..a7a9a63 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -269,6 +269,9 @@
void ngx_http_upstream_init(ngx_http_request_t *r);
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
ngx_url_t *u, ngx_uint_t flags);
+ngx_int_t ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
+ ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
+ ngx_str_t *default_hide_headers, ngx_hash_init_t *hash);
#define ngx_http_conf_upstream_srv_conf(uscf, module) \