Configuration: support for POST operations on arrays.
It allows to add an array element without specifying the index.
This commit is contained in:
@@ -737,9 +737,9 @@ nxt_conf_array_qsort(nxt_conf_value_t *value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nxt_int_t
|
nxt_conf_op_ret_t
|
||||||
nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
|
nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
|
||||||
nxt_str_t *path, nxt_conf_value_t *value)
|
nxt_str_t *path, nxt_conf_value_t *value, nxt_bool_t add)
|
||||||
{
|
{
|
||||||
nxt_str_t token;
|
nxt_str_t token;
|
||||||
nxt_int_t index;
|
nxt_int_t index;
|
||||||
@@ -757,7 +757,7 @@ nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
|
|||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
op = nxt_mp_zget(mp, sizeof(nxt_conf_op_t));
|
op = nxt_mp_zget(mp, sizeof(nxt_conf_op_t));
|
||||||
if (nxt_slow_path(op == NULL)) {
|
if (nxt_slow_path(op == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_CONF_OP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*parent = op;
|
*parent = op;
|
||||||
@@ -775,7 +775,7 @@ nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
|
|||||||
index = nxt_int_parse(token.start, token.length);
|
index = nxt_int_parse(token.start, token.length);
|
||||||
|
|
||||||
if (index < 0 || index > NXT_INT32_T_MAX) {
|
if (index < 0 || index > NXT_INT32_T_MAX) {
|
||||||
return NXT_DECLINED;
|
return NXT_CONF_OP_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
op->index = index;
|
op->index = index;
|
||||||
@@ -792,7 +792,7 @@ nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
return NXT_DECLINED;
|
return NXT_CONF_OP_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
op->action = NXT_CONF_OP_PASS;
|
op->action = NXT_CONF_OP_PASS;
|
||||||
@@ -802,26 +802,51 @@ nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
|
|||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
|
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
return NXT_DECLINED;
|
return NXT_CONF_OP_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
op->action = NXT_CONF_OP_DELETE;
|
op->action = NXT_CONF_OP_DELETE;
|
||||||
|
|
||||||
return NXT_OK;
|
return NXT_CONF_OP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add) {
|
||||||
|
if (node == NULL) {
|
||||||
|
return NXT_CONF_OP_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->type != NXT_CONF_VALUE_ARRAY) {
|
||||||
|
return NXT_CONF_OP_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
op->action = NXT_CONF_OP_PASS;
|
||||||
|
|
||||||
|
op = nxt_mp_zget(mp, sizeof(nxt_conf_op_t));
|
||||||
|
if (nxt_slow_path(op == NULL)) {
|
||||||
|
return NXT_CONF_OP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*parent = op;
|
||||||
|
|
||||||
|
op->index = node->u.array->count;
|
||||||
|
op->action = NXT_CONF_OP_CREATE;
|
||||||
|
op->ctx = value;
|
||||||
|
|
||||||
|
return NXT_CONF_OP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
op->action = NXT_CONF_OP_REPLACE;
|
op->action = NXT_CONF_OP_REPLACE;
|
||||||
op->ctx = value;
|
op->ctx = value;
|
||||||
|
|
||||||
return NXT_OK;
|
return NXT_CONF_OP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
op->action = NXT_CONF_OP_CREATE;
|
op->action = NXT_CONF_OP_CREATE;
|
||||||
|
|
||||||
if (root->type == NXT_CONF_VALUE_ARRAY) {
|
if (root->type == NXT_CONF_VALUE_ARRAY) {
|
||||||
if (op->index > root->u.array->count) {
|
if (op->index > root->u.array->count) {
|
||||||
return NXT_DECLINED;
|
return NXT_CONF_OP_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
op->ctx = value;
|
op->ctx = value;
|
||||||
@@ -829,7 +854,7 @@ nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
|
|||||||
} else {
|
} else {
|
||||||
member = nxt_mp_zget(mp, sizeof(nxt_conf_object_member_t));
|
member = nxt_mp_zget(mp, sizeof(nxt_conf_object_member_t));
|
||||||
if (nxt_slow_path(member == NULL)) {
|
if (nxt_slow_path(member == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_CONF_OP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_conf_set_string(&member->name, &token);
|
nxt_conf_set_string(&member->name, &token);
|
||||||
@@ -840,7 +865,7 @@ nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
|
|||||||
op->ctx = member;
|
op->ctx = member;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NXT_OK;
|
return NXT_CONF_OP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ typedef enum {
|
|||||||
} nxt_conf_type_t;
|
} nxt_conf_type_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NXT_CONF_OP_OK = 0,
|
||||||
|
NXT_CONF_OP_NOT_FOUND,
|
||||||
|
NXT_CONF_OP_NOT_ALLOWED,
|
||||||
|
NXT_CONF_OP_ERROR,
|
||||||
|
} nxt_conf_op_ret_t;
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -80,8 +88,9 @@ NXT_EXPORT nxt_conf_value_t *nxt_conf_get_array_element(nxt_conf_value_t *value,
|
|||||||
NXT_EXPORT nxt_int_t nxt_conf_map_object(nxt_mp_t *mp, nxt_conf_value_t *value,
|
NXT_EXPORT nxt_int_t nxt_conf_map_object(nxt_mp_t *mp, nxt_conf_value_t *value,
|
||||||
nxt_conf_map_t *map, nxt_uint_t n, void *data);
|
nxt_conf_map_t *map, nxt_uint_t n, void *data);
|
||||||
|
|
||||||
nxt_int_t nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops,
|
nxt_conf_op_ret_t nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops,
|
||||||
nxt_conf_value_t *root, nxt_str_t *path, nxt_conf_value_t *value);
|
nxt_conf_value_t *root, nxt_str_t *path, nxt_conf_value_t *value,
|
||||||
|
nxt_bool_t add);
|
||||||
nxt_conf_value_t *nxt_conf_clone(nxt_mp_t *mp, nxt_conf_op_t *op,
|
nxt_conf_value_t *nxt_conf_clone(nxt_mp_t *mp, nxt_conf_op_t *op,
|
||||||
nxt_conf_value_t *value);
|
nxt_conf_value_t *value);
|
||||||
|
|
||||||
|
|||||||
@@ -930,6 +930,7 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
|
|||||||
nxt_mp_t *mp;
|
nxt_mp_t *mp;
|
||||||
nxt_int_t rc;
|
nxt_int_t rc;
|
||||||
nxt_conn_t *c;
|
nxt_conn_t *c;
|
||||||
|
nxt_bool_t post;
|
||||||
nxt_buf_mem_t *mbuf;
|
nxt_buf_mem_t *mbuf;
|
||||||
nxt_conf_op_t *ops;
|
nxt_conf_op_t *ops;
|
||||||
nxt_conf_value_t *value;
|
nxt_conf_value_t *value;
|
||||||
@@ -958,7 +959,18 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nxt_str_eq(&req->parser.method, "PUT", 3)) {
|
if (nxt_str_eq(&req->parser.method, "POST", 4)) {
|
||||||
|
if (path->length == 1) {
|
||||||
|
goto not_allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
post = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
post = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (post || nxt_str_eq(&req->parser.method, "PUT", 3)) {
|
||||||
|
|
||||||
if (!nxt_queue_is_empty(&nxt_controller_waiting_requests)) {
|
if (!nxt_queue_is_empty(&nxt_controller_waiting_requests)) {
|
||||||
nxt_queue_insert_tail(&nxt_controller_waiting_requests, &req->link);
|
nxt_queue_insert_tail(&nxt_controller_waiting_requests, &req->link);
|
||||||
@@ -1000,15 +1012,20 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
|
|||||||
if (path->length != 1) {
|
if (path->length != 1) {
|
||||||
rc = nxt_conf_op_compile(c->mem_pool, &ops,
|
rc = nxt_conf_op_compile(c->mem_pool, &ops,
|
||||||
nxt_controller_conf.root,
|
nxt_controller_conf.root,
|
||||||
path, value);
|
path, value, post);
|
||||||
|
|
||||||
if (rc != NXT_OK) {
|
if (rc != NXT_CONF_OP_OK) {
|
||||||
nxt_mp_destroy(mp);
|
nxt_mp_destroy(mp);
|
||||||
|
|
||||||
if (rc == NXT_DECLINED) {
|
switch (rc) {
|
||||||
|
case NXT_CONF_OP_NOT_FOUND:
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
case NXT_CONF_OP_NOT_ALLOWED:
|
||||||
|
goto not_allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rc == NXT_CONF_OP_ERROR */
|
||||||
goto alloc_fail;
|
goto alloc_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1080,13 +1097,14 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
|
|||||||
} else {
|
} else {
|
||||||
rc = nxt_conf_op_compile(c->mem_pool, &ops,
|
rc = nxt_conf_op_compile(c->mem_pool, &ops,
|
||||||
nxt_controller_conf.root,
|
nxt_controller_conf.root,
|
||||||
path, NULL);
|
path, NULL, 0);
|
||||||
|
|
||||||
if (rc != NXT_OK) {
|
if (rc != NXT_OK) {
|
||||||
if (rc == NXT_DECLINED) {
|
if (rc == NXT_CONF_OP_NOT_FOUND) {
|
||||||
goto not_found;
|
goto not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rc == NXT_CONF_OP_ERROR */
|
||||||
goto alloc_fail;
|
goto alloc_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1145,8 +1163,10 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
not_allowed:
|
||||||
|
|
||||||
resp.status = 405;
|
resp.status = 405;
|
||||||
resp.title = (u_char *) "Invalid method.";
|
resp.title = (u_char *) "Method isn't allowed.";
|
||||||
resp.offset = -1;
|
resp.offset = -1;
|
||||||
|
|
||||||
nxt_controller_response(task, req, &resp);
|
nxt_controller_response(task, req, &resp);
|
||||||
|
|||||||
Reference in New Issue
Block a user