30c30
< nxt_str_t status_line;
---
> nxt_uint_t status;
32c32,37
< nxt_str_t json;
---
>
> u_char *title;
> u_char *detail;
> ssize_t offset;
> nxt_uint_t line;
> nxt_uint_t column;
66,67c71,72
< static nxt_buf_t *nxt_controller_response_body(nxt_controller_response_t *resp,
< nxt_mp_t *pool);
---
> static u_char *nxt_controller_date(u_char *buf, nxt_realtime_t *now,
> struct tm *tm, size_t size, const char *format);
564d568
< nxt_uint_t status;
567a572
> nxt_conf_json_error_t error;
586,587c591
< status = 404;
< goto done;
---
> goto not_found;
589a594
> resp.status = 200;
592,593c597,598
< status = 200;
< goto done;
---
> nxt_controller_response(task, req, &resp);
> return;
601,602c606
< status = 500;
< goto done;
---
> goto alloc_fail;
607c611
< value = nxt_conf_json_parse(mp, mbuf->pos, mbuf->free);
---
> nxt_memzero(&error, sizeof(nxt_conf_json_error_t));
608a613,614
> value = nxt_conf_json_parse(mp, mbuf->pos, mbuf->free, &error);
>
611,613c617,631
< status = 400;
< nxt_str_set(&resp.json, "{ \"error\": \"Invalid JSON.\" }");
< goto done;
---
>
> if (error.pos == NULL) {
> goto alloc_fail;
> }
>
> resp.status = 400;
> resp.title = (u_char *) "Invalid JSON.";
> resp.detail = error.detail;
> resp.offset = error.pos - mbuf->pos;
>
> nxt_conf_json_position(mbuf->pos, error.pos,
> &resp.line, &resp.column);
>
> nxt_controller_response(task, req, &resp);
> return;
623,624c641
< status = 404;
< goto done;
---
> goto not_found;
627,628c644
< status = 500;
< goto done;
---
> goto alloc_fail;
635,636c651
< status = 500;
< goto done;
---
> goto alloc_fail;
642,645c657
< status = 400;
< nxt_str_set(&resp.json,
< "{ \"error\": \"Invalid configuration.\" }");
< goto done;
---
> goto invalid_conf;
653,654c665
< status = 500;
< goto done;
---
> goto alloc_fail;
666,667c677
< status = 500;
< goto done;
---
> goto alloc_fail;
679,680c689
< status = 404;
< goto done;
---
> goto not_found;
683,684c692
< status = 500;
< goto done;
---
> goto alloc_fail;
690,691c698
< status = 500;
< goto done;
---
> goto alloc_fail;
699,700c706
< status = 500;
< goto done;
---
> goto alloc_fail;
705,708c711
< status = 400;
< nxt_str_set(&resp.json,
< "{ \"error\": \"Invalid configuration.\" }");
< goto done;
---
> goto invalid_conf;
716,717c719
< status = 500;
< goto done;
---
> goto alloc_fail;
723c725,727
< status = 405;
---
> resp.status = 405;
> resp.title = (u_char *) "Invalid method.";
> resp.offset = -1;
725c729,730
< done:
---
> nxt_controller_response(task, req, &resp);
> return;
727c732
< switch (status) {
---
> alloc_fail:
729,731c734,736
< case 200:
< nxt_str_set(&resp.status_line, "200 OK");
< break;
---
> resp.status = 500;
> resp.title = (u_char *) "Memory allocation failed.";
> resp.offset = -1;
733,735c738,739
< case 400:
< nxt_str_set(&resp.status_line, "400 Bad Request");
< break;
---
> nxt_controller_response(task, req, &resp);
> return;
737,740c741
< case 404:
< nxt_str_set(&resp.status_line, "404 Not Found");
< nxt_str_set(&resp.json, "{ \"error\": \"Value doesn't exist.\" }");
< break;
---
> not_found:
742,745c743,745
< case 405:
< nxt_str_set(&resp.status_line, "405 Method Not Allowed");
< nxt_str_set(&resp.json, "{ \"error\": \"Invalid method.\" }");
< break;
---
> resp.status = 404;
> resp.title = (u_char *) "Value doesn't exist.";
> resp.offset = -1;
747,751c747,748
< case 500:
< nxt_str_set(&resp.status_line, "500 Internal Server Error");
< nxt_str_set(&resp.json, "{ \"error\": \"Memory allocation failed.\" }");
< break;
< }
---
> nxt_controller_response(task, req, &resp);
> return;
752a750,755
> invalid_conf:
>
> resp.status = 400;
> resp.title = (u_char *) "Invalid configuration.";
> resp.offset = -1;
>
753a757
> return;
799,800c803,804
< nxt_str_set(&resp.status_line, "200 OK");
< nxt_str_set(&resp.json, "{ \"success\": \"Reconfiguration done.\" }");
---
> resp.status = 200;
> resp.title = (u_char *) "Reconfiguration done.";
805,807c809,811
< nxt_str_set(&resp.status_line, "500 Internal Server Error");
< nxt_str_set(&resp.json,
< "{ \"error\": \"Failed to apply new configuration.\" }");
---
> resp.status = 500;
> resp.title = (u_char *) "Failed to apply new configuration.";
> resp.offset = -1;
833,835c837
< nxt_str_set(&resp.status_line, "500 Internal Server Error");
< nxt_str_set(&resp.json,
< "{ \"error\": \"Memory allocation failed.\" }");
---
> nxt_memzero(&resp, sizeof(nxt_controller_response_t));
836a839,842
> resp.status = 500;
> resp.title = (u_char *) "Memory allocation failed.";
> resp.offset = -1;
>
880d885
<
885,887c890,896
< size_t size;
< nxt_buf_t *b;
< nxt_conn_t *c;
---
> size_t size;
> nxt_str_t status_line, str;
> nxt_buf_t *b, *body;
> nxt_conn_t *c;
> nxt_uint_t n;
> nxt_conf_value_t *value, *location;
> nxt_conf_json_pretty_t pretty;
889c898,904
< c = req->conn;
---
> static nxt_str_t success_str = nxt_string("success");
> static nxt_str_t error_str = nxt_string("error");
> static nxt_str_t detail_str = nxt_string("detail");
> static nxt_str_t location_str = nxt_string("location");
> static nxt_str_t offset_str = nxt_string("offset");
> static nxt_str_t line_str = nxt_string("line");
> static nxt_str_t column_str = nxt_string("column");
891c906,913
< size = sizeof("HTTP/1.0 " "\r\n\r\n") - 1 + resp->status_line.length;
---
> static nxt_time_string_t date_cache = {
> (nxt_atomic_uint_t) -1,
> nxt_controller_date,
> "%s, %02d %s %4d %02d:%02d:%02d GMT",
> sizeof("Wed, 31 Dec 1986 16:40:00 GMT") - 1,
> NXT_THREAD_TIME_GMT,
> NXT_THREAD_TIME_SEC,
> };
893,897c915
< b = nxt_buf_mem_alloc(c->mem_pool, size, 0);
< if (nxt_slow_path(b == NULL)) {
< nxt_controller_conn_close(task, c, req);
< return;
< }
---
> switch (resp->status) {
899,901c917,919
< 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);
---
> case 200:
> nxt_str_set(&status_line, "200 OK");
> break;
903c921,923
< b->mem.free = nxt_cpymem(b->mem.free, "\r\n\r\n", sizeof("\r\n\r\n") - 1);
---
> case 400:
> nxt_str_set(&status_line, "400 Bad Request");
> break;
905c925,927
< b->next = nxt_controller_response_body(resp, c->mem_pool);
---
> case 404:
> nxt_str_set(&status_line, "404 Not Found");
> break;
907,909c929,935
< if (nxt_slow_path(b->next == NULL)) {
< nxt_controller_conn_close(task, c, req);
< return;
---
> case 405:
> nxt_str_set(&status_line, "405 Method Not Allowed");
> break;
>
> case 500:
> nxt_str_set(&status_line, "500 Internal Server Error");
> break;
912,913c938,939
< c->write = b;
< c->write_state = &nxt_controller_conn_write_state;
---
> c = req->conn;
> value = resp->conf;
915,916c941,944
< nxt_conn_write(task->thread->engine, c);
< }
---
> if (value == NULL) {
> n = 1
> + (resp->detail != NULL)
> + (resp->status >= 400 && resp->offset != -1);
917a946
> value = nxt_conf_create_object(c->mem_pool, n);
919,925c948,951
< static nxt_buf_t *
< nxt_controller_response_body(nxt_controller_response_t *resp, nxt_mp_t *pool)
< {
< size_t size;
< nxt_buf_t *b;
< nxt_conf_value_t *value;
< nxt_conf_json_pretty_t pretty;
---
> if (nxt_slow_path(value == NULL)) {
> nxt_controller_conn_close(task, c, req);
> return;
> }
927,928c953,954
< if (resp->conf) {
< value = resp->conf;
---
> str.length = nxt_strlen(resp->title);
> str.start = resp->title;
930,931c956,957
< } else {
< value = nxt_conf_json_parse_str(pool, &resp->json);
---
> if (resp->status < 400) {
> nxt_conf_set_member_string(value, &success_str, &str, 0);
933,934c959,960
< if (nxt_slow_path(value == NULL)) {
< return NULL;
---
> } else {
> nxt_conf_set_member_string(value, &error_str, &str, 0);
935a962,991
>
> n = 0;
>
> if (resp->detail != NULL) {
> str.length = nxt_strlen(resp->detail);
> str.start = resp->detail;
>
> n++;
>
> nxt_conf_set_member_string(value, &detail_str, &str, n);
> }
>
> if (resp->status >= 400 && resp->offset != -1) {
> n++;
>
> location = nxt_conf_create_object(c->mem_pool,
> resp->line != 0 ? 3 : 1);
>
> nxt_conf_set_member(value, &location_str, location, n);
>
> nxt_conf_set_member_integer(location, &offset_str, resp->offset, 0);
>
> if (resp->line != 0) {
> nxt_conf_set_member_integer(location, &line_str,
> resp->line, 1);
>
> nxt_conf_set_member_integer(location, &column_str,
> resp->column, 2);
> }
> }
942,944c998,1001
< b = nxt_buf_mem_alloc(pool, size, 0);
< if (nxt_slow_path(b == NULL)) {
< return NULL;
---
> body = nxt_buf_mem_alloc(c->mem_pool, size, 0);
> if (nxt_slow_path(body == NULL)) {
> nxt_controller_conn_close(task, c, req);
> return;
949c1006
< b->mem.free = nxt_conf_json_print(b->mem.free, value, &pretty);
---
> body->mem.free = nxt_conf_json_print(body->mem.free, value, &pretty);
951,952c1008
< *b->mem.free++ = '\r';
< *b->mem.free++ = '\n';
---
> body->mem.free = nxt_cpymem(body->mem.free, "\r\n", 2);
954c1010,1059
< return b;
---
> size = sizeof("HTTP/1.1 " "\r\n") - 1 + status_line.length
> + sizeof("Server: nginext/0.1\r\n") - 1
> + sizeof("Date: Wed, 31 Dec 1986 16:40:00 GMT\r\n") - 1
> + sizeof("Content-Type: application/json\r\n") - 1
> + sizeof("Content-Length: " "\r\n") - 1 + NXT_SIZE_T_LEN
> + sizeof("Connection: close\r\n") - 1
> + sizeof("\r\n") - 1;
>
> b = nxt_buf_mem_alloc(c->mem_pool, size, 0);
> if (nxt_slow_path(b == NULL)) {
> nxt_controller_conn_close(task, c, req);
> return;
> }
>
> b->next = body;
>
> nxt_str_set(&str, "HTTP/1.1 ");
>
> b->mem.free = nxt_cpymem(b->mem.free, str.start, str.length);
> b->mem.free = nxt_cpymem(b->mem.free, status_line.start,
> status_line.length);
>
> nxt_str_set(&str, "\r\n"
> "Server: nginext/0.1\r\n"
> "Date: ");
>
> b->mem.free = nxt_cpymem(b->mem.free, str.start, str.length);
>
> b->mem.free = nxt_thread_time_string(task->thread, &date_cache,
> b->mem.free);
>
> nxt_str_set(&str, "\r\n"
> "Content-Type: application/json\r\n"
> "Content-Length: ");
>
> b->mem.free = nxt_cpymem(b->mem.free, str.start, str.length);
>
> b->mem.free = nxt_sprintf(b->mem.free, b->mem.end, "%uz",
> nxt_buf_mem_used_size(&body->mem));
>
> nxt_str_set(&str, "\r\n"
> "Connection: close\r\n"
> "\r\n");
>
> b->mem.free = nxt_cpymem(b->mem.free, str.start, str.length);
>
> c->write = b;
> c->write_state = &nxt_controller_conn_write_state;
>
> nxt_conn_write(task->thread->engine, c);
955a1061,1077
>
>
> static u_char *
> nxt_controller_date(u_char *buf, nxt_realtime_t *now, struct tm *tm,
> size_t size, const char *format)
> {
> static const char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
> "Sat" };
>
> static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
> "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
>
> return nxt_sprintf(buf, buf + size, format,
> week[tm->tm_wday], tm->tm_mday,
> month[tm->tm_mon], tm->tm_year + 1900,
> tm->tm_hour, tm->tm_min, tm->tm_sec);
> }