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>2007-06-11 23:49:22 +0400
committerIgor Sysoev <igor@sysoev.ru>2007-06-11 23:49:22 +0400
commit9d8a75c5256ada429fdeff93584044eca6cf1a56 (patch)
tree98226bea23d49242292bd5ee4ec0c969d07099b6 /src/http/modules
parentad39e5c7464bebda27c1ccb85fa4872265a399d0 (diff)
the "www.example.*" wildcard hash support
Diffstat (limited to 'src/http/modules')
-rw-r--r--src/http/modules/ngx_http_map_module.c113
-rw-r--r--src/http/modules/ngx_http_referer_module.c87
2 files changed, 97 insertions, 103 deletions
diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c
index fb8e8ee60..4a8acd00d 100644
--- a/src/http/modules/ngx_http_map_module.c
+++ b/src/http/modules/ngx_http_map_module.c
@@ -26,8 +26,7 @@ typedef struct {
typedef struct {
- ngx_hash_t hash;
- ngx_hash_wildcard_t *dns_wildcards;
+ ngx_hash_combined_t hash;
ngx_int_t index;
ngx_http_variable_value_t *default_value;
ngx_uint_t hostnames; /* unsigned hostnames:1 */
@@ -142,28 +141,13 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
key = ngx_hash(key, name[i]);
}
- value = NULL;
-
- if (map->hash.buckets) {
- value = ngx_hash_find(&map->hash, key, name, len);
- }
+ value = ngx_hash_find_combined(&map->hash, key, name, len);
if (value) {
*v = *value;
} else {
- if (map->dns_wildcards && map->dns_wildcards->hash.buckets) {
- value = ngx_hash_find_wildcard(map->dns_wildcards, name, len);
- if (value) {
- *v = *value;
-
- } else {
- *v = *map->default_value;
- }
-
- } else {
- *v = *map->default_value;
- }
+ *v = *map->default_value;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -282,6 +266,9 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return rv;
}
+ map->default_value = ctx.default_value ? ctx.default_value:
+ &ngx_http_variable_null_value;
+
hash.key = ngx_hash_key_lc;
hash.max_size = mcf->hash_max_size;
hash.bucket_size = mcf->hash_bucket_size;
@@ -289,7 +276,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
hash.pool = cf->pool;
if (ctx.keys.keys.nelts) {
- hash.hash = &map->hash;
+ hash.hash = &map->hash.hash;
hash.temp_pool = NULL;
if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts)
@@ -300,27 +287,44 @@ 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.keys.dns_wc_head.nelts) {
+
+ ngx_qsort(ctx.keys.dns_wc_head.elts,
+ (size_t) ctx.keys.dns_wc_head.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.keys.dns_wc_head.elts,
+ ctx.keys.dns_wc_head.nelts)
+ != NGX_OK)
+ {
+ ngx_destroy_pool(pool);
+ return NGX_CONF_ERROR;
+ }
- if (ctx.keys.dns_wildcards.nelts) {
+ map->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
+ }
+
+ if (ctx.keys.dns_wc_tail.nelts) {
- ngx_qsort(ctx.keys.dns_wildcards.elts,
- (size_t) ctx.keys.dns_wildcards.nelts,
+ ngx_qsort(ctx.keys.dns_wc_tail.elts,
+ (size_t) ctx.keys.dns_wc_tail.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.keys.dns_wildcards.elts,
- ctx.keys.dns_wildcards.nelts)
+ if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_tail.elts,
+ ctx.keys.dns_wc_tail.nelts)
!= NGX_OK)
{
ngx_destroy_pool(pool);
return NGX_CONF_ERROR;
}
- map->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
+ map->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
}
ngx_destroy_pool(pool);
@@ -344,10 +348,9 @@ ngx_http_map_cmp_dns_wildcards(const void *one, const void *two)
static char *
ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
{
- u_char ch;
ngx_int_t rc;
ngx_str_t *value, file;
- ngx_uint_t i, key, flags;
+ ngx_uint_t i, key;
ngx_http_map_conf_ctx_t *ctx;
ngx_http_variable_value_t *var, **vp;
@@ -439,50 +442,36 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
found:
- ch = value[0].data[0];
-
- if ((ch != '*' && ch != '.') || ctx->hostnames == 0) {
-
- if (ngx_strcmp(value[0].data, "default") == 0) {
-
- if (ctx->default_value) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate default map parameter");
- return NGX_CONF_ERROR;
- }
-
- ctx->default_value = var;
-
- return NGX_CONF_OK;
- }
-
- if (value[0].len && ch == '!') {
- value[0].len--;
- value[0].data++;
- }
-
- flags = 0;
+ if (ngx_strcmp(value[0].data, "default") == 0) {
- } else {
-
- if ((ch == '*' && (value[0].len < 3 || value[0].data[1] != '.'))
- || (ch == '.' && value[0].len < 2))
- {
+ if (ctx->default_value) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid DNS wildcard \"%V\"", &value[0]);
-
+ "duplicate default map parameter");
return NGX_CONF_ERROR;
}
- flags = NGX_HASH_WILDCARD_KEY;
+ ctx->default_value = var;
+
+ return NGX_CONF_OK;
}
- rc = ngx_hash_add_key(&ctx->keys, &value[0], var, flags);
+ if (value[0].len && value[0].data[0] == '!') {
+ value[0].len--;
+ value[0].data++;
+ }
+
+ rc = ngx_hash_add_key(&ctx->keys, &value[0], var,
+ (ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0);
if (rc == NGX_OK) {
return NGX_CONF_OK;
}
+ if (rc == NGX_DECLINED) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid hostname or wildcard \"%V\"", &value[0]);
+ }
+
if (rc == NGX_BUSY) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"conflicting parameter \"%V\"", &value[0]);
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
index 2d16bd5cb..8559521e2 100644
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -12,8 +12,7 @@
#define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
typedef struct {
- ngx_hash_t hash;
- ngx_hash_wildcard_t *dns_wildcards;
+ ngx_hash_combined_t hash;
ngx_flag_t no_referer;
ngx_flag_t blocked_referer;
@@ -90,7 +89,10 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
- if (rlcf->hash.buckets == NULL && rlcf->dns_wildcards == NULL) {
+ if (rlcf->hash.hash.buckets == NULL
+ && rlcf->hash.wc_head == NULL
+ && rlcf->hash.wc_tail == NULL)
+ {
goto valid;
}
@@ -135,18 +137,10 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
len = p - ref;
- if (rlcf->hash.buckets) {
- uri = ngx_hash_find(&rlcf->hash, key, buf, len);
- if (uri) {
- goto uri;
- }
- }
+ uri = ngx_hash_find_combined(&rlcf->hash, key, buf, len);
- if (rlcf->dns_wildcards) {
- uri = ngx_hash_find_wildcard(rlcf->dns_wildcards, buf, len);
- if (uri) {
- goto uri;
- }
+ if (uri) {
+ goto uri;
}
invalid:
@@ -208,7 +202,6 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
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);
@@ -217,7 +210,9 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
}
if ((conf->no_referer == 1 || conf->blocked_referer == 1)
- && conf->keys->keys.nelts == 0 && conf->keys->dns_wildcards.nelts == 0)
+ && conf->keys->keys.nelts == 0
+ && conf->keys->dns_wc_head.nelts == 0
+ && conf->keys->dns_wc_tail.nelts == 0)
{
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"the \"none\" or \"blocked\" referers are specified "
@@ -233,7 +228,7 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
hash.pool = cf->pool;
if (conf->keys->keys.nelts) {
- hash.hash = &conf->hash;
+ hash.hash = &conf->hash.hash;
hash.temp_pool = NULL;
if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts)
@@ -243,24 +238,44 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
}
}
- if (conf->keys->dns_wildcards.nelts) {
+ if (conf->keys->dns_wc_head.nelts) {
- ngx_qsort(conf->keys->dns_wildcards.elts,
- (size_t) conf->keys->dns_wildcards.nelts,
+ ngx_qsort(conf->keys->dns_wc_head.elts,
+ (size_t) conf->keys->dns_wc_head.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)
+ if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_head.elts,
+ conf->keys->dns_wc_head.nelts)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
- conf->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
+ conf->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
+ }
+
+ if (conf->keys->dns_wc_tail.nelts) {
+
+ ngx_qsort(conf->keys->dns_wc_tail.elts,
+ (size_t) conf->keys->dns_wc_tail.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_wc_tail.elts,
+ conf->keys->dns_wc_tail.nelts)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+
+ conf->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
}
if (conf->no_referer == NGX_CONF_UNSET) {
@@ -373,23 +388,8 @@ static char *
ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
ngx_str_t *value, ngx_str_t *uri)
{
- u_char ch;
- ngx_int_t rc;
- ngx_str_t *u;
- 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;
+ ngx_int_t rc;
+ ngx_str_t *u;
if (uri->len == 0) {
u = NGX_HTTP_REFERER_NO_URI_PART;
@@ -403,12 +403,17 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
*u = *uri;
}
- rc = ngx_hash_add_key(keys, value, u, flags);
+ rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
if (rc == NGX_OK) {
return NGX_CONF_OK;
}
+ if (rc == NGX_DECLINED) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid hostname or wildcard \"%V\"", value);
+ }
+
if (rc == NGX_BUSY) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"conflicting parameter \"%V\"", value);