summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_controller.c
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2017-05-30 17:12:20 +0300
committerValentin Bartenev <vbart@nginx.com>2017-05-30 17:12:20 +0300
commitc0bf729c8e7a79d9d7929cb715e3f7237218fcd9 (patch)
tree4c77611846553c3155f723cb97c94e639aa8cc8f /src/nxt_controller.c
parentf5c3b1c637b4c7c98a9efbc1b99f825dbbe37a51 (diff)
downloadunit-c0bf729c8e7a79d9d7929cb715e3f7237218fcd9.tar.gz
unit-c0bf729c8e7a79d9d7929cb715e3f7237218fcd9.tar.bz2
Controller: support for partial PUT and DELETE operations.
Diffstat (limited to '')
-rw-r--r--src/nxt_controller.c203
1 files changed, 152 insertions, 51 deletions
diff --git a/src/nxt_controller.c b/src/nxt_controller.c
index 15c7b0cd..299242d7 100644
--- a/src/nxt_controller.c
+++ b/src/nxt_controller.c
@@ -55,8 +55,6 @@ static nxt_int_t nxt_controller_request_content_length(void *ctx,
static void nxt_controller_process_request(nxt_task_t *task,
nxt_event_conn_t *c, nxt_controller_request_t *r);
-static nxt_int_t nxt_controller_request_body_parse(nxt_task_t *task,
- nxt_event_conn_t *c, nxt_controller_request_t *r);
static nxt_int_t nxt_controller_response(nxt_task_t *task, nxt_event_conn_t *c,
nxt_controller_response_t *resp);
static nxt_buf_t *nxt_controller_response_body(nxt_controller_response_t *resp,
@@ -554,89 +552,192 @@ static void
nxt_controller_process_request(nxt_task_t *task, nxt_event_conn_t *c,
nxt_controller_request_t *req)
{
+ nxt_int_t rc;
nxt_str_t path;
+ nxt_uint_t status;
+ nxt_buf_mem_t *mbuf;
+ nxt_mem_pool_t *mp;
+ nxt_conf_json_op_t *ops;
nxt_conf_json_value_t *value;
nxt_controller_response_t resp;
+ static const nxt_str_t empty_obj = nxt_string("{}");
+
+ path.start = req->parser.target_start;
+
+ if (req->parser.args_start != NULL) {
+ path.length = req->parser.args_start - path.start;
+
+ } else {
+ path.length = req->parser.target_end - path.start;
+ }
+
+ if (path.length > 1 && path.start[path.length - 1] == '/') {
+ path.length--;
+ }
+
nxt_memzero(&resp, sizeof(nxt_controller_response_t));
if (nxt_str_eq(&req->parser.method, "GET", 3)) {
- path.start = req->parser.target_start;
+ value = nxt_conf_json_get_value(nxt_controller_conf.root, &path);
- if (req->parser.args_start != NULL) {
- path.length = req->parser.args_start - path.start;
+ if (value == NULL) {
+ status = 404;
+ goto done;
+ }
- } else {
- path.length = req->parser.target_end - path.start;
+ resp.json_value = value;
+
+ status = 200;
+ goto done;
+ }
+
+ if (nxt_str_eq(&req->parser.method, "PUT", 3)) {
+
+ mp = nxt_mem_pool_create(512);
+
+ if (nxt_slow_path(mp == NULL)) {
+ status = 500;
+ goto done;
}
- value = nxt_conf_json_get_value(nxt_controller_conf.root, &path);
+ mbuf = &c->read->mem;
- if (value != NULL) {
- nxt_str_set(&resp.status_line, "200 OK");
- resp.json_value = value;
+ value = nxt_conf_json_parse(mbuf->pos, mbuf->free - mbuf->pos, mp);
- } else {
- nxt_str_set(&resp.status_line, "404 Not Found");
- nxt_str_set(&resp.json_string,
- "{ \"error\": \"Requested value doesn't exist\" }");
+ if (value == NULL) {
+ nxt_mem_pool_destroy(mp);
+ status = 400;
+ goto done;
}
- } else if (nxt_str_eq(&req->parser.method, "PUT", 3)) {
+ if (path.length != 1) {
+ rc = nxt_conf_json_op_compile(nxt_controller_conf.root, value,
+ &ops, &path, c->mem_pool);
- if (nxt_controller_request_body_parse(task, c, req) == NXT_OK) {
+ if (rc != NXT_OK) {
+ if (rc == NXT_DECLINED) {
+ status = 404;
+ goto done;
+ }
- nxt_mem_pool_destroy(nxt_controller_conf.pool);
- nxt_controller_conf = req->conf;
+ status = 500;
+ goto done;
+ }
- nxt_str_set(&resp.status_line, "201 Created");
- nxt_str_set(&resp.json_string,
- "{ \"success\": \"Configuration updated\" }");
+ value = nxt_conf_json_clone_value(nxt_controller_conf.root,
+ ops, mp);
- } else {
- nxt_str_set(&resp.status_line, "400 Bad Request");
- nxt_str_set(&resp.json_string,
- "{ \"error\": \"Invalid JSON\" }");
+ if (nxt_slow_path(value == NULL)) {
+ nxt_mem_pool_destroy(mp);
+ status = 500;
+ goto done;
+ }
}
- } else {
- nxt_str_set(&resp.status_line, "405 Method Not Allowed");
- nxt_str_set(&resp.json_string, "{ \"error\": \"Invalid method\" }");
- }
+ nxt_mem_pool_destroy(nxt_controller_conf.pool);
- if (nxt_controller_response(task, c, &resp) != NXT_OK) {
- nxt_controller_conn_close(task, c, req);
+ nxt_controller_conf.root = value;
+ nxt_controller_conf.pool = mp;
+
+ nxt_str_set(&resp.json_string, "{ \"success\": \"Updated.\" }");
+
+ status = 200;
+ goto done;
}
-}
+ if (nxt_str_eq(&req->parser.method, "DELETE", 6)) {
-static nxt_int_t
-nxt_controller_request_body_parse(nxt_task_t *task, nxt_event_conn_t *c,
- nxt_controller_request_t *r)
-{
- nxt_buf_mem_t *mbuf;
- nxt_mem_pool_t *mp;
- nxt_conf_json_value_t *value;
+ if (path.length == 1) {
+ mp = nxt_mem_pool_create(128);
- mp = nxt_mem_pool_create(512);
+ if (nxt_slow_path(mp == NULL)) {
+ status = 500;
+ goto done;
+ }
- if (nxt_slow_path(mp == NULL)) {
- return NXT_ERROR;
- }
+ value = nxt_conf_json_parse(empty_obj.start, empty_obj.length, mp);
- mbuf = &c->read->mem;
+ } else {
+ rc = nxt_conf_json_op_compile(nxt_controller_conf.root, NULL, &ops,
+ &path, c->mem_pool);
- value = nxt_conf_json_parse(mbuf->pos, mbuf->free - mbuf->pos, mp);
+ if (rc != NXT_OK) {
+ if (rc == NXT_DECLINED) {
+ status = 404;
+ goto done;
+ }
- if (value == NULL) {
- return NXT_ERROR;
+ status = 500;
+ goto done;
+ }
+
+ mp = nxt_mem_pool_create(512);
+
+ if (nxt_slow_path(mp == NULL)) {
+ status = 500;
+ goto done;
+ }
+
+ value = nxt_conf_json_clone_value(nxt_controller_conf.root,
+ ops, mp);
+ }
+
+ if (nxt_slow_path(value == NULL)) {
+ nxt_mem_pool_destroy(mp);
+ status = 500;
+ goto done;
+ }
+
+ nxt_mem_pool_destroy(nxt_controller_conf.pool);
+
+ nxt_controller_conf.root = value;
+ nxt_controller_conf.pool = mp;
+
+ nxt_str_set(&resp.json_string, "{ \"success\": \"Deleted.\" }");
+
+ status = 200;
+ goto done;
}
- r->conf.root = value;
- r->conf.pool = mp;
+ status = 405;
- return NXT_OK;
+done:
+
+ switch (status) {
+
+ case 200:
+ nxt_str_set(&resp.status_line, "200 OK");
+ break;
+
+ case 400:
+ nxt_str_set(&resp.status_line, "400 Bad Request");
+ nxt_str_set(&resp.json_string,
+ "{ \"error\": \"Invalid JSON.\" }");
+ break;
+
+ case 404:
+ nxt_str_set(&resp.status_line, "404 Not Found");
+ nxt_str_set(&resp.json_string,
+ "{ \"error\": \"Value doesn't exist.\" }");
+ break;
+
+ case 405:
+ nxt_str_set(&resp.status_line, "405 Method Not Allowed");
+ nxt_str_set(&resp.json_string, "{ \"error\": \"Invalid method.\" }");
+ break;
+
+ case 500:
+ nxt_str_set(&resp.status_line, "500 Internal Server Error");
+ nxt_str_set(&resp.json_string,
+ "{ \"error\": \"Memory allocation failed.\" }");
+ break;
+ }
+
+ if (nxt_controller_response(task, c, &resp) != NXT_OK) {
+ nxt_controller_conn_close(task, c, req);
+ }
}