summaryrefslogtreecommitdiffhomepage
path: root/src/http/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/modules')
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c183
-rw-r--r--src/http/modules/ngx_http_memcached_module.c3
-rw-r--r--src/http/modules/ngx_http_proxy_module.c297
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c142
4 files changed, 479 insertions, 146 deletions
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index ff5511804..777a7dd8b 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -246,13 +246,6 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.redirect_errors),
NULL },
- { ngx_string("fastcgi_x_powered_by"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_x_powered_by),
- NULL },
-
{ ngx_string("fastcgi_read_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
@@ -318,11 +311,25 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
{ ngx_string("fastcgi_param"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_table_elt_slot,
+ ngx_conf_set_keyval_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_fastcgi_loc_conf_t, params_source),
NULL },
+ { ngx_string("fastcgi_pass_header"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_str_array_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_headers),
+ NULL },
+
+ { ngx_string("fastcgi_hide_header"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_str_array_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.hide_headers),
+ NULL },
+
ngx_null_command
};
@@ -358,6 +365,16 @@ ngx_module_t ngx_http_fastcgi_module = {
};
+static ngx_str_t ngx_http_fastcgi_hide_headers[] = {
+ ngx_string("Status"),
+ ngx_string("X-Accel-Expires"),
+ ngx_string("X-Accel-Redirect"),
+ ngx_string("X-Accel-Limit-Rate"),
+ ngx_string("X-Accel-Buffer"),
+ ngx_null_string
+};
+
+
static ngx_int_t
ngx_http_fastcgi_handler(ngx_http_request_t *r)
{
@@ -390,6 +407,8 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
u->abort_request = ngx_http_fastcgi_abort_request;
u->finalize_request = ngx_http_fastcgi_finalize_request;
+ u->buffering = 1;
+
u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
if (u->pipe == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -796,7 +815,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
u_char *start, *last;
ngx_str_t *status_line, line;
ngx_int_t rc, status;
- ngx_uint_t key;
+ ngx_uint_t i;
ngx_table_elt_t *h;
ngx_http_upstream_t *u;
ngx_http_fastcgi_ctx_t *f;
@@ -806,7 +825,6 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
- hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets;
if (f == NULL) {
f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
@@ -980,26 +998,34 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
h->value.len = r->header_end - r->header_start;
h->key.data = ngx_palloc(r->pool,
- h->key.len + 1 + h->value.len + 1);
+ h->key.len + 1 + h->value.len + 1 + h->key.len);
if (h->key.data == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
h->value.data = h->key.data + h->key.len + 1;
+ h->lowcase_key = h->key.data + h->key.len + 1
+ + h->value.len + 1;
ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
- key = h->hash % umcf->headers_in_hash.hash_size;
+ if (h->key.len == r->lowcase_index) {
+ ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
- if (hh[key].name.len == h->key.len
- && ngx_strcasecmp(hh[key].name.data, h->key.data) == 0)
- {
- if (hh[key].handler(r, h, hh[key].offset) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ } else {
+ for (i = 0; i < h->key.len; i++) {
+ h->lowcase_key[i] = ngx_tolower(h->lowcase_key[i]);
}
}
+ hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
+ h->lowcase_key, h->key.len);
+
+ if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http fastcgi header: \"%V: %V\"",
&h->key, &h->value);
@@ -1474,9 +1500,11 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
* set by ngx_pcalloc():
*
* conf->upstream.bufs.num = 0;
- * conf->upstream.path = NULL;
* 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;
@@ -1510,12 +1538,6 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
/* "fastcgi_cyclic_temp_file" is disabled */
conf->upstream.cyclic_temp_file = 0;
- conf->upstream.pass_x_powered_by = NGX_CONF_UNSET;
-
- /* the hardcoded values */
- conf->upstream.pass_server = 1;
- conf->upstream.pass_date = 1;
-
return conf;
}
@@ -1529,8 +1551,12 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
u_char *p;
size_t size;
uintptr_t *code;
- ngx_uint_t i;
- ngx_table_elt_t *src;
+ ngx_str_t *header;
+ ngx_uint_t i, j;
+ ngx_array_t hide_headers;
+ 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;
@@ -1682,12 +1708,111 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->upstream.redirect_errors,
prev->upstream.redirect_errors, 0);
- ngx_conf_merge_value(conf->upstream.pass_x_powered_by,
- prev->upstream.pass_x_powered_by, 1);
-
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))
+ != 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_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->peers == NULL) {
conf->peers = prev->peers;
conf->upstream.schema = prev->upstream.schema;
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index ace8723e2..6384af03e 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -524,11 +524,8 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
conf->upstream.busy_buffers_size = 0;
conf->upstream.max_temp_file_size = 0;
conf->upstream.temp_file_write_size = 0;
- conf->upstream.pass_x_powered_by = 0;
conf->upstream.redirect_errors = 1;
conf->upstream.redirect_404 = 1;
- conf->upstream.pass_server = 1;
- conf->upstream.pass_date = 1;
conf->upstream.pass_request_headers = 0;
conf->upstream.pass_request_body = 0;
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 0e3c9491c..dd66bfabc 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -42,7 +42,7 @@ typedef struct {
ngx_array_t *body_set;
ngx_array_t *headers_set_len;
ngx_array_t *headers_set;
- ngx_hash0_t *headers_set_hash;
+ ngx_hash_t headers_set_hash;
ngx_array_t *headers_source;
ngx_array_t *headers_names;
@@ -187,7 +187,7 @@ static ngx_command_t ngx_http_proxy_commands[] = {
{ ngx_string("proxy_set_header"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_table_elt_slot,
+ ngx_conf_set_keyval_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_proxy_loc_conf_t, headers_source),
NULL },
@@ -297,25 +297,18 @@ static ngx_command_t ngx_http_proxy_commands[] = {
offsetof(ngx_http_proxy_loc_conf_t, upstream.fail_timeout),
NULL },
- { ngx_string("proxy_pass_x_powered_by"),
+ { ngx_string("proxy_pass_header"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
+ ngx_conf_set_str_array_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_x_powered_by),
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_headers),
NULL },
- { ngx_string("proxy_pass_server"),
+ { ngx_string("proxy_hide_header"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_server),
- NULL },
-
- { ngx_string("proxy_pass_x_accel_expires"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
+ ngx_conf_set_str_array_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_x_accel_expires),
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.hide_headers),
NULL },
ngx_null_command
@@ -356,11 +349,23 @@ ngx_module_t ngx_http_proxy_module = {
static char ngx_http_proxy_version[] = " HTTP/1.0" CRLF;
-static ngx_table_elt_t ngx_http_proxy_headers[] = {
- { 0, ngx_string("Host"), ngx_string("$proxy_host") },
- { 0, ngx_string("Connection"), ngx_string("close") },
- { 0, ngx_string("Keep-Alive"), ngx_string("") },
- { 0, ngx_null_string, ngx_null_string }
+static ngx_keyval_t ngx_http_proxy_headers[] = {
+ { ngx_string("Host"), ngx_string("$proxy_host") },
+ { ngx_string("Connection"), ngx_string("close") },
+ { ngx_string("Keep-Alive"), ngx_string("") },
+ { ngx_null_string, ngx_null_string }
+};
+
+
+static ngx_str_t ngx_http_proxy_hide_headers[] = {
+ ngx_string("Date"),
+ ngx_string("Server"),
+ ngx_string("X-Pad"),
+ ngx_string("X-Accel-Expires"),
+ ngx_string("X-Accel-Redirect"),
+ ngx_string("X-Accel-Limit-Rate"),
+ ngx_string("X-Accel-Buffer"),
+ ngx_null_string
};
@@ -422,16 +427,15 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;
}
- if (plcf->upstream.buffering) {
+ u->buffering = plcf->upstream.buffering;
- u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
- if (u->pipe == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
+ u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
+ if (u->pipe == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
+
u->accel = 1;
r->upstream = u;
@@ -450,10 +454,10 @@ static ngx_int_t
ngx_http_proxy_create_request(ngx_http_request_t *r)
{
size_t len, loc_len, body_len;
- ngx_uint_t i, key, unparsed_uri;
uintptr_t escape;
ngx_buf_t *b;
- ngx_str_t *hh, method;
+ ngx_str_t method;
+ ngx_uint_t i, unparsed_uri;
ngx_chain_t *cl, *body;
ngx_list_part_t *part;
ngx_table_elt_t *header;
@@ -541,8 +545,6 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
}
- hh = (ngx_str_t *) plcf->headers_set_hash->buckets;
-
if (plcf->upstream.pass_request_headers) {
part = &r->headers_in.headers.part;
header = part->elts;
@@ -559,10 +561,8 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
i = 0;
}
- key = header[i].hash % plcf->headers_set_hash->hash_size;
-
- if (hh[key].len == header[i].key.len
- && ngx_strcasecmp(hh[key].data, header[i].key.data) == 0)
+ if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash,
+ header[i].lowcase_key, header[i].key.len))
{
continue;
}
@@ -676,10 +676,8 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
i = 0;
}
- key = header[i].hash % plcf->headers_set_hash->hash_size;
-
- if (hh[key].len == header[i].key.len
- && ngx_strcasecmp(hh[key].data, header[i].key.data) == 0)
+ if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash,
+ header[i].lowcase_key, header[i].key.len))
{
continue;
}
@@ -1055,13 +1053,12 @@ static ngx_int_t
ngx_http_proxy_process_header(ngx_http_request_t *r)
{
ngx_int_t rc;
- ngx_uint_t key;
+ ngx_uint_t i;
ngx_table_elt_t *h;
ngx_http_upstream_header_t *hh;
ngx_http_upstream_main_conf_t *umcf;
umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
- hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets;
for ( ;; ) {
@@ -1082,26 +1079,33 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
h->value.len = r->header_end - r->header_start;
h->key.data = ngx_palloc(r->pool,
- h->key.len + 1 + h->value.len + 1);
+ h->key.len + 1 + h->value.len + 1 + h->key.len);
if (h->key.data == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
h->value.data = h->key.data + h->key.len + 1;
+ h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
- key = h->hash % umcf->headers_in_hash.hash_size;
+ if (h->key.len == r->lowcase_index) {
+ ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
- if (hh[key].name.len == h->key.len
- && ngx_strcasecmp(hh[key].name.data, h->key.data) == 0)
- {
- if (hh[key].handler(r, h, hh[key].offset) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ } else {
+ for (i = 0; i < h->key.len; i++) {
+ h->lowcase_key[i] = ngx_tolower(h->lowcase_key[i]);
}
}
+ hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
+ h->lowcase_key, h->key.len);
+
+ if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http proxy header: \"%V: %V\"",
&h->key, &h->value);
@@ -1116,6 +1120,42 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http proxy header done");
+ /*
+ * if no "Server" and "Date" in header line,
+ * then add the special empty headers
+ */
+
+ if (r->upstream->headers_in.server == NULL) {
+ h = ngx_list_push(&r->upstream->headers_in.headers);
+ if (h == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(
+ ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r');
+
+ h->key.len = sizeof("Server") - 1;
+ h->key.data = (u_char *) "Server";
+ h->value.len = 0;
+ h->value.data = NULL;
+ h->lowcase_key = (u_char *) "server";
+ }
+
+ if (r->upstream->headers_in.date == NULL) {
+ h = ngx_list_push(&r->upstream->headers_in.headers);
+ if (h == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e');
+
+ h->key.len = sizeof("Date") - 1;
+ h->key.data = (u_char *) "Date";
+ h->value.len = 0;
+ h->value.data = NULL;
+ h->lowcase_key = (u_char *) "date";
+ }
+
return NGX_OK;
}
@@ -1406,6 +1446,9 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.bufs.num = 0;
* 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;
@@ -1446,12 +1489,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
/* "proxy_cyclic_temp_file" is disabled */
conf->upstream.cyclic_temp_file = 0;
- conf->upstream.pass_x_powered_by = NGX_CONF_UNSET;
- conf->upstream.pass_server = NGX_CONF_UNSET;
- conf->upstream.pass_date = 0;
- conf->upstream.pass_x_accel_expires = NGX_CONF_UNSET;
-
conf->redirect = NGX_CONF_UNSET;
+ conf->upstream.change_buffering = 1;
return conf;
}
@@ -1466,9 +1505,12 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
u_char *p;
size_t size;
uintptr_t *code;
- ngx_str_t *name;
- ngx_uint_t i;
- ngx_table_elt_t *src, *s, *h;
+ ngx_str_t *header;
+ ngx_uint_t i, j;
+ ngx_array_t hide_headers;
+ ngx_keyval_t *src, *s, *h;
+ ngx_hash_key_t *hk;
+ ngx_hash_init_t hash;
ngx_http_proxy_redirect_t *pr;
ngx_http_script_compile_t sc;
ngx_http_script_copy_code_t *copy;
@@ -1627,14 +1669,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->upstream.redirect_errors,
prev->upstream.redirect_errors, 0);
- ngx_conf_merge_value(conf->upstream.pass_x_powered_by,
- prev->upstream.pass_x_powered_by, 1);
- ngx_conf_merge_value(conf->upstream.pass_server,
- prev->upstream.pass_server, 0);
- ngx_conf_merge_value(conf->upstream.pass_x_accel_expires,
- prev->upstream.pass_x_accel_expires, 0);
-
-
ngx_conf_merge_value(conf->redirect, prev->redirect, 1);
if (conf->redirect) {
@@ -1662,6 +1696,106 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
}
+ 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))
+ != 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 = 512;
+ hash.bucket_size = ngx_cacheline_size;
+ hash.name = "proxy_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->peers == NULL) {
conf->peers = prev->peers;
@@ -1696,7 +1830,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (conf->headers_source == NULL) {
conf->headers_source = ngx_array_create(cf->pool, 4,
- sizeof(ngx_table_elt_t));
+ sizeof(ngx_keyval_t));
if (conf->headers_source == NULL) {
return NGX_CONF_ERROR;
}
@@ -1707,7 +1841,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
- s->hash = 0;
s->key.len = sizeof("Content-Length") - 1;
s->key.data = (u_char *) "Content-Length";
s->value.len = sizeof("$proxy_internal_body_length") - 1;
@@ -1723,19 +1856,19 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->headers_source = prev->headers_source;
}
- if (conf->headers_set_hash) {
+ if (conf->headers_set_hash.buckets) {
return NGX_CONF_OK;
}
- conf->headers_names = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
+ conf->headers_names = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t));
if (conf->headers_names == NULL) {
return NGX_CONF_ERROR;
}
if (conf->headers_source == NULL) {
conf->headers_source = ngx_array_create(cf->pool, 4,
- sizeof(ngx_table_elt_t));
+ sizeof(ngx_keyval_t));
if (conf->headers_source == NULL) {
return NGX_CONF_ERROR;
}
@@ -1780,12 +1913,14 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
src = conf->headers_source->elts;
for (i = 0; i < conf->headers_source->nelts; i++) {
- name = ngx_array_push(conf->headers_names);
- if (name == NULL) {
+ hk = ngx_array_push(conf->headers_names);
+ if (hk == NULL) {
return NGX_CONF_ERROR;
}
- *name = src[i].key;
+ hk->key = src[i].key;
+ hk->key_hash = ngx_hash_key_lc(src[i].key.data, src[i].key.len);
+ hk->value = (void *) 1;
if (src[i].value.len == 0) {
continue;
@@ -1918,6 +2053,23 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
*code = (uintptr_t) NULL;
+ hash.hash = &conf->headers_set_hash;
+ hash.key = ngx_hash_key_lc;
+ hash.max_size = 512;
+ hash.bucket_size = ngx_cacheline_size;
+ hash.name = "proxy_set_header_hash";
+ hash.pool = cf->pool;
+ hash.temp_pool = NULL;
+
+ if (ngx_hash_init(&hash, conf->headers_names->elts,
+ conf->headers_names->nelts)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+
+
+#if 0
conf->headers_set_hash = ngx_pcalloc(cf->pool, sizeof(ngx_hash0_t));
if (conf->headers_set_hash == NULL) {
return NGX_CONF_ERROR;
@@ -1940,6 +2092,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
"max buckets per entry: %ui",
conf->headers_set_hash->hash_size,
conf->headers_set_hash->min_buckets);
+#endif
return NGX_CONF_OK;
}
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index aa0e41d25..6b7298c63 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -51,6 +51,8 @@ static char *ngx_http_perl_init_interpreter(ngx_conf_t *cf,
static PerlInterpreter *
ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
ngx_log_t *log);
+static ngx_int_t ngx_http_perl_run_requires(ngx_array_t *requires,
+ ngx_log_t *log);
static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r,
SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv);
static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv);
@@ -67,7 +69,10 @@ static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_perl_interp_max_unsupported(ngx_conf_t *cf, void *post,
void *data);
+#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
static void ngx_http_perl_cleanup_perl(void *data);
+#endif
+static void ngx_http_perl_cleanup_sv(void *data);
static ngx_conf_post_handler_pt ngx_http_perl_interp_max_p =
@@ -394,22 +399,6 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,
dTHXa(ctx->perl);
-#if 0
-
- ngx_http_perl_eval_anon_sub(aTHX_ handler, &sv);
-
- if (sv == &PL_sv_undef) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "eval_pv(\"%V\") failed", handler);
- return NGX_ERROR;
- }
-
- if (sv == NULL) {
- sv = newSVpvn((char *) handler->data, handler->len);
- }
-
-#endif
-
sv = newSVpvn((char *) handler->data, handler->len);
rc = ngx_http_perl_call_handler(aTHX_ r, sv, &params[NGX_HTTP_PERL_SSI_ARG],
@@ -470,13 +459,18 @@ ngx_http_perl_free_interpreter(ngx_http_perl_main_conf_t *pmcf,
static char *
ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
{
- ngx_pool_cleanup_t *cln;
+#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
+ ngx_pool_cleanup_t *cln;
cln = ngx_pool_cleanup_add(cf->pool, 0);
if (cln == NULL) {
return NGX_CONF_ERROR;
}
+#else
+ static PerlInterpreter *perl;
+#endif
+
#ifdef NGX_PERL_MODULES
if (pmcf->modules.data == NULL) {
pmcf->modules.data = NGX_PERL_MODULES;
@@ -489,6 +483,20 @@ ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
}
}
+#if !(NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
+
+ if (perl) {
+ if (ngx_http_perl_run_requires(&pmcf->requires, cf->log) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ pmcf->perl = perl;
+
+ return NGX_CONF_OK;
+ }
+
+#endif
+
PERL_SYS_INIT(&ngx_argc, &ngx_argv);
pmcf->perl = ngx_http_perl_create_interpreter(pmcf, cf->log);
@@ -498,9 +506,17 @@ ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
return NGX_CONF_ERROR;
}
+#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
+
cln->handler = ngx_http_perl_cleanup_perl;
cln->data = pmcf->perl;
+#else
+
+ perl = pmcf->perl;
+
+#endif
+
return NGX_CONF_OK;
}
@@ -511,10 +527,6 @@ ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
{
int n;
char *embedding[6];
- char **script;
- STRLEN len;
- ngx_str_t err;
- ngx_uint_t i;
PerlInterpreter *perl;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "create perl interpreter");
@@ -583,22 +595,8 @@ ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf,
goto fail;
}
- script = pmcf->requires.elts;
- for (i = 0; i < pmcf->requires.nelts; i++) {
- require_pv(script[i]);
-
- if (SvTRUE(ERRSV)) {
-
- err.data = (u_char *) SvPV(ERRSV, len);
- for (len--; err.data[len] == LF || err.data[len] == CR; len--) {
- /* void */
- }
- err.len = len + 1;
-
- ngx_log_error(NGX_LOG_EMERG, log, 0,
- "require_pv(\"%s\") failed: \"%V\"", script[i], &err);
- goto fail;
- }
+ if (ngx_http_perl_run_requires(&pmcf->requires, log) != NGX_OK) {
+ goto fail;
}
}
@@ -617,6 +615,38 @@ fail:
}
+static ngx_int_t
+ngx_http_perl_run_requires(ngx_array_t *requires, ngx_log_t *log)
+{
+ char **script;
+ STRLEN len;
+ ngx_str_t err;
+ ngx_uint_t i;
+
+ script = requires->elts;
+ for (i = 0; i < requires->nelts; i++) {
+
+ require_pv(script[i]);
+
+ if (SvTRUE(ERRSV)) {
+
+ err.data = (u_char *) SvPV(ERRSV, len);
+ for (len--; err.data[len] == LF || err.data[len] == CR; len--) {
+ /* void */
+ }
+ err.len = len + 1;
+
+ ngx_log_error(NGX_LOG_EMERG, log, 0,
+ "require_pv(\"%s\") failed: \"%V\"", script[i], &err);
+
+ return NGX_ERROR;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
#if (__INTEL_COMPILER)
/*
* disable 'declaration hides parameter "my_perl"' warning for ENTER and LEAVE
@@ -740,11 +770,8 @@ ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv)
}
}
- if (ngx_strncmp(p, "sub ", 4) == 0
- || ngx_strncmp(p, "use ", 4) == 0)
- {
+ if (ngx_strncmp(p, "sub ", 4) == 0 || ngx_strncmp(p, "use ", 4) == 0) {
*sv = eval_pv((char *) p, FALSE);
-
return;
}
@@ -805,10 +832,12 @@ ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf)
}
+#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY)
+
static void
ngx_http_perl_cleanup_perl(void *data)
{
- PerlInterpreter *perl = data;
+ PerlInterpreter *perl = data;
(void) perl_destruct(perl);
@@ -817,6 +846,17 @@ ngx_http_perl_cleanup_perl(void *data)
PERL_SYS_TERM();
}
+#endif
+
+
+static void
+ngx_http_perl_cleanup_sv(void *data)
+{
+ SV *sv = data;
+
+ SvREFCNT_dec(sv);
+}
+
static ngx_int_t
ngx_http_perl_preconfiguration(ngx_conf_t *cf)
@@ -908,6 +948,7 @@ ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_perl_loc_conf_t *plcf = conf;
ngx_str_t *value;
+ ngx_pool_cleanup_t *cln;
ngx_http_core_loc_conf_t *clcf;
ngx_http_perl_main_conf_t *pmcf;
@@ -927,6 +968,11 @@ ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
+ if (cln == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
plcf->handler = value[1];
{
@@ -947,6 +993,9 @@ ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
+ cln->handler = ngx_http_perl_cleanup_sv;
+ cln->data = plcf->sub;
+
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_perl_handler;
@@ -959,6 +1008,7 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_int_t index;
ngx_str_t *value;
+ ngx_pool_cleanup_t *cln;
ngx_http_variable_t *v;
ngx_http_perl_variable_t *pv;
ngx_http_perl_main_conf_t *pmcf;
@@ -997,6 +1047,11 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
+ if (cln == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
pv->handler = value[2];
{
@@ -1017,6 +1072,9 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
+ cln->handler = ngx_http_perl_cleanup_sv;
+ cln->data = pv->sub;
+
v->get_handler = ngx_http_perl_variable;
v->data = (uintptr_t) pv;