diff options
author | Valentin Bartenev <vbart@nginx.com> | 2019-04-24 20:31:00 +0300 |
---|---|---|
committer | Valentin Bartenev <vbart@nginx.com> | 2019-04-24 20:31:00 +0300 |
commit | 6a6bc63c48501027f01d16fbd211eb4425c1a1e8 (patch) | |
tree | d718054805235dad13d0d06cf33e291cc385ce1b | |
parent | 4d35a7bbacb1013388491140964dab8ffab1d0ae (diff) | |
download | unit-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.c | 47 | ||||
-rw-r--r-- | src/nxt_conf.h | 13 | ||||
-rw-r--r-- | src/nxt_controller.c | 34 |
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); |