diff options
author | Zhidao HONG <z.hong@f5.com> | 2023-06-19 16:29:22 +0800 |
---|---|---|
committer | Zhidao HONG <z.hong@f5.com> | 2023-06-19 16:29:22 +0800 |
commit | c61ccec7b4926476b2188092e25990e433332688 (patch) | |
tree | 191c14c58ae229e6060644eafce25a82040a2bbc | |
parent | 18d3637e4bffd5fff09091a536dca3fdecc931d7 (diff) | |
download | unit-c61ccec7b4926476b2188092e25990e433332688.tar.gz unit-c61ccec7b4926476b2188092e25990e433332688.tar.bz2 |
Variables refactoring.
This commit is to reimplement the variables with an unknown field
such as $header_{name} to make the parsing more generic,
it's a preparation for supporting response header variables.
-rw-r--r-- | src/nxt_http_variables.c | 168 | ||||
-rw-r--r-- | src/nxt_main.h | 2 | ||||
-rw-r--r-- | src/nxt_tstr.c | 14 | ||||
-rw-r--r-- | src/nxt_tstr.h | 6 | ||||
-rw-r--r-- | src/nxt_var.c | 166 | ||||
-rw-r--r-- | src/nxt_var.h | 28 |
6 files changed, 204 insertions, 180 deletions
diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index 71f7ff7f..04e21e67 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -8,39 +8,39 @@ static nxt_int_t nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_request_time(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field); + void *data); static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field); + void *data); static nxt_int_t nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static u_char *nxt_http_log_date(u_char *buf, nxt_realtime_t *now, struct tm *tm, size_t size, const char *format); static nxt_int_t nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field); + void *data); static nxt_int_t nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_int_t nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, - void *ctx, uint16_t field); + void *ctx, void *data); static nxt_var_decl_t nxt_http_vars[] = { @@ -96,21 +96,6 @@ static nxt_var_decl_t nxt_http_vars[] = { .name = nxt_string("header_user_agent"), .handler = nxt_http_var_user_agent, .cacheable = 1, - }, { - .name = nxt_string("arg"), - .handler = nxt_http_var_arg, - .field_hash = nxt_http_argument_hash, - .cacheable = 1, - }, { - .name = nxt_string("header"), - .handler = nxt_http_var_header, - .field_hash = nxt_http_header_hash, - .cacheable = 1, - }, { - .name = nxt_string("cookie"), - .handler = nxt_http_var_cookie, - .field_hash = nxt_http_cookie_hash, - .cacheable = 1, }, }; @@ -122,8 +107,76 @@ nxt_http_register_variables(void) } +nxt_int_t +nxt_http_unknown_var_ref(nxt_tstr_state_t *state, nxt_var_ref_t *ref, + nxt_str_t *name) +{ + int64_t hash; + nxt_str_t str; + + if (nxt_str_start(name, "header_", 7)) { + ref->handler = nxt_http_var_header; + ref->cacheable = 1; + + str.start = name->start + 7; + str.length = name->length - 7; + + if (str.length == 0) { + return NXT_ERROR; + } + + hash = nxt_http_header_hash(state->pool, &str); + if (nxt_slow_path(hash == -1)) { + return NXT_ERROR; + } + + } else if (nxt_str_start(name, "arg_", 4)) { + ref->handler = nxt_http_var_arg; + ref->cacheable = 1; + + str.start = name->start + 4; + str.length = name->length - 4; + + if (str.length == 0) { + return NXT_ERROR; + } + + hash = nxt_http_argument_hash(state->pool, &str); + if (nxt_slow_path(hash == -1)) { + return NXT_ERROR; + } + + } else if (nxt_str_start(name, "cookie_", 7)) { + ref->handler = nxt_http_var_cookie; + ref->cacheable = 1; + + str.start = name->start + 7; + str.length = name->length - 7; + + if (str.length == 0) { + return NXT_ERROR; + } + + hash = nxt_http_cookie_hash(state->pool, &str); + if (nxt_slow_path(hash == -1)) { + return NXT_ERROR; + } + + } else { + return NXT_ERROR; + } + + ref->data = nxt_var_field_new(state->pool, &str, (uint32_t) hash); + if (nxt_slow_path(ref->data == NULL)) { + return NXT_ERROR; + } + + return NXT_OK; +} + + static nxt_int_t -nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { nxt_str_set(str, "$"); @@ -133,7 +186,7 @@ nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) static nxt_int_t nxt_http_var_request_time(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field) + void *data) { u_char *p; nxt_msec_t ms; @@ -160,7 +213,7 @@ nxt_http_var_request_time(nxt_task_t *task, nxt_str_t *str, void *ctx, static nxt_int_t -nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { nxt_http_request_t *r; @@ -174,7 +227,7 @@ nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field) + void *data) { nxt_http_request_t *r; @@ -187,7 +240,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, uint16_t field) +nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { nxt_http_request_t *r; @@ -200,7 +253,7 @@ 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) +nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { nxt_http_request_t *r; @@ -214,7 +267,7 @@ nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) static nxt_int_t nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field) + void *data) { nxt_http_request_t *r; @@ -228,8 +281,7 @@ nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str, void *ctx, static nxt_int_t -nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field) +nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { nxt_http_request_t *r; @@ -287,7 +339,7 @@ nxt_http_log_date(u_char *buf, nxt_realtime_t *now, struct tm *tm, static nxt_int_t nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field) + void *data) { nxt_http_request_t *r; @@ -301,7 +353,7 @@ nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx, static nxt_int_t nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field) + void *data) { nxt_off_t bytes; nxt_http_request_t *r; @@ -323,7 +375,7 @@ nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, void *ctx, static nxt_int_t -nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { nxt_http_request_t *r; @@ -342,8 +394,7 @@ nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) static nxt_int_t -nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field) +nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { nxt_http_request_t *r; @@ -362,8 +413,7 @@ nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, void *ctx, static nxt_int_t -nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, void *ctx, - uint16_t field) +nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { nxt_http_request_t *r; @@ -382,19 +432,15 @@ nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, void *ctx, static nxt_int_t -nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { 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->tstr_state->var_fields, field); + vf = data; args = nxt_http_arguments_parse(r); if (nxt_slow_path(args == NULL)) { @@ -426,18 +472,14 @@ 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) +nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { 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->tstr_state->var_fields, field); + vf = data; nxt_list_each(f, r->fields) { @@ -460,19 +502,15 @@ 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) +nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data) { 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->tstr_state->var_fields, field); + vf = data; cookies = nxt_http_cookies_parse(r); if (nxt_slow_path(cookies == NULL)) { diff --git a/src/nxt_main.h b/src/nxt_main.h index a7e0c283..aa96256e 100644 --- a/src/nxt_main.h +++ b/src/nxt_main.h @@ -68,6 +68,8 @@ typedef uint16_t nxt_port_id_t; #include <nxt_sprintf.h> #include <nxt_parse.h> + +typedef struct nxt_tstr_state_s nxt_tstr_state_t; #include <nxt_var.h> #include <nxt_tstr.h> diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c index 0e084bb4..edf6860a 100644 --- a/src/nxt_tstr.c +++ b/src/nxt_tstr.c @@ -64,8 +64,8 @@ nxt_tstr_state_new(nxt_mp_t *mp, nxt_bool_t test) state->pool = mp; state->test = test; - state->var_fields = nxt_array_create(mp, 4, sizeof(nxt_var_field_t)); - if (nxt_slow_path(state->var_fields == NULL)) { + state->var_refs = nxt_array_create(mp, 4, sizeof(nxt_var_ref_t)); + if (nxt_slow_path(state->var_refs == NULL)) { return NULL; } @@ -133,8 +133,7 @@ nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str, if (p != NULL) { tstr->type = NXT_TSTR_VAR; - tstr->u.var = nxt_var_compile(&tstr->str, state->pool, - state->var_fields); + tstr->u.var = nxt_var_compile(state, &tstr->str); if (nxt_slow_path(tstr->u.var == NULL)) { return NULL; } @@ -168,7 +167,7 @@ nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error) p = memchr(str->start, '$', str->length); if (p != NULL) { - return nxt_var_test(str, state->var_fields, error); + return nxt_var_test(state, str, error); } } @@ -263,8 +262,9 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, } if (tstr->type == NXT_TSTR_VAR) { - ret = nxt_var_interpreter(task, &query->cache->var, tstr->u.var, val, - query->ctx, tstr->flags & NXT_TSTR_LOGGING); + ret = nxt_var_interpreter(task, query->state, &query->cache->var, + tstr->u.var, val, query->ctx, + tstr->flags & NXT_TSTR_LOGGING); if (nxt_slow_path(ret != NXT_OK)) { query->failed = 1; diff --git a/src/nxt_tstr.h b/src/nxt_tstr.h index afa7f56d..3e842f81 100644 --- a/src/nxt_tstr.h +++ b/src/nxt_tstr.h @@ -13,14 +13,14 @@ typedef struct nxt_tstr_s nxt_tstr_t; typedef struct nxt_tstr_query_s nxt_tstr_query_t; -typedef struct { +struct nxt_tstr_state_s { nxt_mp_t *pool; - nxt_array_t *var_fields; + nxt_array_t *var_refs; #if (NXT_HAVE_NJS) nxt_js_conf_t *jcf; #endif uint8_t test; /* 1 bit */ -} nxt_tstr_state_t; +}; typedef struct { diff --git a/src/nxt_var.c b/src/nxt_var.c index e4299a09..729de788 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -50,14 +50,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_var_ref_t *nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name); 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_cache_t *cache, - uint32_t index, void *ctx); +static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state, + nxt_var_cache_t *cache, uint32_t index, void *ctx); static u_char *nxt_var_next_part(u_char *start, u_char *end, nxt_str_t *part); @@ -111,95 +108,70 @@ 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_ref_t * +nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name) { - 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); + nxt_int_t ret; + nxt_uint_t i; + nxt_var_ref_t *ref; + nxt_var_decl_t *decl; - if (decl == NULL) { - p = name->start; - end = p + name->length; + ref = state->var_refs->elts; - while (p < end) { - if (*p++ == '_') { - break; - } - } + for (i = 0; i < state->var_refs->nelts; i++) { - if (p == end) { - return NULL; + if (nxt_strstr_eq(ref[i].name, name)) { + return &ref[i]; } + } - str.start = name->start; - str.length = p - 1 - name->start; + ref = nxt_array_add(state->var_refs); + if (nxt_slow_path(ref == NULL)) { + return NULL; + } - decl = nxt_var_hash_find(&str); + ref->index = state->var_refs->nelts - 1; - if (decl != NULL) { - str.start = p; - str.length = end - p; + ref->name = nxt_str_dup(state->pool, NULL, name); + if (nxt_slow_path(ref->name == NULL)) { + return NULL; + } - hash = decl->field_hash(fields->mem_pool, &str); - if (nxt_slow_path(hash == -1)) { - return NULL; - } + decl = nxt_var_hash_find(name); - f = nxt_var_field_add(fields, &str, (uint32_t) hash); - if (nxt_slow_path(f == NULL)) { - return NULL; - } + if (decl != NULL) { + ref->handler = decl->handler; + ref->cacheable = decl->cacheable; - field = f->index; - } + return ref; } - if (decl != NULL) { - if (decl->field_hash != NULL && f == NULL) { - return NULL; - } - - if (index != NULL) { - *index = (decl->index << 16) | field; - } + ret = nxt_http_unknown_var_ref(state, ref, name); + if (nxt_slow_path(ret != NXT_OK)) { + return NULL; } - return decl; + return ref; } -static nxt_var_field_t * -nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name, uint32_t hash) +nxt_var_field_t * +nxt_var_field_new(nxt_mp_t *mp, nxt_str_t *name, uint32_t hash) { - nxt_uint_t i; + nxt_str_t *str; 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_mp_alloc(mp, sizeof(nxt_var_field_t)); + if (nxt_slow_path(field == NULL)) { + return NULL; } - field = nxt_array_add(fields); - if (nxt_slow_path(field == NULL)) { + str = nxt_str_dup(mp, &field->name, name); + if (nxt_slow_path(str == NULL)) { return NULL; } - field->name = *name; field->hash = hash; - field->index = fields->nelts - 1; return field; } @@ -230,15 +202,16 @@ 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_cache_t *cache, uint32_t index, - void *ctx) +nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state, + nxt_var_cache_t *cache, uint32_t index, void *ctx) { nxt_int_t ret; nxt_str_t *value; - nxt_var_decl_t *var; + nxt_var_ref_t *ref; nxt_lvlhsh_query_t lhq; - var = nxt_vars[index >> 16]; + ref = state->var_refs->elts; + ref = &ref[index]; value = cache->spare; @@ -251,7 +224,7 @@ nxt_var_cache_value(nxt_task_t *task, nxt_var_cache_t *cache, uint32_t index, cache->spare = value; } - if (!var->cacheable) { + if (!ref->cacheable) { goto not_cached; } @@ -274,7 +247,7 @@ nxt_var_cache_value(nxt_task_t *task, nxt_var_cache_t *cache, uint32_t index, not_cached: - ret = var->handler(task, value, ctx, index & 0xffff); + ret = ref->handler(task, value, ctx, ref->data); if (nxt_slow_path(ret != NXT_OK)) { return NULL; } @@ -326,7 +299,6 @@ nxt_var_index_init(void) for (i = 0; i < nxt_var_count; i++) { decl = nxt_lvlhsh_each(&nxt_var_hash, &lhe); - decl->index = i; vars[i] = decl; } @@ -337,16 +309,15 @@ nxt_var_index_init(void) nxt_var_t * -nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields) +nxt_var_compile(nxt_tstr_state_t *state, nxt_str_t *str) { - u_char *p, *end, *next, *src; - size_t size; - uint32_t index; - nxt_var_t *var; - nxt_str_t part; - nxt_uint_t n; - nxt_var_sub_t *subs; - nxt_var_decl_t *decl; + u_char *p, *end, *next, *src; + size_t size; + nxt_var_t *var; + nxt_str_t part; + nxt_uint_t n; + nxt_var_sub_t *subs; + nxt_var_ref_t *ref; n = 0; @@ -366,7 +337,7 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields) size = sizeof(nxt_var_t) + n * sizeof(nxt_var_sub_t) + str->length; - var = nxt_mp_get(mp, size); + var = nxt_mp_get(state->pool, size); if (nxt_slow_path(var == NULL)) { return NULL; } @@ -386,12 +357,12 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields) next = nxt_var_next_part(p, end, &part); if (part.start != NULL) { - decl = nxt_var_decl_get(&part, fields, &index); - if (nxt_slow_path(decl == NULL)) { + ref = nxt_var_ref_get(state, &part); + if (nxt_slow_path(ref == NULL)) { return NULL; } - subs[n].index = index; + subs[n].index = ref->index; subs[n].length = next - p; subs[n].position = p - str->start; @@ -406,11 +377,11 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields) nxt_int_t -nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error) +nxt_var_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error) { - u_char *p, *end, *next; - nxt_str_t part; - nxt_var_decl_t *decl; + u_char *p, *end, *next; + nxt_str_t part; + nxt_var_ref_t *ref; p = str->start; end = p + str->length; @@ -426,9 +397,9 @@ nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error) } if (part.start != NULL) { - decl = nxt_var_decl_get(&part, fields, NULL); + ref = nxt_var_ref_get(state, &part); - if (decl == NULL) { + if (ref == NULL) { nxt_sprintf(error, error + NXT_MAX_ERROR_STR, "Unknown variable \"%V\"%Z", &part); @@ -514,8 +485,9 @@ nxt_var_next_part(u_char *start, u_char *end, nxt_str_t *part) nxt_int_t -nxt_var_interpreter(nxt_task_t *task, nxt_var_cache_t *cache, nxt_var_t *var, - nxt_str_t *str, void *ctx, nxt_bool_t logging) +nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state, + nxt_var_cache_t *cache, nxt_var_t *var, nxt_str_t *str, void *ctx, + nxt_bool_t logging) { u_char *p, *src; size_t length, last, next; @@ -532,7 +504,7 @@ nxt_var_interpreter(nxt_task_t *task, nxt_var_cache_t *cache, nxt_var_t *var, length = var->length; for (i = 0; i < var->vars; i++) { - value = nxt_var_cache_value(task, cache, subs[i].index, ctx); + value = nxt_var_cache_value(task, state, cache, subs[i].index, ctx); if (nxt_slow_path(value == NULL)) { return NXT_ERROR; } diff --git a/src/nxt_var.h b/src/nxt_var.h index d3da26eb..fde64f1e 100644 --- a/src/nxt_var.h +++ b/src/nxt_var.h @@ -13,23 +13,29 @@ 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, uint16_t field); + void *ctx, void *data); 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; - nxt_var_field_hash_t field_hash; - uint32_t index; uint8_t cacheable; /* 1 bit */ } nxt_var_decl_t; typedef struct { + nxt_str_t *name; + nxt_var_handler_t handler; + void *data; + uint32_t index; + uint8_t cacheable; /* 1 bit */ +} nxt_var_ref_t; + + +typedef struct { nxt_str_t name; uint16_t hash; - uint32_t index; } nxt_var_field_t; @@ -44,14 +50,20 @@ nxt_int_t nxt_var_register(nxt_var_decl_t *decl, size_t n); nxt_int_t nxt_var_index_init(void); nxt_var_field_t *nxt_var_field_get(nxt_array_t *fields, uint16_t index); +nxt_var_field_t *nxt_var_field_new(nxt_mp_t *mp, nxt_str_t *name, + uint32_t hash); -nxt_var_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields); -nxt_int_t nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error); +nxt_var_t *nxt_var_compile(nxt_tstr_state_t *state, nxt_str_t *str); +nxt_int_t nxt_var_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error); -nxt_int_t nxt_var_interpreter(nxt_task_t *task, nxt_var_cache_t *cache, - nxt_var_t *var, nxt_str_t *str, void *ctx, nxt_bool_t logging); +nxt_int_t nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state, + nxt_var_cache_t *cache, nxt_var_t *var, nxt_str_t *str, void *ctx, + nxt_bool_t logging); nxt_str_t *nxt_var_get(nxt_task_t *task, nxt_var_cache_t *cache, nxt_str_t *name, void *ctx); +nxt_int_t nxt_http_unknown_var_ref(nxt_tstr_state_t *state, nxt_var_ref_t *ref, + nxt_str_t *name); + #endif /* _NXT_VAR_H_INCLUDED_ */ |