From: Schanzenbach, Martin Date: Fri, 26 Apr 2019 09:08:21 +0000 (+0200) Subject: REST: add config plugin X-Git-Tag: v0.11.4~90 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=480c8f1ee2b86cdf082fb1f0964bc2db43ea3805;p=oweals%2Fgnunet.git REST: add config plugin --- diff --git a/src/rest/Makefile.am b/src/rest/Makefile.am index acb95140b..8fe48198f 100644 --- a/src/rest/Makefile.am +++ b/src/rest/Makefile.am @@ -23,9 +23,11 @@ lib_LTLIBRARIES = \ libgnunetrest.la libexec_PROGRAMS = \ - gnunet-rest-server + gnunet-rest-server -plugin_LTLIBRARIES = libgnunet_plugin_rest_copying.la +plugin_LTLIBRARIES = \ + libgnunet_plugin_rest_copying.la \ + libgnunet_plugin_rest_config.la EXTRA_DIST = \ rest.conf @@ -39,6 +41,15 @@ libgnunet_plugin_rest_copying_la_LIBADD = \ libgnunet_plugin_rest_copying_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) +libgnunet_plugin_rest_config_la_SOURCES = \ + plugin_rest_config.c +libgnunet_plugin_rest_config_la_LIBADD = \ + libgnunetrest.la \ + $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ + $(LTLIBINTL) -lmicrohttpd -ljansson +libgnunet_plugin_rest_config_la_LDFLAGS = \ + $(GN_PLUGIN_LDFLAGS) + gnunet_rest_server_SOURCES = \ diff --git a/src/rest/plugin_rest_config.c b/src/rest/plugin_rest_config.c new file mode 100644 index 000000000..fe8d9bf7f --- /dev/null +++ b/src/rest/plugin_rest_config.c @@ -0,0 +1,288 @@ +/* + This file is part of GNUnet. + Copyright (C) 2012-2018 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Martin Schanzenbach + * @file gns/plugin_rest_config.c + * @brief REST plugin for configuration + * + */ + +#include "platform.h" +#include "gnunet_rest_plugin.h" +#include +#include +#include + +#define GNUNET_REST_API_NS_CONFIG "/config" + +/** + * @brief struct returned by the initialization function of the plugin + */ +struct Plugin +{ + const struct GNUNET_CONFIGURATION_Handle *cfg; +}; + +const struct GNUNET_CONFIGURATION_Handle *cfg; + +struct RequestHandle +{ + /** + * Handle to rest request + */ + struct GNUNET_REST_RequestHandle *rest_handle; + + /** + * The plugin result processor + */ + GNUNET_REST_ResultProcessor proc; + + /** + * The closure of the result processor + */ + void *proc_cls; + + /** + * HTTP response code + */ + int response_code; + + /** + * The URL + */ + char *url; +}; + + +/** + * Cleanup request handle. + * + * @param handle Handle to clean up + */ +static void +cleanup_handle (struct RequestHandle *handle) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); + if (NULL != handle->url) + GNUNET_free (handle->url); + GNUNET_free (handle); +} + + +/** + * Task run on shutdown. Cleans up everything. + * + * @param cls unused + * @param tc scheduler context + */ +static void +do_error (void *cls) +{ + struct RequestHandle *handle = cls; + struct MHD_Response *resp; + + resp = GNUNET_REST_create_response (NULL); + handle->proc (handle->proc_cls, resp, handle->response_code); + cleanup_handle (handle); +} + + +static void +add_sections (void *cls, + const char *section, + const char *option, + const char *value) +{ + json_t *sections_obj = cls; + json_t *sec_obj; + + sec_obj = json_object_get (sections_obj, section); + if (NULL != sec_obj) + { + json_object_set_new (sec_obj, option, json_string (value)); + return; + } + sec_obj = json_object (); + json_object_set_new (sec_obj, option, json_string (value)); + json_object_set_new (sections_obj, section, sec_obj); +} + +static void +add_section_contents (void *cls, + const char *section, + const char *option, + const char *value) +{ + json_t *section_obj = cls; + json_object_set_new (section_obj, option, json_string (value)); +} + + +/** + * Handle rest request + * + * @param handle the lookup handle + */ +static void +get_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char *url, + void *cls) +{ + struct MHD_Response *resp; + struct RequestHandle *handle = cls; + const char *section; + char *response; + json_t *result; + + if (strlen (GNUNET_REST_API_NS_CONFIG) > strlen (handle->url)) + { + handle->response_code = MHD_HTTP_BAD_REQUEST; + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + if (strlen (GNUNET_REST_API_NS_CONFIG) == strlen (handle->url)) + { + result = json_object (); + GNUNET_CONFIGURATION_iterate (cfg, &add_sections, result); + } + else + { + result = json_object (); + section = &handle->url[strlen (GNUNET_REST_API_NS_CONFIG) + 1]; + GNUNET_CONFIGURATION_iterate_section_values (cfg, + section, + &add_section_contents, + result); + } + response = json_dumps (result, 0); + resp = GNUNET_REST_create_response (response); + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + cleanup_handle (handle); + GNUNET_free (response); + json_decref (result); +} + + +/** + * Handle rest request + * + * @param handle the lookup handle + */ +static void +options_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char *url, + void *cls) +{ + struct MHD_Response *resp; + struct RequestHandle *handle = cls; + + resp = GNUNET_REST_create_response (NULL); + MHD_add_response_header (resp, + "Access-Control-Allow-Methods", + MHD_HTTP_METHOD_GET); + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + cleanup_handle (handle); +} + + +/** + * Function processing the REST call + * + * @param method HTTP method + * @param url URL of the HTTP request + * @param data body of the HTTP request (optional) + * @param data_size length of the body + * @param proc callback function for the result + * @param proc_cls closure for @a proc + * @return #GNUNET_OK if request accepted + */ +static void +rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, + GNUNET_REST_ResultProcessor proc, + void *proc_cls) +{ + static const struct GNUNET_REST_RequestHandler handlers[] = { + {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CONFIG, &get_cont}, + {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CONFIG, &options_cont}, + GNUNET_REST_HANDLER_END}; + struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + + handle->proc_cls = proc_cls; + handle->proc = proc; + handle->rest_handle = conndata_handle; + handle->url = GNUNET_strdup (conndata_handle->url); + if (handle->url[strlen (handle->url) - 1] == '/') + handle->url[strlen (handle->url) - 1] = '\0'; + + if (GNUNET_NO == + GNUNET_REST_handle_request (conndata_handle, handlers, &err, handle)) + { + handle->response_code = err.error_code; + GNUNET_SCHEDULER_add_now (&do_error, handle); + } +} + + +/** + * Entry point for the plugin. + * + * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*" + * @return NULL on error, otherwise the plugin context + */ +void * +libgnunet_plugin_rest_config_init (void *cls) +{ + static struct Plugin plugin; + cfg = cls; + struct GNUNET_REST_Plugin *api; + + if (NULL != plugin.cfg) + return NULL; /* can only initialize once! */ + memset (&plugin, 0, sizeof (struct Plugin)); + plugin.cfg = cfg; + api = GNUNET_new (struct GNUNET_REST_Plugin); + api->cls = &plugin; + api->name = GNUNET_REST_API_NS_CONFIG; + api->process_request = &rest_config_process_request; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("CONFIG REST API initialized\n")); + return api; +} + + +/** + * Exit point from the plugin. + * + * @param cls the plugin context (as returned by "init") + * @return always NULL + */ +void * +libgnunet_plugin_rest_config_done (void *cls) +{ + struct GNUNET_REST_Plugin *api = cls; + struct Plugin *plugin = api->cls; + + plugin->cfg = NULL; + GNUNET_free (api); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONFIG REST plugin is finished\n"); + return NULL; +} + +/* end of plugin_rest_config.c */