Var: dynamic variables support.
This commit adds the variables $arg_NAME, $header_NAME, and $cookie_NAME.
This commit is contained in:
@@ -37,6 +37,12 @@ forwarded header to replace client address and protocol.
|
|||||||
</para>
|
</para>
|
||||||
</change>
|
</change>
|
||||||
|
|
||||||
|
<change type="feature">
|
||||||
|
<para>
|
||||||
|
ability to get dynamic variables.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
<change type="bugfix">
|
<change type="bugfix">
|
||||||
<para>
|
<para>
|
||||||
an index file that didn't contain a file extension was incorrectly
|
an index file that didn't contain a file extension was incorrectly
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ typedef struct {
|
|||||||
nxt_mp_t *pool;
|
nxt_mp_t *pool;
|
||||||
nxt_str_t error;
|
nxt_str_t error;
|
||||||
void *ctx;
|
void *ctx;
|
||||||
|
nxt_array_t *var_fields; /* of nxt_var_field_t */
|
||||||
nxt_mp_t *conf_pool;
|
nxt_mp_t *conf_pool;
|
||||||
nxt_uint_t ver;
|
nxt_uint_t ver;
|
||||||
} nxt_conf_validation_t;
|
} nxt_conf_validation_t;
|
||||||
|
|||||||
@@ -1210,6 +1210,11 @@ nxt_conf_validate(nxt_conf_validation_t *vldt)
|
|||||||
{
|
{
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
|
|
||||||
|
vldt->var_fields = nxt_array_create(vldt->pool, 4, sizeof(nxt_var_field_t));
|
||||||
|
if (nxt_slow_path(vldt->var_fields == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_VLDT_OBJECT);
|
ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_VLDT_OBJECT);
|
||||||
if (ret != NXT_OK) {
|
if (ret != NXT_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1342,7 +1347,7 @@ nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name,
|
|||||||
{
|
{
|
||||||
u_char error[NXT_MAX_ERROR_STR];
|
u_char error[NXT_MAX_ERROR_STR];
|
||||||
|
|
||||||
if (nxt_var_test(value, error) != NXT_OK) {
|
if (nxt_var_test(value, vldt->var_fields, error) != NXT_OK) {
|
||||||
return nxt_conf_vldt_error(vldt, "%s in the \"%V\" value.",
|
return nxt_conf_vldt_error(vldt, "%s in the \"%V\" value.",
|
||||||
error, name);
|
error, name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -339,6 +339,9 @@ nxt_array_t *nxt_http_cookies_parse(nxt_http_request_t *r);
|
|||||||
|
|
||||||
int64_t nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name,
|
int64_t nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name,
|
||||||
nxt_bool_t case_sensitive, uint8_t encoding);
|
nxt_bool_t case_sensitive, uint8_t encoding);
|
||||||
|
int64_t nxt_http_argument_hash(nxt_mp_t *mp, nxt_str_t *name);
|
||||||
|
int64_t nxt_http_header_hash(nxt_mp_t *mp, nxt_str_t *name);
|
||||||
|
int64_t nxt_http_cookie_hash(nxt_mp_t *mp, nxt_str_t *name);
|
||||||
|
|
||||||
nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task,
|
nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task,
|
||||||
nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf);
|
nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf);
|
||||||
@@ -369,8 +372,8 @@ nxt_int_t nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
nxt_int_t nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf,
|
nxt_int_t nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf,
|
||||||
nxt_upstream_t ***upstream_joint);
|
nxt_upstream_t ***upstream_joint);
|
||||||
|
|
||||||
nxt_int_t nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action,
|
nxt_int_t nxt_http_return_init(nxt_router_conf_t *rtcf,
|
||||||
nxt_http_action_conf_t *acf);
|
nxt_http_action_t *action, nxt_http_action_conf_t *acf);
|
||||||
|
|
||||||
nxt_int_t nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
nxt_int_t nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||||
nxt_http_action_t *action, nxt_http_action_conf_t *acf);
|
nxt_http_action_t *action, nxt_http_action_conf_t *acf);
|
||||||
|
|||||||
@@ -1180,3 +1180,57 @@ end:
|
|||||||
|
|
||||||
return nxt_http_field_hash_end(hash) & 0xFFFF;
|
return nxt_http_field_hash_end(hash) & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
nxt_http_argument_hash(nxt_mp_t *mp, nxt_str_t *name)
|
||||||
|
{
|
||||||
|
return nxt_http_field_hash(mp, name, 1, NXT_HTTP_URI_ENCODING_PLUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
nxt_http_header_hash(nxt_mp_t *mp, nxt_str_t *name)
|
||||||
|
{
|
||||||
|
u_char c, *p;
|
||||||
|
uint32_t i, hash;
|
||||||
|
nxt_str_t str;
|
||||||
|
|
||||||
|
str.length = name->length;
|
||||||
|
|
||||||
|
str.start = nxt_mp_nget(mp, str.length);
|
||||||
|
if (nxt_slow_path(str.start == NULL)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = str.start;
|
||||||
|
hash = NXT_HTTP_FIELD_HASH_INIT;
|
||||||
|
|
||||||
|
for (i = 0; i < name->length; i++) {
|
||||||
|
c = name->start[i];
|
||||||
|
|
||||||
|
if (c >= 'A' && c <= 'Z') {
|
||||||
|
*p = c | 0x20;
|
||||||
|
|
||||||
|
} else if (c == '_') {
|
||||||
|
*p = '-';
|
||||||
|
|
||||||
|
} else {
|
||||||
|
*p = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash = nxt_http_field_hash_char(hash, *p);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*name = str;
|
||||||
|
|
||||||
|
return nxt_http_field_hash_end(hash) & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
nxt_http_cookie_hash(nxt_mp_t *mp, nxt_str_t *name)
|
||||||
|
{
|
||||||
|
return nxt_http_field_hash(mp, name, 1, NXT_HTTP_URI_ENCODING_NONE);
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,12 +32,15 @@ static const nxt_http_request_state_t nxt_http_return_send_state;
|
|||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action,
|
nxt_http_return_init(nxt_router_conf_t *rtcf, nxt_http_action_t *action,
|
||||||
nxt_http_action_conf_t *acf)
|
nxt_http_action_conf_t *acf)
|
||||||
{
|
{
|
||||||
|
nxt_mp_t *mp;
|
||||||
nxt_str_t str;
|
nxt_str_t str;
|
||||||
nxt_http_return_conf_t *conf;
|
nxt_http_return_conf_t *conf;
|
||||||
|
|
||||||
|
mp = rtcf->mem_pool;
|
||||||
|
|
||||||
conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t));
|
conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t));
|
||||||
if (nxt_slow_path(conf == NULL)) {
|
if (nxt_slow_path(conf == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
@@ -54,7 +57,7 @@ nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action,
|
|||||||
|
|
||||||
nxt_conf_get_string(acf->location, &str);
|
nxt_conf_get_string(acf->location, &str);
|
||||||
|
|
||||||
conf->location = nxt_var_compile(&str, mp, 0);
|
conf->location = nxt_var_compile(&str, mp, rtcf->var_fields, 0);
|
||||||
if (nxt_slow_path(conf->location == NULL)) {
|
if (nxt_slow_path(conf->location == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -643,6 +643,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
nxt_mp_t *mp;
|
nxt_mp_t *mp;
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
nxt_str_t pass;
|
nxt_str_t pass;
|
||||||
|
nxt_router_conf_t *rtcf;
|
||||||
nxt_http_action_conf_t acf;
|
nxt_http_action_conf_t acf;
|
||||||
|
|
||||||
nxt_memzero(&acf, sizeof(acf));
|
nxt_memzero(&acf, sizeof(acf));
|
||||||
@@ -655,10 +656,11 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
|
|
||||||
nxt_memzero(action, sizeof(nxt_http_action_t));
|
nxt_memzero(action, sizeof(nxt_http_action_t));
|
||||||
|
|
||||||
mp = tmcf->router_conf->mem_pool;
|
rtcf = tmcf->router_conf;
|
||||||
|
mp = rtcf->mem_pool;
|
||||||
|
|
||||||
if (acf.ret != NULL) {
|
if (acf.ret != NULL) {
|
||||||
return nxt_http_return_init(mp, action, &acf);
|
return nxt_http_return_init(rtcf, action, &acf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acf.share != NULL) {
|
if (acf.share != NULL) {
|
||||||
@@ -671,7 +673,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
|
|
||||||
nxt_conf_get_string(acf.pass, &pass);
|
nxt_conf_get_string(acf.pass, &pass);
|
||||||
|
|
||||||
action->u.var = nxt_var_compile(&pass, mp, 0);
|
action->u.var = nxt_var_compile(&pass, mp, rtcf->var_fields, 0);
|
||||||
if (nxt_slow_path(action->u.var == NULL)) {
|
if (nxt_slow_path(action->u.var == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1484,16 +1486,18 @@ nxt_http_action_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
{
|
{
|
||||||
nxt_mp_t *mp;
|
nxt_mp_t *mp;
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
|
nxt_router_conf_t *rtcf;
|
||||||
nxt_http_action_t *action;
|
nxt_http_action_t *action;
|
||||||
|
|
||||||
mp = tmcf->router_conf->mem_pool;
|
rtcf = tmcf->router_conf;
|
||||||
|
mp = rtcf->mem_pool;
|
||||||
|
|
||||||
action = nxt_mp_alloc(mp, sizeof(nxt_http_action_t));
|
action = nxt_mp_alloc(mp, sizeof(nxt_http_action_t));
|
||||||
if (nxt_slow_path(action == NULL)) {
|
if (nxt_slow_path(action == NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
action->u.var = nxt_var_compile(pass, mp, 0);
|
action->u.var = nxt_var_compile(pass, mp, rtcf->var_fields, 0);
|
||||||
if (nxt_slow_path(action->u.var == NULL)) {
|
if (nxt_slow_path(action->u.var == NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,9 +79,11 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
nxt_str_t str, *ret;
|
nxt_str_t str, *ret;
|
||||||
nxt_var_t *var;
|
nxt_var_t *var;
|
||||||
nxt_conf_value_t *cv;
|
nxt_conf_value_t *cv;
|
||||||
|
nxt_router_conf_t *rtcf;
|
||||||
nxt_http_static_conf_t *conf;
|
nxt_http_static_conf_t *conf;
|
||||||
|
|
||||||
mp = tmcf->router_conf->mem_pool;
|
rtcf = tmcf->router_conf;
|
||||||
|
mp = rtcf->mem_pool;
|
||||||
|
|
||||||
conf = nxt_mp_zget(mp, sizeof(nxt_http_static_conf_t));
|
conf = nxt_mp_zget(mp, sizeof(nxt_http_static_conf_t));
|
||||||
if (nxt_slow_path(conf == NULL)) {
|
if (nxt_slow_path(conf == NULL)) {
|
||||||
@@ -102,7 +104,7 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
cv = nxt_conf_get_array_element_or_itself(acf->share, i);
|
cv = nxt_conf_get_array_element_or_itself(acf->share, i);
|
||||||
nxt_conf_get_string(cv, &str);
|
nxt_conf_get_string(cv, &str);
|
||||||
|
|
||||||
var = nxt_var_compile(&str, mp, 1);
|
var = nxt_var_compile(&str, mp, rtcf->var_fields, 1);
|
||||||
if (nxt_slow_path(var == NULL)) {
|
if (nxt_slow_path(var == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -128,7 +130,7 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
nxt_str_t chr, shr;
|
nxt_str_t chr, shr;
|
||||||
nxt_bool_t is_const;
|
nxt_bool_t is_const;
|
||||||
|
|
||||||
conf->chroot = nxt_var_compile(&acf->chroot, mp, 1);
|
conf->chroot = nxt_var_compile(&acf->chroot, mp, rtcf->var_fields, 1);
|
||||||
if (nxt_slow_path(conf->chroot == NULL)) {
|
if (nxt_slow_path(conf->chroot == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,29 +8,47 @@
|
|||||||
|
|
||||||
|
|
||||||
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);
|
void *ctx, uint16_t field);
|
||||||
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);
|
void *ctx, uint16_t field);
|
||||||
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,
|
||||||
static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx);
|
uint16_t field);
|
||||||
|
static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
||||||
|
uint16_t field);
|
||||||
|
static nxt_int_t nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
||||||
|
uint16_t field);
|
||||||
|
static nxt_int_t nxt_http_var_header(nxt_task_t *task, nxt_str_t *str,
|
||||||
|
void *ctx, uint16_t field);
|
||||||
|
static nxt_int_t nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str,
|
||||||
|
void *ctx, uint16_t field);
|
||||||
|
|
||||||
|
|
||||||
static nxt_var_decl_t nxt_http_vars[] = {
|
static nxt_var_decl_t nxt_http_vars[] = {
|
||||||
{ nxt_string("method"),
|
{
|
||||||
&nxt_http_var_method,
|
.name = nxt_string("method"),
|
||||||
0 },
|
.handler = nxt_http_var_method,
|
||||||
|
}, {
|
||||||
{ nxt_string("request_uri"),
|
.name = nxt_string("request_uri"),
|
||||||
&nxt_http_var_request_uri,
|
.handler = nxt_http_var_request_uri,
|
||||||
0 },
|
}, {
|
||||||
|
.name = nxt_string("uri"),
|
||||||
{ nxt_string("uri"),
|
.handler = nxt_http_var_uri,
|
||||||
&nxt_http_var_uri,
|
}, {
|
||||||
0 },
|
.name = nxt_string("host"),
|
||||||
|
.handler = nxt_http_var_host,
|
||||||
{ nxt_string("host"),
|
}, {
|
||||||
&nxt_http_var_host,
|
.name = nxt_string("arg"),
|
||||||
0 },
|
.handler = nxt_http_var_arg,
|
||||||
|
.field_hash = nxt_http_argument_hash,
|
||||||
|
}, {
|
||||||
|
.name = nxt_string("header"),
|
||||||
|
.handler = nxt_http_var_header,
|
||||||
|
.field_hash = nxt_http_header_hash,
|
||||||
|
}, {
|
||||||
|
.name = nxt_string("cookie"),
|
||||||
|
.handler = nxt_http_var_cookie,
|
||||||
|
.field_hash = nxt_http_cookie_hash,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -42,7 +60,7 @@ nxt_http_register_variables(void)
|
|||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx)
|
nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
|
||||||
{
|
{
|
||||||
nxt_http_request_t *r;
|
nxt_http_request_t *r;
|
||||||
|
|
||||||
@@ -55,7 +73,8 @@ nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx)
|
|||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx)
|
nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx,
|
||||||
|
uint16_t field)
|
||||||
{
|
{
|
||||||
nxt_http_request_t *r;
|
nxt_http_request_t *r;
|
||||||
|
|
||||||
@@ -68,7 +87,7 @@ nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx)
|
|||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx)
|
nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
|
||||||
{
|
{
|
||||||
nxt_http_request_t *r;
|
nxt_http_request_t *r;
|
||||||
|
|
||||||
@@ -81,7 +100,7 @@ nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx)
|
|||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx)
|
nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
|
||||||
{
|
{
|
||||||
nxt_http_request_t *r;
|
nxt_http_request_t *r;
|
||||||
|
|
||||||
@@ -91,3 +110,125 @@ nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx)
|
|||||||
|
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
|
||||||
|
{
|
||||||
|
nxt_array_t *args;
|
||||||
|
nxt_var_field_t *vf;
|
||||||
|
nxt_router_conf_t *rtcf;
|
||||||
|
nxt_http_request_t *r;
|
||||||
|
nxt_http_name_value_t *nv, *start;
|
||||||
|
|
||||||
|
r = ctx;
|
||||||
|
|
||||||
|
rtcf = r->conf->socket_conf->router_conf;
|
||||||
|
|
||||||
|
vf = nxt_var_field_get(rtcf->var_fields, field);
|
||||||
|
|
||||||
|
args = nxt_http_arguments_parse(r);
|
||||||
|
if (nxt_slow_path(args == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = args->elts;
|
||||||
|
nv = start + args->nelts - 1;
|
||||||
|
|
||||||
|
while (nv >= start) {
|
||||||
|
|
||||||
|
if (vf->hash == nv->hash
|
||||||
|
&& vf->name.length == nv->name_length
|
||||||
|
&& nxt_memcmp(vf->name.start, nv->name, nv->name_length) == 0)
|
||||||
|
{
|
||||||
|
str->start = nv->value;
|
||||||
|
str->length = nv->value_length;
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nv--;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxt_str_null(str);
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
|
||||||
|
{
|
||||||
|
nxt_var_field_t *vf;
|
||||||
|
nxt_http_field_t *f;
|
||||||
|
nxt_router_conf_t *rtcf;
|
||||||
|
nxt_http_request_t *r;
|
||||||
|
|
||||||
|
r = ctx;
|
||||||
|
|
||||||
|
rtcf = r->conf->socket_conf->router_conf;
|
||||||
|
|
||||||
|
vf = nxt_var_field_get(rtcf->var_fields, field);
|
||||||
|
|
||||||
|
nxt_list_each(f, r->fields) {
|
||||||
|
|
||||||
|
if (vf->hash == f->hash
|
||||||
|
&& vf->name.length == f->name_length
|
||||||
|
&& nxt_strncasecmp(vf->name.start, f->name, f->name_length) == 0)
|
||||||
|
{
|
||||||
|
str->start = f->value;
|
||||||
|
str->length = f->value_length;
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} nxt_list_loop;
|
||||||
|
|
||||||
|
nxt_str_null(str);
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field)
|
||||||
|
{
|
||||||
|
nxt_array_t *cookies;
|
||||||
|
nxt_var_field_t *vf;
|
||||||
|
nxt_router_conf_t *rtcf;
|
||||||
|
nxt_http_request_t *r;
|
||||||
|
nxt_http_name_value_t *nv, *end;
|
||||||
|
|
||||||
|
r = ctx;
|
||||||
|
|
||||||
|
rtcf = r->conf->socket_conf->router_conf;
|
||||||
|
|
||||||
|
vf = nxt_var_field_get(rtcf->var_fields, field);
|
||||||
|
|
||||||
|
cookies = nxt_http_cookies_parse(r);
|
||||||
|
if (nxt_slow_path(cookies == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nv = cookies->elts;
|
||||||
|
end = nv + cookies->nelts;
|
||||||
|
|
||||||
|
while (nv < end) {
|
||||||
|
|
||||||
|
if (vf->hash == nv->hash
|
||||||
|
&& vf->name.length == nv->name_length
|
||||||
|
&& nxt_memcmp(vf->name.start, nv->name, nv->name_length) == 0)
|
||||||
|
{
|
||||||
|
str->start = nv->value;
|
||||||
|
str->length = nv->value_length;
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nv++;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxt_str_null(str);
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1004,6 +1004,11 @@ nxt_router_temp_conf(nxt_task_t *task)
|
|||||||
|
|
||||||
rtcf->mem_pool = mp;
|
rtcf->mem_pool = mp;
|
||||||
|
|
||||||
|
rtcf->var_fields = nxt_array_create(mp, 4, sizeof(nxt_var_field_t));
|
||||||
|
if (nxt_slow_path(rtcf->var_fields == NULL)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = nxt_mp_create(1024, 128, 256, 32);
|
tmp = nxt_mp_create(1024, 128, 256, 32);
|
||||||
if (nxt_slow_path(tmp == NULL)) {
|
if (nxt_slow_path(tmp == NULL)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ typedef struct {
|
|||||||
uint32_t threads;
|
uint32_t threads;
|
||||||
|
|
||||||
nxt_mp_t *mem_pool;
|
nxt_mp_t *mem_pool;
|
||||||
|
nxt_array_t *var_fields; /* of nxt_var_field_t */
|
||||||
|
|
||||||
nxt_router_t *router;
|
nxt_router_t *router;
|
||||||
nxt_http_routes_t *routes;
|
nxt_http_routes_t *routes;
|
||||||
|
|||||||
131
src/nxt_var.c
131
src/nxt_var.c
@@ -52,6 +52,11 @@ struct nxt_var_query_s {
|
|||||||
static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data);
|
static nxt_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,
|
||||||
|
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_query_t *query,
|
static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query,
|
||||||
uint32_t index);
|
uint32_t index);
|
||||||
@@ -109,6 +114,117 @@ nxt_var_hash_find(nxt_str_t *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_var_decl_t *
|
||||||
|
nxt_var_decl_get(nxt_str_t *name, nxt_array_t *fields, uint32_t *index)
|
||||||
|
{
|
||||||
|
u_char *p, *end;
|
||||||
|
int64_t hash;
|
||||||
|
uint16_t field;
|
||||||
|
nxt_str_t str;
|
||||||
|
nxt_var_decl_t *decl;
|
||||||
|
nxt_var_field_t *f;
|
||||||
|
|
||||||
|
f = NULL;
|
||||||
|
field = 0;
|
||||||
|
decl = nxt_var_hash_find(name);
|
||||||
|
|
||||||
|
if (decl == NULL) {
|
||||||
|
p = name->start;
|
||||||
|
end = p + name->length;
|
||||||
|
|
||||||
|
while (p < end) {
|
||||||
|
if (*p++ == '_') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == end) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
str.start = name->start;
|
||||||
|
str.length = p - 1 - name->start;
|
||||||
|
|
||||||
|
decl = nxt_var_hash_find(&str);
|
||||||
|
|
||||||
|
if (decl != NULL) {
|
||||||
|
str.start = p;
|
||||||
|
str.length = end - p;
|
||||||
|
|
||||||
|
hash = decl->field_hash(fields->mem_pool, &str);
|
||||||
|
if (nxt_slow_path(hash == -1)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = nxt_var_field_add(fields, &str, (uint32_t) hash);
|
||||||
|
if (nxt_slow_path(f == NULL)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
field = f->index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decl != NULL) {
|
||||||
|
if (decl->field_hash != NULL && f == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index != NULL) {
|
||||||
|
*index = (decl->index << 16) | field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return decl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_var_field_t *
|
||||||
|
nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name, uint32_t hash)
|
||||||
|
{
|
||||||
|
nxt_uint_t i;
|
||||||
|
nxt_var_field_t *field;
|
||||||
|
|
||||||
|
field = fields->elts;
|
||||||
|
|
||||||
|
for (i = 0; i < fields->nelts; i++) {
|
||||||
|
if (field[i].hash == hash
|
||||||
|
&& nxt_strstr_eq(&field[i].name, name))
|
||||||
|
{
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field = nxt_array_add(fields);
|
||||||
|
if (nxt_slow_path(field == NULL)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
field->name = *name;
|
||||||
|
field->hash = hash;
|
||||||
|
field->index = fields->nelts - 1;
|
||||||
|
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nxt_var_field_t *
|
||||||
|
nxt_var_field_get(nxt_array_t *fields, uint16_t index)
|
||||||
|
{
|
||||||
|
nxt_uint_t nfields;
|
||||||
|
nxt_var_field_t *field;
|
||||||
|
|
||||||
|
field = fields->elts;
|
||||||
|
nfields = fields->nelts;
|
||||||
|
|
||||||
|
if (nfields > 0 && index <= nfields) {
|
||||||
|
return &field[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data)
|
nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data)
|
||||||
{
|
{
|
||||||
@@ -148,7 +264,8 @@ nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, uint32_t index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret == NXT_OK) {
|
if (ret == NXT_OK) {
|
||||||
ret = nxt_var_index[index](task, value, query->ctx);
|
ret = nxt_var_index[index >> 16](task, value, query->ctx,
|
||||||
|
index & 0xffff);
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -213,10 +330,12 @@ nxt_var_index_init(void)
|
|||||||
|
|
||||||
|
|
||||||
nxt_var_t *
|
nxt_var_t *
|
||||||
nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz)
|
nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields,
|
||||||
|
nxt_bool_t strz)
|
||||||
{
|
{
|
||||||
u_char *p, *end, *next, *src;
|
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;
|
||||||
@@ -267,12 +386,12 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz)
|
|||||||
next = nxt_var_next_part(p, end - p, &part, &is_var);
|
next = nxt_var_next_part(p, end - p, &part, &is_var);
|
||||||
|
|
||||||
if (is_var) {
|
if (is_var) {
|
||||||
decl = nxt_var_hash_find(&part);
|
decl = nxt_var_decl_get(&part, fields, &index);
|
||||||
if (nxt_slow_path(decl == NULL)) {
|
if (nxt_slow_path(decl == NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
subs[n].index = decl->index;
|
subs[n].index = index;
|
||||||
subs[n].length = next - p;
|
subs[n].length = next - p;
|
||||||
subs[n].position = p - str->start;
|
subs[n].position = p - str->start;
|
||||||
|
|
||||||
@@ -287,7 +406,7 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz)
|
|||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_var_test(nxt_str_t *str, u_char *error)
|
nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error)
|
||||||
{
|
{
|
||||||
u_char *p, *end, *next;
|
u_char *p, *end, *next;
|
||||||
nxt_str_t part;
|
nxt_str_t part;
|
||||||
@@ -308,7 +427,7 @@ nxt_var_test(nxt_str_t *str, u_char *error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_var) {
|
if (is_var) {
|
||||||
decl = nxt_var_hash_find(&part);
|
decl = nxt_var_decl_get(&part, fields, NULL);
|
||||||
|
|
||||||
if (decl == NULL) {
|
if (decl == NULL) {
|
||||||
nxt_sprintf(error, error + NXT_MAX_ERROR_STR,
|
nxt_sprintf(error, error + NXT_MAX_ERROR_STR,
|
||||||
|
|||||||
@@ -13,15 +13,25 @@ typedef struct nxt_var_query_s nxt_var_query_t;
|
|||||||
|
|
||||||
typedef nxt_int_t (*nxt_var_handler_t)(nxt_task_t *task,
|
typedef nxt_int_t (*nxt_var_handler_t)(nxt_task_t *task,
|
||||||
nxt_str_t *str,
|
nxt_str_t *str,
|
||||||
void *ctx);
|
void *ctx, uint16_t field);
|
||||||
|
|
||||||
|
typedef int64_t (*nxt_var_field_hash_t)(nxt_mp_t *mp, nxt_str_t *str);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nxt_str_t name;
|
nxt_str_t name;
|
||||||
nxt_var_handler_t handler;
|
nxt_var_handler_t handler;
|
||||||
uint32_t index;
|
nxt_var_field_hash_t field_hash;
|
||||||
|
uint32_t index;
|
||||||
} nxt_var_decl_t;
|
} nxt_var_decl_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
nxt_str_t name;
|
||||||
|
uint16_t hash;
|
||||||
|
uint32_t index;
|
||||||
|
} nxt_var_field_t;
|
||||||
|
|
||||||
|
|
||||||
nxt_inline nxt_bool_t
|
nxt_inline nxt_bool_t
|
||||||
nxt_is_var(nxt_str_t *str)
|
nxt_is_var(nxt_str_t *str)
|
||||||
{
|
{
|
||||||
@@ -31,11 +41,15 @@ nxt_is_var(nxt_str_t *str)
|
|||||||
|
|
||||||
nxt_int_t nxt_var_register(nxt_var_decl_t *decl, size_t n);
|
nxt_int_t nxt_var_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_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz);
|
|
||||||
nxt_int_t nxt_var_test(nxt_str_t *str, u_char *error);
|
|
||||||
|
|
||||||
void nxt_var_raw(nxt_var_t *var, nxt_str_t *str);
|
nxt_var_field_t *nxt_var_field_get(nxt_array_t *fields, uint16_t index);
|
||||||
|
|
||||||
|
nxt_var_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields,
|
||||||
|
nxt_bool_t strz);
|
||||||
|
nxt_int_t nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error);
|
||||||
|
|
||||||
nxt_bool_t nxt_var_is_const(nxt_var_t *var);
|
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_int_t nxt_var_query_init(nxt_var_query_t **query_p, void *ctx,
|
||||||
nxt_mp_t *mp);
|
nxt_mp_t *mp);
|
||||||
|
|||||||
Reference in New Issue
Block a user