aboutsummaryrefslogtreecommitdiff
path: root/src/rest
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2019-04-26 11:08:21 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2019-04-26 11:08:21 +0200
commit480c8f1ee2b86cdf082fb1f0964bc2db43ea3805 (patch)
treed98b9ae53f03d403aeac9f020cb45020bd446e64 /src/rest
parentf5f5a9f680df2cebe6435ec87650cb3cb6e3ef6e (diff)
downloadgnunet-480c8f1ee2b86cdf082fb1f0964bc2db43ea3805.tar.gz
gnunet-480c8f1ee2b86cdf082fb1f0964bc2db43ea3805.zip
REST: add config plugin
Diffstat (limited to 'src/rest')
-rw-r--r--src/rest/Makefile.am15
-rw-r--r--src/rest/plugin_rest_config.c288
2 files changed, 301 insertions, 2 deletions
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 = \
23 libgnunetrest.la 23 libgnunetrest.la
24 24
25libexec_PROGRAMS = \ 25libexec_PROGRAMS = \
26 gnunet-rest-server 26 gnunet-rest-server
27 27
28plugin_LTLIBRARIES = libgnunet_plugin_rest_copying.la 28plugin_LTLIBRARIES = \
29 libgnunet_plugin_rest_copying.la \
30 libgnunet_plugin_rest_config.la
29 31
30EXTRA_DIST = \ 32EXTRA_DIST = \
31 rest.conf 33 rest.conf
@@ -39,6 +41,15 @@ libgnunet_plugin_rest_copying_la_LIBADD = \
39libgnunet_plugin_rest_copying_la_LDFLAGS = \ 41libgnunet_plugin_rest_copying_la_LDFLAGS = \
40 $(GN_PLUGIN_LDFLAGS) 42 $(GN_PLUGIN_LDFLAGS)
41 43
44libgnunet_plugin_rest_config_la_SOURCES = \
45 plugin_rest_config.c
46libgnunet_plugin_rest_config_la_LIBADD = \
47 libgnunetrest.la \
48 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
49 $(LTLIBINTL) -lmicrohttpd -ljansson
50libgnunet_plugin_rest_config_la_LDFLAGS = \
51 $(GN_PLUGIN_LDFLAGS)
52
42 53
43 54
44gnunet_rest_server_SOURCES = \ 55gnunet_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 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @author Martin Schanzenbach
22 * @file gns/plugin_rest_config.c
23 * @brief REST plugin for configuration
24 *
25 */
26
27#include "platform.h"
28#include "gnunet_rest_plugin.h"
29#include <gnunet_rest_lib.h>
30#include <gnunet_util_lib.h>
31#include <jansson.h>
32
33#define GNUNET_REST_API_NS_CONFIG "/config"
34
35/**
36 * @brief struct returned by the initialization function of the plugin
37 */
38struct Plugin
39{
40 const struct GNUNET_CONFIGURATION_Handle *cfg;
41};
42
43const struct GNUNET_CONFIGURATION_Handle *cfg;
44
45struct RequestHandle
46{
47 /**
48 * Handle to rest request
49 */
50 struct GNUNET_REST_RequestHandle *rest_handle;
51
52 /**
53 * The plugin result processor
54 */
55 GNUNET_REST_ResultProcessor proc;
56
57 /**
58 * The closure of the result processor
59 */
60 void *proc_cls;
61
62 /**
63 * HTTP response code
64 */
65 int response_code;
66
67 /**
68 * The URL
69 */
70 char *url;
71};
72
73
74/**
75 * Cleanup request handle.
76 *
77 * @param handle Handle to clean up
78 */
79static void
80cleanup_handle (struct RequestHandle *handle)
81{
82 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
83 if (NULL != handle->url)
84 GNUNET_free (handle->url);
85 GNUNET_free (handle);
86}
87
88
89/**
90 * Task run on shutdown. Cleans up everything.
91 *
92 * @param cls unused
93 * @param tc scheduler context
94 */
95static void
96do_error (void *cls)
97{
98 struct RequestHandle *handle = cls;
99 struct MHD_Response *resp;
100
101 resp = GNUNET_REST_create_response (NULL);
102 handle->proc (handle->proc_cls, resp, handle->response_code);
103 cleanup_handle (handle);
104}
105
106
107static void
108add_sections (void *cls,
109 const char *section,
110 const char *option,
111 const char *value)
112{
113 json_t *sections_obj = cls;
114 json_t *sec_obj;
115
116 sec_obj = json_object_get (sections_obj, section);
117 if (NULL != sec_obj)
118 {
119 json_object_set_new (sec_obj, option, json_string (value));
120 return;
121 }
122 sec_obj = json_object ();
123 json_object_set_new (sec_obj, option, json_string (value));
124 json_object_set_new (sections_obj, section, sec_obj);
125}
126
127static void
128add_section_contents (void *cls,
129 const char *section,
130 const char *option,
131 const char *value)
132{
133 json_t *section_obj = cls;
134 json_object_set_new (section_obj, option, json_string (value));
135}
136
137
138/**
139 * Handle rest request
140 *
141 * @param handle the lookup handle
142 */
143static void
144get_cont (struct GNUNET_REST_RequestHandle *con_handle,
145 const char *url,
146 void *cls)
147{
148 struct MHD_Response *resp;
149 struct RequestHandle *handle = cls;
150 const char *section;
151 char *response;
152 json_t *result;
153
154 if (strlen (GNUNET_REST_API_NS_CONFIG) > strlen (handle->url))
155 {
156 handle->response_code = MHD_HTTP_BAD_REQUEST;
157 GNUNET_SCHEDULER_add_now (&do_error, handle);
158 return;
159 }
160 if (strlen (GNUNET_REST_API_NS_CONFIG) == strlen (handle->url))
161 {
162 result = json_object ();
163 GNUNET_CONFIGURATION_iterate (cfg, &add_sections, result);
164 }
165 else
166 {
167 result = json_object ();
168 section = &handle->url[strlen (GNUNET_REST_API_NS_CONFIG) + 1];
169 GNUNET_CONFIGURATION_iterate_section_values (cfg,
170 section,
171 &add_section_contents,
172 result);
173 }
174 response = json_dumps (result, 0);
175 resp = GNUNET_REST_create_response (response);
176 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
177 cleanup_handle (handle);
178 GNUNET_free (response);
179 json_decref (result);
180}
181
182
183/**
184 * Handle rest request
185 *
186 * @param handle the lookup handle
187 */
188static void
189options_cont (struct GNUNET_REST_RequestHandle *con_handle,
190 const char *url,
191 void *cls)
192{
193 struct MHD_Response *resp;
194 struct RequestHandle *handle = cls;
195
196 resp = GNUNET_REST_create_response (NULL);
197 MHD_add_response_header (resp,
198 "Access-Control-Allow-Methods",
199 MHD_HTTP_METHOD_GET);
200 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
201 cleanup_handle (handle);
202}
203
204
205/**
206 * Function processing the REST call
207 *
208 * @param method HTTP method
209 * @param url URL of the HTTP request
210 * @param data body of the HTTP request (optional)
211 * @param data_size length of the body
212 * @param proc callback function for the result
213 * @param proc_cls closure for @a proc
214 * @return #GNUNET_OK if request accepted
215 */
216static void
217rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
218 GNUNET_REST_ResultProcessor proc,
219 void *proc_cls)
220{
221 static const struct GNUNET_REST_RequestHandler handlers[] = {
222 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CONFIG, &get_cont},
223 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CONFIG, &options_cont},
224 GNUNET_REST_HANDLER_END};
225 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
226 struct GNUNET_REST_RequestHandlerError err;
227
228 handle->proc_cls = proc_cls;
229 handle->proc = proc;
230 handle->rest_handle = conndata_handle;
231 handle->url = GNUNET_strdup (conndata_handle->url);
232 if (handle->url[strlen (handle->url) - 1] == '/')
233 handle->url[strlen (handle->url) - 1] = '\0';
234
235 if (GNUNET_NO ==
236 GNUNET_REST_handle_request (conndata_handle, handlers, &err, handle))
237 {
238 handle->response_code = err.error_code;
239 GNUNET_SCHEDULER_add_now (&do_error, handle);
240 }
241}
242
243
244/**
245 * Entry point for the plugin.
246 *
247 * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
248 * @return NULL on error, otherwise the plugin context
249 */
250void *
251libgnunet_plugin_rest_config_init (void *cls)
252{
253 static struct Plugin plugin;
254 cfg = cls;
255 struct GNUNET_REST_Plugin *api;
256
257 if (NULL != plugin.cfg)
258 return NULL; /* can only initialize once! */
259 memset (&plugin, 0, sizeof (struct Plugin));
260 plugin.cfg = cfg;
261 api = GNUNET_new (struct GNUNET_REST_Plugin);
262 api->cls = &plugin;
263 api->name = GNUNET_REST_API_NS_CONFIG;
264 api->process_request = &rest_config_process_request;
265 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("CONFIG REST API initialized\n"));
266 return api;
267}
268
269
270/**
271 * Exit point from the plugin.
272 *
273 * @param cls the plugin context (as returned by "init")
274 * @return always NULL
275 */
276void *
277libgnunet_plugin_rest_config_done (void *cls)
278{
279 struct GNUNET_REST_Plugin *api = cls;
280 struct Plugin *plugin = api->cls;
281
282 plugin->cfg = NULL;
283 GNUNET_free (api);
284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONFIG REST plugin is finished\n");
285 return NULL;
286}
287
288/* end of plugin_rest_config.c */