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.
This commit is contained in:
@@ -8,39 +8,39 @@
|
|||||||
|
|
||||||
|
|
||||||
static nxt_int_t nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
static u_char *nxt_http_log_date(u_char *buf, nxt_realtime_t *now,
|
||||||
struct tm *tm, size_t size, const char *format);
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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[] = {
|
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"),
|
.name = nxt_string("header_user_agent"),
|
||||||
.handler = nxt_http_var_user_agent,
|
.handler = nxt_http_var_user_agent,
|
||||||
.cacheable = 1,
|
.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
|
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, "$");
|
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
|
static nxt_int_t
|
||||||
nxt_http_var_request_time(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
nxt_http_var_request_time(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
||||||
uint16_t field)
|
void *data)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
nxt_msec_t ms;
|
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
|
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;
|
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
|
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)
|
void *data)
|
||||||
{
|
{
|
||||||
nxt_http_request_t *r;
|
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
|
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;
|
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
|
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;
|
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
|
static nxt_int_t
|
||||||
nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
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;
|
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
|
static nxt_int_t
|
||||||
nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
|
||||||
uint16_t field)
|
|
||||||
{
|
{
|
||||||
nxt_http_request_t *r;
|
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
|
static nxt_int_t
|
||||||
nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
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;
|
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
|
static nxt_int_t
|
||||||
nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
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_off_t bytes;
|
||||||
nxt_http_request_t *r;
|
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
|
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;
|
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
|
static nxt_int_t
|
||||||
nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
|
||||||
uint16_t field)
|
|
||||||
{
|
{
|
||||||
nxt_http_request_t *r;
|
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
|
static nxt_int_t
|
||||||
nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
|
||||||
uint16_t field)
|
|
||||||
{
|
{
|
||||||
nxt_http_request_t *r;
|
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
|
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_array_t *args;
|
||||||
nxt_var_field_t *vf;
|
nxt_var_field_t *vf;
|
||||||
nxt_router_conf_t *rtcf;
|
|
||||||
nxt_http_request_t *r;
|
nxt_http_request_t *r;
|
||||||
nxt_http_name_value_t *nv, *start;
|
nxt_http_name_value_t *nv, *start;
|
||||||
|
|
||||||
r = ctx;
|
r = ctx;
|
||||||
|
vf = data;
|
||||||
rtcf = r->conf->socket_conf->router_conf;
|
|
||||||
|
|
||||||
vf = nxt_var_field_get(rtcf->tstr_state->var_fields, field);
|
|
||||||
|
|
||||||
args = nxt_http_arguments_parse(r);
|
args = nxt_http_arguments_parse(r);
|
||||||
if (nxt_slow_path(args == NULL)) {
|
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
|
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_var_field_t *vf;
|
||||||
nxt_http_field_t *f;
|
nxt_http_field_t *f;
|
||||||
nxt_router_conf_t *rtcf;
|
|
||||||
nxt_http_request_t *r;
|
nxt_http_request_t *r;
|
||||||
|
|
||||||
r = ctx;
|
r = ctx;
|
||||||
|
vf = data;
|
||||||
rtcf = r->conf->socket_conf->router_conf;
|
|
||||||
|
|
||||||
vf = nxt_var_field_get(rtcf->tstr_state->var_fields, field);
|
|
||||||
|
|
||||||
nxt_list_each(f, r->fields) {
|
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
|
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_array_t *cookies;
|
||||||
nxt_var_field_t *vf;
|
nxt_var_field_t *vf;
|
||||||
nxt_router_conf_t *rtcf;
|
|
||||||
nxt_http_request_t *r;
|
nxt_http_request_t *r;
|
||||||
nxt_http_name_value_t *nv, *end;
|
nxt_http_name_value_t *nv, *end;
|
||||||
|
|
||||||
r = ctx;
|
r = ctx;
|
||||||
|
vf = data;
|
||||||
rtcf = r->conf->socket_conf->router_conf;
|
|
||||||
|
|
||||||
vf = nxt_var_field_get(rtcf->tstr_state->var_fields, field);
|
|
||||||
|
|
||||||
cookies = nxt_http_cookies_parse(r);
|
cookies = nxt_http_cookies_parse(r);
|
||||||
if (nxt_slow_path(cookies == NULL)) {
|
if (nxt_slow_path(cookies == NULL)) {
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ typedef uint16_t nxt_port_id_t;
|
|||||||
|
|
||||||
#include <nxt_sprintf.h>
|
#include <nxt_sprintf.h>
|
||||||
#include <nxt_parse.h>
|
#include <nxt_parse.h>
|
||||||
|
|
||||||
|
typedef struct nxt_tstr_state_s nxt_tstr_state_t;
|
||||||
#include <nxt_var.h>
|
#include <nxt_var.h>
|
||||||
#include <nxt_tstr.h>
|
#include <nxt_tstr.h>
|
||||||
|
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ nxt_tstr_state_new(nxt_mp_t *mp, nxt_bool_t test)
|
|||||||
state->pool = mp;
|
state->pool = mp;
|
||||||
state->test = test;
|
state->test = test;
|
||||||
|
|
||||||
state->var_fields = nxt_array_create(mp, 4, sizeof(nxt_var_field_t));
|
state->var_refs = nxt_array_create(mp, 4, sizeof(nxt_var_ref_t));
|
||||||
if (nxt_slow_path(state->var_fields == NULL)) {
|
if (nxt_slow_path(state->var_refs == NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,8 +133,7 @@ nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str,
|
|||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
tstr->type = NXT_TSTR_VAR;
|
tstr->type = NXT_TSTR_VAR;
|
||||||
|
|
||||||
tstr->u.var = nxt_var_compile(&tstr->str, state->pool,
|
tstr->u.var = nxt_var_compile(state, &tstr->str);
|
||||||
state->var_fields);
|
|
||||||
if (nxt_slow_path(tstr->u.var == NULL)) {
|
if (nxt_slow_path(tstr->u.var == NULL)) {
|
||||||
return 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);
|
p = memchr(str->start, '$', str->length);
|
||||||
|
|
||||||
if (p != NULL) {
|
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) {
|
if (tstr->type == NXT_TSTR_VAR) {
|
||||||
ret = nxt_var_interpreter(task, &query->cache->var, tstr->u.var, val,
|
ret = nxt_var_interpreter(task, query->state, &query->cache->var,
|
||||||
query->ctx, tstr->flags & NXT_TSTR_LOGGING);
|
tstr->u.var, val, query->ctx,
|
||||||
|
tstr->flags & NXT_TSTR_LOGGING);
|
||||||
|
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
query->failed = 1;
|
query->failed = 1;
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ typedef struct nxt_tstr_s nxt_tstr_t;
|
|||||||
typedef struct nxt_tstr_query_s nxt_tstr_query_t;
|
typedef struct nxt_tstr_query_s nxt_tstr_query_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
struct nxt_tstr_state_s {
|
||||||
nxt_mp_t *pool;
|
nxt_mp_t *pool;
|
||||||
nxt_array_t *var_fields;
|
nxt_array_t *var_refs;
|
||||||
#if (NXT_HAVE_NJS)
|
#if (NXT_HAVE_NJS)
|
||||||
nxt_js_conf_t *jcf;
|
nxt_js_conf_t *jcf;
|
||||||
#endif
|
#endif
|
||||||
uint8_t test; /* 1 bit */
|
uint8_t test; /* 1 bit */
|
||||||
} nxt_tstr_state_t;
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
162
src/nxt_var.c
162
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_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data);
|
||||||
static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name);
|
static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name);
|
||||||
|
|
||||||
static nxt_var_decl_t *nxt_var_decl_get(nxt_str_t *name, nxt_array_t *fields,
|
static nxt_var_ref_t *nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name);
|
||||||
uint32_t *index);
|
|
||||||
static nxt_var_field_t *nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name,
|
|
||||||
uint32_t hash);
|
|
||||||
|
|
||||||
static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data);
|
static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data);
|
||||||
static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_var_cache_t *cache,
|
static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state,
|
||||||
uint32_t index, void *ctx);
|
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);
|
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 *
|
static nxt_var_ref_t *
|
||||||
nxt_var_decl_get(nxt_str_t *name, nxt_array_t *fields, uint32_t *index)
|
nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name)
|
||||||
{
|
{
|
||||||
u_char *p, *end;
|
nxt_int_t ret;
|
||||||
int64_t hash;
|
nxt_uint_t i;
|
||||||
uint16_t field;
|
nxt_var_ref_t *ref;
|
||||||
nxt_str_t str;
|
|
||||||
nxt_var_decl_t *decl;
|
nxt_var_decl_t *decl;
|
||||||
nxt_var_field_t *f;
|
|
||||||
|
|
||||||
f = NULL;
|
ref = state->var_refs->elts;
|
||||||
field = 0;
|
|
||||||
|
for (i = 0; i < state->var_refs->nelts; i++) {
|
||||||
|
|
||||||
|
if (nxt_strstr_eq(ref[i].name, name)) {
|
||||||
|
return &ref[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = nxt_array_add(state->var_refs);
|
||||||
|
if (nxt_slow_path(ref == NULL)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref->index = state->var_refs->nelts - 1;
|
||||||
|
|
||||||
|
ref->name = nxt_str_dup(state->pool, NULL, name);
|
||||||
|
if (nxt_slow_path(ref->name == NULL)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
decl = nxt_var_hash_find(name);
|
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) {
|
if (decl != NULL) {
|
||||||
str.start = p;
|
ref->handler = decl->handler;
|
||||||
str.length = end - p;
|
ref->cacheable = decl->cacheable;
|
||||||
|
|
||||||
hash = decl->field_hash(fields->mem_pool, &str);
|
return ref;
|
||||||
if (nxt_slow_path(hash == -1)) {
|
}
|
||||||
|
|
||||||
|
ret = nxt_http_unknown_var_ref(state, ref, name);
|
||||||
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = nxt_var_field_add(fields, &str, (uint32_t) hash);
|
return ref;
|
||||||
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_t *
|
||||||
nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name, uint32_t hash)
|
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;
|
nxt_var_field_t *field;
|
||||||
|
|
||||||
field = fields->elts;
|
field = nxt_mp_alloc(mp, sizeof(nxt_var_field_t));
|
||||||
|
|
||||||
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)) {
|
if (nxt_slow_path(field == NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
field->name = *name;
|
str = nxt_str_dup(mp, &field->name, name);
|
||||||
|
if (nxt_slow_path(str == NULL)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
field->hash = hash;
|
field->hash = hash;
|
||||||
field->index = fields->nelts - 1;
|
|
||||||
|
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
@@ -230,15 +202,16 @@ nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data)
|
|||||||
|
|
||||||
|
|
||||||
static nxt_str_t *
|
static nxt_str_t *
|
||||||
nxt_var_cache_value(nxt_task_t *task, nxt_var_cache_t *cache, uint32_t index,
|
nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state,
|
||||||
void *ctx)
|
nxt_var_cache_t *cache, uint32_t index, void *ctx)
|
||||||
{
|
{
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
nxt_str_t *value;
|
nxt_str_t *value;
|
||||||
nxt_var_decl_t *var;
|
nxt_var_ref_t *ref;
|
||||||
nxt_lvlhsh_query_t lhq;
|
nxt_lvlhsh_query_t lhq;
|
||||||
|
|
||||||
var = nxt_vars[index >> 16];
|
ref = state->var_refs->elts;
|
||||||
|
ref = &ref[index];
|
||||||
|
|
||||||
value = cache->spare;
|
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;
|
cache->spare = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!var->cacheable) {
|
if (!ref->cacheable) {
|
||||||
goto not_cached;
|
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:
|
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)) {
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -326,7 +299,6 @@ nxt_var_index_init(void)
|
|||||||
|
|
||||||
for (i = 0; i < nxt_var_count; i++) {
|
for (i = 0; i < nxt_var_count; i++) {
|
||||||
decl = nxt_lvlhsh_each(&nxt_var_hash, &lhe);
|
decl = nxt_lvlhsh_each(&nxt_var_hash, &lhe);
|
||||||
decl->index = i;
|
|
||||||
vars[i] = decl;
|
vars[i] = decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,16 +309,15 @@ nxt_var_index_init(void)
|
|||||||
|
|
||||||
|
|
||||||
nxt_var_t *
|
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;
|
u_char *p, *end, *next, *src;
|
||||||
size_t size;
|
size_t size;
|
||||||
uint32_t index;
|
|
||||||
nxt_var_t *var;
|
nxt_var_t *var;
|
||||||
nxt_str_t part;
|
nxt_str_t part;
|
||||||
nxt_uint_t n;
|
nxt_uint_t n;
|
||||||
nxt_var_sub_t *subs;
|
nxt_var_sub_t *subs;
|
||||||
nxt_var_decl_t *decl;
|
nxt_var_ref_t *ref;
|
||||||
|
|
||||||
n = 0;
|
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;
|
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)) {
|
if (nxt_slow_path(var == NULL)) {
|
||||||
return 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);
|
next = nxt_var_next_part(p, end, &part);
|
||||||
|
|
||||||
if (part.start != NULL) {
|
if (part.start != NULL) {
|
||||||
decl = nxt_var_decl_get(&part, fields, &index);
|
ref = nxt_var_ref_get(state, &part);
|
||||||
if (nxt_slow_path(decl == NULL)) {
|
if (nxt_slow_path(ref == NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
subs[n].index = index;
|
subs[n].index = ref->index;
|
||||||
subs[n].length = next - p;
|
subs[n].length = next - p;
|
||||||
subs[n].position = p - str->start;
|
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_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;
|
u_char *p, *end, *next;
|
||||||
nxt_str_t part;
|
nxt_str_t part;
|
||||||
nxt_var_decl_t *decl;
|
nxt_var_ref_t *ref;
|
||||||
|
|
||||||
p = str->start;
|
p = str->start;
|
||||||
end = p + str->length;
|
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) {
|
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,
|
nxt_sprintf(error, error + NXT_MAX_ERROR_STR,
|
||||||
"Unknown variable \"%V\"%Z", &part);
|
"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_int_t
|
||||||
nxt_var_interpreter(nxt_task_t *task, nxt_var_cache_t *cache, nxt_var_t *var,
|
nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state,
|
||||||
nxt_str_t *str, void *ctx, nxt_bool_t logging)
|
nxt_var_cache_t *cache, nxt_var_t *var, nxt_str_t *str, void *ctx,
|
||||||
|
nxt_bool_t logging)
|
||||||
{
|
{
|
||||||
u_char *p, *src;
|
u_char *p, *src;
|
||||||
size_t length, last, next;
|
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;
|
length = var->length;
|
||||||
|
|
||||||
for (i = 0; i < var->vars; i++) {
|
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)) {
|
if (nxt_slow_path(value == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
typedef nxt_int_t (*nxt_var_handler_t)(nxt_task_t *task,
|
||||||
nxt_str_t *str,
|
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 int64_t (*nxt_var_field_hash_t)(nxt_mp_t *mp, nxt_str_t *str);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nxt_str_t name;
|
nxt_str_t name;
|
||||||
nxt_var_handler_t handler;
|
nxt_var_handler_t handler;
|
||||||
nxt_var_field_hash_t field_hash;
|
|
||||||
uint32_t index;
|
|
||||||
uint8_t cacheable; /* 1 bit */
|
uint8_t cacheable; /* 1 bit */
|
||||||
} nxt_var_decl_t;
|
} 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 {
|
typedef struct {
|
||||||
nxt_str_t name;
|
nxt_str_t name;
|
||||||
uint16_t hash;
|
uint16_t hash;
|
||||||
uint32_t index;
|
|
||||||
} nxt_var_field_t;
|
} 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_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_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_var_t *nxt_var_compile(nxt_tstr_state_t *state, nxt_str_t *str);
|
||||||
nxt_int_t nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error);
|
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_int_t nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state,
|
||||||
nxt_var_t *var, nxt_str_t *str, void *ctx, nxt_bool_t logging);
|
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 *nxt_var_get(nxt_task_t *task, nxt_var_cache_t *cache,
|
||||||
nxt_str_t *name, void *ctx);
|
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_ */
|
#endif /* _NXT_VAR_H_INCLUDED_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user