# HG changeset patch # User Igor Sysoev # Date 1197223400 0 # Node ID 40d004d95d88e4bf735393f96e997367a6118ad7 # Parent 7f3350b18e75cd6c2ebbb564377da2c2468807cc *) 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/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -934,7 +934,7 @@ ngx_conf_set_str_array_slot(ngx_conf_t * a = (ngx_array_t **) (p + cmd->offset); - if (*a == NULL) { + if (*a == NGX_CONF_UNSET_PTR) { *a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t)); if (*a == NULL) { return NGX_CONF_ERROR; diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -1643,8 +1643,6 @@ ngx_http_fastcgi_create_loc_conf(ngx_con * 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 @@ ngx_http_fastcgi_create_loc_conf(ngx_con 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 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf 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_http_fastcgi_merge_loc_conf(ngx_conf 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; - - 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)) + hash.max_size = 512; + hash.bucket_size = ngx_align(64, ngx_cacheline_size); + hash.name = "fastcgi_hide_headers_hash"; + + 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 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1634,8 +1634,6 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ * 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 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ 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 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t 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 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t 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; - - 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)) + hash.max_size = conf->headers_hash_max_size; + hash.bucket_size = conf->headers_hash_bucket_size; + hash.name = "proxy_headers_hash"; + + 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 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -3408,6 +3408,113 @@ ngx_http_upstream_add(ngx_conf_t *cf, ng } +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 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -269,6 +269,9 @@ ngx_int_t ngx_http_upstream_header_varia 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) \