Mercurial > hg > nginx
changeset 6535:db699978a33f
Map: support of complex values in resulting strings.
author | Dmitry Volyntsev <xeioex@nginx.com> |
---|---|
date | Thu, 12 May 2016 16:43:19 +0300 |
parents | 19a54ba76c04 |
children | f7849bfb6d21 |
files | src/http/modules/ngx_http_map_module.c |
diffstat | 1 files changed, 68 insertions(+), 60 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_map_module.c Wed May 11 17:55:30 2016 +0300 +++ b/src/http/modules/ngx_http_map_module.c Thu May 12 16:43:19 2016 +0300 @@ -20,7 +20,6 @@ ngx_hash_keys_arrays_t keys; ngx_array_t *values_hash; - ngx_array_t var_values; #if (NGX_PCRE) ngx_array_t regexes; #endif @@ -110,7 +109,8 @@ { ngx_http_map_ctx_t *map = (ngx_http_map_ctx_t *) data; - ngx_str_t val; + ngx_str_t val, str; + ngx_http_complex_value_t *cv; ngx_http_variable_value_t *value; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -131,15 +131,22 @@ } if (!value->valid) { - value = ngx_http_get_flushed_variable(r, (uintptr_t) value->data); + cv = (ngx_http_complex_value_t *) value->data; + + if (ngx_http_complex_value(r, cv, &str) != NGX_OK) { + return NGX_ERROR; + } - if (value == NULL || value->not_found) { - value = &ngx_http_variable_null_value; - } + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->len = str.len; + v->data = str.data; + + } else { + *v = *value; } - *v = *value; - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http map: \"%V\" \"%v\"", &val, v); @@ -246,14 +253,6 @@ return NGX_CONF_ERROR; } - if (ngx_array_init(&ctx.var_values, cf->pool, 2, - sizeof(ngx_http_variable_value_t)) - != NGX_OK) - { - ngx_destroy_pool(pool); - return NGX_CONF_ERROR; - } - #if (NGX_PCRE) if (ngx_array_init(&ctx.regexes, cf->pool, 2, sizeof(ngx_http_map_regex_t)) != NGX_OK) @@ -375,11 +374,15 @@ static char * ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) { - ngx_int_t rv, index; - ngx_str_t *value, name; - ngx_uint_t i, key; - ngx_http_map_conf_ctx_t *ctx; - ngx_http_variable_value_t *var, **vp; + u_char *data; + size_t len; + ngx_int_t rv; + ngx_str_t *value, v; + ngx_uint_t i, key; + ngx_http_map_conf_ctx_t *ctx; + ngx_http_complex_value_t cv, *cvp; + ngx_http_variable_value_t *var, **vp; + ngx_http_compile_complex_value_t ccv; ctx = cf->ctx; @@ -401,39 +404,6 @@ return ngx_conf_include(cf, dummy, conf); } - if (value[1].data[0] == '$') { - name = value[1]; - name.len--; - name.data++; - - index = ngx_http_get_variable_index(ctx->cf, &name); - if (index == NGX_ERROR) { - return NGX_CONF_ERROR; - } - - var = ctx->var_values.elts; - - for (i = 0; i < ctx->var_values.nelts; i++) { - if (index == (intptr_t) var[i].data) { - var = &var[i]; - goto found; - } - } - - var = ngx_array_push(&ctx->var_values); - if (var == NULL) { - return NGX_CONF_ERROR; - } - - var->valid = 0; - var->no_cacheable = 0; - var->not_found = 0; - var->len = 0; - var->data = (u_char *) (intptr_t) index; - - goto found; - } - key = 0; for (i = 0; i < value[1].len; i++) { @@ -446,11 +416,22 @@ if (vp) { for (i = 0; i < ctx->values_hash[key].nelts; i++) { - if (value[1].len != (size_t) vp[i]->len) { + + if (vp[i]->valid) { + data = vp[i]->data; + len = vp[i]->len; + + } else { + cvp = (ngx_http_complex_value_t *) vp[i]->data; + data = cvp->value.data; + len = cvp->value.len; + } + + if (value[1].len != len) { continue; } - if (ngx_strncmp(value[1].data, vp[i]->data, value[1].len) == 0) { + if (ngx_strncmp(value[1].data, data, len) == 0) { var = vp[i]; goto found; } @@ -470,13 +451,40 @@ return NGX_CONF_ERROR; } - var->len = value[1].len; - var->data = ngx_pstrdup(ctx->keys.pool, &value[1]); - if (var->data == NULL) { + v.len = value[1].len; + v.data = ngx_pstrdup(ctx->keys.pool, &value[1]); + if (v.data == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = ctx->cf; + ccv.value = &v; + ccv.complex_value = &cv; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; } - var->valid = 1; + if (cv.lengths != NULL) { + cvp = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_complex_value_t)); + if (cvp == NULL) { + return NGX_CONF_ERROR; + } + + *cvp = cv; + + var->len = 0; + var->data = (u_char *) cvp; + var->valid = 0; + + } else { + var->len = v.len; + var->data = v.data; + var->valid = 1; + } + var->no_cacheable = 0; var->not_found = 0;