mirror of
https://github.com/nginx/nginx.git
synced 2024-11-27 15:39:01 +08:00
nginx-0.3.18-RELEASE import
*) Feature: the "server_names" directive supports the ".domain.tld" names. *) Feature: the "server_names" directive uses the hash for the "*.domain.tld" names and more effective hash for usual names. *) Change: the "server_names_hash_max_size" and "server_names_hash_bucket_size" directives. *) Change: the "server_names_hash" and "server_names_hash_threshold" directives were canceled. *) Feature: the "valid_referers" directive uses the hash site names. *) Change: now the "valid_referers" directive checks the site names only without the URI part. *) Bugfix: some ".domain.tld" names incorrectly processed by the ngx_http_map_module. *) Bugfix: segmentation fault was occurred if configuration file did not exist; the bug had appeared in 0.3.12. *) Bugfix: on 64-bit platforms segmentation fault may occurred on start; the bug had appeared in 0.3.16.
This commit is contained in:
parent
f9cbecc16a
commit
305a9d83cf
@ -2,7 +2,7 @@
|
||||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
CFLAGS = -q -O2 -tWM $(CPU_OPT)
|
||||
CFLAGS = -q -O2 -tWM -w-8004 $(CPU_OPT)
|
||||
PCREFLAGS = -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
CFLAGS = -q -O2 -tWM $(CPU_OPT)
|
||||
CFLAGS = -q -O2 -tWM -w-8004 -w-8012 $(CPU_OPT)
|
||||
|
||||
zlib.lib:
|
||||
bcc32 -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c \
|
||||
|
13
auto/make
13
auto/make
@ -320,6 +320,19 @@ END
|
||||
fi
|
||||
|
||||
|
||||
# the addons config.make
|
||||
|
||||
if test -n "$NGX_ADDONS"; then
|
||||
|
||||
for ngx_addon_dir in $NGX_ADDONS
|
||||
do
|
||||
if test -f $ngx_addon_dir/config.make; then
|
||||
. $ngx_addon_dir/config.make
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Win32 resource file
|
||||
|
||||
if test -n "$NGX_RES"; then
|
||||
|
@ -64,7 +64,7 @@ case "$NGX_MACHINE" in
|
||||
NGX_MACH_CACHE_LINE=32
|
||||
;;
|
||||
|
||||
amd64)
|
||||
amd64 | x86_64)
|
||||
have=NGX_HAVE_NONALIGNED . auto/have
|
||||
NGX_MACH_CACHE_LINE=64
|
||||
;;
|
||||
|
@ -266,7 +266,6 @@ HTTP_DEPS="src/http/ngx_http.h \
|
||||
|
||||
HTTP_SRCS="src/http/ngx_http.c \
|
||||
src/http/ngx_http_core_module.c \
|
||||
src/http/ngx_http_config.c \
|
||||
src/http/ngx_http_special_response.c \
|
||||
src/http/ngx_http_request.c \
|
||||
src/http/ngx_http_parse.c \
|
||||
|
@ -18,7 +18,7 @@ http {
|
||||
include conf/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
#log_format main '$remote_addr - $remote_user [$time_gmt] $status '
|
||||
#log_format main '$remote_addr - $remote_user [$time_local] $status '
|
||||
# '"$request" $body_bytes_sent "$http_referer" '
|
||||
# '"$http_user_agent" "http_x_forwarded_for"';
|
||||
|
||||
|
@ -9,6 +9,101 @@
|
||||
<title lang="en">nginx changelog</title>
|
||||
|
||||
|
||||
<changes ver="0.3.18" date="26.12.2005">
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á server_names ÐÏÄÄÅÒÖÉ×ÁÅÔ ÉÍÅÎÁ ×ÉÄÁ ".domain.tld".
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "server_names" directive supports the ".domain.tld" names.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á server_names ÉÓÐÏÌØÚÕÅÔ ÈÜÛ ÄÌÑ ÉͣΠ×ÉÄÁ "*.domain.tld"
|
||||
É ÂÏÌÅÅ ÜÆÆÅËÔÉ×ÎÙÊ ÈÜÛ ÄÌÑ ÏÂÙÞÎÙÈ ÉÍ£Î.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "server_names" directive uses the hash for the "*.domain.tld" names
|
||||
and more effective hash for usual names.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Ù server_names_hash_max_size É server_names_hash_bucket_size.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "server_names_hash_max_size" and "server_names_hash_bucket_size" directives.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Ù server_names_hash É server_names_hash_threshold ÕÐÒÁÚÄÎÅÎÙ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "server_names_hash" and "server_names_hash_threshold" directives
|
||||
were canceled.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á valid_referers ÉÓÐÏÌØÚÕÅÔ ÈÜÛ ÄÌÑ ÉͣΠÓÁÊÔÏ×.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "valid_referers" directive uses the hash site names.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÔÅÐÅÒØ ÄÉÒÅËÔÉ×Á valid_referers ÐÒÏ×ÅÒÑÅÔ ÔÏÌØËÏ ÉÍÅÎÁ ÓÁÊÔÏ× ÂÅÚ ÕÞ£ÔÁ URI.
|
||||
</para>
|
||||
<para lang="en">
|
||||
now the "valid_referers" directive checks the site names only without
|
||||
the URI part.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÎÅËÏÔÏÒÙÅ ÉÍÅÎÁ ×ÉÄÁ ".domain.tld" ÎÅ×ÅÒÎÏ ÏÂÒÁÂÁÔÙ×ÁÌÉÓØ ÍÏÄÕÌÅÍ
|
||||
ngx_http_map_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
some ".domain.tld" names incorrectly processed by the ngx_http_map_module.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÅÓÌÉ ËÏÎÆÉÇÕÒÁÃÉÏÎÎÏÇÏ ÆÁÊÌÁ ÎÅ ÂÙÌÏ, ÔÏ ÐÒÏÉÓÈÏÄÉÌ segmentation fault;
|
||||
ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.3.12.
|
||||
</para>
|
||||
<para lang="en">
|
||||
segmentation fault was occurred if configuration file did not exist;
|
||||
bug appeared in 0.3.12.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÎÁ 64-ÂÉÔÎÙÈ ÐÌÁÔÆÏÒÍÁÈ ÐÒÉ ÓÔÁÒÔÅ ÍÏÇ ÐÒÏÉÚÏÊÔÉ segmentation fault;
|
||||
ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.3.16.
|
||||
</para>
|
||||
<para lang="en">
|
||||
on 64-bit platforms segmentation fault may occurred on start;
|
||||
bug appeared in 0.3.16.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="0.3.17" date="18.12.2005">
|
||||
|
||||
<change type="change">
|
||||
@ -31,10 +126,12 @@ the "map" directive supports domain names in the ".domain.tld" form.
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
×Ï ×ÒÅÍÑ SSL handshake ÎÅ ÉcÐÏÌØÚÏ×ÁÌÉÓØ ÔÁÊÍÁÕÔÙ.
|
||||
×Ï ×ÒÅÍÑ SSL handshake ÎÅ ÉcÐÏÌØÚÏ×ÁÌÉÓØ ÔÁÊÍÁÕÔÙ;
|
||||
ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.2.4.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the timeouts were not used in SSL handshake.
|
||||
the timeouts were not used in SSL handshake;
|
||||
bug appeared in 0.2.4.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
@ -1978,7 +2075,7 @@ or "Authorization" lines, then nginx now returns the 400 error.
|
||||
ÄÉÒÅËÔÉ×Á post_accept_timeout ÕÐÒÁÚÄÎÅÎÁ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
The "post_accept_timeout" directive was canceled.
|
||||
the "post_accept_timeout" directive was canceled.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define NGINX_VER "nginx/0.3.17"
|
||||
#define NGINX_VER "nginx/0.3.18"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
|
@ -78,7 +78,8 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
|
||||
fd = ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN);
|
||||
if (fd == NGX_INVALID_FILE) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
|
||||
ngx_open_file_n " \"%s\" failed", filename->data);
|
||||
ngx_open_file_n " \"%s\" failed",
|
||||
filename->data);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
@ -811,6 +812,11 @@ ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf, ngx_err_t err,
|
||||
*buf = '\0';
|
||||
}
|
||||
|
||||
if (cf->conf_file == NULL) {
|
||||
ngx_log_error(level, cf->log, 0, "%s", errstr);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_log_error(level, cf->log, 0, "%s in %s:%ui",
|
||||
errstr, cf->conf_file->file.name.data, cf->conf_file->line);
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ struct ngx_conf_s {
|
||||
|
||||
ngx_cycle_t *cycle;
|
||||
ngx_pool_t *pool;
|
||||
ngx_pool_t *temp_pool;
|
||||
ngx_conf_file_t *conf_file;
|
||||
ngx_log_t *log;
|
||||
|
||||
|
@ -295,6 +295,9 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
|
||||
"bind() %V #%d ", &ls[i].addr_text, s);
|
||||
|
||||
if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
|
||||
err = ngx_socket_errno;
|
||||
|
||||
|
@ -162,6 +162,12 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
|
||||
if (conf.temp_pool == NULL) {
|
||||
ngx_destroy_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conf.ctx = cycle->conf_ctx;
|
||||
conf.cycle = cycle;
|
||||
conf.pool = pool;
|
||||
@ -174,6 +180,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
||||
#endif
|
||||
|
||||
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
|
||||
ngx_destroy_pool(conf.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
@ -196,6 +203,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
||||
if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
|
||||
== NGX_CONF_ERROR)
|
||||
{
|
||||
ngx_destroy_pool(conf.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
@ -421,6 +429,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
||||
}
|
||||
|
||||
if (ngx_test_config) {
|
||||
ngx_destroy_pool(conf.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
@ -438,6 +447,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
||||
}
|
||||
}
|
||||
|
||||
ngx_destroy_pool(conf.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
@ -521,6 +531,8 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
||||
}
|
||||
}
|
||||
|
||||
ngx_destroy_pool(conf.temp_pool);
|
||||
|
||||
if (old_cycle->connections == NULL) {
|
||||
/* an old cycle is an init cycle */
|
||||
ngx_destroy_pool(old_cycle->pool);
|
||||
|
@ -158,7 +158,7 @@ ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
|
||||
}
|
||||
}
|
||||
|
||||
test = ngx_alloc(hinit->max_size * sizeof(ngx_uint_t), hinit->pool->log);
|
||||
test = ngx_alloc(hinit->max_size * sizeof(size_t), hinit->pool->log);
|
||||
if (test == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -170,7 +170,7 @@ ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
|
||||
|
||||
for (size = start; size < hinit->max_size; size++) {
|
||||
|
||||
ngx_memzero(test, size * sizeof(ngx_uint_t));
|
||||
ngx_memzero(test, size * sizeof(size_t));
|
||||
|
||||
for (n = 0; n < nelts; n++) {
|
||||
if (names[n].key.data == NULL) {
|
||||
@ -347,7 +347,7 @@ ngx_int_t
|
||||
ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
|
||||
ngx_uint_t nelts)
|
||||
{
|
||||
size_t len;
|
||||
size_t len, dot_len;
|
||||
ngx_uint_t i, n, dot;
|
||||
ngx_array_t curr_names, next_names;
|
||||
ngx_hash_key_t *name, *next_name;
|
||||
@ -396,9 +396,11 @@ ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
|
||||
|
||||
#if 0
|
||||
ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
|
||||
"wc1: \"%V\"", &name->key);
|
||||
"wc1: \"%V\" %ui", &name->key, dot);
|
||||
#endif
|
||||
|
||||
dot_len = len + 1;
|
||||
|
||||
if (dot) {
|
||||
len++;
|
||||
}
|
||||
@ -427,13 +429,20 @@ ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!dot
|
||||
&& names[i].key.len > len
|
||||
&& names[i].key.data[len] != '.')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
next_name = ngx_array_push(&next_names);
|
||||
if (next_name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
next_name->key.len = names[i].key.len - len;
|
||||
next_name->key.data = names[i].key.data + len;
|
||||
next_name->key.len = names[i].key.len - dot_len;
|
||||
next_name->key.data = names[i].key.data + dot_len;
|
||||
next_name->key_hash= 0;
|
||||
next_name->value = names[i].value;
|
||||
|
||||
@ -444,6 +453,7 @@ ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
|
||||
}
|
||||
|
||||
if (next_names.nelts) {
|
||||
|
||||
h = *hinit;
|
||||
h.hash = NULL;
|
||||
|
||||
@ -681,3 +691,249 @@ ngx_hash0_init(ngx_hash0_t *hash, ngx_pool_t *pool, void *names,
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
|
||||
{
|
||||
ngx_uint_t asize;
|
||||
|
||||
if (type == NGX_HASH_SMALL) {
|
||||
asize = 4;
|
||||
ha->hsize = 107;
|
||||
|
||||
} else {
|
||||
asize = NGX_HASH_LARGE_ASIZE;
|
||||
ha->hsize = NGX_HASH_LARGE_HSIZE;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&ha->keys, ha->temp_pool, asize, sizeof(ngx_hash_key_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&ha->dns_wildcards, ha->temp_pool, asize,
|
||||
sizeof(ngx_hash_key_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ha->keys_hash = ngx_pcalloc(ha->temp_pool, sizeof(ngx_array_t) * ha->hsize);
|
||||
if (ha->keys_hash == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ha->dns_wildcards_hash = ngx_pcalloc(ha->temp_pool,
|
||||
sizeof(ngx_array_t) * ha->hsize);
|
||||
if (ha->dns_wildcards_hash == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
|
||||
ngx_uint_t flags)
|
||||
{
|
||||
size_t len;
|
||||
ngx_str_t *name;
|
||||
ngx_uint_t i, k, n, skip;
|
||||
ngx_hash_key_t *hk;
|
||||
u_char buf[2048];
|
||||
|
||||
if (!(flags & NGX_HASH_WILDCARD_KEY)) {
|
||||
|
||||
/* exact hash */
|
||||
|
||||
k = 0;
|
||||
|
||||
for (i = 0; i < key->len; i++) {
|
||||
key->data[i] = ngx_tolower(key->data[i]);
|
||||
k = ngx_hash(k, key->data[i]);
|
||||
}
|
||||
|
||||
k %= ha->hsize;
|
||||
|
||||
/* check conflicts in exact hash */
|
||||
|
||||
name = ha->keys_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
|
||||
if (key->len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(key->data, name[i].data, key->len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
|
||||
sizeof(ngx_str_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(&ha->keys_hash[k]);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*name = *key;
|
||||
|
||||
hk = ngx_array_push(&ha->keys);
|
||||
if (hk == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key = *key;
|
||||
hk->key_hash = ngx_hash_key(key->data, key->len);
|
||||
hk->value = value;
|
||||
|
||||
} else {
|
||||
|
||||
/* wildcard hash */
|
||||
|
||||
skip = (key->data[0] == '*') ? 2 : 1;
|
||||
k = 0;
|
||||
|
||||
for (i = skip; i < key->len; i++) {
|
||||
key->data[i] = ngx_tolower(key->data[i]);
|
||||
k = ngx_hash(k, key->data[i]);
|
||||
}
|
||||
|
||||
k %= ha->hsize;
|
||||
|
||||
if (skip == 1) {
|
||||
|
||||
/* check conflicts in exact hash for ".example.com" */
|
||||
|
||||
name = ha->keys_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
len = key->len - skip;
|
||||
|
||||
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
|
||||
if (len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
|
||||
sizeof(ngx_str_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(&ha->keys_hash[k]);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
name->len = key->len - 1;
|
||||
name->data = ngx_palloc(ha->temp_pool, name->len);
|
||||
if (name->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(name->data, &key->data[1], name->len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* convert "*.example.com" to "com.example.\0"
|
||||
* and ".example.com" to "com.example\0"
|
||||
*/
|
||||
|
||||
len = 0;
|
||||
n = 0;
|
||||
|
||||
for (i = key->len - 1; i; i--) {
|
||||
if (key->data[i] == '.') {
|
||||
ngx_memcpy(&buf[n], &key->data[i + 1], len);
|
||||
n += len;
|
||||
buf[n++] = '.';
|
||||
len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
ngx_memcpy(&buf[n], &key->data[1], len);
|
||||
n += len;
|
||||
}
|
||||
|
||||
buf[n] = '\0';
|
||||
|
||||
|
||||
/* check conflicts in wildcard hash */
|
||||
|
||||
name = ha->dns_wildcards_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
len = key->len - skip;
|
||||
|
||||
for (i = 0; i < ha->dns_wildcards_hash[k].nelts; i++) {
|
||||
if (len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(&ha->dns_wildcards_hash[k], ha->temp_pool, 4,
|
||||
sizeof(ngx_str_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(&ha->dns_wildcards_hash[k]);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
name->len = key->len - skip;
|
||||
name->data = ngx_palloc(ha->temp_pool, name->len);
|
||||
if (name->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ngx_memcpy(name->data, key->data + skip, name->len);
|
||||
|
||||
|
||||
ngx_memcpy(key->data, buf, key->len);
|
||||
key->len--;
|
||||
|
||||
hk = ngx_array_push(&ha->dns_wildcards);
|
||||
if (hk == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key = *key;
|
||||
hk->key_hash = 0;
|
||||
hk->value = value;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -54,6 +54,29 @@ typedef struct {
|
||||
} ngx_hash_init_t;
|
||||
|
||||
|
||||
#define NGX_HASH_SMALL 1
|
||||
#define NGX_HASH_LARGE 2
|
||||
|
||||
#define NGX_HASH_LARGE_ASIZE 16384
|
||||
#define NGX_HASH_LARGE_HSIZE 10007
|
||||
|
||||
#define NGX_HASH_WILDCARD_KEY 1
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t hsize;
|
||||
|
||||
ngx_pool_t *pool;
|
||||
ngx_pool_t *temp_pool;
|
||||
|
||||
ngx_array_t keys;
|
||||
ngx_array_t *keys_hash;
|
||||
|
||||
ngx_array_t dns_wildcards;
|
||||
ngx_array_t *dns_wildcards_hash;
|
||||
} ngx_hash_keys_arrays_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
void **buckets;
|
||||
ngx_uint_t hash_size;
|
||||
@ -86,6 +109,10 @@ ngx_int_t ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
|
||||
ngx_uint_t ngx_hash_key(u_char *data, size_t len);
|
||||
ngx_uint_t ngx_hash_key_lc(u_char *data, size_t len);
|
||||
|
||||
ngx_int_t ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type);
|
||||
ngx_int_t ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key,
|
||||
void *value, ngx_uint_t flags);
|
||||
|
||||
|
||||
ngx_int_t ngx_hash0_init(ngx_hash0_t *hash, ngx_pool_t *pool, void *names,
|
||||
ngx_uint_t nelts);
|
||||
|
@ -16,7 +16,7 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_hash_conf_t hash;
|
||||
ngx_hash_keys_arrays_t keys;
|
||||
|
||||
ngx_array_t *values_hash;
|
||||
|
||||
@ -245,44 +245,20 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&ctx.hash.keys, pool, 16384, sizeof(ngx_hash_key_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
ctx.keys.pool = cf->pool;
|
||||
ctx.keys.temp_pool = pool;
|
||||
|
||||
if (ngx_hash_keys_array_init(&ctx.keys, NGX_HASH_LARGE) != NGX_OK) {
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&ctx.hash.dns_wildcards, pool, 16384,
|
||||
sizeof(ngx_hash_key_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ctx.hash.keys_hash = ngx_pcalloc(pool,
|
||||
sizeof(ngx_array_t) * NGX_HTTP_CONFIG_HASH);
|
||||
if (ctx.hash.keys_hash == NULL) {
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ctx.hash.dns_hash = ngx_pcalloc(pool,
|
||||
sizeof(ngx_array_t) * NGX_HTTP_CONFIG_HASH);
|
||||
if (ctx.hash.dns_hash == NULL) {
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ctx.values_hash = ngx_pcalloc(pool,
|
||||
sizeof(ngx_array_t) * NGX_HTTP_CONFIG_HASH);
|
||||
ctx.values_hash = ngx_pcalloc(pool, sizeof(ngx_array_t) * ctx.keys.hsize);
|
||||
if (ctx.values_hash == NULL) {
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ctx.hash.pool = cf->pool;
|
||||
ctx.hash.temp_pool = pool;
|
||||
ctx.default_value = NULL;
|
||||
ctx.hostnames = 0;
|
||||
|
||||
@ -298,7 +274,6 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
if (rv != NGX_CONF_OK) {
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -308,13 +283,14 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
hash.name = "map_hash";
|
||||
hash.pool = cf->pool;
|
||||
|
||||
if (ctx.hash.keys.nelts) {
|
||||
if (ctx.keys.keys.nelts) {
|
||||
hash.hash = &map->hash;
|
||||
hash.temp_pool = NULL;
|
||||
|
||||
if (ngx_hash_init(&hash, ctx.hash.keys.elts, ctx.hash.keys.nelts)
|
||||
if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
@ -322,19 +298,20 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
map->default_value = ctx.default_value ? ctx.default_value:
|
||||
&ngx_http_variable_null_value;
|
||||
|
||||
if (ctx.hash.dns_wildcards.nelts) {
|
||||
if (ctx.keys.dns_wildcards.nelts) {
|
||||
|
||||
ngx_qsort(ctx.hash.dns_wildcards.elts,
|
||||
(size_t) ctx.hash.dns_wildcards.nelts,
|
||||
ngx_qsort(ctx.keys.dns_wildcards.elts,
|
||||
(size_t) ctx.keys.dns_wildcards.nelts,
|
||||
sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards);
|
||||
|
||||
hash.hash = NULL;
|
||||
hash.temp_pool = pool;
|
||||
|
||||
if (ngx_hash_wildcard_init(&hash, ctx.hash.dns_wildcards.elts,
|
||||
ctx.hash.dns_wildcards.nelts)
|
||||
if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wildcards.elts,
|
||||
ctx.keys.dns_wildcards.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
@ -408,7 +385,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||
key = ngx_hash(key, value[1].data[i]);
|
||||
}
|
||||
|
||||
key %= NGX_HTTP_CONFIG_HASH;
|
||||
key %= ctx->keys.hsize;
|
||||
|
||||
vp = ctx->values_hash[key].elts;
|
||||
|
||||
@ -433,13 +410,13 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||
}
|
||||
}
|
||||
|
||||
var = ngx_palloc(ctx->hash.pool, sizeof(ngx_http_variable_value_t));
|
||||
var = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_variable_value_t));
|
||||
if (var == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
var->len = value[1].len;
|
||||
var->data = ngx_pstrdup(ctx->hash.pool, &value[1]);
|
||||
var->data = ngx_pstrdup(ctx->keys.pool, &value[1]);
|
||||
if (var->data == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
@ -492,10 +469,10 @@ found:
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
flags = NGX_HTTP_WILDCARD_HASH;
|
||||
flags = NGX_HASH_WILDCARD_KEY;
|
||||
}
|
||||
|
||||
rc = ngx_http_config_add_hash(&ctx->hash, &value[0], var, flags);
|
||||
rc = ngx_hash_add_key(&ctx->keys, &value[0], var, flags);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_CONF_OK;
|
||||
|
@ -1925,8 +1925,8 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_http_proxy_loc_conf_t *plcf = conf;
|
||||
|
||||
size_t add;
|
||||
u_short port;
|
||||
ngx_str_t *value, *url;
|
||||
ngx_uint_t port;
|
||||
ngx_inet_upstream_t inet_upstream;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
#if (NGX_HTTP_SSL)
|
||||
|
@ -10,15 +10,13 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_uint_t wildcard;
|
||||
} ngx_http_referer_t;
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *referers; /* ngx_http_referer_t */
|
||||
ngx_hash_t hash;
|
||||
ngx_hash_wildcard_t *dns_wildcards;
|
||||
|
||||
ngx_flag_t no_referer;
|
||||
ngx_flag_t blocked_referer;
|
||||
|
||||
ngx_hash_keys_arrays_t *keys;
|
||||
} ngx_http_referer_conf_t;
|
||||
|
||||
|
||||
@ -27,6 +25,10 @@ static char * ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent,
|
||||
void *child);
|
||||
static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
|
||||
ngx_str_t *value);
|
||||
static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
|
||||
const void *two);
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_referer_commands[] = {
|
||||
@ -77,21 +79,22 @@ static ngx_int_t
|
||||
ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
u_char *ref;
|
||||
u_char *p, *ref;
|
||||
size_t len;
|
||||
ngx_uint_t i, n;
|
||||
ngx_http_referer_t *refs;
|
||||
ngx_http_referer_conf_t *cf;
|
||||
ngx_http_referer_conf_t *rlcf;
|
||||
|
||||
cf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
|
||||
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
|
||||
|
||||
if (cf->referers == NULL) {
|
||||
if (rlcf->hash.buckets == NULL
|
||||
&& rlcf->dns_wildcards == NULL
|
||||
&& rlcf->dns_wildcards->hash.buckets == NULL)
|
||||
{
|
||||
*v = ngx_http_variable_null_value;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (r->headers_in.referer == NULL) {
|
||||
if (cf->no_referer) {
|
||||
if (rlcf->no_referer) {
|
||||
*v = ngx_http_variable_null_value;
|
||||
return NGX_OK;
|
||||
|
||||
@ -107,7 +110,7 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
if (len < sizeof("http://i.ru") - 1
|
||||
|| (ngx_strncasecmp(ref, "http://", 7) != 0))
|
||||
{
|
||||
if (cf->blocked_referer) {
|
||||
if (rlcf->blocked_referer) {
|
||||
*v = ngx_http_variable_null_value;
|
||||
return NGX_OK;
|
||||
|
||||
@ -120,39 +123,27 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
len -= 7;
|
||||
ref += 7;
|
||||
|
||||
refs = cf->referers->elts;
|
||||
for (i = 0; i < cf->referers->nelts; i++ ){
|
||||
|
||||
if (refs[i].name.len > len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (refs[i].wildcard) {
|
||||
for (n = 0; n < len; n++) {
|
||||
if (ref[n] == '/' || ref[n] == ':') {
|
||||
for (p = ref; p < ref + len; p++) {
|
||||
if (*p == '/' || *p == ':') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ref[n] != '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(&ref[n], refs[i].name.data,
|
||||
refs[i].name.len) == 0)
|
||||
{
|
||||
len = p - ref;
|
||||
|
||||
if (rlcf->hash.buckets) {
|
||||
if (ngx_hash_find(&rlcf->hash, ngx_hash_key_lc(ref, len), ref, len)) {
|
||||
*v = ngx_http_variable_null_value;
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_strncasecmp(refs[i].name.data, ref, refs[i].name.len) == 0)
|
||||
{
|
||||
if (rlcf->dns_wildcards && rlcf->dns_wildcards->hash.buckets) {
|
||||
if (ngx_hash_find_wildcard(rlcf->dns_wildcards, ref, len)) {
|
||||
*v = ngx_http_variable_null_value;
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*v = ngx_http_variable_true_value;
|
||||
|
||||
@ -165,12 +156,11 @@ ngx_http_referer_create_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_referer_conf_t *conf;
|
||||
|
||||
conf = ngx_palloc(cf->pool, sizeof(ngx_http_referer_conf_t));
|
||||
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_referer_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->referers = NULL;
|
||||
conf->no_referer = NGX_CONF_UNSET;
|
||||
conf->blocked_referer = NGX_CONF_UNSET;
|
||||
|
||||
@ -184,10 +174,53 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_http_referer_conf_t *prev = parent;
|
||||
ngx_http_referer_conf_t *conf = child;
|
||||
|
||||
if (conf->referers == NULL) {
|
||||
conf->referers = prev->referers;
|
||||
ngx_hash_init_t hash;
|
||||
|
||||
if (conf->keys == NULL) {
|
||||
conf->hash = prev->hash;
|
||||
conf->dns_wildcards = prev->dns_wildcards;
|
||||
|
||||
ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
|
||||
ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
hash.key = ngx_hash_key_lc;
|
||||
hash.max_size = 2048; /* TODO: referer_hash_max_size; */
|
||||
hash.bucket_size = 64; /* TODO: referer_hash_bucket_size; */
|
||||
hash.name = "referers_hash";
|
||||
hash.pool = cf->pool;
|
||||
|
||||
if (conf->keys->keys.nelts) {
|
||||
hash.hash = &conf->hash;
|
||||
hash.temp_pool = NULL;
|
||||
|
||||
if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->keys->dns_wildcards.nelts) {
|
||||
|
||||
ngx_qsort(conf->keys->dns_wildcards.elts,
|
||||
(size_t) conf->keys->dns_wildcards.nelts,
|
||||
sizeof(ngx_hash_key_t),
|
||||
ngx_http_cmp_referer_wildcards);
|
||||
|
||||
hash.hash = NULL;
|
||||
hash.temp_pool = cf->temp_pool;
|
||||
|
||||
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wildcards.elts,
|
||||
conf->keys->dns_wildcards.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
if (conf->no_referer == NGX_CONF_UNSET) {
|
||||
@ -205,11 +238,11 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
static char *
|
||||
ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_referer_conf_t *lcf = conf;
|
||||
ngx_http_referer_conf_t *rlcf = conf;
|
||||
|
||||
ngx_uint_t i, server_names;
|
||||
u_char *p;
|
||||
ngx_str_t *value, name;
|
||||
ngx_http_referer_t *ref;
|
||||
ngx_uint_t i, n;
|
||||
ngx_http_variable_t *var;
|
||||
ngx_http_server_name_t *sn;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
@ -225,19 +258,21 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
var->handler = ngx_http_referer_variable;
|
||||
|
||||
cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
|
||||
if (rlcf->keys == NULL) {
|
||||
rlcf->keys = ngx_pcalloc(cf->temp_pool, sizeof(ngx_hash_keys_arrays_t));
|
||||
if (rlcf->keys == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (lcf->referers == NULL) {
|
||||
lcf->referers = ngx_array_create(cf->pool,
|
||||
cf->args->nelts + cscf->server_names.nelts,
|
||||
sizeof(ngx_http_referer_t));
|
||||
if (lcf->referers == NULL) {
|
||||
rlcf->keys->pool = cf->pool;
|
||||
rlcf->keys->temp_pool = cf->pool;
|
||||
|
||||
if (ngx_hash_keys_array_init(rlcf->keys, NGX_HASH_SMALL) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
server_names = 0;
|
||||
|
||||
for (i = 1; i < cf->args->nelts; i++) {
|
||||
if (value[i].len == 0) {
|
||||
@ -247,64 +282,90 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[i].data, "none") == 0) {
|
||||
lcf->no_referer = 1;
|
||||
rlcf->no_referer = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[i].data, "blocked") == 0) {
|
||||
lcf->blocked_referer = 1;
|
||||
rlcf->blocked_referer = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[i].data, "server_names") == 0) {
|
||||
server_names = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ref = ngx_array_push(lcf->referers);
|
||||
if (ref == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (value[i].data[0] != '*') {
|
||||
ref->name = value[i];
|
||||
ref->wildcard = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (value[i].data[1] != '.') {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid wildcard referer \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ref->name.len = value[i].len - 1;
|
||||
ref->name.data = value[i].data + 1;
|
||||
ref->wildcard = 1;
|
||||
}
|
||||
|
||||
if (!server_names) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
|
||||
|
||||
sn = cscf->server_names.elts;
|
||||
for (i = 0; i < cscf->server_names.nelts; i++) {
|
||||
ref = ngx_array_push(lcf->referers);
|
||||
if (ref == NULL) {
|
||||
for (n = 0; n < cscf->server_names.nelts; n++) {
|
||||
if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ref->name.len = sn[i].name.len + 1;
|
||||
ref->name.data = ngx_palloc(cf->pool, ref->name.len);
|
||||
if (ref->name.data == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(ref->name.data, sn[i].name.data, sn[i].name.len);
|
||||
ref->name.data[sn[i].name.len] = '/';
|
||||
ref->wildcard = sn[i].wildcard;
|
||||
continue;
|
||||
}
|
||||
|
||||
p = (u_char *) ngx_strstr(value[i].data, "/");
|
||||
|
||||
if (p) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"URI part \"%s\" is deprecated, ignored", p);
|
||||
|
||||
value[i].len = p - value[i].data;
|
||||
}
|
||||
|
||||
if (ngx_http_add_referer(cf, rlcf->keys, &value[i]) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
|
||||
ngx_str_t *value)
|
||||
{
|
||||
u_char ch;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t flags;
|
||||
|
||||
ch = value->data[0];
|
||||
|
||||
if ((ch == '*' && (value->len < 3 || value->data[1] != '.'))
|
||||
|| (ch == '.' && value->len < 2))
|
||||
{
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid DNS wildcard \"%V\"", value);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
flags = (ch == '*' || ch == '.') ? NGX_HASH_WILDCARD_KEY : 0;
|
||||
|
||||
rc = ngx_hash_add_key(keys, value, (void *) 4, flags);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"conflicting parameter \"%V\"", value);
|
||||
}
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static int ngx_libc_cdecl
|
||||
ngx_http_cmp_referer_wildcards(const void *one, const void *two)
|
||||
{
|
||||
ngx_hash_key_t *first, *second;
|
||||
|
||||
first = (ngx_hash_key_t *) one;
|
||||
second = (ngx_hash_key_t *) two;
|
||||
|
||||
return ngx_strcmp(first->key.data, second->key.data);
|
||||
}
|
||||
|
@ -14,13 +14,17 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
static int ngx_libc_cdecl ngx_cmp_server_names(const void *one,
|
||||
const void *two);
|
||||
static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
|
||||
ngx_http_in_port_t *in_port, ngx_http_listen_t *lscf,
|
||||
ngx_http_conf_in_port_t *in_port, ngx_http_listen_t *lscf,
|
||||
ngx_http_core_srv_conf_t *cscf);
|
||||
static ngx_int_t ngx_http_add_names(ngx_conf_t *cf,
|
||||
ngx_http_in_addr_t *in_addr, ngx_http_core_srv_conf_t *cscf);
|
||||
ngx_http_conf_in_addr_t *in_addr, ngx_http_core_srv_conf_t *cscf);
|
||||
static char *ngx_http_merge_locations(ngx_conf_t *cf,
|
||||
ngx_array_t *locations, void **loc_conf, ngx_http_module_t *module,
|
||||
ngx_uint_t ctx_index);
|
||||
static int ngx_libc_cdecl ngx_http_cmp_conf_in_addrs(const void *one,
|
||||
const void *two);
|
||||
static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one,
|
||||
const void *two);
|
||||
|
||||
ngx_uint_t ngx_http_max_module;
|
||||
|
||||
@ -72,19 +76,24 @@ static char *
|
||||
ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
char *rv;
|
||||
ngx_uint_t mi, m, s, l, p, a, n, key;
|
||||
ngx_uint_t port_found, addr_found;
|
||||
ngx_uint_t virtual_names, separate_binding;
|
||||
u_char ch;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t mi, m, s, l, p, a, n, i;
|
||||
ngx_uint_t last, bind_all, done;
|
||||
ngx_conf_t pcf;
|
||||
ngx_array_t in_ports;
|
||||
ngx_hash_init_t hash;
|
||||
ngx_listening_t *ls;
|
||||
ngx_http_listen_t *lscf;
|
||||
ngx_http_module_t *module;
|
||||
ngx_http_in_port_t *hip;
|
||||
ngx_http_handler_pt *h;
|
||||
ngx_http_conf_ctx_t *ctx;
|
||||
ngx_http_in_port_t *in_port, *inport;
|
||||
ngx_http_in_addr_t *in_addr, *inaddr;
|
||||
ngx_http_server_name_t *s_name, *name;
|
||||
ngx_http_conf_in_port_t *in_port;
|
||||
ngx_http_conf_in_addr_t *in_addr;
|
||||
ngx_hash_keys_arrays_t ha;
|
||||
ngx_http_server_name_t *name;
|
||||
ngx_http_virtual_names_t *vn;
|
||||
ngx_http_core_srv_conf_t **cscfp, *cscf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
@ -414,7 +423,8 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
* to quickly find the server core module configuration at run-time
|
||||
*/
|
||||
|
||||
if (ngx_array_init(&in_ports, cf->pool, 2, sizeof(ngx_http_in_port_t))
|
||||
if (ngx_array_init(&in_ports, cf->temp_pool, 2,
|
||||
sizeof(ngx_http_conf_in_port_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
@ -430,29 +440,27 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
lscf = cscfp[s]->listen.elts;
|
||||
for (l = 0; l < cscfp[s]->listen.nelts; l++) {
|
||||
|
||||
port_found = 0;
|
||||
|
||||
/* AF_INET only */
|
||||
|
||||
in_port = in_ports.elts;
|
||||
for (p = 0; p < in_ports.nelts; p++) {
|
||||
|
||||
if (lscf[l].port == in_port[p].port) {
|
||||
if (lscf[l].port != in_port[p].port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* the port is already in the port list */
|
||||
|
||||
port_found = 1;
|
||||
addr_found = 0;
|
||||
|
||||
in_addr = in_port[p].addrs.elts;
|
||||
for (a = 0; a < in_port[p].addrs.nelts; a++) {
|
||||
|
||||
if (lscf[l].addr == in_addr[a].addr) {
|
||||
if (lscf[l].addr != in_addr[a].addr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* the address is already in the address list */
|
||||
|
||||
if (ngx_http_add_names(cf, &in_addr[a], cscfp[s])
|
||||
!= NGX_OK)
|
||||
if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) != NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
@ -464,7 +472,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
if (lscf[l].conf.default_server) {
|
||||
|
||||
if (in_addr[a].conf.default_server) {
|
||||
if (in_addr[a].default_server) {
|
||||
ngx_log_error(NGX_LOG_ERR, cf->log, 0,
|
||||
"the duplicate default server in %V:%d",
|
||||
&lscf[l].file_name, lscf[l].line);
|
||||
@ -473,68 +481,25 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
|
||||
in_addr[a].core_srv_conf = cscfp[s];
|
||||
in_addr[a].conf.default_server = 1;
|
||||
in_addr[a].default_server = 1;
|
||||
}
|
||||
|
||||
addr_found = 1;
|
||||
|
||||
break;
|
||||
|
||||
} else if (in_addr[a].addr == INADDR_ANY) {
|
||||
|
||||
/* the INADDR_ANY is always the last address */
|
||||
|
||||
inaddr = ngx_array_push(&in_port[p].addrs);
|
||||
if (inaddr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
goto found;
|
||||
}
|
||||
in_addr = in_port[p].addrs.elts;
|
||||
|
||||
/*
|
||||
* the INADDR_ANY must be the last resort
|
||||
* so we move it to the end of the address list
|
||||
* and put the new address in its place
|
||||
*/
|
||||
|
||||
ngx_memcpy(inaddr, &in_addr[a],
|
||||
sizeof(ngx_http_in_addr_t));
|
||||
|
||||
in_addr[a].addr = lscf[l].addr;
|
||||
in_addr[a].names.elts = NULL;
|
||||
in_addr[a].hash = NULL;
|
||||
in_addr[a].wildcards.elts = NULL;
|
||||
in_addr[a].core_srv_conf = cscfp[s];
|
||||
in_addr[a].conf = lscf[l].conf;
|
||||
|
||||
if (ngx_http_add_names(cf, &in_addr[a], cscfp[s])
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
addr_found = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!addr_found) {
|
||||
|
||||
/*
|
||||
* add the address to the addresses list that
|
||||
* bound to this port
|
||||
*/
|
||||
|
||||
if (ngx_http_add_address(cf, &in_port[p], &lscf[l],
|
||||
cscfp[s]) != NGX_OK)
|
||||
if (ngx_http_add_address(cf, &in_port[p], &lscf[l], cscfp[s])
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!port_found) {
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* add the port to the in_port list */
|
||||
|
||||
@ -546,21 +511,14 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
in_port->port = lscf[l].port;
|
||||
in_port->addrs.elts = NULL;
|
||||
|
||||
in_port->port_text.data = ngx_palloc(cf->pool, 7);
|
||||
if (in_port->port_text.data == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
in_port->port_text.len = ngx_sprintf(in_port->port_text.data,
|
||||
":%d", in_port->port)
|
||||
- in_port->port_text.data;
|
||||
|
||||
if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s])
|
||||
!= NGX_OK)
|
||||
if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s]) != NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
found:
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -572,7 +530,8 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
in_port = in_ports.elts;
|
||||
for (p = 0; p < in_ports.nelts; p++) {
|
||||
|
||||
separate_binding = 0;
|
||||
ngx_qsort(in_port[p].addrs.elts, (size_t) in_port[p].addrs.nelts,
|
||||
sizeof(ngx_http_conf_in_addr_t), ngx_http_cmp_conf_in_addrs);
|
||||
|
||||
/*
|
||||
* check whether all name-based servers have the same configuraiton
|
||||
@ -582,33 +541,13 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
in_addr = in_port[p].addrs.elts;
|
||||
for (a = 0; a < in_port[p].addrs.nelts; a++) {
|
||||
|
||||
if (in_addr[a].conf.bind) {
|
||||
separate_binding = 1;
|
||||
}
|
||||
|
||||
virtual_names = 0;
|
||||
|
||||
name = in_addr[a].names.elts;
|
||||
for (n = 0; n < in_addr[a].names.nelts; n++) {
|
||||
if (in_addr[a].core_srv_conf != name[n].core_srv_conf
|
||||
|| name[n].core_srv_conf->restrict_host_names
|
||||
!= NGX_HTTP_RESTRICT_HOST_OFF)
|
||||
{
|
||||
virtual_names = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!virtual_names) {
|
||||
name = in_addr[a].wildcards.elts;
|
||||
for (n = 0; n < in_addr[a].wildcards.nelts; n++) {
|
||||
if (in_addr[a].core_srv_conf != name[n].core_srv_conf
|
||||
|| name[n].core_srv_conf->restrict_host_names
|
||||
!= NGX_HTTP_RESTRICT_HOST_OFF)
|
||||
{
|
||||
virtual_names = 1;
|
||||
break;
|
||||
}
|
||||
goto virtual_names;
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,65 +557,132 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
* then we do not need to check them at run-time at all
|
||||
*/
|
||||
|
||||
if (!virtual_names) {
|
||||
in_addr[a].names.nelts = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
virtual_names:
|
||||
|
||||
ngx_qsort(in_addr[a].names.elts, in_addr[a].names.nelts,
|
||||
sizeof(ngx_http_server_name_t), ngx_cmp_server_names);
|
||||
|
||||
|
||||
/* create a hash for many names */
|
||||
|
||||
if (in_addr[a].names.nelts > cmcf->server_names_hash_threshold) {
|
||||
in_addr[a].hash = ngx_palloc(cf->pool,
|
||||
cmcf->server_names_hash
|
||||
* sizeof(ngx_array_t));
|
||||
if (in_addr[a].hash == NULL) {
|
||||
ha.temp_pool = ngx_create_pool(16384, cf->log);
|
||||
if (ha.temp_pool == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (n = 0; n < cmcf->server_names_hash; n++) {
|
||||
if (ngx_array_init(&in_addr[a].hash[n], cf->pool, 4,
|
||||
sizeof(ngx_http_server_name_t)) != NGX_OK)
|
||||
{
|
||||
ha.pool = cf->pool;
|
||||
|
||||
if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
|
||||
ngx_destroy_pool(ha.temp_pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = in_addr[a].names.elts;
|
||||
for (s = 0; s < in_addr[a].names.nelts; s++) {
|
||||
ngx_http_server_names_hash_key(key, name[s].name.data,
|
||||
name[s].name.len,
|
||||
cmcf->server_names_hash);
|
||||
|
||||
s_name = ngx_array_push(&in_addr[a].hash[key]);
|
||||
if (s_name == NULL) {
|
||||
ch = name[s].name.data[0];
|
||||
|
||||
if (ch == '*' || ch == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
|
||||
0);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
name = in_addr[a].names.elts;
|
||||
|
||||
*s_name = name[s];
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
|
||||
"conflicting server name \"%V\", ignored",
|
||||
&name[s].name);
|
||||
}
|
||||
}
|
||||
|
||||
for (s = 0; s < in_addr[a].names.nelts; s++) {
|
||||
|
||||
ch = name[s].name.data[0];
|
||||
|
||||
if (ch != '*' && ch != '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
|
||||
NGX_HASH_WILDCARD_KEY);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
|
||||
"conflicting server name \"%V\", ignored",
|
||||
&name[s].name);
|
||||
}
|
||||
}
|
||||
|
||||
hash.key = ngx_hash_key_lc;
|
||||
hash.max_size = cmcf->server_names_hash_max_size;
|
||||
hash.bucket_size = cmcf->server_names_hash_bucket_size;
|
||||
hash.name = "server_names_hash";
|
||||
hash.pool = cf->pool;
|
||||
|
||||
if (ha.keys.nelts) {
|
||||
hash.hash = &in_addr[a].hash;
|
||||
hash.temp_pool = NULL;
|
||||
|
||||
if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(ha.temp_pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ha.dns_wildcards.nelts) {
|
||||
|
||||
ngx_qsort(ha.dns_wildcards.elts,
|
||||
(size_t) ha.dns_wildcards.nelts,
|
||||
sizeof(ngx_hash_key_t),
|
||||
ngx_http_cmp_dns_wildcards);
|
||||
|
||||
hash.hash = NULL;
|
||||
hash.temp_pool = ha.temp_pool;
|
||||
|
||||
if (ngx_hash_wildcard_init(&hash, ha.dns_wildcards.elts,
|
||||
ha.dns_wildcards.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(ha.temp_pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
in_addr[a].dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
ngx_destroy_pool(ha.temp_pool);
|
||||
}
|
||||
|
||||
in_addr = in_port[p].addrs.elts;
|
||||
last = in_port[p].addrs.nelts;
|
||||
|
||||
/*
|
||||
* if there is the binding to the "*:port" then we need to bind()
|
||||
* to the "*:port" only and ignore the other bindings
|
||||
*/
|
||||
|
||||
if (in_addr[a - 1].addr == INADDR_ANY && !separate_binding) {
|
||||
a--;
|
||||
if (in_addr[last - 1].addr == INADDR_ANY) {
|
||||
in_addr[last - 1].bind = 1;
|
||||
bind_all = 0;
|
||||
|
||||
} else {
|
||||
a = 0;
|
||||
bind_all = 1;
|
||||
}
|
||||
|
||||
in_addr = in_port[p].addrs.elts;
|
||||
while (a < in_port[p].addrs.nelts) {
|
||||
for (a = 0; a < last; /* void */ ) {
|
||||
|
||||
if (!bind_all && !in_addr[a].bind) {
|
||||
a++;
|
||||
continue;
|
||||
}
|
||||
|
||||
ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr,
|
||||
in_port[p].port);
|
||||
@ -705,68 +711,98 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
#endif
|
||||
|
||||
ls->backlog = in_addr[a].conf.backlog;
|
||||
ls->rcvbuf = in_addr[a].conf.rcvbuf;
|
||||
ls->sndbuf = in_addr[a].conf.sndbuf;
|
||||
ls->backlog = in_addr[a].listen_conf->backlog;
|
||||
ls->rcvbuf = in_addr[a].listen_conf->rcvbuf;
|
||||
ls->sndbuf = in_addr[a].listen_conf->sndbuf;
|
||||
|
||||
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
|
||||
ls->accept_filter = in_addr[a].conf.accept_filter;
|
||||
ls->accept_filter = in_addr[a].listen_conf->accept_filter;
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
|
||||
ls->deferred_accept = in_addr[a].conf.deferred_accept;
|
||||
ls->deferred_accept = in_addr[a].listen_conf->deferred_accept;
|
||||
#endif
|
||||
|
||||
ls->ctx = ctx;
|
||||
|
||||
if (in_port[p].addrs.nelts > 1) {
|
||||
hip = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t));
|
||||
if (hip == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
hip->port = in_port[p].port;
|
||||
|
||||
hip->port_text.data = ngx_palloc(cf->pool, 7);
|
||||
if (hip->port_text.data == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ls->servers = hip;
|
||||
|
||||
hip->port_text.len = ngx_sprintf(hip->port_text.data, ":%d",
|
||||
hip->port)
|
||||
- hip->port_text.data;
|
||||
|
||||
in_addr = in_port[p].addrs.elts;
|
||||
if (in_addr[in_port[p].addrs.nelts - 1].addr != INADDR_ANY) {
|
||||
|
||||
/*
|
||||
* if this port has not the "*:port" binding then create
|
||||
* the separate ngx_http_in_port_t for the all bindings
|
||||
*/
|
||||
if (in_addr[a].bind && in_addr[a].addr != INADDR_ANY) {
|
||||
hip->naddrs = 1;
|
||||
done = 0;
|
||||
|
||||
inport = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t));
|
||||
if (inport == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
inport->port = in_port[p].port;
|
||||
inport->port_text = in_port[p].port_text;
|
||||
|
||||
/* init list of the addresses ... */
|
||||
|
||||
if (ngx_array_init(&inport->addrs, cf->pool, 1,
|
||||
sizeof(ngx_http_in_addr_t)) != NGX_OK)
|
||||
} else if (in_port[p].addrs.nelts > 1
|
||||
&& in_addr[last - 1].addr == INADDR_ANY)
|
||||
{
|
||||
hip->naddrs = last;
|
||||
done = 1;
|
||||
|
||||
} else {
|
||||
hip->naddrs = 1;
|
||||
done = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
|
||||
"%ui: %V %d %ui %ui",
|
||||
a, &ls->addr_text, in_addr[a].bind,
|
||||
hip->naddrs, last);
|
||||
#endif
|
||||
|
||||
hip->addrs = ngx_pcalloc(cf->pool,
|
||||
hip->naddrs * sizeof(ngx_http_in_addr_t));
|
||||
if (hip->addrs == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/* ... and set up it with the first address */
|
||||
|
||||
inport->addrs.nelts = 1;
|
||||
inport->addrs.elts = in_port[p].addrs.elts;
|
||||
|
||||
ls->servers = inport;
|
||||
|
||||
/* prepare for the next cycle */
|
||||
|
||||
in_port[p].addrs.elts = (char *) in_port[p].addrs.elts
|
||||
+ in_port[p].addrs.size;
|
||||
in_port[p].addrs.nelts--;
|
||||
|
||||
in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts;
|
||||
a = 0;
|
||||
for (i = 0; i < hip->naddrs; i++) {
|
||||
hip->addrs[i].addr = in_addr[i].addr;
|
||||
hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf;
|
||||
|
||||
if (in_addr[i].hash.buckets == NULL
|
||||
&& (in_addr[i].dns_wildcards == NULL
|
||||
|| in_addr[i].dns_wildcards->hash.buckets == NULL))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
|
||||
if (vn == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
hip->addrs[i].virtual_names = vn;
|
||||
|
||||
vn->hash = in_addr[i].hash;
|
||||
vn->dns_wildcards = in_addr[i].dns_wildcards;
|
||||
}
|
||||
|
||||
ls->servers = &in_port[p];
|
||||
a++;
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
in_addr++;
|
||||
in_port[p].addrs.elts = in_addr;
|
||||
last--;
|
||||
|
||||
a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -785,12 +821,12 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"%s:%d %p",
|
||||
address, in_port[p].port, in_addr[a].core_srv_conf);
|
||||
s_name = in_addr[a].names.elts;
|
||||
name = in_addr[a].names.elts;
|
||||
for (n = 0; n < in_addr[a].names.nelts; n++) {
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"%s:%d %V %p",
|
||||
address, in_port[p].port, &s_name[n].name,
|
||||
s_name[n].core_srv_conf);
|
||||
address, in_port[p].port, &name[n].name,
|
||||
name[n].core_srv_conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -801,30 +837,20 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
|
||||
|
||||
static int ngx_libc_cdecl
|
||||
ngx_cmp_server_names(const void *one, const void *two)
|
||||
{
|
||||
ngx_http_server_name_t *first = (ngx_http_server_name_t *) one;
|
||||
ngx_http_server_name_t *second = (ngx_http_server_name_t *) two;
|
||||
|
||||
return ngx_strcmp(first->name.data, second->name.data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* add the server address, the server names and the server core module
|
||||
* configurations to the port (in_port)
|
||||
*/
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_add_address(ngx_conf_t *cf, ngx_http_in_port_t *in_port,
|
||||
ngx_http_add_address(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port,
|
||||
ngx_http_listen_t *lscf, ngx_http_core_srv_conf_t *cscf)
|
||||
{
|
||||
ngx_http_in_addr_t *in_addr;
|
||||
ngx_http_conf_in_addr_t *in_addr;
|
||||
|
||||
if (in_port->addrs.elts == NULL) {
|
||||
if (ngx_array_init(&in_port->addrs, cf->pool, 4,
|
||||
sizeof(ngx_http_in_addr_t)) != NGX_OK)
|
||||
if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4,
|
||||
sizeof(ngx_http_conf_in_addr_t)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -836,11 +862,14 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_in_port_t *in_port,
|
||||
}
|
||||
|
||||
in_addr->addr = lscf->addr;
|
||||
in_addr->hash.buckets = NULL;
|
||||
in_addr->hash.size = 0;
|
||||
in_addr->dns_wildcards = NULL;
|
||||
in_addr->names.elts = NULL;
|
||||
in_addr->hash = NULL;
|
||||
in_addr->wildcards.elts = NULL;
|
||||
in_addr->core_srv_conf = cscf;
|
||||
in_addr->conf = lscf->conf;
|
||||
in_addr->default_server = lscf->conf.default_server;
|
||||
in_addr->bind = lscf->conf.bind;
|
||||
in_addr->listen_conf = &lscf->conf;
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
{
|
||||
@ -861,23 +890,14 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_in_port_t *in_port,
|
||||
*/
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_add_names(ngx_conf_t *cf, ngx_http_in_addr_t *in_addr,
|
||||
ngx_http_add_names(ngx_conf_t *cf, ngx_http_conf_in_addr_t *in_addr,
|
||||
ngx_http_core_srv_conf_t *cscf)
|
||||
{
|
||||
ngx_uint_t i, n;
|
||||
ngx_array_t *array;
|
||||
ngx_http_server_name_t *server_names, *name;
|
||||
|
||||
if (in_addr->names.elts == NULL) {
|
||||
if (ngx_array_init(&in_addr->names, cf->pool, 4,
|
||||
sizeof(ngx_http_server_name_t)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_addr->wildcards.elts == NULL) {
|
||||
if (ngx_array_init(&in_addr->wildcards, cf->pool, 1,
|
||||
if (ngx_array_init(&in_addr->names, cf->temp_pool, 4,
|
||||
sizeof(ngx_http_server_name_t)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
@ -895,17 +915,8 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_http_in_addr_t *in_addr,
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"name: %V", &server_names[i].name);
|
||||
|
||||
/* TODO: duplicate names can be checked here */
|
||||
|
||||
|
||||
if (server_names[i].wildcard) {
|
||||
array = &in_addr->wildcards;
|
||||
|
||||
} else {
|
||||
array = &in_addr->names;
|
||||
}
|
||||
|
||||
name = ngx_array_push(array);
|
||||
name = ngx_array_push(&in_addr->names);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -926,7 +937,7 @@ ngx_http_merge_locations(ngx_conf_t *cf, ngx_array_t *locations,
|
||||
ngx_uint_t i;
|
||||
ngx_http_core_loc_conf_t **clcfp;
|
||||
|
||||
clcfp = /* (ngx_http_core_loc_conf_t **) */ locations->elts;
|
||||
clcfp = locations->elts;
|
||||
|
||||
for (i = 0; i < locations->nelts; i++) {
|
||||
rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
|
||||
@ -944,3 +955,44 @@ ngx_http_merge_locations(ngx_conf_t *cf, ngx_array_t *locations,
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static int ngx_libc_cdecl
|
||||
ngx_http_cmp_conf_in_addrs(const void *one, const void *two)
|
||||
{
|
||||
ngx_http_conf_in_addr_t *first, *second;
|
||||
|
||||
first = (ngx_http_conf_in_addr_t *) one;
|
||||
second = (ngx_http_conf_in_addr_t *) two;
|
||||
|
||||
if (first->addr == INADDR_ANY) {
|
||||
/* the INADDR_ANY must be the last resort, shift it to the end */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (first->bind && !second->bind) {
|
||||
/* shift explicit bind()ed addresses to the start */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!first->bind && second->bind) {
|
||||
/* shift explicit bind()ed addresses to the start */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* do not sort by default */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ngx_libc_cdecl
|
||||
ngx_http_cmp_dns_wildcards(const void *one, const void *two)
|
||||
{
|
||||
ngx_hash_key_t *first, *second;
|
||||
|
||||
first = (ngx_hash_key_t *) one;
|
||||
second = (ngx_hash_key_t *) two;
|
||||
|
||||
return ngx_strcmp(first->key.data, second->key.data);
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
typedef struct ngx_http_request_s ngx_http_request_t;
|
||||
typedef struct ngx_http_upstream_s ngx_http_upstream_t;
|
||||
typedef struct ngx_http_log_ctx_s ngx_http_log_ctx_t;
|
||||
typedef struct ngx_http_in_addr_s ngx_http_in_addr_t;
|
||||
|
||||
typedef ngx_int_t (*ngx_http_header_handler_pt)(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
|
@ -1,214 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) Igor Sysoev
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_event.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_config_add_hash(ngx_http_hash_conf_t *h, ngx_str_t *key, void *value,
|
||||
ngx_uint_t flags)
|
||||
{
|
||||
size_t len;
|
||||
ngx_str_t *name;
|
||||
ngx_uint_t i, k, n, skip;
|
||||
ngx_hash_key_t *hk;
|
||||
u_char buf[2048];
|
||||
|
||||
if (!(flags & NGX_HTTP_WILDCARD_HASH)) {
|
||||
|
||||
/* exact hash */
|
||||
|
||||
k = 0;
|
||||
|
||||
for (i = 0; i < key->len; i++) {
|
||||
key->data[i] = ngx_tolower(key->data[i]);
|
||||
k = ngx_hash(k, key->data[i]);
|
||||
}
|
||||
|
||||
k %= NGX_HTTP_CONFIG_HASH;
|
||||
|
||||
/* check conflicts in exact hash */
|
||||
|
||||
name = h->keys_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
for (i = 0; i < h->keys_hash[k].nelts; i++) {
|
||||
if (key->len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(key->data, name[i].data, key->len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(&h->keys_hash[k], h->temp_pool, 4,
|
||||
sizeof(ngx_str_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(&h->keys_hash[k]);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*name = *key;
|
||||
|
||||
hk = ngx_array_push(&h->keys);
|
||||
if (hk == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key = *key;
|
||||
hk->key_hash = ngx_hash_key(key->data, key->len);
|
||||
hk->value = value;
|
||||
|
||||
} else {
|
||||
|
||||
/* wildcard hash */
|
||||
|
||||
skip = (key->data[0] == '*') ? 2 : 1;
|
||||
k = 0;
|
||||
|
||||
for (i = skip; i < key->len; i++) {
|
||||
key->data[i] = ngx_tolower(key->data[i]);
|
||||
k = ngx_hash(k, key->data[i]);
|
||||
}
|
||||
|
||||
k %= NGX_HTTP_CONFIG_HASH;
|
||||
|
||||
if (skip == 1) {
|
||||
|
||||
/* check conflicts in exact hash for ".example.com" */
|
||||
|
||||
name = h->keys_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
len = key->len - skip;
|
||||
|
||||
for (i = 0; i < h->keys_hash[k].nelts; i++) {
|
||||
if (len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(&h->keys_hash[k], h->temp_pool, 4,
|
||||
sizeof(ngx_str_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(&h->keys_hash[k]);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
name->len = key->len - 1;
|
||||
name->data = ngx_palloc(h->temp_pool, name->len);
|
||||
if (name->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(name->data, &key->data[1], name->len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* convert "*.example.com" to "com.example.\0"
|
||||
* and ".example.com" to "com.example\0"
|
||||
*/
|
||||
|
||||
len = 0;
|
||||
n = 0;
|
||||
|
||||
for (i = key->len - 1; i; i--) {
|
||||
if (key->data[i] == '.') {
|
||||
ngx_memcpy(&buf[n], &key->data[i + 1], len);
|
||||
n += len;
|
||||
buf[n++] = '.';
|
||||
len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
ngx_memcpy(&buf[n], &key->data[1], len);
|
||||
n += len;
|
||||
}
|
||||
|
||||
buf[n] = '\0';
|
||||
|
||||
|
||||
/* check conflicts in wildcard hash */
|
||||
|
||||
name = h->dns_hash[k].elts;
|
||||
|
||||
if (name) {
|
||||
len = key->len - skip;
|
||||
|
||||
for (i = 0; i < h->dns_hash[k].nelts; i++) {
|
||||
if (len != name[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {
|
||||
return NGX_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_array_init(&h->dns_hash[k], h->temp_pool, 4,
|
||||
sizeof(ngx_str_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
name = ngx_array_push(&h->dns_hash[k]);
|
||||
if (name == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
name->len = key->len - skip;
|
||||
name->data = ngx_palloc(h->temp_pool, name->len);
|
||||
if (name->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ngx_memcpy(name->data, key->data + skip, name->len);
|
||||
|
||||
|
||||
ngx_memcpy(key->data, buf, key->len);
|
||||
key->len--;
|
||||
|
||||
hk = ngx_array_push(&h->dns_wildcards);
|
||||
if (hk == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
hk->key = *key;
|
||||
hk->key_hash = 0;
|
||||
hk->value = value;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
@ -72,25 +72,4 @@ typedef struct {
|
||||
cycle->conf_ctx[ngx_http_module.index])->main_conf[module.ctx_index]
|
||||
|
||||
|
||||
#define NGX_HTTP_CONFIG_HASH 10007
|
||||
|
||||
#define NGX_HTTP_WILDCARD_HASH 1
|
||||
|
||||
typedef struct {
|
||||
ngx_pool_t *pool;
|
||||
ngx_pool_t *temp_pool;
|
||||
|
||||
ngx_array_t keys;
|
||||
ngx_array_t *keys_hash;
|
||||
|
||||
ngx_array_t dns_wildcards;
|
||||
ngx_array_t *dns_hash;
|
||||
} ngx_http_hash_conf_t;
|
||||
|
||||
|
||||
ngx_int_t ngx_http_config_add_hash(ngx_http_hash_conf_t *h, ngx_str_t *key,
|
||||
void *value, ngx_uint_t flags);
|
||||
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_CONFIG_H_INCLUDED_ */
|
||||
|
@ -73,18 +73,18 @@ static ngx_conf_enum_t ngx_http_restrict_host_names[] = {
|
||||
|
||||
static ngx_command_t ngx_http_core_commands[] = {
|
||||
|
||||
{ ngx_string("server_names_hash"),
|
||||
{ ngx_string("server_names_hash_max_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_MAIN_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_main_conf_t, server_names_hash),
|
||||
offsetof(ngx_http_core_main_conf_t, server_names_hash_max_size),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("server_names_hash_threshold"),
|
||||
{ ngx_string("server_names_hash_bucket_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_MAIN_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_main_conf_t, server_names_hash_threshold),
|
||||
offsetof(ngx_http_core_main_conf_t, server_names_hash_bucket_size),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("server"),
|
||||
@ -1715,8 +1715,8 @@ ngx_http_core_create_main_conf(ngx_conf_t *cf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cmcf->server_names_hash = NGX_CONF_UNSET_UINT;
|
||||
cmcf->server_names_hash_threshold = NGX_CONF_UNSET_UINT;
|
||||
cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
|
||||
cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;
|
||||
|
||||
return cmcf;
|
||||
}
|
||||
@ -1727,14 +1727,17 @@ ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
|
||||
{
|
||||
ngx_http_core_main_conf_t *cmcf = conf;
|
||||
|
||||
if (cmcf->server_names_hash == NGX_CONF_UNSET_UINT) {
|
||||
cmcf->server_names_hash = 1009;
|
||||
if (cmcf->server_names_hash_max_size == NGX_CONF_UNSET_UINT) {
|
||||
cmcf->server_names_hash_max_size = 512;
|
||||
}
|
||||
|
||||
if (cmcf->server_names_hash_threshold == NGX_CONF_UNSET_UINT) {
|
||||
cmcf->server_names_hash_threshold = 50;
|
||||
if (cmcf->server_names_hash_bucket_size == NGX_CONF_UNSET_UINT) {
|
||||
cmcf->server_names_hash_bucket_size = ngx_cacheline_size;
|
||||
}
|
||||
|
||||
cmcf->server_names_hash_bucket_size =
|
||||
ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
@ -1768,7 +1771,8 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
|
||||
}
|
||||
|
||||
if (ngx_array_init(&cscf->server_names, cf->pool, 4,
|
||||
sizeof(ngx_http_server_name_t)) == NGX_ERROR)
|
||||
sizeof(ngx_http_server_name_t))
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
@ -1792,7 +1796,6 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
ngx_http_listen_t *ls;
|
||||
ngx_http_server_name_t *sn;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
/* TODO: it does not merge, it inits only */
|
||||
|
||||
@ -1837,13 +1840,6 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
sn->name.len = ngx_strlen(sn->name.data);
|
||||
sn->core_srv_conf = conf;
|
||||
sn->wildcard = 0;
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
if (cmcf->max_server_name_len < sn->name.len) {
|
||||
cmcf->max_server_name_len = sn->name.len;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_conf_merge_size_value(conf->connection_pool_size,
|
||||
@ -2279,49 +2275,60 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
static char *
|
||||
ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_srv_conf_t *scf = conf;
|
||||
ngx_http_core_srv_conf_t *cscf = conf;
|
||||
|
||||
u_char ch;
|
||||
ngx_str_t *value, name;
|
||||
ngx_uint_t i;
|
||||
ngx_str_t *value;
|
||||
ngx_http_server_name_t *sn;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
/* TODO: warn about duplicate 'server_name' directives */
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
for (i = 1; i < cf->args->nelts; i++) {
|
||||
if (value[i].len == 0) {
|
||||
ch = value[1].data[0];
|
||||
|
||||
if (cscf->server_name.data == NULL && value[1].len) {
|
||||
if (ch == '*') {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"server name \"%V\" is invalid "
|
||||
"in \"%V\" directive",
|
||||
&value[i], &cmd->name);
|
||||
"first server name \"%V\" must not be wildcard",
|
||||
&value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
sn = ngx_array_push(&scf->server_names);
|
||||
name = value[1];
|
||||
|
||||
if (ch == '.') {
|
||||
name.len--;
|
||||
name.data++;
|
||||
}
|
||||
|
||||
cscf->server_name.len = name.len;
|
||||
cscf->server_name.data = ngx_pstrdup(cf->pool, &name);
|
||||
if (cscf->server_name.data == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < cf->args->nelts; i++) {
|
||||
|
||||
ch = value[i].data[0];
|
||||
|
||||
if (value[i].len == 0
|
||||
|| (ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
|
||||
|| (ch == '.' && value[i].len < 2))
|
||||
{
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"server name \"%V\" is invalid", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
sn = ngx_array_push(&cscf->server_names);
|
||||
if (sn == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
sn->name.len = value[i].len;
|
||||
sn->name.data = value[i].data;
|
||||
sn->core_srv_conf = scf;
|
||||
|
||||
if (sn->name.data[0] == '*') {
|
||||
sn->name.len--;
|
||||
sn->name.data++;
|
||||
sn->wildcard = 1;
|
||||
|
||||
} else {
|
||||
sn->wildcard = 0;
|
||||
}
|
||||
|
||||
if (cmcf->max_server_name_len < sn->name.len) {
|
||||
cmcf->max_server_name_len = sn->name.len;
|
||||
}
|
||||
sn->core_srv_conf = cscf;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
@ -73,10 +73,8 @@ typedef struct {
|
||||
ngx_hash0_t headers_in_hash;
|
||||
ngx_hash0_t variables_hash;
|
||||
|
||||
ngx_uint_t server_names_hash;
|
||||
ngx_uint_t server_names_hash_threshold;
|
||||
|
||||
size_t max_server_name_len;
|
||||
ngx_uint_t server_names_hash_max_size;
|
||||
ngx_uint_t server_names_hash_bucket_size;
|
||||
|
||||
ngx_array_t variables; /* ngx_http_variable_t */
|
||||
ngx_array_t all_variables; /* ngx_http_variable_t */
|
||||
@ -99,6 +97,8 @@ typedef struct {
|
||||
/* server ctx */
|
||||
ngx_http_conf_ctx_t *ctx;
|
||||
|
||||
ngx_str_t server_name;
|
||||
|
||||
size_t connection_pool_size;
|
||||
size_t request_pool_size;
|
||||
size_t client_header_buffer_size;
|
||||
@ -115,45 +115,53 @@ typedef struct {
|
||||
|
||||
/* list of structures to find core_srv_conf quickly at run time */
|
||||
|
||||
|
||||
typedef struct {
|
||||
in_addr_t addr;
|
||||
/* the default server configuration for this address:port */
|
||||
ngx_http_core_srv_conf_t *core_srv_conf;
|
||||
ngx_http_virtual_names_t *virtual_names;
|
||||
} ngx_http_in_addr_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
in_port_t port;
|
||||
ngx_str_t port_text;
|
||||
ngx_array_t addrs; /* array of ngx_http_in_addr_t */
|
||||
ngx_http_in_addr_t *addrs;
|
||||
ngx_uint_t naddrs;
|
||||
} ngx_http_in_port_t;
|
||||
|
||||
|
||||
struct ngx_http_in_addr_s {
|
||||
typedef struct {
|
||||
in_port_t port;
|
||||
ngx_array_t addrs; /* array of ngx_http_conf_in_addr_t */
|
||||
} ngx_http_conf_in_port_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
in_addr_t addr;
|
||||
|
||||
ngx_hash_t hash;
|
||||
ngx_hash_wildcard_t *dns_wildcards;
|
||||
|
||||
ngx_array_t names; /* array of ngx_http_server_name_t */
|
||||
ngx_array_t *hash; /* hash of ngx_http_server_name_t */
|
||||
ngx_array_t wildcards; /* array of ngx_http_server_name_t */
|
||||
|
||||
/* the default server configuration for this address:port */
|
||||
ngx_http_core_srv_conf_t *core_srv_conf;
|
||||
|
||||
ngx_http_listen_conf_t conf;
|
||||
};
|
||||
unsigned default_server:1;
|
||||
unsigned bind:1;
|
||||
|
||||
ngx_http_listen_conf_t *listen_conf;
|
||||
} ngx_http_conf_in_addr_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_http_core_srv_conf_t *core_srv_conf; /* virtual name server conf */
|
||||
|
||||
ngx_uint_t wildcard; /* unsigned wildcard:1 */
|
||||
} ngx_http_server_name_t;
|
||||
|
||||
|
||||
#define ngx_http_server_names_hash_key(key, name, len, prime) \
|
||||
{ \
|
||||
ngx_uint_t n0; \
|
||||
for (key = 0, n0 = 0; n0 < len; n0++) { \
|
||||
key += name[n0]; \
|
||||
} \
|
||||
key %= prime; \
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_int_t status;
|
||||
ngx_int_t overwrite;
|
||||
|
@ -203,11 +203,10 @@ void ngx_http_init_request(ngx_event_t *rev)
|
||||
struct sockaddr_in sin;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_in_port_t *in_port;
|
||||
ngx_http_in_addr_t *in_addr;
|
||||
ngx_http_in_port_t *hip;
|
||||
ngx_http_in_addr_t *hia;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_server_name_t *server_name;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
@ -269,15 +268,15 @@ void ngx_http_init_request(ngx_event_t *rev)
|
||||
|
||||
/* AF_INET only */
|
||||
|
||||
in_port = c->servers;
|
||||
in_addr = in_port->addrs.elts;
|
||||
hip = c->servers;
|
||||
hia = hip->addrs;
|
||||
|
||||
r->port = in_port->port;
|
||||
r->port_text = &in_port->port_text;
|
||||
r->port = hip->port;
|
||||
r->port_text = &hip->port_text;
|
||||
|
||||
i = 0;
|
||||
|
||||
if (in_port->addrs.nelts > 1) {
|
||||
if (hip->naddrs > 1) {
|
||||
|
||||
/*
|
||||
* There are several addresses on this port and one of them
|
||||
@ -308,25 +307,27 @@ void ngx_http_init_request(ngx_event_t *rev)
|
||||
|
||||
/* the last in_port->addrs address is "*" */
|
||||
|
||||
for ( /* void */ ; i < in_port->addrs.nelts - 1; i++) {
|
||||
if (in_addr[i].addr == r->in_addr) {
|
||||
for ( /* void */ ; i < hip->naddrs - 1; i++) {
|
||||
if (hia[i].addr == r->in_addr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
r->in_addr = in_addr[0].addr;
|
||||
r->in_addr = hia[0].addr;
|
||||
}
|
||||
|
||||
r->virtual_names = &in_addr[i];
|
||||
r->virtual_names = hia[i].virtual_names;
|
||||
|
||||
/* the default server configuration for the address:port */
|
||||
cscf = in_addr[i].core_srv_conf;
|
||||
cscf = hia[i].core_srv_conf;
|
||||
|
||||
r->main_conf = cscf->ctx->main_conf;
|
||||
r->srv_conf = cscf->ctx->srv_conf;
|
||||
r->loc_conf = cscf->ctx->loc_conf;
|
||||
|
||||
r->server_name = cscf->server_name;
|
||||
|
||||
rev->handler = ngx_http_process_request_line;
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
@ -350,9 +351,6 @@ void ngx_http_init_request(ngx_event_t *rev)
|
||||
|
||||
#endif
|
||||
|
||||
server_name = cscf->server_names.elts;
|
||||
r->server_name = server_name->name;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
c->log->file = clcf->err_log->file;
|
||||
if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
|
||||
@ -1321,80 +1319,37 @@ ngx_http_process_request_header(ngx_http_request_t *r)
|
||||
static ngx_int_t
|
||||
ngx_http_find_virtual_server(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i, n, key;
|
||||
ngx_http_server_name_t *name;
|
||||
size_t len;
|
||||
u_char *host;
|
||||
ngx_http_virtual_names_t *vn;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
if (r->virtual_names->hash) {
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
vn = r->virtual_names;
|
||||
|
||||
ngx_http_server_names_hash_key(key,
|
||||
r->headers_in.host->value.data,
|
||||
r->headers_in.host_name_len,
|
||||
cmcf->server_names_hash);
|
||||
|
||||
name = r->virtual_names->hash[key].elts;
|
||||
n = r->virtual_names->hash[key].nelts;
|
||||
|
||||
} else {
|
||||
name = r->virtual_names->names.elts;
|
||||
n = r->virtual_names->names.nelts;
|
||||
if (vn == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
host = r->headers_in.host->value.data;
|
||||
len = r->headers_in.host_name_len;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"server name: %V", &name[i].name);
|
||||
/* STUB: ngx_hash_key() here is STUB */
|
||||
|
||||
if (r->headers_in.host_name_len != name[i].name.len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = ngx_strncmp(r->headers_in.host->value.data,
|
||||
name[i].name.data, name[i].name.len);
|
||||
|
||||
if (rc == 0) {
|
||||
r->server_name = name[i].name;
|
||||
if (vn->hash.buckets) {
|
||||
cscf = ngx_hash_find(&vn->hash, ngx_hash_key(host, len), host, len);
|
||||
if (cscf) {
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
/* the server names are lexicographically sorted */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (r->virtual_names->wildcards.nelts) {
|
||||
|
||||
name = r->virtual_names->wildcards.elts;
|
||||
for (i = 0; i < r->virtual_names->wildcards.nelts; i++) {
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"server name: %V", &name[i].name);
|
||||
|
||||
if (r->headers_in.host_name_len <= name[i].name.len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"server name: %s",
|
||||
r->headers_in.host->value.data
|
||||
+ (r->headers_in.host_name_len - name[i].name.len));
|
||||
|
||||
if (ngx_strncmp(r->headers_in.host->value.data
|
||||
+ (r->headers_in.host_name_len - name[i].name.len),
|
||||
name[i].name.data, name[i].name.len) == 0)
|
||||
{
|
||||
r->server_name.len = r->headers_in.host_name_len;
|
||||
r->server_name.data = r->headers_in.host->value.data;
|
||||
if (vn->dns_wildcards && vn->dns_wildcards->hash.buckets) {
|
||||
cscf = ngx_hash_find_wildcard(vn->dns_wildcards, host, len);
|
||||
|
||||
if (cscf) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
@ -1406,8 +1361,11 @@ ngx_http_find_virtual_server(ngx_http_request_t *r)
|
||||
|
||||
found:
|
||||
|
||||
r->srv_conf = name[i].core_srv_conf->ctx->srv_conf;
|
||||
r->loc_conf = name[i].core_srv_conf->ctx->loc_conf;
|
||||
r->server_name.len = len;
|
||||
r->server_name.data = host;
|
||||
|
||||
r->srv_conf = cscf->ctx->srv_conf;
|
||||
r->loc_conf = cscf->ctx->loc_conf;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
r->connection->log->file = clcf->err_log->file;
|
||||
|
@ -250,6 +250,12 @@ typedef struct {
|
||||
} ngx_http_connection_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_t hash;
|
||||
ngx_hash_wildcard_t *dns_wildcards;
|
||||
} ngx_http_virtual_names_t;
|
||||
|
||||
|
||||
typedef void (*ngx_http_cleanup_pt)(void *data);
|
||||
|
||||
typedef struct ngx_http_cleanup_s ngx_http_cleanup_t;
|
||||
@ -325,7 +331,7 @@ struct ngx_http_request_s {
|
||||
ngx_uint_t port;
|
||||
ngx_str_t *port_text; /* ":80" */
|
||||
ngx_str_t server_name;
|
||||
ngx_http_in_addr_t *virtual_names;
|
||||
ngx_http_virtual_names_t *virtual_names;
|
||||
|
||||
ngx_uint_t phase;
|
||||
ngx_int_t phase_handler;
|
||||
|
@ -344,7 +344,7 @@ ngx_http_upstream_init(ngx_http_request_t *r)
|
||||
|
||||
u->state->response_time = tp->sec * 1000 + tp->msec;
|
||||
|
||||
cln = ngx_http_cleanup_add(r, sizeof(void *));
|
||||
cln = ngx_http_cleanup_add(r, 0);
|
||||
if (cln == NULL) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user