diff --git a/src/core/nginx.c b/src/core/nginx.c index 5df9919ce..2d619c6e3 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -957,6 +957,8 @@ ngx_get_options(int argc, char *const *argv) #if (NGX_CONTROL_API) case 'l': + ngx_control_api_enabled = 1; + if (*p) { ngx_control_addr = p; goto next; diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c index 6ac0d8829..5aee80146 100644 --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -217,6 +217,9 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) type = parse_file; if (ngx_dump_config +#if (NGX_CONTROL_API) + || ngx_control_api_enabled +#endif #if (NGX_DEBUG) || 1 #endif diff --git a/src/os/unix/ngx_control.c b/src/os/unix/ngx_control.c index b60738995..8a6167077 100644 --- a/src/os/unix/ngx_control.c +++ b/src/os/unix/ngx_control.c @@ -63,6 +63,7 @@ static ngx_int_t ngx_control_api_endpoints(ngx_control_request_t *r, static ngx_int_t ngx_control_show_processes(ngx_control_request_t *r); static ngx_int_t ngx_control_show_version(ngx_control_request_t *r); static ngx_int_t ngx_control_reload_config(ngx_control_request_t *r); +static ngx_int_t ngx_control_print_config(ngx_control_request_t *r); static void ngx_control_log_capture(ngx_log_t *log, ngx_uint_t l, u_char *buf, size_t len); @@ -117,6 +118,18 @@ static ngx_data_decl_t ngx_control_status_fields[] = { ngx_data_null_decl }; +static ngx_data_decl_t ngx_control_config_fields[] = { + { ngx_string("name"), + ngx_data_struct_str_handler, + offsetof(ngx_keyval_t, key) }, + + { ngx_string("content"), + ngx_data_struct_str_handler, + offsetof(ngx_keyval_t, value) }, + + ngx_data_null_decl +}; + ngx_int_t ngx_control_init(u_char *addr) @@ -630,11 +643,15 @@ ngx_control_content(ngx_control_request_t *r) case 17: if (ngx_strncmp(p, "/1/control/config", len) == 0) { - if (r->method != NGX_CTRL_PATCH) { - return ngx_control_send_response(r, NGX_CTRL_NOT_ALLOWED, NULL); + if (r->method == NGX_CTRL_PATCH) { + return ngx_control_reload_config(r); } - return ngx_control_reload_config(r); + if (r->method == NGX_CTRL_GET) { + return ngx_control_print_config(r); + } + + return ngx_control_send_response(r, NGX_CTRL_NOT_ALLOWED, NULL); } break; @@ -861,6 +878,40 @@ ngx_control_show_version(ngx_control_request_t *r) } +static ngx_int_t +ngx_control_print_config(ngx_control_request_t *r) +{ + ngx_uint_t i; + ngx_keyval_t item; + ngx_data_item_t *list, *obj; + ngx_conf_dump_t *dump; + + list = ngx_data_new_list(r->pool); + if (list == NULL) { + return NGX_ERROR; + } + + dump = ngx_cycle->config_dump.elts; + + for (i = 0; i < ngx_cycle->config_dump.nelts; i++) { + + item.key = dump[i].name; + item.value.data = dump[i].buffer->pos; + item.value.len = dump[i].buffer->last - dump[i].buffer->pos; + + obj = ngx_data_obj_handler((uintptr_t) ngx_control_config_fields, + r->pool, &item); + if (obj == NULL) { + return NGX_ERROR; + } + + ngx_data_add_item(list, NULL, obj); + } + + return ngx_control_send_json(r, NGX_CTRL_OK, list); +} + + static ngx_data_item_t * ngx_control_json_logs(ngx_array_t *logs) {