mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
allow regex as "map" parameter
This commit is contained in:
parent
32c73df97a
commit
0519b43a77
@ -20,6 +20,9 @@ typedef struct {
|
||||
|
||||
ngx_array_t *values_hash;
|
||||
ngx_array_t var_values;
|
||||
#if (NGX_PCRE)
|
||||
ngx_array_t regexes;
|
||||
#endif
|
||||
|
||||
ngx_http_variable_value_t *default_value;
|
||||
ngx_conf_t *cf;
|
||||
@ -28,7 +31,7 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_combined_t hash;
|
||||
ngx_http_map_t map;
|
||||
ngx_http_complex_value_t value;
|
||||
ngx_http_variable_value_t *default_value;
|
||||
ngx_uint_t hostnames; /* unsigned hostnames:1 */
|
||||
@ -126,7 +129,7 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
|
||||
key = ngx_hash_strlow(val.data, val.data, len);
|
||||
|
||||
value = ngx_hash_find_combined(&map->hash, key, val.data, len);
|
||||
value = ngx_http_map_find(r, &map->map, key, val.data, len, &val);
|
||||
|
||||
if (value == NULL) {
|
||||
value = map->default_value;
|
||||
@ -249,6 +252,15 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
if (ngx_array_init(&ctx.regexes, cf->pool, 2, sizeof(ngx_http_map_regex_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx.default_value = NULL;
|
||||
ctx.cf = &save;
|
||||
ctx.hostnames = 0;
|
||||
@ -278,7 +290,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.hash = &map->map.hash.hash;
|
||||
hash.temp_pool = NULL;
|
||||
|
||||
if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts)
|
||||
@ -306,7 +318,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
map->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
|
||||
map->map.hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
if (ctx.keys.dns_wc_tail.nelts) {
|
||||
@ -326,9 +338,18 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
map->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
|
||||
map->map.hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (ctx.regexes.nelts) {
|
||||
map->map.regex = ctx.regexes.elts;
|
||||
map->map.nregex = ctx.regexes.nelts;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
return rv;
|
||||
@ -491,6 +512,45 @@ found:
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (value[0].len && value[0].data[0] == '~') {
|
||||
ngx_regex_compile_t rc;
|
||||
ngx_http_map_regex_t *regex;
|
||||
u_char errstr[NGX_MAX_CONF_ERRSTR];
|
||||
|
||||
regex = ngx_array_push(&ctx->regexes);
|
||||
if (regex == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
value[0].len--;
|
||||
value[0].data++;
|
||||
|
||||
ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
|
||||
|
||||
if (value[0].data[0] == '*') {
|
||||
value[0].len--;
|
||||
value[0].data++;
|
||||
rc.options = NGX_REGEX_CASELESS;
|
||||
}
|
||||
|
||||
rc.pattern = value[0];
|
||||
rc.err.len = NGX_MAX_CONF_ERRSTR;
|
||||
rc.err.data = errstr;
|
||||
|
||||
regex->regex = ngx_http_regex_compile(ctx->cf, &rc);
|
||||
if (regex->regex == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
regex->value = var;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (value[0].len && value[0].data[0] == '\\') {
|
||||
value[0].len--;
|
||||
value[0].data++;
|
||||
|
@ -1660,6 +1660,50 @@ ngx_http_variable_pid(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_http_map_find(ngx_http_request_t *r, ngx_http_map_t *map, ngx_uint_t key,
|
||||
u_char *text, size_t len, ngx_str_t *match)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = ngx_hash_find_combined(&map->hash, key, text, len);
|
||||
if (p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (len && map->nregex) {
|
||||
ngx_int_t n;
|
||||
ngx_uint_t i;
|
||||
ngx_http_map_regex_t *reg;
|
||||
|
||||
reg = map->regex;
|
||||
|
||||
for (i = 0; i < map->nregex; i++) {
|
||||
|
||||
n = ngx_http_regex_exec(r, reg[i].regex, match);
|
||||
|
||||
if (n == NGX_OK) {
|
||||
return reg[i].value;
|
||||
}
|
||||
|
||||
if (n == NGX_DECLINED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* NGX_ERROR */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
static ngx_int_t
|
||||
|
@ -76,6 +76,12 @@ typedef struct {
|
||||
} ngx_http_regex_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_regex_t *regex;
|
||||
void *value;
|
||||
} ngx_http_map_regex_t;
|
||||
|
||||
|
||||
ngx_http_regex_t *ngx_http_regex_compile(ngx_conf_t *cf,
|
||||
ngx_regex_compile_t *rc);
|
||||
ngx_int_t ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re,
|
||||
@ -84,6 +90,19 @@ ngx_int_t ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re,
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_hash_combined_t hash;
|
||||
#if (NGX_PCRE)
|
||||
ngx_http_map_regex_t *regex;
|
||||
ngx_uint_t nregex;
|
||||
#endif
|
||||
} ngx_http_map_t;
|
||||
|
||||
|
||||
void *ngx_http_map_find(ngx_http_request_t *r, ngx_http_map_t *map,
|
||||
ngx_uint_t key, u_char *text, size_t len, ngx_str_t *match);
|
||||
|
||||
|
||||
ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf);
|
||||
ngx_int_t ngx_http_variables_init_vars(ngx_conf_t *cf);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user