Var: dynamic variables support.

This commit adds the variables $arg_NAME, $header_NAME, and $cookie_NAME.
This commit is contained in:
Zhidao HONG
2022-07-14 04:32:49 +08:00
parent 7b80186f09
commit 45b89e3257
13 changed files with 407 additions and 49 deletions

View File

@@ -37,6 +37,12 @@ forwarded header to replace client address and protocol.
</para> </para>
</change> </change>
<change type="feature">
<para>
ability to get dynamic variables.
</para>
</change>
<change type="bugfix"> <change type="bugfix">
<para> <para>
an index file that didn't contain a file extension was incorrectly an index file that didn't contain a file extension was incorrectly

View File

@@ -72,6 +72,7 @@ typedef struct {
nxt_mp_t *pool; nxt_mp_t *pool;
nxt_str_t error; nxt_str_t error;
void *ctx; void *ctx;
nxt_array_t *var_fields; /* of nxt_var_field_t */
nxt_mp_t *conf_pool; nxt_mp_t *conf_pool;
nxt_uint_t ver; nxt_uint_t ver;
} nxt_conf_validation_t; } nxt_conf_validation_t;

View File

@@ -1210,6 +1210,11 @@ nxt_conf_validate(nxt_conf_validation_t *vldt)
{ {
nxt_int_t ret; nxt_int_t ret;
vldt->var_fields = nxt_array_create(vldt->pool, 4, sizeof(nxt_var_field_t));
if (nxt_slow_path(vldt->var_fields == NULL)) {
return NXT_ERROR;
}
ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_VLDT_OBJECT); ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_VLDT_OBJECT);
if (ret != NXT_OK) { if (ret != NXT_OK) {
return ret; return ret;
@@ -1342,7 +1347,7 @@ nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name,
{ {
u_char error[NXT_MAX_ERROR_STR]; u_char error[NXT_MAX_ERROR_STR];
if (nxt_var_test(value, error) != NXT_OK) { if (nxt_var_test(value, vldt->var_fields, error) != NXT_OK) {
return nxt_conf_vldt_error(vldt, "%s in the \"%V\" value.", return nxt_conf_vldt_error(vldt, "%s in the \"%V\" value.",
error, name); error, name);
} }

View File

@@ -339,6 +339,9 @@ nxt_array_t *nxt_http_cookies_parse(nxt_http_request_t *r);
int64_t nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name, int64_t nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name,
nxt_bool_t case_sensitive, uint8_t encoding); nxt_bool_t case_sensitive, uint8_t encoding);
int64_t nxt_http_argument_hash(nxt_mp_t *mp, nxt_str_t *name);
int64_t nxt_http_header_hash(nxt_mp_t *mp, nxt_str_t *name);
int64_t nxt_http_cookie_hash(nxt_mp_t *mp, nxt_str_t *name);
nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task, nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task,
nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf); nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf);
@@ -369,8 +372,8 @@ nxt_int_t nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_int_t nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf, nxt_int_t nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf,
nxt_upstream_t ***upstream_joint); nxt_upstream_t ***upstream_joint);
nxt_int_t nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, nxt_int_t nxt_http_return_init(nxt_router_conf_t *rtcf,
nxt_http_action_conf_t *acf); nxt_http_action_t *action, nxt_http_action_conf_t *acf);
nxt_int_t nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_int_t nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_http_action_t *action, nxt_http_action_conf_t *acf); nxt_http_action_t *action, nxt_http_action_conf_t *acf);

View File

