diff options
author | Igor Sysoev <igor@sysoev.ru> | 2007-06-11 23:49:22 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2007-06-11 23:49:22 +0400 |
commit | 9d8a75c5256ada429fdeff93584044eca6cf1a56 (patch) | |
tree | 98226bea23d49242292bd5ee4ec0c969d07099b6 /src/http/modules | |
parent | ad39e5c7464bebda27c1ccb85fa4872265a399d0 (diff) |
the "www.example.*" wildcard hash support
Diffstat (limited to 'src/http/modules')
-rw-r--r-- | src/http/modules/ngx_http_map_module.c | 113 | ||||
-rw-r--r-- | src/http/modules/ngx_http_referer_module.c | 87 |
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); |