Var: separating nxt_tstr_t from nxt_var_t.

It's for the introduction of njs support.
For each option that supports native variable and JS template literals introduced next,
it's unified as template string.

No functional changes.
This commit is contained in:
Zhidao HONG
2022-11-20 23:15:01 +08:00
parent 0c9f417aff
commit 4735931ace
17 changed files with 403 additions and 226 deletions

View File

@@ -72,7 +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_tstr_state_t *tstr_state;
nxt_mp_t *conf_pool;
nxt_uint_t ver;
} nxt_conf_validation_t;

View File

@@ -1227,8 +1227,8 @@ 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)) {
vldt->tstr_state = nxt_tstr_state_new(vldt->pool);
if (nxt_slow_path(vldt->tstr_state == NULL)) {
return NXT_ERROR;
}
@@ -1364,7 +1364,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, vldt->var_fields, error) != NXT_OK) {
if (nxt_tstr_test(vldt->tstr_state, value, error) != NXT_OK) {
return nxt_conf_vldt_error(vldt, "%s in the \"%V\" value.",
error, name);
}

View File

@@ -169,7 +169,8 @@ struct nxt_http_request_s {
nxt_timer_t timer;
void *timer_data;
nxt_var_query_t *var_query;
nxt_tstr_query_t *tstr_query;
nxt_var_cache_t var_cache;
void *req_rpc_data;
@@ -245,7 +246,7 @@ struct nxt_http_action_s {
nxt_http_route_t *route;
nxt_upstream_t *upstream;
uint32_t upstream_number;
nxt_var_t *var;
nxt_tstr_t *tstr;
nxt_str_t *pass;
} u;

View File

@@ -282,6 +282,8 @@ nxt_http_request_create(nxt_task_t *task)
task->thread->engine->requests_cnt++;
r->var_cache.pool = mp;
return r;
fail:
@@ -795,7 +797,7 @@ nxt_http_request_error_handler(nxt_task_t *task, void *obj, void *data)
void
nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data)
{
nxt_var_t *log_format;
nxt_tstr_t *log_format;
nxt_http_proto_t proto;
nxt_http_request_t *r;
nxt_http_protocol_t protocol;

View File

@@ -9,7 +9,7 @@
typedef struct {
nxt_http_status_t status;
nxt_var_t *location;
nxt_tstr_t *location;
nxt_str_t encoded;
} nxt_http_return_conf_t;
@@ -25,7 +25,7 @@ static nxt_http_action_t *nxt_http_return(nxt_task_t *task,
static nxt_int_t nxt_http_return_encode(nxt_mp_t *mp, nxt_str_t *encoded,
const nxt_str_t *location);
static void nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data);
static void nxt_http_return_var_error(nxt_task_t *task, void *obj, void *data);
static void nxt_http_return_send_error(nxt_task_t *task, void *obj, void *data);
static const nxt_http_request_state_t nxt_http_return_send_state;
@@ -57,13 +57,13 @@ nxt_http_return_init(nxt_router_conf_t *rtcf, nxt_http_action_t *action,
nxt_conf_get_string(acf->location, &str);
conf->location = nxt_var_compile(&str, mp, rtcf->var_fields, 0);
conf->location = nxt_tstr_compile(rtcf->tstr_state, &str, 0);
if (nxt_slow_path(conf->location == NULL)) {
return NXT_ERROR;
}
if (nxt_var_is_const(conf->location)) {
nxt_var_raw(conf->location, &str);
if (nxt_tstr_is_const(conf->location)) {
nxt_tstr_str(conf->location, &str);
return nxt_http_return_encode(mp, &conf->encoded, &str);
}
@@ -76,6 +76,7 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r,
nxt_http_action_t *action)
{
nxt_int_t ret;
nxt_router_conf_t *rtcf;
nxt_http_return_ctx_t *ctx;
nxt_http_return_conf_t *conf;
@@ -88,7 +89,7 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r,
nxt_str_set(&loc, "");
} else {
nxt_var_raw(conf->location, &loc);
nxt_tstr_str(conf->location, &loc);
}
nxt_debug(task, "http return: %d (loc: \"%V\")", conf->status, &loc);
@@ -114,7 +115,7 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r,
r->status = conf->status;
r->resp.content_length_n = 0;
if (ctx == NULL || nxt_var_is_const(conf->location)) {
if (ctx == NULL || nxt_tstr_is_const(conf->location)) {
if (ctx != NULL) {
ctx->encoded = conf->encoded;
}
@@ -122,16 +123,19 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r,
nxt_http_return_send_ready(task, r, ctx);
} else {
ret = nxt_var_query_init(&r->var_query, r, r->mem_pool);
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);
if (nxt_slow_path(ret != NXT_OK)) {
goto fail;
}
nxt_var_query(task, r->var_query, conf->location, &ctx->location);
nxt_tstr_query(task, r->tstr_query, conf->location, &ctx->location);
nxt_var_query_resolve(task, r->var_query, ctx,
nxt_http_return_send_ready,
nxt_http_return_var_error);
nxt_tstr_query_resolve(task, r->tstr_query, ctx,
nxt_http_return_send_ready,
nxt_http_return_send_error);
}
return NULL;
@@ -213,7 +217,7 @@ fail:
static void
nxt_http_return_var_error(nxt_task_t *task, void *obj, void *data)
nxt_http_return_send_error(nxt_task_t *task, void *obj, void *data)
{
nxt_http_request_t *r;

View File

@@ -193,8 +193,8 @@ static nxt_int_t nxt_http_action_resolve(nxt_task_t *task,
nxt_router_temp_conf_t *tmcf, nxt_http_action_t *action);
static nxt_http_action_t *nxt_http_pass_var(nxt_task_t *task,
nxt_http_request_t *r, nxt_http_action_t *action);
static void nxt_http_pass_var_ready(nxt_task_t *task, void *obj, void *data);
static void nxt_http_pass_var_error(nxt_task_t *task, void *obj, void *data);
static void nxt_http_pass_query_ready(nxt_task_t *task, void *obj, void *data);
static void nxt_http_pass_query_error(nxt_task_t *task, void *obj, void *data);
static nxt_int_t nxt_http_pass_find(nxt_mp_t *mp, nxt_router_conf_t *rtcf,
nxt_str_t *pass, nxt_http_action_t *action);
static nxt_int_t nxt_http_route_find(nxt_http_routes_t *routes, nxt_str_t *name,
@@ -673,8 +673,8 @@ 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, rtcf->var_fields, 0);
if (nxt_slow_path(action->u.var == NULL)) {
action->u.tstr = nxt_tstr_compile(rtcf->tstr_state, &pass, 0);
if (nxt_slow_path(action->u.tstr == NULL)) {
return NXT_ERROR;
}
@@ -1272,8 +1272,8 @@ nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
return NXT_OK;
}
if (nxt_var_is_const(action->u.var)) {
nxt_var_raw(action->u.var, &pass);
if (nxt_tstr_is_const(action->u.tstr)) {
nxt_tstr_str(action->u.tstr, &pass);
ret = nxt_http_pass_find(tmcf->mem_pool, tmcf->router_conf, &pass,
action);
@@ -1293,17 +1293,21 @@ static nxt_http_action_t *
nxt_http_pass_var(nxt_task_t *task, nxt_http_request_t *r,
nxt_http_action_t *action)
{
nxt_int_t ret;
nxt_str_t str;
nxt_var_t *var;
nxt_int_t ret;
nxt_str_t str;
nxt_tstr_t *tstr;
nxt_router_conf_t *rtcf;
var = action->u.var;
tstr = action->u.tstr;
nxt_var_raw(var, &str);
nxt_tstr_str(tstr, &str);
nxt_debug(task, "http pass: \"%V\"", &str);
ret = nxt_var_query_init(&r->var_query, r, r->mem_pool);
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);
if (nxt_slow_path(ret != NXT_OK)) {
goto fail;
}
@@ -1316,10 +1320,10 @@ nxt_http_pass_var(nxt_task_t *task, nxt_http_request_t *r,
action->u.pass = nxt_pointer_to(action, sizeof(nxt_http_action_t));
nxt_var_query(task, r->var_query, var, action->u.pass);
nxt_var_query_resolve(task, r->var_query, action,
nxt_http_pass_var_ready,
nxt_http_pass_var_error);
nxt_tstr_query(task, r->tstr_query, tstr, action->u.pass);
nxt_tstr_query_resolve(task, r->tstr_query, action,
nxt_http_pass_query_ready,
nxt_http_pass_query_error);
return NULL;
fail:
@@ -1330,7 +1334,7 @@ fail:
static void
nxt_http_pass_var_ready(nxt_task_t *task, void *obj, void *data)
nxt_http_pass_query_ready(nxt_task_t *task, void *obj, void *data)
{
nxt_int_t ret;
nxt_router_conf_t *rtcf;
@@ -1359,7 +1363,7 @@ nxt_http_pass_var_ready(nxt_task_t *task, void *obj, void *data)
static void
nxt_http_pass_var_error(nxt_task_t *task, void *obj, void *data)
nxt_http_pass_query_error(nxt_task_t *task, void *obj, void *data)
{
nxt_http_request_t *r;
@@ -1497,8 +1501,8 @@ nxt_http_action_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
return NULL;
}
action->u.var = nxt_var_compile(pass, mp, rtcf->var_fields, 0);
if (nxt_slow_path(action->u.var == NULL)) {
action->u.tstr = nxt_tstr_compile(rtcf->tstr_state, pass, 0);
if (nxt_slow_path(action->u.tstr == NULL)) {
return NULL;
}

View File

@@ -8,7 +8,7 @@
typedef struct {
nxt_var_t *var;
nxt_tstr_t *tstr;
#if (NXT_HAVE_OPENAT2)
u_char *fname;
#endif
@@ -21,7 +21,7 @@ typedef struct {
nxt_http_static_share_t *shares;
nxt_str_t index;
#if (NXT_HAVE_OPENAT2)
nxt_var_t *chroot;
nxt_tstr_t *chroot;
nxt_uint_t resolve;
#endif
nxt_http_route_rule_t *types;
@@ -48,7 +48,7 @@ static nxt_http_action_t *nxt_http_static(nxt_task_t *task,
static void nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r,
nxt_http_static_ctx_t *ctx);
static void nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data);
static void nxt_http_static_var_error(nxt_task_t *task, void *obj, void *data);
static void nxt_http_static_send_error(nxt_task_t *task, void *obj, void *data);
static void nxt_http_static_next(nxt_task_t *task, nxt_http_request_t *r,
nxt_http_static_ctx_t *ctx, nxt_http_status_t status);
#if (NXT_HAVE_OPENAT2)
@@ -77,7 +77,7 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
uint32_t i;
nxt_mp_t *mp;
nxt_str_t str, *ret;
nxt_var_t *var;
nxt_tstr_t *tstr;
nxt_conf_value_t *cv;
nxt_router_conf_t *rtcf;
nxt_http_static_conf_t *conf;
@@ -104,13 +104,13 @@ 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, rtcf->var_fields, NXT_VAR_STRZ);
if (nxt_slow_path(var == NULL)) {
tstr = nxt_tstr_compile(rtcf->tstr_state, &str, NXT_TSTR_STRZ);
if (nxt_slow_path(tstr == NULL)) {
return NXT_ERROR;
}
conf->shares[i].var = var;
conf->shares[i].is_const = nxt_var_is_const(var);
conf->shares[i].tstr = tstr;
conf->shares[i].is_const = nxt_tstr_is_const(tstr);
}
if (acf->index == NULL) {
@@ -130,20 +130,20 @@ 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, rtcf->var_fields,
NXT_VAR_STRZ);
conf->chroot = nxt_tstr_compile(rtcf->tstr_state, &acf->chroot,
NXT_TSTR_STRZ);
if (nxt_slow_path(conf->chroot == NULL)) {
return NXT_ERROR;
}
is_const = nxt_var_is_const(conf->chroot);
is_const = nxt_tstr_is_const(conf->chroot);
for (i = 0; i < conf->nshares; i++) {
conf->shares[i].is_const &= is_const;
if (conf->shares[i].is_const) {
nxt_var_raw(conf->chroot, &chr);
nxt_var_raw(conf->shares[i].var, &shr);
nxt_tstr_str(conf->chroot, &chr);
nxt_tstr_str(conf->shares[i].tstr, &shr);
conf->shares[i].fname = nxt_http_static_chroot_match(chr.start,
shr.start);
@@ -229,6 +229,7 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r,
nxt_http_static_ctx_t *ctx)
{
nxt_int_t ret;
nxt_router_conf_t *rtcf;
nxt_http_static_conf_t *conf;
nxt_http_static_share_t *share;
@@ -240,14 +241,14 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r,
nxt_str_t shr;
nxt_str_t idx;
nxt_var_raw(share->var, &shr);
nxt_tstr_str(share->tstr, &shr);
idx = conf->index;
#if (NXT_HAVE_OPENAT2)
nxt_str_t chr;
if (conf->chroot != NULL) {
nxt_var_raw(conf->chroot, &chr);
nxt_tstr_str(conf->chroot, &chr);
} else {
nxt_str_set(&chr, "");
@@ -261,34 +262,37 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r,
#endif /* NXT_DEBUG */
if (share->is_const) {
nxt_var_raw(share->var, &ctx->share);
nxt_tstr_str(share->tstr, &ctx->share);
#if (NXT_HAVE_OPENAT2)
if (conf->chroot != NULL && ctx->share_idx == 0) {
nxt_var_raw(conf->chroot, &ctx->chroot);
nxt_tstr_str(conf->chroot, &ctx->chroot);
}
#endif
nxt_http_static_send_ready(task, r, ctx);
} else {
ret = nxt_var_query_init(&r->var_query, r, r->mem_pool);
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);
if (nxt_slow_path(ret != NXT_OK)) {
nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
return;
}
nxt_var_query(task, r->var_query, share->var, &ctx->share);
nxt_tstr_query(task, r->tstr_query, share->tstr, &ctx->share);
#if (NXT_HAVE_OPENAT2)
if (conf->chroot != NULL && ctx->share_idx == 0) {
nxt_var_query(task, r->var_query, conf->chroot, &ctx->chroot);
nxt_tstr_query(task, r->tstr_query, conf->chroot, &ctx->chroot);
}
#endif
nxt_var_query_resolve(task, r->var_query, ctx,
nxt_http_static_send_ready,
nxt_http_static_var_error);
nxt_tstr_query_resolve(task, r->tstr_query, ctx,
nxt_http_static_send_ready,
nxt_http_static_send_error);
}
}
@@ -658,7 +662,7 @@ fail:
static void
nxt_http_static_var_error(nxt_task_t *task, void *obj, void *data)
nxt_http_static_send_error(nxt_task_t *task, void *obj, void *data)
{
nxt_http_request_t *r;

View File

@@ -407,7 +407,7 @@ nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
rtcf = r->conf->socket_conf->router_conf;
vf = nxt_var_field_get(rtcf->var_fields, field);
vf = nxt_var_field_get(rtcf->tstr_state->var_fields, field);
args = nxt_http_arguments_parse(r);
if (nxt_slow_path(args == NULL)) {
@@ -450,7 +450,7 @@ nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
rtcf = r->conf->socket_conf->router_conf;
vf = nxt_var_field_get(rtcf->var_fields, field);
vf = nxt_var_field_get(rtcf->tstr_state->var_fields, field);
nxt_list_each(f, r->fields) {
@@ -485,7 +485,7 @@ nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
rtcf = r->conf->socket_conf->router_conf;
vf = nxt_var_field_get(rtcf->var_fields, field);
vf = nxt_var_field_get(rtcf->tstr_state->var_fields, field);
cookies = nxt_http_cookies_parse(r);
if (nxt_slow_path(cookies == NULL)) {

View File

@@ -68,6 +68,7 @@ typedef uint16_t nxt_port_id_t;
#include <nxt_sprintf.h>
#include <nxt_parse.h>
#include <nxt_var.h>
#include <nxt_tstr.h>
/* TODO: remove unused */

View File

@@ -1060,8 +1060,8 @@ 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)) {
rtcf->tstr_state = nxt_tstr_state_new(mp);
if (nxt_slow_path(rtcf->tstr_state == NULL)) {
goto fail;
}

View File

@@ -43,7 +43,7 @@ typedef struct {
uint32_t threads;
nxt_mp_t *mem_pool;
nxt_array_t *var_fields; /* of nxt_var_field_t */
nxt_tstr_state_t *tstr_state;
nxt_router_t *router;
nxt_http_routes_t *routes;
@@ -53,7 +53,7 @@ typedef struct {
nxt_lvlhsh_t apps_hash;
nxt_router_access_log_t *access_log;
nxt_var_t *log_format;
nxt_tstr_t *log_format;
} nxt_router_conf_t;
@@ -225,7 +225,7 @@ typedef struct {
struct nxt_router_access_log_s {
void (*handler)(nxt_task_t *task, nxt_http_request_t *r,
nxt_router_access_log_t *access_log,
nxt_var_t *format);
nxt_tstr_t *format);
nxt_fd_t fd;
nxt_str_t path;
uint32_t count;

View File

@@ -24,7 +24,7 @@ typedef struct {
static void nxt_router_access_log_writer(nxt_task_t *task,
nxt_http_request_t *r, nxt_router_access_log_t *access_log,
nxt_var_t *format);
nxt_tstr_t *format);
static void nxt_router_access_log_write_ready(nxt_task_t *task, void *obj,
void *data);
static void nxt_router_access_log_write_error(nxt_task_t *task, void *obj,
@@ -63,7 +63,7 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf,
u_char *p;
nxt_int_t ret;
nxt_str_t str;
nxt_var_t *format;
nxt_tstr_t *format;
nxt_router_t *router;
nxt_router_access_log_t *access_log;
nxt_router_access_log_conf_t alcf;
@@ -125,8 +125,7 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf,
p = nxt_cpymem(str.start, alcf.format.start, alcf.format.length);
*p = '\n';
format = nxt_var_compile(&str, rtcf->mem_pool, rtcf->var_fields,
NXT_VAR_LOGGING);
format = nxt_tstr_compile(rtcf->tstr_state, &str, NXT_TSTR_LOGGING);
if (nxt_slow_path(format == NULL)) {
return NXT_ERROR;
}
@@ -140,9 +139,10 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf,
static void
nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r,
nxt_router_access_log_t *access_log, nxt_var_t *format)
nxt_router_access_log_t *access_log, nxt_tstr_t *format)
{
nxt_int_t ret;
nxt_router_conf_t *rtcf;
nxt_router_access_log_ctx_t *ctx;
ctx = nxt_mp_get(r->mem_pool, sizeof(nxt_router_access_log_ctx_t));
@@ -152,21 +152,24 @@ nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r,
ctx->access_log = access_log;
if (nxt_var_is_const(format)) {
nxt_var_raw(format, &ctx->text);
if (nxt_tstr_is_const(format)) {
nxt_tstr_str(format, &ctx->text);
nxt_router_access_log_write_ready(task, r, ctx);
} else {
ret = nxt_var_query_init(&r->var_query, r, r->mem_pool);
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);
if (nxt_slow_path(ret != NXT_OK)) {
return;
}
nxt_var_query(task, r->var_query, format, &ctx->text);
nxt_var_query_resolve(task, r->var_query, ctx,
nxt_router_access_log_write_ready,
nxt_router_access_log_write_error);
nxt_tstr_query(task, r->tstr_query, format, &ctx->text);
nxt_tstr_query_resolve(task, r->tstr_query, ctx,
nxt_router_access_log_write_ready,
nxt_router_access_log_write_error);
}
}

223
src/nxt_tstr.c Normal file
View File

@@ -0,0 +1,223 @@
/*
* Copyright (C) NGINX, Inc.
*/
#include <nxt_main.h>
typedef enum {
NXT_TSTR_CONST = 0,
NXT_TSTR_VAR,
} nxt_tstr_type_t;
struct nxt_tstr_s {
nxt_str_t str;
nxt_var_t *var;
nxt_tstr_flags_t flags;
nxt_tstr_type_t type;
};
struct nxt_tstr_query_s {
nxt_mp_t *pool;
nxt_tstr_state_t *state;
nxt_var_cache_t *cache;
nxt_uint_t waiting;
nxt_uint_t failed; /* 1 bit */
void *ctx;
void *data;
nxt_work_handler_t ready;
nxt_work_handler_t error;
};
nxt_tstr_state_t *
nxt_tstr_state_new(nxt_mp_t *mp)
{
nxt_tstr_state_t *state;
state = nxt_mp_get(mp, sizeof(nxt_tstr_state_t));
if (nxt_slow_path(state == NULL)) {
return NULL;
}
state->pool = mp;
state->var_fields = nxt_array_create(mp, 4, sizeof(nxt_var_field_t));
if (nxt_slow_path(state->var_fields == NULL)) {
return NULL;
}
return state;
}
nxt_tstr_t *
nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str,
nxt_tstr_flags_t flags)
{
u_char *p;
nxt_tstr_t *tstr;
nxt_bool_t strz;
strz = (flags & NXT_TSTR_STRZ) != 0;
tstr = nxt_mp_get(state->pool, sizeof(nxt_tstr_t));
if (nxt_slow_path(tstr == NULL)) {
return NULL;
}
tstr->str.length = str->length + strz;
tstr->str.start = nxt_mp_nget(state->pool, tstr->str.length);
if (nxt_slow_path(tstr->str.start == NULL)) {
return NULL;
}
p = nxt_cpymem(tstr->str.start, str->start, str->length);
if (strz) {
*p = '\0';
}
tstr->flags = flags;
p = nxt_memchr(str->start, '$', str->length);
if (p != NULL) {
tstr->type = NXT_TSTR_VAR;
tstr->var = nxt_var_compile(&tstr->str, state->pool, state->var_fields);
if (nxt_slow_path(tstr->var == NULL)) {
return NULL;
}
} else {
tstr->type = NXT_TSTR_CONST;
}
return tstr;
}
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);
}
nxt_bool_t
nxt_tstr_is_const(nxt_tstr_t *tstr)
{
return (tstr->type == NXT_TSTR_CONST);
}
void
nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str)
{
*str = tstr->str;
if (tstr->flags & NXT_TSTR_STRZ) {
str->length--;
}
}
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_query_t *query;
query = *query_p;
if (*query_p == NULL) {
query = nxt_mp_zget(mp, sizeof(nxt_tstr_query_t));
if (nxt_slow_path(query == NULL)) {
return NXT_ERROR;
}
}
query->pool = mp;
query->state = state;
query->cache = cache;
query->ctx = ctx;
*query_p = query;
return NXT_OK;
}
void
nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr,
nxt_str_t *val)
{
nxt_int_t ret;
if (nxt_tstr_is_const(tstr)) {
nxt_tstr_str(tstr, val);
return;
}
if (nxt_slow_path(query->failed)) {
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->flags & NXT_TSTR_STRZ) {
val->length--;
}
#if (NXT_DEBUG)
nxt_str_t str;
nxt_tstr_str(tstr, &str);
nxt_debug(task, "tstr: \"%V\" -> \"%V\"", &str, val);
#endif
}
void
nxt_tstr_query_resolve(nxt_task_t *task, nxt_tstr_query_t *query, void *data,
nxt_work_handler_t ready, nxt_work_handler_t error)
{
query->data = data;
query->ready = ready;
query->error = error;
if (query->waiting == 0) {
nxt_work_queue_add(&task->thread->engine->fast_work_queue,
query->failed ? query->error : query->ready,
task, query->ctx, query->data);
}
}
void
nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query,
nxt_bool_t failed)
{
query->failed |= failed;
if (--query->waiting == 0) {
nxt_work_queue_add(&task->thread->engine->fast_work_queue,
query->failed ? query->error : query->ready,
task, query->ctx, query->data);
}
}

45
src/nxt_tstr.h Normal file
View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) NGINX, Inc.
*/
#ifndef _NXT_TSTR_H_INCLUDED_
#define _NXT_TSTR_H_INCLUDED_
typedef struct nxt_tstr_s nxt_tstr_t;
typedef struct nxt_tstr_query_s nxt_tstr_query_t;
typedef struct {
nxt_mp_t *pool;
nxt_array_t *var_fields;
} nxt_tstr_state_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_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_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_mp_t *mp);
void nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr,
nxt_str_t *val);
void nxt_tstr_query_resolve(nxt_task_t *task, nxt_tstr_query_t *query,
void *data, nxt_work_handler_t ready, nxt_work_handler_t error);
void nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query,
nxt_bool_t failed);
#endif /* _NXT_TSTR_H_INCLUDED_ */

View File

@@ -9,7 +9,6 @@
struct nxt_var_s {
size_t length;
nxt_uint_t vars;
nxt_var_flags_t flags;
u_char data[];
/*
@@ -29,8 +28,7 @@ typedef struct {
struct nxt_var_query_s {
nxt_mp_t *pool;
nxt_lvlhsh_t cache;
nxt_str_t *spare;
nxt_var_cache_t cache;
nxt_uint_t waiting;
nxt_uint_t failed; /* 1 bit */
@@ -58,8 +56,8 @@ 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);
static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, 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);
@@ -232,21 +230,22 @@ 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)
nxt_var_cache_value(nxt_task_t *task, nxt_var_cache_t *cache, uint32_t index,
void *ctx)
{
nxt_int_t ret;
nxt_str_t *value;
nxt_lvlhsh_query_t lhq;
value = query->spare;
value = cache->spare;
if (value == NULL) {
value = nxt_mp_zget(query->pool, sizeof(nxt_str_t));
value = nxt_mp_zget(cache->pool, sizeof(nxt_str_t));
if (nxt_slow_path(value == NULL)) {
return NULL;
}
query->spare = value;
cache->spare = value;
}
lhq.key_hash = nxt_murmur_hash2_uint32(&index);
@@ -255,21 +254,20 @@ nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, uint32_t index)
lhq.key.start = (u_char *) &index;
lhq.value = value;
lhq.proto = &nxt_var_cache_proto;
lhq.pool = query->pool;
lhq.pool = cache->pool;
ret = nxt_lvlhsh_insert(&query->cache, &lhq);
ret = nxt_lvlhsh_insert(&cache->hash, &lhq);
if (nxt_slow_path(ret == NXT_ERROR)) {
return NULL;
}
if (ret == NXT_OK) {
ret = nxt_var_index[index >> 16](task, value, query->ctx,
index & 0xffff);
ret = nxt_var_index[index >> 16](task, value, ctx, index & 0xffff);
if (nxt_slow_path(ret != NXT_OK)) {
return NULL;
}
query->spare = NULL;
cache->spare = NULL;
}
return lhq.value;
@@ -329,21 +327,17 @@ 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_flags_t flags)
nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields)
{
u_char *p, *end, *next, *src;
size_t size;
uint32_t index;
nxt_bool_t strz;
nxt_var_t *var;
nxt_str_t part;
nxt_uint_t n;
nxt_var_sub_t *subs;
nxt_var_decl_t *decl;
strz = (flags & NXT_VAR_STRZ) != 0;
n = 0;
p = str->start;
@@ -362,24 +356,19 @@ 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 + strz);
var = nxt_mp_get(mp, size);
if (nxt_slow_path(var == NULL)) {
return NULL;
}
var->length = str->length;
var->vars = n;
var->flags = flags;
subs = nxt_var_subs(var);
src = nxt_var_raw_start(var);
nxt_memcpy(src, str->start, str->length);
if (strz) {
src[str->length] = '\0';
}
n = 0;
p = str->start;
@@ -514,84 +503,33 @@ nxt_var_next_part(u_char *start, u_char *end, nxt_str_t *part)
}
inline void
nxt_var_raw(nxt_var_t *var, nxt_str_t *str)
{
str->length = var->length;
str->start = nxt_var_raw_start(var);
}
inline nxt_bool_t
nxt_var_is_const(nxt_var_t *var)
{
return (var->vars == 0);
}
nxt_int_t
nxt_var_query_init(nxt_var_query_t **query_p, void *ctx, nxt_mp_t *mp)
{
nxt_var_query_t *query;
query = *query_p;
if (*query_p == NULL) {
query = nxt_mp_zget(mp, sizeof(nxt_var_query_t));
if (nxt_slow_path(query == NULL)) {
return NXT_ERROR;
}
}
query->pool = mp;
query->ctx = ctx;
*query_p = query;
return NXT_OK;
}
void
nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var,
nxt_str_t *str)
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)
{
u_char *p, *src;
size_t length, last, next;
nxt_str_t *value, **part;
nxt_uint_t i;
nxt_bool_t strz, logging;
nxt_array_t parts;
nxt_var_sub_t *subs;
if (nxt_var_is_const(var)) {
nxt_var_raw(var, str);
return;
}
if (nxt_slow_path(query->failed)) {
return;
}
nxt_memzero(&parts, sizeof(nxt_array_t));
nxt_array_init(&parts, query->pool, sizeof(nxt_str_t *));
strz = (var->flags & NXT_VAR_STRZ) != 0;
logging = (var->flags & NXT_VAR_LOGGING) != 0;
nxt_array_init(&parts, cache->pool, sizeof(nxt_str_t *));
subs = nxt_var_subs(var);
length = var->length;
for (i = 0; i < var->vars; i++) {
value = nxt_var_cache_value(task, query, subs[i].index);
value = nxt_var_cache_value(task, cache, subs[i].index, ctx);
if (nxt_slow_path(value == NULL)) {
goto fail;
return NXT_ERROR;
}
part = nxt_array_add(&parts);
if (nxt_slow_path(part == NULL)) {
goto fail;
return NXT_ERROR;
}
*part = value;
@@ -603,9 +541,9 @@ nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var,
}
}
p = nxt_mp_nget(query->pool, length + strz);
p = nxt_mp_nget(cache->pool, length);
if (nxt_slow_path(p == NULL)) {
goto fail;
return NXT_ERROR;
}
str->length = length;
@@ -636,45 +574,5 @@ nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var,
p = nxt_cpymem(p, &src[last], var->length - last);
}
if (strz) {
*p = '\0';
}
nxt_debug(task, "var: \"%*s\" -> \"%V\"", length, src, str);
return;
fail:
query->failed = 1;
}
void
nxt_var_query_resolve(nxt_task_t *task, nxt_var_query_t *query, void *data,
nxt_work_handler_t ready, nxt_work_handler_t error)
{
query->data = data;
query->ready = ready;
query->error = error;
if (query->waiting == 0) {
nxt_work_queue_add(&task->thread->engine->fast_work_queue,
query->failed ? query->error : query->ready,
task, query->ctx, query->data);
}
}
void
nxt_var_query_handle(nxt_task_t *task, nxt_var_query_t *query,
nxt_bool_t failed)
{
query->failed |= failed;
if (--query->waiting == 0) {
nxt_work_queue_add(&task->thread->engine->fast_work_queue,
query->failed ? query->error : query->ready,
task, query->ctx, query->data);
}
return NXT_OK;
}

View File

@@ -32,10 +32,11 @@ typedef struct {
} nxt_var_field_t;
typedef enum {
NXT_VAR_STRZ = 1 << 0,
NXT_VAR_LOGGING = 1 << 1,
} nxt_var_flags_t;
typedef struct {
nxt_mp_t *pool;
nxt_lvlhsh_t hash;
nxt_str_t *spare;
} nxt_var_cache_t;
nxt_inline nxt_bool_t
@@ -50,21 +51,11 @@ 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_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields,
nxt_var_flags_t flags);
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_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);
void nxt_var_query(nxt_task_t *task, nxt_var_query_t *query,
nxt_var_t *var, nxt_str_t *str);
void nxt_var_query_resolve(nxt_task_t *task, nxt_var_query_t *query, void *data,
nxt_work_handler_t ready, nxt_work_handler_t error);
void nxt_var_query_handle(nxt_task_t *task, nxt_var_query_t *query,
nxt_bool_t failed);
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);
#endif /* _NXT_VAR_H_INCLUDED_ */