Basic njs support.
This commit is contained in:
@@ -34,7 +34,7 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
NXT_CONF_VLDT_REQUIRED = 1 << 0,
|
||||
NXT_CONF_VLDT_VAR = 1 << 1,
|
||||
NXT_CONF_VLDT_TSTR = 1 << 1,
|
||||
} nxt_conf_vldt_flags_t;
|
||||
|
||||
|
||||
@@ -367,7 +367,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = {
|
||||
.name = nxt_string("pass"),
|
||||
.type = NXT_CONF_VLDT_STRING,
|
||||
.validator = nxt_conf_vldt_pass,
|
||||
.flags = NXT_CONF_VLDT_VAR,
|
||||
.flags = NXT_CONF_VLDT_TSTR,
|
||||
}, {
|
||||
.name = nxt_string("application"),
|
||||
.type = NXT_CONF_VLDT_STRING,
|
||||
@@ -652,7 +652,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_pass_action_members[] = {
|
||||
.name = nxt_string("pass"),
|
||||
.type = NXT_CONF_VLDT_STRING,
|
||||
.validator = nxt_conf_vldt_pass,
|
||||
.flags = NXT_CONF_VLDT_VAR,
|
||||
.flags = NXT_CONF_VLDT_TSTR,
|
||||
},
|
||||
|
||||
NXT_CONF_VLDT_END
|
||||
@@ -667,7 +667,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_return_action_members[] = {
|
||||
}, {
|
||||
.name = nxt_string("location"),
|
||||
.type = NXT_CONF_VLDT_STRING,
|
||||
.flags = NXT_CONF_VLDT_VAR,
|
||||
.flags = NXT_CONF_VLDT_TSTR,
|
||||
},
|
||||
|
||||
NXT_CONF_VLDT_END
|
||||
@@ -697,7 +697,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_share_action_members[] = {
|
||||
.validator = nxt_conf_vldt_unsupported,
|
||||
.u.string = "chroot",
|
||||
#endif
|
||||
.flags = NXT_CONF_VLDT_VAR,
|
||||
.flags = NXT_CONF_VLDT_TSTR,
|
||||
}, {
|
||||
.name = nxt_string("follow_symlinks"),
|
||||
.type = NXT_CONF_VLDT_BOOLEAN,
|
||||
@@ -1226,8 +1226,9 @@ nxt_int_t
|
||||
nxt_conf_validate(nxt_conf_validation_t *vldt)
|
||||
{
|
||||
nxt_int_t ret;
|
||||
u_char error[NXT_MAX_ERROR_STR];
|
||||
|
||||
vldt->tstr_state = nxt_tstr_state_new(vldt->pool);
|
||||
vldt->tstr_state = nxt_tstr_state_new(vldt->pool, 1);
|
||||
if (nxt_slow_path(vldt->tstr_state == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
@@ -1237,7 +1238,17 @@ nxt_conf_validate(nxt_conf_validation_t *vldt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return nxt_conf_vldt_object(vldt, vldt->conf, nxt_conf_vldt_root_members);
|
||||
ret = nxt_conf_vldt_object(vldt, vldt->conf, nxt_conf_vldt_root_members);
|
||||
if (ret != NXT_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nxt_tstr_state_done(vldt->tstr_state, error);
|
||||
if (ret != NXT_OK) {
|
||||
return nxt_conf_vldt_error(vldt, "%s", error);
|
||||
}
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1721,7 +1732,7 @@ nxt_conf_vldt_share_element(nxt_conf_validation_t *vldt,
|
||||
|
||||
nxt_conf_get_string(value, &str);
|
||||
|
||||
if (nxt_is_var(&str)) {
|
||||
if (nxt_is_tstr(&str)) {
|
||||
return nxt_conf_vldt_var(vldt, &share, &str);
|
||||
}
|
||||
|
||||
@@ -2501,12 +2512,12 @@ nxt_conf_vldt_object(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vals->flags & NXT_CONF_VLDT_VAR
|
||||
if (vals->flags & NXT_CONF_VLDT_TSTR
|
||||
&& nxt_conf_type(member) == NXT_CONF_STRING)
|
||||
{
|
||||
nxt_conf_get_string(member, &var);
|
||||
|
||||
if (nxt_is_var(&var)) {
|
||||
if (nxt_is_tstr(&var)) {
|
||||
ret = nxt_conf_vldt_var(vldt, &name, &var);
|
||||
if (ret != NXT_OK) {
|
||||
return ret;
|
||||
@@ -3147,7 +3158,7 @@ nxt_conf_vldt_access_log(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
||||
"The \"path\" string must not be empty.");
|
||||
}
|
||||
|
||||
if (nxt_is_var(&conf.format)) {
|
||||
if (nxt_is_tstr(&conf.format)) {
|
||||
return nxt_conf_vldt_var(vldt, &format_str, &conf.format);
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ struct nxt_http_request_s {
|
||||
void *timer_data;
|
||||
|
||||
nxt_tstr_query_t *tstr_query;
|
||||
nxt_var_cache_t var_cache;
|
||||
nxt_tstr_cache_t tstr_cache;
|
||||
|
||||
void *req_rpc_data;
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@ nxt_http_request_create(nxt_task_t *task)
|
||||
|
||||
task->thread->engine->requests_cnt++;
|
||||
|
||||
r->var_cache.pool = mp;
|
||||
r->tstr_cache.var.pool = mp;
|
||||
|
||||
return r;
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r,
|
||||
rtcf = r->conf->socket_conf->router_conf;
|
||||
|
||||
ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state,
|
||||
&r->var_cache, r, r->mem_pool);
|
||||
&r->tstr_cache, r, r->mem_pool);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -1306,7 +1306,7 @@ nxt_http_pass_var(nxt_task_t *task, nxt_http_request_t *r,
|
||||
|
||||
rtcf = r->conf->socket_conf->router_conf;
|
||||
|
||||
ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state, &r->var_cache,
|
||||
ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state, &r->tstr_cache,
|
||||
r, r->mem_pool);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
goto fail;
|
||||
|
||||
@@ -276,7 +276,7 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r,
|
||||
rtcf = r->conf->socket_conf->router_conf;
|
||||
|
||||
ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state,
|
||||
&r->var_cache, r, r->mem_pool);
|
||||
&r->tstr_cache, r, r->mem_pool);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
|
||||
230
src/nxt_js.c
Normal file
230
src/nxt_js.c
Normal file
@@ -0,0 +1,230 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) NGINX, Inc.
|
||||
*/
|
||||
|
||||
#include <nxt_main.h>
|
||||
|
||||
|
||||
struct nxt_js_s {
|
||||
uint32_t index;
|
||||
njs_vm_t *vm;
|
||||
};
|
||||
|
||||
|
||||
struct nxt_js_conf_s {
|
||||
nxt_mp_t *pool;
|
||||
njs_vm_t *vm;
|
||||
nxt_array_t *funcs;
|
||||
};
|
||||
|
||||
|
||||
nxt_js_conf_t *
|
||||
nxt_js_conf_new(nxt_mp_t *mp)
|
||||
{
|
||||
njs_vm_opt_t opts;
|
||||
nxt_js_conf_t *jcf;
|
||||
|
||||
jcf = nxt_mp_zget(mp, sizeof(nxt_js_conf_t));
|
||||
if (nxt_slow_path(jcf == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jcf->pool = mp;
|
||||
|
||||
njs_vm_opt_init(&opts);
|
||||
|
||||
jcf->vm = njs_vm_create(&opts);
|
||||
if (nxt_slow_path(jcf->vm == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jcf->funcs = nxt_array_create(mp, 4, sizeof(nxt_str_t));
|
||||
if (nxt_slow_path(jcf->funcs == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return jcf;
|
||||
}
|
||||
|
||||
|
||||
nxt_js_t *
|
||||
nxt_js_add_tpl(nxt_js_conf_t *jcf, nxt_str_t *str, nxt_bool_t strz)
|
||||
{
|
||||
size_t size;
|
||||
u_char *p, *start;
|
||||
nxt_js_t *js;
|
||||
nxt_str_t *func;
|
||||
|
||||
static nxt_str_t func_str = nxt_string("function() {"
|
||||
" return ");
|
||||
|
||||
/*
|
||||
* Appending a terminating null character if strz is true.
|
||||
*/
|
||||
static nxt_str_t strz_str = nxt_string(" + '\\x00'");
|
||||
|
||||
size = func_str.length + str->length + 1;
|
||||
|
||||
if (strz) {
|
||||
size += strz_str.length;
|
||||
}
|
||||
|
||||
start = nxt_mp_nget(jcf->pool, size);
|
||||
if (nxt_slow_path(start == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = start;
|
||||
|
||||
p = nxt_cpymem(p, func_str.start, func_str.length);
|
||||
p = nxt_cpymem(p, str->start, str->length);
|
||||
|
||||
if (strz) {
|
||||
p = nxt_cpymem(p, strz_str.start, strz_str.length);
|
||||
}
|
||||
|
||||
*p++ = '}';
|
||||
|
||||
js = nxt_mp_get(jcf->pool, sizeof(nxt_js_t));
|
||||
if (nxt_slow_path(js == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js->vm = jcf->vm;
|
||||
|
||||
func = nxt_array_add(jcf->funcs);
|
||||
if (nxt_slow_path(func == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
func->start = start;
|
||||
func->length = p - start;
|
||||
|
||||
js->index = jcf->funcs->nelts - 1;
|
||||
|
||||
return js;
|
||||
}
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_js_compile(nxt_js_conf_t *jcf)
|
||||
{
|
||||
size_t size;
|
||||
u_char *p, *start;
|
||||
njs_int_t ret;
|
||||
nxt_str_t *func;
|
||||
nxt_uint_t i;
|
||||
|
||||
size = 2;
|
||||
func = jcf->funcs->elts;
|
||||
|
||||
for (i = 0; i < jcf->funcs->nelts; i++) {
|
||||
size += func[i].length + 1;
|
||||
}
|
||||
|
||||
start = nxt_mp_nget(jcf->pool, size);
|
||||
if (nxt_slow_path(start == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
p = start;
|
||||
*p++ = '[';
|
||||
|
||||
func = jcf->funcs->elts;
|
||||
|
||||
for (i = 0; i < jcf->funcs->nelts; i++) {
|
||||
p = nxt_cpymem(p, func[i].start, func[i].length);
|
||||
*p++ = ',';
|
||||
}
|
||||
|
||||
*p++ = ']';
|
||||
|
||||
ret = njs_vm_compile(jcf->vm, &start, p);
|
||||
|
||||
return (ret == NJS_OK) ? NXT_OK : NXT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_js_test(nxt_js_conf_t *jcf, nxt_str_t *str, u_char *error)
|
||||
{
|
||||
u_char *start;
|
||||
nxt_str_t err;
|
||||
njs_int_t ret;
|
||||
njs_str_t res;
|
||||
|
||||
start = nxt_mp_nget(jcf->pool, str->length);
|
||||
if (nxt_slow_path(start == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
nxt_memcpy(start, str->start, str->length);
|
||||
|
||||
ret = njs_vm_compile(jcf->vm, &start, start + str->length);
|
||||
|
||||
if (nxt_slow_path(ret != NJS_OK)) {
|
||||
(void) njs_vm_retval_string(jcf->vm, &res);
|
||||
|
||||
err.start = res.start;
|
||||
err.length = res.length;
|
||||
|
||||
nxt_sprintf(error, error + NXT_MAX_ERROR_STR, "\"%V\"%Z", &err);
|
||||
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_js_call(nxt_task_t *task, nxt_js_cache_t *cache, nxt_js_t *js,
|
||||
nxt_str_t *str, void *ctx)
|
||||
{
|
||||
njs_vm_t *vm;
|
||||
njs_int_t rc, ret;
|
||||
njs_str_t res;
|
||||
njs_value_t *array, *value;
|
||||
njs_function_t *func;
|
||||
njs_opaque_value_t opaque_value;
|
||||
|
||||
vm = cache->vm;
|
||||
|
||||
if (vm == NULL) {
|
||||
vm = njs_vm_clone(js->vm, ctx);
|
||||
if (nxt_slow_path(vm == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
ret = njs_vm_start(vm);
|
||||
if (ret != NJS_OK) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
array = njs_vm_retval(vm);
|
||||
|
||||
cache->vm = vm;
|
||||
cache->array = *array;
|
||||
}
|
||||
|
||||
value = njs_vm_array_prop(vm, &cache->array, js->index, &opaque_value);
|
||||
func = njs_value_function(value);
|
||||
|
||||
ret = njs_vm_call(vm, func, NULL, 0);
|
||||
|
||||
rc = njs_vm_retval_string(vm, &res);
|
||||
if (rc != NJS_OK) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
if (ret != NJS_OK) {
|
||||
nxt_alert(task, "js exception: %V", &res);
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
str->length = res.length;
|
||||
str->start = res.start;
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
34
src/nxt_js.h
Normal file
34
src/nxt_js.h
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) NGINX, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _NXT_JS_H_INCLUDED_
|
||||
#define _NXT_JS_H_INCLUDED_
|
||||
|
||||
#if (NXT_HAVE_NJS)
|
||||
|
||||
#include <njs_main.h>
|
||||
|
||||
|
||||
typedef struct nxt_js_s nxt_js_t;
|
||||
typedef struct nxt_js_conf_s nxt_js_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
njs_vm_t *vm;
|
||||
njs_value_t array;
|
||||
} nxt_js_cache_t;
|
||||
|
||||
|
||||
nxt_js_conf_t *nxt_js_conf_new(nxt_mp_t *mp);
|
||||
nxt_js_t *nxt_js_add_tpl(nxt_js_conf_t *jcf, nxt_str_t *str, nxt_bool_t strz);
|
||||
nxt_int_t nxt_js_compile(nxt_js_conf_t *jcf);
|
||||
nxt_int_t nxt_js_test(nxt_js_conf_t *jcf, nxt_str_t *str, u_char *error);
|
||||
nxt_int_t nxt_js_call(nxt_task_t *task, nxt_js_cache_t *cache, nxt_js_t *js,
|
||||
nxt_str_t *str, void *ctx);
|
||||
|
||||
|
||||
#endif /* NXT_HAVE_NJS */
|
||||
|
||||
#endif /* _NXT_JS_H_INCLUDED_ */
|
||||
@@ -1060,7 +1060,7 @@ nxt_router_temp_conf(nxt_task_t *task)
|
||||
|
||||
rtcf->mem_pool = mp;
|
||||
|
||||
rtcf->tstr_state = nxt_tstr_state_new(mp);
|
||||
rtcf->tstr_state = nxt_tstr_state_new(mp, 0);
|
||||
if (nxt_slow_path(rtcf->tstr_state == NULL)) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -2042,6 +2042,11 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
}
|
||||
}
|
||||
|
||||
ret = nxt_tstr_state_done(rtcf->tstr_state, NULL);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nxt_queue_add(&deleting_sockets, &router->sockets);
|
||||
nxt_queue_init(&router->sockets);
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r,
|
||||
rtcf = r->conf->socket_conf->router_conf;
|
||||
|
||||
ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state,
|
||||
&r->var_cache, r, r->mem_pool);
|
||||
&r->tstr_cache, r, r->mem_pool);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
return;
|
||||
}
|
||||
|
||||
128
src/nxt_tstr.c
128
src/nxt_tstr.c
@@ -9,12 +9,22 @@
|
||||
typedef enum {
|
||||
NXT_TSTR_CONST = 0,
|
||||
NXT_TSTR_VAR,
|
||||
#if (NXT_HAVE_NJS)
|
||||
NXT_TSTR_JS,
|
||||
#endif
|
||||
} nxt_tstr_type_t;
|
||||
|
||||
|
||||
struct nxt_tstr_s {
|
||||
nxt_str_t str;
|
||||
nxt_var_t *var;
|
||||
|
||||
union {
|
||||
nxt_var_t *var;
|
||||
#if (NXT_HAVE_NJS)
|
||||
nxt_js_t *js;
|
||||
#endif
|
||||
} u;
|
||||
|
||||
nxt_tstr_flags_t flags;
|
||||
nxt_tstr_type_t type;
|
||||
};
|
||||
@@ -24,7 +34,7 @@ struct nxt_tstr_query_s {
|
||||
nxt_mp_t *pool;
|
||||
|
||||
nxt_tstr_state_t *state;
|
||||
nxt_var_cache_t *cache;
|
||||
nxt_tstr_cache_t *cache;
|
||||
|
||||
nxt_uint_t waiting;
|
||||
nxt_uint_t failed; /* 1 bit */
|
||||
@@ -37,8 +47,12 @@ struct nxt_tstr_query_s {
|
||||
};
|
||||
|
||||
|
||||
#define nxt_tstr_is_js(str) \
|
||||
nxt_strchr_start(str, '`')
|
||||
|
||||
|
||||
nxt_tstr_state_t *
|
||||
nxt_tstr_state_new(nxt_mp_t *mp)
|
||||
nxt_tstr_state_new(nxt_mp_t *mp, nxt_bool_t test)
|
||||
{
|
||||
nxt_tstr_state_t *state;
|
||||
|
||||
@@ -48,12 +62,20 @@ nxt_tstr_state_new(nxt_mp_t *mp)
|
||||
}
|
||||
|
||||
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)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if (NXT_HAVE_NJS)
|
||||
state->jcf = nxt_js_conf_new(mp);
|
||||
if (nxt_slow_path(state->jcf == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -88,18 +110,38 @@ nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str,
|
||||
|
||||
tstr->flags = flags;
|
||||
|
||||
p = nxt_memchr(str->start, '$', str->length);
|
||||
if (nxt_tstr_is_js(str)) {
|
||||
|
||||
if (p != NULL) {
|
||||
tstr->type = NXT_TSTR_VAR;
|
||||
#if (NXT_HAVE_NJS)
|
||||
|
||||
tstr->var = nxt_var_compile(&tstr->str, state->pool, state->var_fields);
|
||||
if (nxt_slow_path(tstr->var == NULL)) {
|
||||
nxt_str_t tpl;
|
||||
|
||||
tstr->type = NXT_TSTR_JS;
|
||||
|
||||
nxt_tstr_str(tstr, &tpl);
|
||||
|
||||
tstr->u.js = nxt_js_add_tpl(state->jcf, &tpl, strz);
|
||||
if (nxt_slow_path(tstr->u.js == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} else {
|
||||
tstr->type = NXT_TSTR_CONST;
|
||||
p = memchr(str->start, '$', str->length);
|
||||
|
||||
if (p != NULL) {
|
||||
tstr->type = NXT_TSTR_VAR;
|
||||
|
||||
tstr->u.var = nxt_var_compile(&tstr->str, state->pool,
|
||||
state->var_fields);
|
||||
if (nxt_slow_path(tstr->u.var == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
tstr->type = NXT_TSTR_CONST;
|
||||
}
|
||||
}
|
||||
|
||||
return tstr;
|
||||
@@ -109,7 +151,46 @@ nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str,
|
||||
nxt_int_t
|
||||
nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error)
|
||||
{
|
||||
return nxt_var_test(str, state->var_fields, error);
|
||||
u_char *p;
|
||||
|
||||
if (nxt_tstr_is_js(str)) {
|
||||
#if (NXT_HAVE_NJS)
|
||||
return nxt_js_test(state->jcf, str, error);
|
||||
|
||||
#else
|
||||
nxt_sprintf(error, error + NXT_MAX_ERROR_STR,
|
||||
"Unit is built without support of njs: "
|
||||
"\"--njs\" ./configure option is missing.");
|
||||
return NXT_ERROR;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
p = memchr(str->start, '$', str->length);
|
||||
|
||||
if (p != NULL) {
|
||||
return nxt_var_test(str, state->var_fields, error);
|
||||
}
|
||||
}
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_tstr_state_done(nxt_tstr_state_t *state, u_char *error)
|
||||
{
|
||||
#if (NXT_HAVE_NJS)
|
||||
if (!state->test) {
|
||||
nxt_int_t ret;
|
||||
|
||||
ret = nxt_js_compile(state->jcf);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +214,7 @@ nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str)
|
||||
|
||||
nxt_int_t
|
||||
nxt_tstr_query_init(nxt_tstr_query_t **query_p, nxt_tstr_state_t *state,
|
||||
nxt_var_cache_t *cache, void *ctx, nxt_mp_t *mp)
|
||||
nxt_tstr_cache_t *cache, void *ctx, nxt_mp_t *mp)
|
||||
{
|
||||
nxt_tstr_query_t *query;
|
||||
|
||||
@@ -172,11 +253,24 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr,
|
||||
return;
|
||||
}
|
||||
|
||||
ret = nxt_var_interpreter(task, query->cache, tstr->var, val, query->ctx,
|
||||
tstr->flags & NXT_TSTR_LOGGING);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
query->failed = 1;
|
||||
return;
|
||||
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);
|
||||
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
query->failed = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
#if (NXT_HAVE_NJS)
|
||||
ret = nxt_js_call(task, &query->cache->js, tstr->u.js, val, query->ctx);
|
||||
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
query->failed = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (tstr->flags & NXT_TSTR_STRZ) {
|
||||
@@ -188,7 +282,7 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr,
|
||||
|
||||
nxt_tstr_str(tstr, &str);
|
||||
|
||||
nxt_debug(task, "tstr: \"%V\" -> \"%V\"", &str, val);
|
||||
nxt_debug(task, "tstr query: \"%V\", result: \"%V\"", &str, val);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#define _NXT_TSTR_H_INCLUDED_
|
||||
|
||||
|
||||
#include <nxt_js.h>
|
||||
|
||||
typedef struct nxt_tstr_s nxt_tstr_t;
|
||||
typedef struct nxt_tstr_query_s nxt_tstr_query_t;
|
||||
|
||||
@@ -14,25 +16,38 @@ typedef struct nxt_tstr_query_s nxt_tstr_query_t;
|
||||
typedef struct {
|
||||
nxt_mp_t *pool;
|
||||
nxt_array_t *var_fields;
|
||||
#if (NXT_HAVE_NJS)
|
||||
nxt_js_conf_t *jcf;
|
||||
#endif
|
||||
uint8_t test; /* 1 bit */
|
||||
} nxt_tstr_state_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
nxt_var_cache_t var;
|
||||
#if (NXT_HAVE_NJS)
|
||||
nxt_js_cache_t js;
|
||||
#endif
|
||||
} nxt_tstr_cache_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
NXT_TSTR_STRZ = 1 << 0,
|
||||
NXT_TSTR_LOGGING = 1 << 1,
|
||||
} nxt_tstr_flags_t;
|
||||
|
||||
|
||||
nxt_tstr_state_t *nxt_tstr_state_new(nxt_mp_t *mp);
|
||||
nxt_tstr_state_t *nxt_tstr_state_new(nxt_mp_t *mp, nxt_bool_t test);
|
||||
nxt_tstr_t *nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str,
|
||||
nxt_tstr_flags_t flags);
|
||||
nxt_int_t nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error);
|
||||
nxt_int_t nxt_tstr_state_done(nxt_tstr_state_t *state, u_char *error);
|
||||
|
||||
nxt_bool_t nxt_tstr_is_const(nxt_tstr_t *tstr);
|
||||
void nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str);
|
||||
|
||||
nxt_int_t nxt_tstr_query_init(nxt_tstr_query_t **query_p,
|
||||
nxt_tstr_state_t *state, nxt_var_cache_t *cache, void *ctx,
|
||||
nxt_tstr_state_t *state, nxt_tstr_cache_t *cache, void *ctx,
|
||||
nxt_mp_t *mp);
|
||||
void nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr,
|
||||
nxt_str_t *val);
|
||||
@@ -42,4 +57,23 @@ void nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query,
|
||||
nxt_bool_t failed);
|
||||
|
||||
|
||||
nxt_inline nxt_bool_t
|
||||
nxt_is_tstr(nxt_str_t *str)
|
||||
{
|
||||
u_char *p;
|
||||
|
||||
p = memchr(str->start, '`', str->length);
|
||||
if (p != NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = memchr(str->start, '$', str->length);
|
||||
if (p != NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* _NXT_TSTR_H_INCLUDED_ */
|
||||
|
||||
@@ -39,13 +39,6 @@ typedef struct {
|
||||
} nxt_var_cache_t;
|
||||
|
||||
|
||||
nxt_inline nxt_bool_t
|
||||
nxt_is_var(nxt_str_t *str)
|
||||
{
|
||||
return (memchr(str->start, '$', str->length) != NULL);
|
||||
}
|
||||
|
||||
|
||||
nxt_int_t nxt_var_register(nxt_var_decl_t *decl, size_t n);
|
||||
nxt_int_t nxt_var_index_init(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user