summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2019-04-24 20:31:00 +0300
committerValentin Bartenev <vbart@nginx.com>2019-04-24 20:31:00 +0300
commit6a6bc63c48501027f01d16fbd211eb4425c1a1e8 (patch)
treed718054805235dad13d0d06cf33e291cc385ce1b
parent4d35a7bbacb1013388491140964dab8ffab1d0ae (diff)
downloadunit-6a6bc63c48501027f01d16fbd211eb4425c1a1e8.tar.gz
unit-6a6bc63c48501027f01d16fbd211eb4425c1a1e8.tar.bz2
Configuration: support for POST operations on arrays.
It allows to add an array element without specifying the index.
-rw-r--r--src/nxt_conf.c47
-rw-r--r--src/nxt_conf.h13
-rw-r--r--src/nxt_controller.c34
3 files changed, 74 insertions, 20 deletions
diff --git a/src/nxt_conf.c b/src/nxt_conf.c
index fd6a62f5..57870838 100644
--- a/src/nxt_conf.c
+++ b/src/nxt_conf.c
@@ -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_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_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 ( ;; ) {
op = nxt_mp_zget(mp, sizeof(nxt_conf_op_t));
if (nxt_slow_path(op == NULL)) {
- return NXT_ERROR;
+ return NXT_CONF_OP_ERROR;
}
*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);
if (index < 0 || index > NXT_INT32_T_MAX) {
- return NXT_DECLINED;
+ return NXT_CONF_OP_NOT_FOUND;
}
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) {
- return NXT_DECLINED;
+ return NXT_CONF_OP_NOT_FOUND;
}
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 (node == NULL) {
- return NXT_DECLINED;
+ return NXT_CONF_OP_NOT_FOUND;
}
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) {
op->action = NXT_CONF_OP_REPLACE;
op->ctx = value;
- return NXT_OK;
+ return NXT_CONF_OP_OK;
}
op->action = NXT_CONF_OP_CREATE;
if (root->type == NXT_CONF_VALUE_ARRAY) {
if (op->index > root->u.array->count) {
- return NXT_DECLINED;
+ return NXT_CONF_OP_NOT_FOUND;
}
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 {
member = nxt_mp_zget(mp, sizeof(nxt_conf_object_member_t));
if (nxt_slow_path(member == NULL)) {
- return NXT_ERROR;
+ return NXT_CONF_OP_ERROR;
}
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;
}
- return NXT_OK;
+ return NXT_CONF_OP_OK;
}
diff --git a/src/nxt_conf.h b/src/nxt_conf.h
index 20ff3b1e..2435b0e2 100644
--- a/src/nxt_conf.h
+++ b/src/nxt_conf.h
@@ -20,6 +20,14 @@ typedef enum {
} 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_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_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_value_t *root, nxt_str_t *path, nxt_conf_value_t *value);
+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_bool_t add);
nxt_conf_value_t *nxt_conf_clone(nxt_mp_t *mp, nxt_conf_op_t *op,
nxt_conf_value_t *value);
diff --git a/src/nxt_controller.c b/src/nxt_controller.c
index d5534f49..49afbe46 100644
--- a/src/nxt_controller.c
+++ b/src/nxt_controller.c
@@ -930,6 +930,7 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
nxt_mp_t *mp;
nxt_int_t rc;
nxt_conn_t *c;
+ nxt_bool_t post;
nxt_buf_mem_t *mbuf;
nxt_conf_op_t *ops;
nxt_conf_value_t *value;
@@ -958,7 +959,18 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
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)) {
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) {
rc = nxt_conf_op_compile(c->mem_pool, &ops,
nxt_controller_conf.root,
- path, value);
+ path, value, post);
- if (rc != NXT_OK) {
+ if (rc != NXT_CONF_OP_OK) {
nxt_mp_destroy(mp);
- if (rc == NXT_DECLINED) {
+ switch (rc) {
+ case NXT_CONF_OP_NOT_FOUND:
goto not_found;
+
+ case NXT_CONF_OP_NOT_ALLOWED:
+ goto not_allowed;
}
+ /* rc == NXT_CONF_OP_ERROR */
goto alloc_fail;
}
@@ -1080,13 +1097,14 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
} else {
rc = nxt_conf_op_compile(c->mem_pool, &ops,
nxt_controller_conf.root,
- path, NULL);
+ path, NULL, 0);
if (rc != NXT_OK) {
- if (rc == NXT_DECLINED) {
+ if (rc == NXT_CONF_OP_NOT_FOUND) {
goto not_found;
}
+ /* rc == NXT_CONF_OP_ERROR */
goto alloc_fail;
}
@@ -1145,8 +1163,10 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
return;
}
+not_allowed:
+
resp.status = 405;
- resp.title = (u_char *) "Invalid method.";
+ resp.title = (u_char *) "Method isn't allowed.";
resp.offset = -1;
nxt_controller_response(task, req, &resp);