Configuration: basic validation of schema.
This commit is contained in:
@@ -139,6 +139,7 @@ NXT_LIB_SRCS=" \
|
|||||||
src/nxt_app_log.c \
|
src/nxt_app_log.c \
|
||||||
src/nxt_runtime.c \
|
src/nxt_runtime.c \
|
||||||
src/nxt_conf.c \
|
src/nxt_conf.c \
|
||||||
|
src/nxt_conf_validation.c \
|
||||||
src/nxt_stream_module.c \
|
src/nxt_stream_module.c \
|
||||||
src/nxt_master_process.c \
|
src/nxt_master_process.c \
|
||||||
src/nxt_worker_process.c \
|
src/nxt_worker_process.c \
|
||||||
|
|||||||
136
src/nxt_conf.c
136
src/nxt_conf.c
@@ -17,15 +17,15 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NXT_CONF_NULL = 0,
|
NXT_CONF_VALUE_NULL = 0,
|
||||||
NXT_CONF_BOOLEAN,
|
NXT_CONF_VALUE_BOOLEAN,
|
||||||
NXT_CONF_INTEGER,
|
NXT_CONF_VALUE_INTEGER,
|
||||||
NXT_CONF_NUMBER,
|
NXT_CONF_VALUE_NUMBER,
|
||||||
NXT_CONF_SHORT_STRING,
|
NXT_CONF_VALUE_SHORT_STRING,
|
||||||
NXT_CONF_STRING,
|
NXT_CONF_VALUE_STRING,
|
||||||
NXT_CONF_ARRAY,
|
NXT_CONF_VALUE_ARRAY,
|
||||||
NXT_CONF_OBJECT,
|
NXT_CONF_VALUE_OBJECT,
|
||||||
} nxt_conf_type_t;
|
} nxt_conf_value_type_t;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -51,7 +51,7 @@ struct nxt_conf_value_s {
|
|||||||
nxt_conf_object_t *object;
|
nxt_conf_object_t *object;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
nxt_conf_type_t type:8; /* 3 bits. */
|
nxt_conf_value_type_t type:8; /* 3 bits. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ nxt_conf_json_indentation(u_char *p, uint32_t level)
|
|||||||
nxt_inline void
|
nxt_inline void
|
||||||
nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str)
|
nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str)
|
||||||
{
|
{
|
||||||
if (value->type == NXT_CONF_SHORT_STRING) {
|
if (value->type == NXT_CONF_VALUE_SHORT_STRING) {
|
||||||
str->length = value->u.str[0];
|
str->length = value->u.str[0];
|
||||||
str->start = &value->u.str[1];
|
str->start = &value->u.str[1];
|
||||||
|
|
||||||
@@ -150,6 +150,40 @@ nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nxt_uint_t
|
||||||
|
nxt_conf_type(nxt_conf_value_t *value)
|
||||||
|
{
|
||||||
|
switch (value->type) {
|
||||||
|
|
||||||
|
case NXT_CONF_VALUE_NULL:
|
||||||
|
return NXT_CONF_NULL;
|
||||||
|
|
||||||
|
case NXT_CONF_VALUE_BOOLEAN:
|
||||||
|
return NXT_CONF_BOOLEAN;
|
||||||
|
|
||||||
|
case NXT_CONF_VALUE_INTEGER:
|
||||||
|
return NXT_CONF_INTEGER;
|
||||||
|
|
||||||
|
case NXT_CONF_VALUE_NUMBER:
|
||||||
|
return NXT_CONF_NUMBER;
|
||||||
|
|
||||||
|
case NXT_CONF_VALUE_SHORT_STRING:
|
||||||
|
case NXT_CONF_VALUE_STRING:
|
||||||
|
return NXT_CONF_STRING;
|
||||||
|
|
||||||
|
case NXT_CONF_VALUE_ARRAY:
|
||||||
|
return NXT_CONF_ARRAY;
|
||||||
|
|
||||||
|
case NXT_CONF_VALUE_OBJECT:
|
||||||
|
return NXT_CONF_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxt_unreachable();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_char *start;
|
u_char *start;
|
||||||
u_char *end;
|
u_char *end;
|
||||||
@@ -225,7 +259,7 @@ nxt_conf_get_object_member(nxt_conf_value_t *value, nxt_str_t *name,
|
|||||||
nxt_conf_object_t *object;
|
nxt_conf_object_t *object;
|
||||||
nxt_conf_object_member_t *member;
|
nxt_conf_object_member_t *member;
|
||||||
|
|
||||||
if (value->type != NXT_CONF_OBJECT) {
|
if (value->type != NXT_CONF_VALUE_OBJECT) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +307,7 @@ nxt_conf_map_object(nxt_conf_value_t *value, nxt_conf_map_t *map, void *data)
|
|||||||
|
|
||||||
v = nxt_conf_get_object_member(value, &map[i].name, NULL);
|
v = nxt_conf_get_object_member(value, &map[i].name, NULL);
|
||||||
|
|
||||||
if (v == NULL || v->type == NXT_CONF_NULL) {
|
if (v == NULL || v->type == NXT_CONF_VALUE_NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +317,7 @@ nxt_conf_map_object(nxt_conf_value_t *value, nxt_conf_map_t *map, void *data)
|
|||||||
|
|
||||||
case NXT_CONF_MAP_INT8:
|
case NXT_CONF_MAP_INT8:
|
||||||
|
|
||||||
if (v->type != NXT_CONF_BOOLEAN) {
|
if (v->type != NXT_CONF_VALUE_BOOLEAN) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +332,7 @@ nxt_conf_map_object(nxt_conf_value_t *value, nxt_conf_map_t *map, void *data)
|
|||||||
case NXT_CONF_MAP_OFF:
|
case NXT_CONF_MAP_OFF:
|
||||||
case NXT_CONF_MAP_MSEC:
|
case NXT_CONF_MAP_MSEC:
|
||||||
|
|
||||||
if (v->type != NXT_CONF_INTEGER) {
|
if (v->type != NXT_CONF_VALUE_INTEGER) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,10 +370,10 @@ nxt_conf_map_object(nxt_conf_value_t *value, nxt_conf_map_t *map, void *data)
|
|||||||
|
|
||||||
case NXT_CONF_MAP_DOUBLE:
|
case NXT_CONF_MAP_DOUBLE:
|
||||||
|
|
||||||
if (v->type == NXT_CONF_NUMBER) {
|
if (v->type == NXT_CONF_VALUE_NUMBER) {
|
||||||
ptr->dbl = v->u.number;
|
ptr->dbl = v->u.number;
|
||||||
|
|
||||||
} else if (v->type == NXT_CONF_INTEGER) {
|
} else if (v->type == NXT_CONF_VALUE_INTEGER) {
|
||||||
ptr->dbl = v->u.integer;
|
ptr->dbl = v->u.integer;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -350,8 +384,8 @@ nxt_conf_map_object(nxt_conf_value_t *value, nxt_conf_map_t *map, void *data)
|
|||||||
|
|
||||||
case NXT_CONF_MAP_STR:
|
case NXT_CONF_MAP_STR:
|
||||||
|
|
||||||
if (v->type != NXT_CONF_SHORT_STRING
|
if (v->type != NXT_CONF_VALUE_SHORT_STRING
|
||||||
&& v->type != NXT_CONF_STRING)
|
&& v->type != NXT_CONF_VALUE_STRING)
|
||||||
{
|
{
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -381,7 +415,7 @@ nxt_conf_next_object_member(nxt_conf_value_t *value, nxt_str_t *name,
|
|||||||
nxt_conf_object_t *object;
|
nxt_conf_object_t *object;
|
||||||
nxt_conf_object_member_t *member;
|
nxt_conf_object_member_t *member;
|
||||||
|
|
||||||
if (value->type != NXT_CONF_OBJECT) {
|
if (value->type != NXT_CONF_VALUE_OBJECT) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,13 +500,13 @@ nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*member->name.u.string = token;
|
*member->name.u.string = token;
|
||||||
member->name.type = NXT_CONF_STRING;
|
member->name.type = NXT_CONF_VALUE_STRING;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
member->name.u.str[0] = token.length;
|
member->name.u.str[0] = token.length;
|
||||||
nxt_memcpy(&member->name.u.str[1], token.start, token.length);
|
nxt_memcpy(&member->name.u.str[1], token.start, token.length);
|
||||||
|
|
||||||
member->name.type = NXT_CONF_SHORT_STRING;
|
member->name.type = NXT_CONF_VALUE_SHORT_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
member->value = *value;
|
member->value = *value;
|
||||||
@@ -518,7 +552,7 @@ nxt_conf_copy_value(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst,
|
|||||||
nxt_int_t rc;
|
nxt_int_t rc;
|
||||||
nxt_uint_t n;
|
nxt_uint_t n;
|
||||||
|
|
||||||
if (op != NULL && src->type != NXT_CONF_OBJECT) {
|
if (op != NULL && src->type != NXT_CONF_VALUE_OBJECT) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,7 +560,7 @@ nxt_conf_copy_value(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst,
|
|||||||
|
|
||||||
switch (src->type) {
|
switch (src->type) {
|
||||||
|
|
||||||
case NXT_CONF_STRING:
|
case NXT_CONF_VALUE_STRING:
|
||||||
|
|
||||||
dst->u.string = nxt_str_dup(mp, NULL, src->u.string);
|
dst->u.string = nxt_str_dup(mp, NULL, src->u.string);
|
||||||
|
|
||||||
@@ -536,7 +570,7 @@ nxt_conf_copy_value(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NXT_CONF_ARRAY:
|
case NXT_CONF_VALUE_ARRAY:
|
||||||
|
|
||||||
size = sizeof(nxt_conf_array_t)
|
size = sizeof(nxt_conf_array_t)
|
||||||
+ src->u.array->count * sizeof(nxt_conf_value_t);
|
+ src->u.array->count * sizeof(nxt_conf_value_t);
|
||||||
@@ -559,7 +593,7 @@ nxt_conf_copy_value(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NXT_CONF_OBJECT:
|
case NXT_CONF_VALUE_OBJECT:
|
||||||
return nxt_conf_copy_object(mp, op, dst, src);
|
return nxt_conf_copy_object(mp, op, dst, src);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -780,7 +814,7 @@ nxt_conf_json_parse_value(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start,
|
|||||||
&& nxt_memcmp(start, "true", 4) == 0))
|
&& nxt_memcmp(start, "true", 4) == 0))
|
||||||
{
|
{
|
||||||
value->u.boolean = 1;
|
value->u.boolean = 1;
|
||||||
value->type = NXT_CONF_BOOLEAN;
|
value->type = NXT_CONF_VALUE_BOOLEAN;
|
||||||
|
|
||||||
return start + 4;
|
return start + 4;
|
||||||
}
|
}
|
||||||
@@ -792,7 +826,7 @@ nxt_conf_json_parse_value(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start,
|
|||||||
&& nxt_memcmp(start, "false", 5) == 0))
|
&& nxt_memcmp(start, "false", 5) == 0))
|
||||||
{
|
{
|
||||||
value->u.boolean = 0;
|
value->u.boolean = 0;
|
||||||
value->type = NXT_CONF_BOOLEAN;
|
value->type = NXT_CONF_VALUE_BOOLEAN;
|
||||||
|
|
||||||
return start + 5;
|
return start + 5;
|
||||||
}
|
}
|
||||||
@@ -803,7 +837,7 @@ nxt_conf_json_parse_value(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start,
|
|||||||
if (nxt_fast_path(end - start >= 4
|
if (nxt_fast_path(end - start >= 4
|
||||||
&& nxt_memcmp(start, "null", 4) == 0))
|
&& nxt_memcmp(start, "null", 4) == 0))
|
||||||
{
|
{
|
||||||
value->type = NXT_CONF_NULL;
|
value->type = NXT_CONF_VALUE_NULL;
|
||||||
return start + 4;
|
return start + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -929,7 +963,7 @@ nxt_conf_json_parse_object(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
value->u.object = object;
|
value->u.object = object;
|
||||||
value->type = NXT_CONF_OBJECT;
|
value->type = NXT_CONF_VALUE_OBJECT;
|
||||||
|
|
||||||
object->count = count;
|
object->count = count;
|
||||||
member = object->members;
|
member = object->members;
|
||||||
@@ -1082,7 +1116,7 @@ nxt_conf_json_parse_array(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
value->u.array = array;
|
value->u.array = array;
|
||||||
value->type = NXT_CONF_ARRAY;
|
value->type = NXT_CONF_VALUE_ARRAY;
|
||||||
|
|
||||||
array->count = count;
|
array->count = count;
|
||||||
element = array->elements;
|
element = array->elements;
|
||||||
@@ -1204,7 +1238,7 @@ nxt_conf_json_parse_string(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start,
|
|||||||
size = last - start - surplus;
|
size = last - start - surplus;
|
||||||
|
|
||||||
if (size > NXT_CONF_MAX_SHORT_STRING) {
|
if (size > NXT_CONF_MAX_SHORT_STRING) {
|
||||||
value->type = NXT_CONF_STRING;
|
value->type = NXT_CONF_VALUE_STRING;
|
||||||
value->u.string = nxt_str_alloc(mp, size);
|
value->u.string = nxt_str_alloc(mp, size);
|
||||||
|
|
||||||
if (nxt_slow_path(value->u.string == NULL)) {
|
if (nxt_slow_path(value->u.string == NULL)) {
|
||||||
@@ -1214,7 +1248,7 @@ nxt_conf_json_parse_string(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start,
|
|||||||
s = value->u.string->start;
|
s = value->u.string->start;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
value->type = NXT_CONF_SHORT_STRING;
|
value->type = NXT_CONF_VALUE_SHORT_STRING;
|
||||||
value->u.str[0] = size;
|
value->u.str[0] = size;
|
||||||
|
|
||||||
s = &value->u.str[1];
|
s = &value->u.str[1];
|
||||||
@@ -1368,7 +1402,7 @@ nxt_conf_json_parse_number(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ch != '.') {
|
if (ch != '.') {
|
||||||
value->type = NXT_CONF_INTEGER;
|
value->type = NXT_CONF_VALUE_INTEGER;
|
||||||
value->u.integer = sign * integer;
|
value->u.integer = sign * integer;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -1403,7 +1437,7 @@ nxt_conf_json_parse_number(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
value->type = NXT_CONF_NUMBER;
|
value->type = NXT_CONF_VALUE_NUMBER;
|
||||||
value->u.number = integer + (double) frac / power;
|
value->u.number = integer + (double) frac / power;
|
||||||
|
|
||||||
value->u.number = copysign(value->u.number, sign);
|
value->u.number = copysign(value->u.number, sign);
|
||||||
@@ -1463,27 +1497,27 @@ nxt_conf_json_length(nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty)
|
|||||||
{
|
{
|
||||||
switch (value->type) {
|
switch (value->type) {
|
||||||
|
|
||||||
case NXT_CONF_NULL:
|
case NXT_CONF_VALUE_NULL:
|
||||||
return sizeof("null") - 1;
|
return sizeof("null") - 1;
|
||||||
|
|
||||||
case NXT_CONF_BOOLEAN:
|
case NXT_CONF_VALUE_BOOLEAN:
|
||||||
return value->u.boolean ? sizeof("true") - 1 : sizeof("false") - 1;
|
return value->u.boolean ? sizeof("true") - 1 : sizeof("false") - 1;
|
||||||
|
|
||||||
case NXT_CONF_INTEGER:
|
case NXT_CONF_VALUE_INTEGER:
|
||||||
return nxt_conf_json_integer_length(value);
|
return nxt_conf_json_integer_length(value);
|
||||||
|
|
||||||
case NXT_CONF_NUMBER:
|
case NXT_CONF_VALUE_NUMBER:
|
||||||
/* TODO */
|
/* TODO */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case NXT_CONF_SHORT_STRING:
|
case NXT_CONF_VALUE_SHORT_STRING:
|
||||||
case NXT_CONF_STRING:
|
case NXT_CONF_VALUE_STRING:
|
||||||
return nxt_conf_json_string_length(value);
|
return nxt_conf_json_string_length(value);
|
||||||
|
|
||||||
case NXT_CONF_ARRAY:
|
case NXT_CONF_VALUE_ARRAY:
|
||||||
return nxt_conf_json_array_length(value, pretty);
|
return nxt_conf_json_array_length(value, pretty);
|
||||||
|
|
||||||
case NXT_CONF_OBJECT:
|
case NXT_CONF_VALUE_OBJECT:
|
||||||
return nxt_conf_json_object_length(value, pretty);
|
return nxt_conf_json_object_length(value, pretty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1499,28 +1533,28 @@ nxt_conf_json_print(u_char *p, nxt_conf_value_t *value,
|
|||||||
{
|
{
|
||||||
switch (value->type) {
|
switch (value->type) {
|
||||||
|
|
||||||
case NXT_CONF_NULL:
|
case NXT_CONF_VALUE_NULL:
|
||||||
return nxt_cpymem(p, "null", 4);
|
return nxt_cpymem(p, "null", 4);
|
||||||
|
|
||||||
case NXT_CONF_BOOLEAN:
|
case NXT_CONF_VALUE_BOOLEAN:
|
||||||
return value->u.boolean ? nxt_cpymem(p, "true", 4)
|
return value->u.boolean ? nxt_cpymem(p, "true", 4)
|
||||||
: nxt_cpymem(p, "false", 5);
|
: nxt_cpymem(p, "false", 5);
|
||||||
|
|
||||||
case NXT_CONF_INTEGER:
|
case NXT_CONF_VALUE_INTEGER:
|
||||||
return nxt_conf_json_print_integer(p, value);
|
return nxt_conf_json_print_integer(p, value);
|
||||||
|
|
||||||
case NXT_CONF_NUMBER:
|
case NXT_CONF_VALUE_NUMBER:
|
||||||
/* TODO */
|
/* TODO */
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
case NXT_CONF_SHORT_STRING:
|
case NXT_CONF_VALUE_SHORT_STRING:
|
||||||
case NXT_CONF_STRING:
|
case NXT_CONF_VALUE_STRING:
|
||||||
return nxt_conf_json_print_string(p, value);
|
return nxt_conf_json_print_string(p, value);
|
||||||
|
|
||||||
case NXT_CONF_ARRAY:
|
case NXT_CONF_VALUE_ARRAY:
|
||||||
return nxt_conf_json_print_array(p, value, pretty);
|
return nxt_conf_json_print_array(p, value, pretty);
|
||||||
|
|
||||||
case NXT_CONF_OBJECT:
|
case NXT_CONF_VALUE_OBJECT:
|
||||||
return nxt_conf_json_print_object(p, value, pretty);
|
return nxt_conf_json_print_object(p, value, pretty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,15 @@
|
|||||||
#define _NXT_CONF_INCLUDED_
|
#define _NXT_CONF_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
|
#define NXT_CONF_NULL 0x01
|
||||||
|
#define NXT_CONF_BOOLEAN 0x02
|
||||||
|
#define NXT_CONF_INTEGER 0x04
|
||||||
|
#define NXT_CONF_NUMBER 0x08
|
||||||
|
#define NXT_CONF_STRING 0x10
|
||||||
|
#define NXT_CONF_ARRAY 0x20
|
||||||
|
#define NXT_CONF_OBJECT 0x40
|
||||||
|
|
||||||
|
|
||||||
typedef struct nxt_conf_value_s nxt_conf_value_t;
|
typedef struct nxt_conf_value_s nxt_conf_value_t;
|
||||||
typedef struct nxt_conf_op_s nxt_conf_op_t;
|
typedef struct nxt_conf_op_s nxt_conf_op_t;
|
||||||
|
|
||||||
@@ -40,6 +49,8 @@ typedef struct {
|
|||||||
} nxt_conf_json_pretty_t;
|
} nxt_conf_json_pretty_t;
|
||||||
|
|
||||||
|
|
||||||
|
nxt_uint_t nxt_conf_type(nxt_conf_value_t *value);
|
||||||
|
|
||||||
nxt_conf_value_t *nxt_conf_get_path(nxt_conf_value_t *value, nxt_str_t *path);
|
nxt_conf_value_t *nxt_conf_get_path(nxt_conf_value_t *value, nxt_str_t *path);
|
||||||
nxt_conf_value_t *nxt_conf_get_object_member(nxt_conf_value_t *value,
|
nxt_conf_value_t *nxt_conf_get_object_member(nxt_conf_value_t *value,
|
||||||
nxt_str_t *name, uint32_t *index);
|
nxt_str_t *name, uint32_t *index);
|
||||||
@@ -64,5 +75,7 @@ size_t nxt_conf_json_length(nxt_conf_value_t *value,
|
|||||||
u_char *nxt_conf_json_print(u_char *p, nxt_conf_value_t *value,
|
u_char *nxt_conf_json_print(u_char *p, nxt_conf_value_t *value,
|
||||||
nxt_conf_json_pretty_t *pretty);
|
nxt_conf_json_pretty_t *pretty);
|
||||||
|
|
||||||
|
nxt_int_t nxt_conf_validate(nxt_conf_value_t *value);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NXT_CONF_INCLUDED_ */
|
#endif /* _NXT_CONF_INCLUDED_ */
|
||||||
|
|||||||
173
src/nxt_conf_validation.c
Normal file
173
src/nxt_conf_validation.c
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Valentin V. Bartenev
|
||||||
|
* Copyright (C) NGINX, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nxt_main.h>
|
||||||
|
#include <nxt_conf.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
nxt_str_t name;
|
||||||
|
nxt_uint_t type;
|
||||||
|
nxt_int_t (*validator)(nxt_conf_value_t *value, void *data);
|
||||||
|
void *data;
|
||||||
|
} nxt_conf_vldt_object_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef nxt_int_t (*nxt_conf_vldt_member_t)(nxt_str_t *name,
|
||||||
|
nxt_conf_value_t *value);
|
||||||
|
|
||||||
|
static nxt_int_t nxt_conf_vldt_listener(nxt_str_t *name,
|
||||||
|
nxt_conf_value_t *value);
|
||||||
|
static nxt_int_t nxt_conf_vldt_app(nxt_str_t *name, nxt_conf_value_t *value);
|
||||||
|
static nxt_int_t nxt_conf_vldt_app_type(nxt_conf_value_t *value, void *data);
|
||||||
|
static nxt_int_t nxt_conf_vldt_object(nxt_conf_value_t *value, void *data);
|
||||||
|
static nxt_int_t nxt_conf_vldt_object_iterator(nxt_conf_value_t *value,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
|
||||||
|
static const nxt_conf_vldt_object_t nxt_conf_root_members[] = {
|
||||||
|
{ nxt_string("listeners"),
|
||||||
|
NXT_CONF_OBJECT,
|
||||||
|
&nxt_conf_vldt_object_iterator,
|
||||||
|
&nxt_conf_vldt_listener },
|
||||||
|
|
||||||
|
{ nxt_string("applications"),
|
||||||
|
NXT_CONF_OBJECT,
|
||||||
|
&nxt_conf_vldt_object_iterator,
|
||||||
|
&nxt_conf_vldt_app },
|
||||||
|
|
||||||
|
{ nxt_null_string, 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const nxt_conf_vldt_object_t nxt_conf_listener_members[] = {
|
||||||
|
{ nxt_string("application"),
|
||||||
|
NXT_CONF_STRING,
|
||||||
|
NULL,
|
||||||
|
NULL },
|
||||||
|
|
||||||
|
{ nxt_null_string, 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const nxt_conf_vldt_object_t nxt_conf_application_members[] = {
|
||||||
|
{ nxt_string("type"),
|
||||||
|
NXT_CONF_STRING,
|
||||||
|
&nxt_conf_vldt_app_type,
|
||||||
|
NULL },
|
||||||
|
|
||||||
|
{ nxt_string("path"),
|
||||||
|
NXT_CONF_STRING,
|
||||||
|
NULL,
|
||||||
|
NULL },
|
||||||
|
|
||||||
|
{ nxt_null_string, 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
nxt_int_t
|
||||||
|
nxt_conf_validate(nxt_conf_value_t *value)
|
||||||
|
{
|
||||||
|
if (nxt_conf_type(value) != NXT_CONF_OBJECT) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nxt_conf_vldt_object(value, (void *) nxt_conf_root_members);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_conf_vldt_listener(nxt_str_t *name, nxt_conf_value_t *value)
|
||||||
|
{
|
||||||
|
return nxt_conf_vldt_object(value, (void *) nxt_conf_listener_members);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_conf_vldt_app(nxt_str_t *name, nxt_conf_value_t *value)
|
||||||
|
{
|
||||||
|
return nxt_conf_vldt_object(value, (void *) nxt_conf_application_members);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_conf_vldt_app_type(nxt_conf_value_t *value, void *data)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_conf_vldt_object(nxt_conf_value_t *value, void *data)
|
||||||
|
{
|
||||||
|
uint32_t index;
|
||||||
|
nxt_str_t name;
|
||||||
|
nxt_conf_value_t *member;
|
||||||
|
nxt_conf_vldt_object_t *vldt;
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
member = nxt_conf_next_object_member(value, &name, &index);
|
||||||
|
|
||||||
|
if (member == NULL) {
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
vldt = data;
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
if (vldt->name.length == 0) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nxt_strstr_eq(&vldt->name, &name)) {
|
||||||
|
vldt++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nxt_conf_type(member) != vldt->type) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vldt->validator != NULL
|
||||||
|
&& vldt->validator(member, vldt->data) != NXT_OK)
|
||||||
|
{
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_conf_vldt_object_iterator(nxt_conf_value_t *value, void *data)
|
||||||
|
{
|
||||||
|
uint32_t index;
|
||||||
|
nxt_str_t name;
|
||||||
|
nxt_conf_value_t *member;
|
||||||
|
nxt_conf_vldt_member_t validator;
|
||||||
|
|
||||||
|
validator = data;
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
member = nxt_conf_next_object_member(value, &name, &index);
|
||||||
|
|
||||||
|
if (member == NULL) {
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validator(&name, member) != NXT_OK) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
@@ -88,7 +88,7 @@ nxt_controller_start(nxt_task_t *task, nxt_runtime_t *rt)
|
|||||||
nxt_http_fields_hash_t *hash;
|
nxt_http_fields_hash_t *hash;
|
||||||
|
|
||||||
static const nxt_str_t json
|
static const nxt_str_t json
|
||||||
= nxt_string("{ \"sockets\": {}, \"applications\": {} }");
|
= nxt_string("{ \"listeners\": {}, \"applications\": {} }");
|
||||||
|
|
||||||
hash = nxt_http_fields_hash_create(nxt_controller_request_fields,
|
hash = nxt_http_fields_hash_create(nxt_controller_request_fields,
|
||||||
rt->mem_pool);
|
rt->mem_pool);
|
||||||
@@ -593,6 +593,7 @@ nxt_controller_process_request(nxt_task_t *task, nxt_conn_t *c,
|
|||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
nxt_mp_destroy(mp);
|
nxt_mp_destroy(mp);
|
||||||
status = 400;
|
status = 400;
|
||||||
|
nxt_str_set(&resp.json, "{ \"error\": \"Invalid JSON.\" }");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,6 +621,13 @@ nxt_controller_process_request(nxt_task_t *task, nxt_conn_t *c,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nxt_slow_path(nxt_conf_validate(value) != NXT_OK)) {
|
||||||
|
status = 400;
|
||||||
|
nxt_str_set(&resp.json,
|
||||||
|
"{ \"error\": \"Invalid configuration.\" }");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
nxt_mp_destroy(nxt_controller_conf.pool);
|
nxt_mp_destroy(nxt_controller_conf.pool);
|
||||||
|
|
||||||
nxt_controller_conf.root = value;
|
nxt_controller_conf.root = value;
|
||||||
@@ -674,6 +682,13 @@ nxt_controller_process_request(nxt_task_t *task, nxt_conn_t *c,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nxt_slow_path(nxt_conf_validate(value) != NXT_OK)) {
|
||||||
|
status = 400;
|
||||||
|
nxt_str_set(&resp.json,
|
||||||
|
"{ \"error\": \"Invalid configuration.\" }");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
nxt_mp_destroy(nxt_controller_conf.pool);
|
nxt_mp_destroy(nxt_controller_conf.pool);
|
||||||
|
|
||||||
nxt_controller_conf.root = value;
|
nxt_controller_conf.root = value;
|
||||||
@@ -697,7 +712,6 @@ done:
|
|||||||
|
|
||||||
case 400:
|
case 400:
|
||||||
nxt_str_set(&resp.status_line, "400 Bad Request");
|
nxt_str_set(&resp.status_line, "400 Bad Request");
|
||||||
nxt_str_set(&resp.json, "{ \"error\": \"Invalid JSON.\" }");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 404:
|
case 404:
|
||||||
|
|||||||
Reference in New Issue
Block a user