diff options
author | Zhidao HONG <z.hong@f5.com> | 2022-07-14 04:32:49 +0800 |
---|---|---|
committer | Zhidao HONG <z.hong@f5.com> | 2022-07-14 04:32:49 +0800 |
commit | 45b89e32577eef18e473d0c7ae24562e7efedcc0 (patch) | |
tree | d7058ec9ad0fb257897873cc1429182425d17b9b /src | |
parent | 7b80186f097fda3d1c0758a30efa889ec89c5a9d (diff) | |
download | unit-45b89e32577eef18e473d0c7ae24562e7efedcc0.tar.gz unit-45b89e32577eef18e473d0c7ae24562e7efedcc0.tar.bz2 |
Var: dynamic variables support.
This commit adds the variables $arg_NAME, $header_NAME, and $cookie_NAME.
Diffstat (limited to 'src')
-rw-r--r-- | src/nxt_conf.h | 1 | ||||
-rw-r--r-- | src/nxt_conf_validation.c | 7 | ||||
-rw-r--r-- | src/nxt_http.h | 7 | ||||
-rw-r--r-- | src/nxt_http_request.c | 54 | ||||
-rw-r--r-- | src/nxt_http_return.c | 7 | ||||
-rw-r--r-- | src/nxt_http_route.c | 14 | ||||
-rw-r--r-- | src/nxt_http_static.c | 8 | ||||
-rw-r--r-- | src/nxt_http_variables.c | 187 | ||||
-rw-r--r-- | src/nxt_router.c | 5 | ||||
-rw-r--r-- | src/nxt_router.h | 1 | ||||
-rw-r--r-- | src/nxt_var.c | 131 | ||||
-rw-r--r-- | src/nxt_var.h | 28 |
12 files changed, 401 insertions, 49 deletions
diff --git a/src/nxt_conf.h b/src/nxt_conf.h index 46effac4..f95b61c1 100644 --- a/src/nxt_conf.h +++ b/src/nxt_conf.h @@ -72,6 +72,7 @@ typedef struct { nxt_mp_t *pool; nxt_str_t error; void *ctx; + nxt_array_t *var_fields; /* of nxt_var_field_t */ nxt_mp_t *conf_pool; nxt_uint_t ver; } nxt_conf_validation_t; diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index a5958788..47164e92 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -1210,6 +1210,11 @@ nxt_conf_validate(nxt_conf_validation_t *vldt) { 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); if (ret != NXT_OK) { 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]; - 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.", error, name); } diff --git a/src/nxt_http.h b/src/nxt_http.h index 4064a8a5..c2e85840 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -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, 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_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_upstream_t ***upstream_joint); -nxt_int_t nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, - nxt_http_action_conf_t *acf); +nxt_int_t nxt_http_return_init(nxt_router_conf_t *rtcf, + 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_http_action_t *action, nxt_http_action_conf_t *acf); diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index 8aa20e59..5f8fd8f7 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -1180,3 +1180,57 @@ end: 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); +} diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c index 82c91568..9f3c4fc5 100644 --- a/src/nxt_http_return.c +++ b/src/nxt_http_return.c @@ -32,12 +32,15 @@ static const nxt_http_request_state_t nxt_http_return_send_state; 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_mp_t *mp; nxt_str_t str; nxt_http_return_conf_t *conf; + mp = rtcf->mem_pool; + conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t)); if (nxt_slow_path(conf == NULL)) { 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); - 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)) { return NXT_ERROR; } diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index 5a4f349e..e00c37fe 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -643,6 +643,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_mp_t *mp; nxt_int_t ret; nxt_str_t pass; + nxt_router_conf_t *rtcf; nxt_http_action_conf_t 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)); - mp = tmcf->router_conf->mem_pool; + rtcf = tmcf->router_conf; + mp = rtcf->mem_pool; if (acf.ret != NULL) { - return nxt_http_return_init(mp, action, &acf); + return nxt_http_return_init(rtcf, action, &acf); } 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); - 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)) { 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_int_t ret; + nxt_router_conf_t *rtcf; 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)); if (nxt_slow_path(action == 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)) { return NULL; } diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index 387cdec0..19393f2c 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -79,9 +79,11 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_str_t str, *ret; nxt_var_t *var; nxt_conf_value_t *cv; + nxt_router_conf_t *rtcf; 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)); 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); 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)) { 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_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)) { return NXT_ERROR; } diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index c48f9ca3..79e66668 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -8,29 +8,47 @@ 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, - 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); + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_uri(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[] = { - { nxt_string("method"), - &nxt_http_var_method, - 0 }, - - { nxt_string("request_uri"), - &nxt_http_var_request_uri, - 0 }, - - { nxt_string("uri"), - &nxt_http_var_uri, - 0 }, - - { nxt_string("host"), - &nxt_http_var_host, - 0 }, + { + .name = nxt_string("method"), + .handler = nxt_http_var_method, + }, { + .name = nxt_string("request_uri"), + .handler = nxt_http_var_request_uri, + }, { + .name = nxt_string("uri"), + .handler = nxt_http_var_uri, + }, { + .name = nxt_string("host"), + .handler = nxt_http_var_host, + }, { + .name = nxt_string("arg"), + .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 -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; @@ -55,7 +73,8 @@ nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx) 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; @@ -68,7 +87,7 @@ nxt_http_var_request_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) +nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) { 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 -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; @@ -91,3 +110,125 @@ nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx) 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; +} diff --git a/src/nxt_router.c b/src/nxt_router.c index a3cc0a8d..e84b3d9a 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -1004,6 +1004,11 @@ nxt_router_temp_conf(nxt_task_t *task) 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); if (nxt_slow_path(tmp == NULL)) { goto fail; diff --git a/src/nxt_router.h b/src/nxt_router.h index 37008f9d..8c21a70a 100644 --- a/src/nxt_router.h +++ b/src/nxt_router.h @@ -43,6 +43,7 @@ typedef struct { uint32_t threads; nxt_mp_t *mem_pool; + nxt_array_t *var_fields; /* of nxt_var_field_t */ nxt_router_t *router; nxt_http_routes_t *routes; diff --git a/src/nxt_var.c b/src/nxt_var.c index 05cd6fd2..d3057764 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -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_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_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, 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 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) { - 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)) { return NULL; } @@ -213,10 +330,12 @@ nxt_var_index_init(void) 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; size_t size; + uint32_t index; nxt_var_t *var; nxt_str_t part; 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); if (is_var) { - decl = nxt_var_hash_find(&part); + decl = nxt_var_decl_get(&part, fields, &index); if (nxt_slow_path(decl == NULL)) { return NULL; } - subs[n].index = decl->index; + subs[n].index = index; subs[n].length = next - p; 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_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; nxt_str_t part; @@ -308,7 +427,7 @@ nxt_var_test(nxt_str_t *str, u_char *error) } if (is_var) { - decl = nxt_var_hash_find(&part); + decl = nxt_var_decl_get(&part, fields, NULL); if (decl == NULL) { nxt_sprintf(error, error + NXT_MAX_ERROR_STR, diff --git a/src/nxt_var.h b/src/nxt_var.h index 1322d507..3c38be36 100644 --- a/src/nxt_var.h +++ b/src/nxt_var.h @@ -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, 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 { - nxt_str_t name; - nxt_var_handler_t handler; - uint32_t index; + nxt_str_t name; + nxt_var_handler_t handler; + nxt_var_field_hash_t field_hash; + uint32_t index; } 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_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_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); +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_mp_t *mp); |