@@ -1180,3 +1180,57 @@ end:
return nxt_http_field_hash_end(hash) & 0xFFFF; return nxt_http_field_hash_end(hash) & 0xFFFF;
} }
int64_t
nxt_http_argument_hash(nxt_mp_t *mp, nxt_str_t *name)
{
return nxt_http_field_hash(mp, name, 1, NXT_HTTP_URI_ENCODING_PLUS);
}
int64_t
nxt_http_header_hash(nxt_mp_t *mp, nxt_str_t *name)
{
u_char c, *p;
uint32_t i, hash;
nxt_str_t str;
str.length = name->length;
str.start = nxt_mp_nget(mp, str.length);
if (nxt_slow_path(str.start == NULL)) {
return -1;
}
p = str.start;
hash = NXT_HTTP_FIELD_HASH_INIT;
for (i = 0; i < name->length; i++) {
c = name->start[i];
if (c >= 'A' && c <= 'Z') {
*p = c | 0x20;
} else if (c == '_') {
*p = '-';
} else {
*p = c;
}
hash = nxt_http_field_hash_char(hash, *p);
p++;
}
*name = str;
return nxt_http_field_hash_end(hash) & 0xFFFF;
}
int64_t
nxt_http_cookie_hash(nxt_mp_t *mp, nxt_str_t *name)
{
return nxt_http_field_hash(mp, name, 1, NXT_HTTP_URI_ENCODING_NONE);
}

View File

