summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2017-05-15 22:39:53 +0300
committerValentin Bartenev <vbart@nginx.com>2017-05-15 22:39:53 +0300
commit0ca2c2fce2c21a397fc10d19bca6628df7bc62ab (patch)
tree8c30ef891363b35867cf2e3cc6cdc16d4ba039e3
parent952ec2e0ffa37a139844d4883c254e375e7618e2 (diff)
downloadunit-0ca2c2fce2c21a397fc10d19bca6628df7bc62ab.tar.gz
unit-0ca2c2fce2c21a397fc10d19bca6628df7bc62ab.tar.bz2
Controller: trivial abilities to save and request configuration.
Now you can get current configuration with: $ curl 127.0.0.1:8443 and put new configuration with: $ curl -X PUT -d @conf.json 127.0.0.1:8443
Diffstat (limited to '')
-rw-r--r--src/nxt_conf.h2
-rw-r--r--src/nxt_conf_json.c7
-rw-r--r--src/nxt_controller.c148
3 files changed, 109 insertions, 48 deletions
diff --git a/src/nxt_conf.h b/src/nxt_conf.h
index 1d08199c..5dd16177 100644
--- a/src/nxt_conf.h
+++ b/src/nxt_conf.h
@@ -12,7 +12,7 @@
typedef struct nxt_conf_json_value_s nxt_conf_json_value_t;
-nxt_conf_json_value_t *nxt_conf_json_parse(nxt_buf_mem_t *b,
+nxt_conf_json_value_t *nxt_conf_json_parse(u_char *pos, size_t length,
nxt_mem_pool_t *pool);
nxt_buf_t *nxt_conf_json_print(nxt_conf_json_value_t *value,
nxt_mem_pool_t *pool);
diff --git a/src/nxt_conf_json.c b/src/nxt_conf_json.c
index 5808e5a6..b2b830e0 100644
--- a/src/nxt_conf_json.c
+++ b/src/nxt_conf_json.c
@@ -169,9 +169,9 @@ nxt_conf_json_object_member_get(nxt_lvlhsh_t *lvlhsh, u_char *name,
nxt_conf_json_value_t *
-nxt_conf_json_parse(nxt_buf_mem_t *b, nxt_mem_pool_t *pool)
+nxt_conf_json_parse(u_char *pos, size_t length, nxt_mem_pool_t *pool)
{
- u_char *pos, *end;
+ u_char *end;
nxt_conf_json_value_t *value;
value = nxt_mem_alloc(pool, sizeof(nxt_conf_json_value_t));
@@ -179,8 +179,7 @@ nxt_conf_json_parse(nxt_buf_mem_t *b, nxt_mem_pool_t *pool)
return NULL;
}
- pos = b->pos;
- end = b->free;
+ end = pos + length;
pos = nxt_conf_json_skip_space(pos, end);
diff --git a/src/nxt_controller.c b/src/nxt_controller.c
index 901a8875..34be36fc 100644
--- a/src/nxt_controller.c
+++ b/src/nxt_controller.c
@@ -12,13 +12,26 @@
typedef struct {
+ nxt_conf_json_value_t *root;
+ nxt_mem_pool_t *pool;
+} nxt_controller_conf_t;
+
+
+typedef struct {
nxt_http_request_parse_t parser;
size_t length;
- nxt_conf_json_value_t *conf;
+ nxt_controller_conf_t conf;
} nxt_controller_request_t;
+typedef struct {
+ nxt_str_t status_line;
+ nxt_conf_json_value_t *json_value;
+ nxt_str_t json_string;
+} nxt_controller_response_t;
+
+
static void nxt_controller_conn_init(nxt_task_t *task, void *obj, void *data);
static void nxt_controller_conn_read(nxt_task_t *task, void *obj, void *data);
static nxt_msec_t nxt_controller_conn_timeout_value(nxt_event_conn_t *c,
@@ -44,8 +57,8 @@ 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 void nxt_controller_conf_output(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_http_fields_t nxt_controller_request_fields[] = {
@@ -55,10 +68,12 @@ static nxt_http_fields_t nxt_controller_request_fields[] = {
{ nxt_null_string, NULL, 0 }
};
-
static nxt_http_fields_hash_t *nxt_controller_request_fields_hash;
+static nxt_controller_conf_t nxt_controller_conf;
+
+
static const nxt_event_conn_state_t nxt_controller_conn_read_state;
static const nxt_event_conn_state_t nxt_controller_conn_body_read_state;
static const nxt_event_conn_state_t nxt_controller_conn_write_state;
@@ -68,8 +83,13 @@ static const nxt_event_conn_state_t nxt_controller_conn_close_state;
nxt_int_t
nxt_controller_start(nxt_task_t *task, nxt_runtime_t *rt)
{
+ nxt_mem_pool_t *mp;
+ nxt_conf_json_value_t *conf;
nxt_http_fields_hash_t *hash;
+ static const nxt_str_t json
+ = nxt_string("{ \"sockets\": {}, \"applications\": {} }");
+
hash = nxt_http_fields_hash(nxt_controller_request_fields, rt->mem_pool);
if (nxt_slow_path(hash == NULL)) {
@@ -82,6 +102,21 @@ nxt_controller_start(nxt_task_t *task, nxt_runtime_t *rt)
return NXT_ERROR;
}
+ mp = nxt_mem_pool_create(256);
+
+ if (nxt_slow_path(mp == NULL)) {
+ return NXT_ERROR;
+ }
+
+ conf = nxt_conf_json_parse(json.start, json.length, mp);
+
+ if (conf == NULL) {
+ return NXT_ERROR;
+ }
+
+ nxt_controller_conf.root = conf;
+ nxt_controller_conf.pool = mp;
+
return NXT_OK;
}
@@ -515,35 +550,41 @@ nxt_controller_request_content_length(void *ctx, nxt_str_t *name,
static void
nxt_controller_process_request(nxt_task_t *task, nxt_event_conn_t *c,
- nxt_controller_request_t *r)
+ nxt_controller_request_t *req)
{
- nxt_buf_t *b;
+ nxt_controller_response_t resp;
- static const nxt_str_t resp418
- = nxt_string("HTTP/1.0 418 I'm a teapot\r\n\r\nerror\r\n");
+ nxt_memzero(&resp, sizeof(nxt_controller_response_t));
- if (nxt_controller_request_body_parse(task, c, r) != NXT_OK) {
- goto error;
- }
+ if (nxt_str_eq(&req->parser.method, "GET", 3)) {
+ nxt_str_set(&resp.status_line, "200 OK");
+ resp.json_value = nxt_controller_conf.root;
- nxt_controller_conf_output(task, c, r);
+ } else if (nxt_str_eq(&req->parser.method, "PUT", 3)) {
- return;
+ if (nxt_controller_request_body_parse(task, c, req) == NXT_OK) {
-error:
+ nxt_mem_pool_destroy(nxt_controller_conf.pool);
+ nxt_controller_conf = req->conf;
- b = nxt_buf_mem_alloc(c->mem_pool, resp418.length, 0);
- if (nxt_slow_path(b == NULL)) {
- nxt_controller_conn_close(task, c, r);
- return;
- }
+ nxt_str_set(&resp.status_line, "201 Created");
+ nxt_str_set(&resp.json_string,
+ "{ \"success\": \"Configuration updated\" }");
- b->mem.free = nxt_cpymem(b->mem.free, resp418.start, resp418.length);
+ } else {
+ nxt_str_set(&resp.status_line, "400 Bad Request");
+ nxt_str_set(&resp.json_string,
+ "{ \"error\": \"Invalid JSON\" }");
+ }
- c->write = b;
- c->write_state = &nxt_controller_conn_write_state;
+ } else {
+ nxt_str_set(&resp.status_line, "405 Method Not Allowed");
+ nxt_str_set(&resp.json_string, "{ \"error\": \"Invalid method\" }");
+ }
- nxt_event_conn_write(task->thread->engine, c);
+ if (nxt_controller_response(task, c, &resp) != NXT_OK) {
+ nxt_controller_conn_close(task, c, req);
+ }
}
@@ -551,51 +592,72 @@ 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_t *b;
+ nxt_buf_mem_t *mbuf;
+ nxt_mem_pool_t *mp;
nxt_conf_json_value_t *value;
- b = c->read;
+ mp = nxt_mem_pool_create(512);
+
+ if (nxt_slow_path(mp == NULL)) {
+ return NXT_ERROR;
+ }
+
+ mbuf = &c->read->mem;
- value = nxt_conf_json_parse(&b->mem, c->mem_pool);
+ value = nxt_conf_json_parse(mbuf->pos, mbuf->free - mbuf->pos, mp);
if (value == NULL) {
return NXT_ERROR;
}
- r->conf = value;
+ r->conf.root = value;
+ r->conf.pool = mp;
return NXT_OK;
}
-static void
-nxt_controller_conf_output(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)
{
+ size_t size;
nxt_buf_t *b;
- static const nxt_str_t head = nxt_string("HTTP/1.0 200 OK\r\n\r\n");
+ size = sizeof("HTTP/1.0 " "\r\n\r\n") - 1
+ + resp->status_line.length
+ + resp->json_string.length;
- b = nxt_buf_mem_alloc(c->mem_pool, head.length, 0);
+ b = nxt_buf_mem_alloc(c->mem_pool, size, 0);
if (nxt_slow_path(b == NULL)) {
- nxt_controller_conn_close(task, c, r);
- return;
+ return NXT_ERROR;
}
- b->mem.free = nxt_cpymem(b->mem.free, head.start, head.length);
-
- c->write = b;
+ b->mem.free = nxt_cpymem(b->mem.free, "HTTP/1.0 ", sizeof("HTTP/1.0 ") - 1);
+ b->mem.free = nxt_cpymem(b->mem.free, resp->status_line.start,
+ resp->status_line.length);
- b = nxt_conf_json_print(r->conf, c->mem_pool);
+ b->mem.free = nxt_cpymem(b->mem.free, "\r\n\r\n", sizeof("\r\n\r\n") - 1);
- if (b == NULL) {
- nxt_controller_conn_close(task, c, r);
- return;
+ if (resp->json_string.length > 0) {
+ b->mem.free = nxt_cpymem(b->mem.free, resp->json_string.start,
+ resp->json_string.length);
}
- c->write->next = b;
+ c->write = b;
c->write_state = &nxt_controller_conn_write_state;
+ if (resp->json_value != NULL) {
+ b = nxt_conf_json_print(resp->json_value, c->mem_pool);
+
+ if (b == NULL) {
+ return NXT_ERROR;
+ }
+
+ c->write->next = b;
+ }
+
nxt_event_conn_write(task->thread->engine, c);
- return;
+
+ return NXT_OK;
}