Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2005-12-26 20:07:48 +0300
committerIgor Sysoev <igor@sysoev.ru>2005-12-26 20:07:48 +0300
commit305a9d83cfba0d0330bd12af4ca56943b10e958e (patch)
tree8dc3ead91f77a4ae8953f289f57ff49b4ce9c9f1 /src/http/modules
parentf9cbecc16a9851e8403bf7dae96feebf63b1ac3e (diff)
nginx-0.3.18-RELEASE importrelease-0.3.18
*) 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.
Diffstat (limited to 'src/http/modules')
-rw-r--r--src/http/modules/ngx_http_map_module.c61
-rw-r--r--src/http/modules/ngx_http_proxy_module.c2
-rw-r--r--src/http/modules/ngx_http_referer_module.c243
3 files changed, 172 insertions, 134 deletions
diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c
index 04e2e0ac7..2cfb443e2 100644
--- a/src/http/modules/ngx_http_map_module.c
+++ b/src/http/modules/ngx_http_map_module.c
@@ -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)
- {
- 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.keys.pool = cf->pool;
+ ctx.keys.temp_pool = pool;
- ctx.hash.keys_hash = ngx_pcalloc(pool,
- sizeof(ngx_array_t) * NGX_HTTP_CONFIG_HASH);
- if (ctx.hash.keys_hash == NULL) {
+ if (ngx_hash_keys_array_init(&ctx.keys, NGX_HASH_LARGE) != NGX_OK) {
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;
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index c2be2c44e..f63e28872 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -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)
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
index cd8be7879..622f25710 100644
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -10,15 +10,13 @@
typedef struct {
- ngx_str_t name;
- ngx_uint_t wildcard;
-} ngx_http_referer_t;
+ ngx_hash_t hash;
+ ngx_hash_wildcard_t *dns_wildcards;
-typedef struct {
- ngx_array_t *referers; /* ngx_http_referer_t */
+ ngx_flag_t no_referer;
+ ngx_flag_t blocked_referer;
- 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;
- size_t len;
- ngx_uint_t i, n;
- ngx_http_referer_t *refs;
- ngx_http_referer_conf_t *cf;
+ u_char *p, *ref;
+ size_t len;
+ 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,37 +123,25 @@ 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;
+ for (p = ref; p < ref + len; p++) {
+ if (*p == '/' || *p == ':') {
+ break;
}
+ }
- if (refs[i].wildcard) {
- for (n = 0; n < len; n++) {
- if (ref[n] == '/' || ref[n] == ':') {
- break;
- }
-
- if (ref[n] != '.') {
- continue;
- }
+ len = p - ref;
- if (ngx_strncmp(&ref[n], refs[i].name.data,
- refs[i].name.len) == 0)
- {
- *v = ngx_http_variable_null_value;
- return NGX_OK;
- }
- }
+ 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)
- {
- *v = ngx_http_variable_null_value;
- return NGX_OK;
- }
+ 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;
}
}
@@ -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;
+ }
+
+ rlcf->keys->pool = cf->pool;
+ rlcf->keys->temp_pool = cf->pool;
- 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) {
+ 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;
- }
+ cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
+
+ sn = cscf->server_names.elts;
+ 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;
+ }
+ }
- if (value[i].data[0] != '*') {
- ref->name = value[i];
- ref->wildcard = 0;
continue;
}
+ p = (u_char *) ngx_strstr(value[i].data, "/");
- if (value[i].data[1] != '.') {
+ if (p) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid wildcard referer \"%V\"", &value[i]);
+ "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;
}
+ }
- ref->name.len = value[i].len - 1;
- ref->name.data = value[i].data + 1;
- ref->wildcard = 1;
+ 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;
}
- if (!server_names) {
+ 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;
}
- sn = cscf->server_names.elts;
- for (i = 0; i < cscf->server_names.nelts; i++) {
- ref = ngx_array_push(lcf->referers);
- if (ref == NULL) {
- return NGX_CONF_ERROR;
- }
+ if (rc == NGX_BUSY) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "conflicting parameter \"%V\"", value);
+ }
- 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;
- }
+ 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;
- }
- return NGX_CONF_OK;
+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);
}