@@ -32,12 +32,15 @@ static const nxt_http_request_state_t nxt_http_return_send_state;
nxt_int_t nxt_int_t
nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, nxt_http_return_init(nxt_router_conf_t *rtcf, nxt_http_action_t *action,
nxt_http_action_conf_t *acf) nxt_http_action_conf_t *acf)
{ {
nxt_mp_t *mp;
nxt_str_t str; nxt_str_t str;
nxt_http_return_conf_t *conf; nxt_http_return_conf_t *conf;
mp = rtcf->mem_pool;
conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t)); conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t));
if (nxt_slow_path(conf == NULL)) { if (nxt_slow_path(conf == NULL)) {
return NXT_ERROR; return NXT_ERROR;
@@ -54,7 +57,7 @@ nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action,
nxt_conf_get_string(acf->location, &str); nxt_conf_get_string(acf->location, &str);
conf->location = nxt_var_compile(&str, mp, 0); conf->location = nxt_var_compile(&str, mp, rtcf->var_fields, 0);
if (nxt_slow_path(conf->location == NULL)) { if (nxt_slow_path(conf->location == NULL)) {
return NXT_ERROR; return NXT_ERROR;
} }

View File

@@ -643,6 +643,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_mp_t *mp; nxt_mp_t *mp;
nxt_int_t ret; nxt_int_t ret;
nxt_str_t pass; nxt_str_t pass;
nxt_router_conf_t *rtcf;
nxt_http_action_conf_t acf; nxt_http_action_conf_t acf;
nxt_memzero(&acf, sizeof(acf)); nxt_memzero(&acf, sizeof(acf));
@@ -655,10 +656,11 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_memzero(action, sizeof(nxt_http_action_t)); nxt_memzero(action, sizeof(nxt_http_action_t));
mp = tmcf->router_conf->mem_pool; rtcf = tmcf->router_conf;
mp = rtcf->mem_pool;
if (acf.ret != NULL) { if (acf.ret != NULL) {
return nxt_http_return_init(mp, action, &acf); return nxt_http_return_init(rtcf, action, &acf);
} }
if (acf.share != NULL) { if (acf.share != NULL) {
@@ -671,7 +673,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_conf_get_string(acf.pass, &pass); nxt_conf_get_string(acf.pass, &pass);
action->u.var = nxt_var_compile(&pass, mp, 0); action->u.var = nxt_var_compile(&pass, mp, rtcf->var_fields, 0);
if (nxt_slow_path(action->u.var == NULL)) { if (nxt_slow_path(action->u.var == NULL)) {
return NXT_ERROR; return NXT_ERROR;
} }
@@ -1484,16 +1486,18 @@ nxt_http_action_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
{ {
nxt_mp_t *mp; nxt_mp_t *mp;
nxt_int_t ret; nxt_int_t ret;
nxt_router_conf_t *rtcf;
nxt_http_action_t *action; nxt_http_action_t *action;
mp = tmcf->router_conf->mem_pool; rtcf = tmcf->router_conf;
mp = rtcf->mem_pool;
action = nxt_mp_alloc(mp, sizeof(nxt_http_action_t)); action = nxt_mp_alloc(mp, sizeof(nxt_http_action_t));
if (nxt_slow_path(action == NULL)) { if (nxt_slow_path(action == NULL)) {
return NULL; return NULL;
} }
action->u.var = nxt_var_compile(pass, mp, 0); action->u.var = nxt_var_compile(pass, mp, rtcf->var_fields, 0);
if (nxt_slow_path(action->u.var == NULL)) { if (nxt_slow_path(action->u.var == NULL)) {
return NULL; return NULL;
} }

View File

@@ -79,9 +79,11 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_str_t str, *ret; nxt_str_t str, *ret;
nxt_var_t *var; nxt_var_t *var;
nxt_conf_value_t *cv; nxt_conf_value_t *cv;
nxt_router_conf_t *rtcf;
nxt_http_static_conf_t *conf; nxt_http_static_conf_t *conf;
mp = tmcf->router_conf->mem_pool; rtcf = tmcf->router_conf;
mp = rtcf->mem_pool;
conf = nxt_mp_zget(mp, sizeof(nxt_http_static_conf_t)); conf = nxt_mp_zget(mp, sizeof(nxt_http_static_conf_t));
if (nxt_slow_path(conf == NULL)) { if (nxt_slow_path(conf == NULL)) {
@@ -102,7 +104,7 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
cv = nxt_conf_get_array_element_or_itself(acf->share, i); cv = nxt_conf_get_array_element_or_itself(acf->share, i);
nxt_conf_get_string(cv, &str); nxt_conf_get_string(cv, &str);
var = nxt_var_compile(&str, mp, 1); var = nxt_var_compile(&str, mp, rtcf->var_fields, 1);
if (nxt_slow_path(var == NULL)) { if (nxt_slow_path(var == NULL)) {
return NXT_ERROR; return NXT_ERROR;
} }
@@ -128,7 +130,7 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_str_t chr, shr; nxt_str_t chr, shr;
nxt_bool_t is_const; nxt_bool_t is_const;
conf->chroot = nxt_var_compile(&acf->chroot, mp, 1); conf->chroot = nxt_var_compile(&acf->chroot, mp, rtcf->var_fields, 1);
if (nxt_slow_path(conf->chroot == NULL)) { if (nxt_slow_path(conf->chroot == NULL)) {
return NXT_ERROR; return NXT_ERROR;
} }

View File

@@ -8,29 +8,47 @@
static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_str_t *str,
void *ctx); void *ctx, uint16_t field);
static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str,
void *ctx); void *ctx, uint16_t field);
static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx); static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx,
static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx); uint16_t field);
static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx,
uint16_t field);
static nxt_int_t nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx,
uint16_t field);
static nxt_int_t nxt_http_var_header(nxt_task_t *task, nxt_str_t *str,
void *ctx, uint16_t field);
static nxt_int_t nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str,
void *ctx, uint16_t field);
static nxt_var_decl_t nxt_http_vars[] = { static nxt_var_decl_t nxt_http_vars[] = {
{ nxt_string("method"), {
&nxt_http_var_method, .name = nxt_string("method"),
0 }, .handler = nxt_http_var_method,
}, {
{ nxt_string("request_uri"), .name = nxt_string("request_uri"),
&nxt_http_var_request_uri, .handler = nxt_http_var_request_uri,
0 }, }, {
.name = nxt_string("uri"),
{ nxt_string("uri"), .handler = nxt_http_var_uri,
&nxt_http_var_uri, }, {
0 }, .name = nxt_string("host"),
.handler = nxt_http_var_host,
{ nxt_string("host"), }, {
&nxt_http_var_host, .name = nxt_string("arg"),
0 }, .handler = nxt_http_var_arg,
.field_hash = nxt_http_argument_hash,
}, {
.name = nxt_string("header"),
.handler = nxt_http_var_header,
.field_hash = nxt_http_header_hash,
}, {
.name = nxt_string("cookie"),
.handler = nxt_http_var_cookie,
.field_hash = nxt_http_cookie_hash,
},
}; };
@@ -42,7 +60,7 @@ nxt_http_register_variables(void)
static nxt_int_t static nxt_int_t
nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx) nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
{ {
nxt_http_request_t *r; nxt_http_request_t *r;
@@ -55,7 +73,8 @@ nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx)
static nxt_int_t static nxt_int_t
nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx) nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx,
uint16_t field)
{ {
nxt_http_request_t *r; nxt_http_request_t *r;
@@ -68,7 +87,7 @@ nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx)
static nxt_int_t static nxt_int_t
nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx) nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
{ {
nxt_http_request_t *r; nxt_http_request_t *r;
@@ -81,7 +100,7 @@ nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx)
static nxt_int_t static nxt_int_t
nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx) nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
{ {
nxt_http_request_t *r; nxt_http_request_t *r;
@@ -91,3 +110,125 @@ nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx)
return NXT_OK; return NXT_OK;
} }
static nxt_int_t
nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
{
nxt_array_t *args;
nxt_var_field_t *vf;
nxt_router_conf_t *rtcf;
nxt_http_request_t *r;
nxt_http_name_value_t *nv, *start;
r = ctx;
rtcf = r->conf->socket_conf->router_conf;
vf = nxt_var_field_get(rtcf->var_fields, field);
args = nxt_http_arguments_parse(r);
if (nxt_slow_path(args == NULL)) {
return NXT_ERROR;
}
start = args->elts;
nv = start + args->nelts - 1;
while (nv >= start) {
if (vf->hash == nv->hash
&& vf->name.length == nv->name_length
&& nxt_memcmp(vf->name.start, nv->name, nv->name_length) == 0)
{
str->start = nv->value;
str->length = nv->value_length;
return NXT_OK;
}
nv--;
}
nxt_str_null(str);
return NXT_OK;
}
static nxt_int_t
nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
{
nxt_var_field_t *vf;
nxt_http_field_t *f;
nxt_router_conf_t *rtcf;
nxt_http_request_t *r;
r = ctx;
rtcf = r->conf->socket_conf->router_conf;
vf = nxt_var_field_get(rtcf->var_fields, field);
nxt_list_each(f, r->fields) {
if (vf->hash == f->hash
&& vf->name.length == f->name_length
&& nxt_strncasecmp(vf->name.start, f->name, f->name_length) == 0)
{
str->start = f->value;
str->length = f->value_length;
return NXT_OK;
}
} nxt_list_loop;
nxt_str_null(str);
return NXT_OK;
}
static nxt_int_t
nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
{
nxt_array_t *cookies;
nxt_var_field_t *vf;
nxt_router_conf_t *rtcf;
nxt_http_request_t *r;
nxt_http_name_value_t *nv, *end;
r = ctx;
rtcf = r->conf->socket_conf->router_conf;
vf = nxt_var_field_get(rtcf->var_fields, field);
cookies = nxt_http_cookies_parse(r);
if (nxt_slow_path(cookies == NULL)) {
return NXT_ERROR;
}
nv = cookies->elts;
end = nv + cookies->nelts;
while (nv < end) {
if (vf->hash == nv->hash
&& vf->name.length == nv->name_length
&& nxt_memcmp(vf->name.start, nv->name, nv->name_length) == 0)
{
str->start = nv->value;
str->length = nv->value_length;
return NXT_OK;
}
nv++;
}
nxt_str_null(str);
return NXT_OK;
}

View File

@@ -1004,6 +1004,11 @@ nxt_router_temp_conf(nxt_task_t *task)
rtcf->mem_pool = mp; rtcf->mem_pool = mp;
rtcf->var_fields = nxt_array_create(mp, 4, sizeof(nxt_var_field_t));
if (nxt_slow_path(rtcf->var_fields == NULL)) {
goto fail;
}
tmp = nxt_mp_create(1024, 128, 256, 32); tmp = nxt_mp_create(1024, 128, 256, 32);
if (nxt_slow_path(tmp == NULL)) { if (nxt_slow_path(tmp == NULL)) {
goto fail; goto fail;

View File

@@ -43,6 +43,7 @@ typedef struct {
uint32_t threads; uint32_t threads;
nxt_mp_t *mem_pool; nxt_mp_t *mem_pool;
nxt_array_t *var_fields; /* of nxt_var_field_t */
nxt_router_t *router; nxt_router_t *router;
nxt_http_routes_t *routes; nxt_http_routes_t *routes;

View File

@@ -52,6 +52,11 @@ struct nxt_var_query_s {
static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data); static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data);
static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name); static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name);
static nxt_var_decl_t *nxt_var_decl_get(nxt_str_t *name, nxt_array_t *fields,
uint32_t *index);
static nxt_var_field_t *nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name,
uint32_t hash);
static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data); static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data);
static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query,
uint32_t index); uint32_t index);
@@ -109,6 +114,117 @@ nxt_var_hash_find(nxt_str_t *name)
} }
static nxt_var_decl_t *
nxt_var_decl_get(nxt_str_t *name, nxt_array_t *fields, uint32_t *index)
{
u_char *p, *end;
int64_t hash;
uint16_t field;
nxt_str_t str;
nxt_var_decl_t *decl;
nxt_var_field_t *f;
f = NULL;
field = 0;
decl = nxt_var_hash_find(name);
if (decl == NULL) {
p = name->start;
end = p + name->length;
while (p < end) {
if (*p++ == '_') {
break;
}
}
if (p == end) {
return NULL;
}
str.start = name->start;
str.length = p - 1 - name->start;
decl = nxt_var_hash_find(&str);
if (decl != NULL) {
str.start = p;
str.length = end - p;
hash = decl->field_hash(fields->mem_pool, &str);
if (nxt_slow_path(hash == -1)) {
return NULL;
}
f = nxt_var_field_add(fields, &str, (uint32_t) hash);
if (nxt_slow_path(f == NULL)) {
return NULL;
}
field = f->index;
}
}
if (decl != NULL) {
if (decl->field_hash != NULL && f == NULL) {
return NULL;
}
if (index != NULL) {
*index = (decl->index << 16) | field;
}
}
return decl;
}
static nxt_var_field_t *
nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name, uint32_t hash)
{
nxt_uint_t i;
nxt_var_field_t *field;
field = fields->elts;
for (i = 0; i < fields->nelts; i++) {
if (field[i].hash == hash
&& nxt_strstr_eq(&field[i].name, name))
{
return field;
}
}
field = nxt_array_add(fields);
if (nxt_slow_path(field == NULL)) {
return NULL;
}
field->name = *name;
field->hash = hash;
field->index = fields->nelts - 1;
return field;
}
nxt_var_field_t *
nxt_var_field_get(nxt_array_t *fields, uint16_t index)
{
nxt_uint_t nfields;
nxt_var_field_t *field;
field = fields->elts;
nfields = fields->nelts;
if (nfields > 0 && index <= nfields) {
return &field[index];
}
return NULL;
}
static nxt_int_t static nxt_int_t
nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data) nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data)
{ {
@@ -148,7 +264,8 @@ nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, uint32_t index)
} }
if (ret == NXT_OK) { if (ret == NXT_OK) {
ret = nxt_var_index[index](task, value, query->ctx); ret = nxt_var_index[index >> 16](task, value, query->ctx,
index & 0xffff);
if (nxt_slow_path(ret != NXT_OK)) { if (nxt_slow_path(ret != NXT_OK)) {
return NULL; return NULL;
} }
@@ -213,10 +330,12 @@ nxt_var_index_init(void)
nxt_var_t * nxt_var_t *
nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz) nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields,
nxt_bool_t strz)
{ {
u_char *p, *end, *next, *src; u_char *p, *end, *next, *src;
size_t size; size_t size;
uint32_t index;
nxt_var_t *var; nxt_var_t *var;
nxt_str_t part; nxt_str_t part;
nxt_uint_t n; nxt_uint_t n;
@@ -267,12 +386,12 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz)
next = nxt_var_next_part(p, end - p, &part, &is_var); next = nxt_var_next_part(p, end - p, &part, &is_var);
if (is_var) { if (is_var) {
decl = nxt_var_hash_find(&part); decl = nxt_var_decl_get(&part, fields, &index);
if (nxt_slow_path(decl == NULL)) { if (nxt_slow_path(decl == NULL)) {
return NULL; return NULL;
} }
subs[n].index = decl->index; subs[n].index = index;
subs[n].length = next - p; subs[n].length = next - p;
subs[n].position = p - str->start; subs[n].position = p - str->start;
@@ -287,7 +406,7 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz)
nxt_int_t nxt_int_t
nxt_var_test(nxt_str_t *str, u_char *error) nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error)
{ {
u_char *p, *end, *next; u_char *p, *end, *next;
nxt_str_t part; nxt_str_t part;
@@ -308,7 +427,7 @@ nxt_var_test(nxt_str_t *str, u_char *error)
} }
if (is_var) { if (is_var) {
decl = nxt_var_hash_find(&part); decl = nxt_var_decl_get(&part, fields, NULL);
if (decl == NULL) { if (decl == NULL) {
nxt_sprintf(error, error + NXT_MAX_ERROR_STR, nxt_sprintf(error, error + NXT_MAX_ERROR_STR,

View File

@@ -13,15 +13,25 @@ typedef struct nxt_var_query_s nxt_var_query_t;
typedef nxt_int_t (*nxt_var_handler_t)(nxt_task_t *task, typedef nxt_int_t (*nxt_var_handler_t)(nxt_task_t *task,
nxt_str_t *str, nxt_str_t *str,
void *ctx); void *ctx, uint16_t field);
typedef int64_t (*nxt_var_field_hash_t)(nxt_mp_t *mp, nxt_str_t *str);
typedef struct { typedef struct {
nxt_str_t name; nxt_str_t name;
nxt_var_handler_t handler; nxt_var_handler_t handler;
nxt_var_field_hash_t field_hash;
uint32_t index; uint32_t index;
} nxt_var_decl_t; } nxt_var_decl_t;
typedef struct {
nxt_str_t name;
uint16_t hash;
uint32_t index;
} nxt_var_field_t;
nxt_inline nxt_bool_t nxt_inline nxt_bool_t
nxt_is_var(nxt_str_t *str) nxt_is_var(nxt_str_t *str)
{ {
@@ -31,11 +41,15 @@ nxt_is_var(nxt_str_t *str)
nxt_int_t nxt_var_register(nxt_var_decl_t *decl, size_t n); nxt_int_t nxt_var_register(nxt_var_decl_t *decl, size_t n);
nxt_int_t nxt_var_index_init(void); nxt_int_t nxt_var_index_init(void);
nxt_var_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz);
nxt_int_t nxt_var_test(nxt_str_t *str, u_char *error);
void nxt_var_raw(nxt_var_t *var, nxt_str_t *str); nxt_var_field_t *nxt_var_field_get(nxt_array_t *fields, uint16_t index);
nxt_var_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields,
nxt_bool_t strz);
nxt_int_t nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error);
nxt_bool_t nxt_var_is_const(nxt_var_t *var); nxt_bool_t nxt_var_is_const(nxt_var_t *var);
void nxt_var_raw(nxt_var_t *var, nxt_str_t *str);
nxt_int_t nxt_var_query_init(nxt_var_query_t **query_p, void *ctx, nxt_int_t nxt_var_query_init(nxt_var_query_t **query_p, void *ctx,
nxt_mp_t *mp); nxt_mp_t *mp);