GNUnet  0.19.4
plugin_rest_config.c File Reference
#include "platform.h"
#include "gnunet_rest_plugin.h"
#include <gnunet_rest_lib.h>
#include <gnunet_util_lib.h>
#include <jansson.h>
Include dependency graph for plugin_rest_config.c:

Go to the source code of this file.

Data Structures

struct  Plugin
 Handle for a plugin. More...
 
struct  RequestHandle
 The request handle. More...
 

Macros

#define GNUNET_REST_API_NS_CONFIG   "/config"
 

Functions

static void cleanup_handle (struct RequestHandle *handle)
 Cleanup request handle. More...
 
static void do_error (void *cls)
 Task run on shutdown. More...
 
static void add_sections (void *cls, const char *section, const char *option, const char *value)
 
static void add_section_contents (void *cls, const char *section, const char *option, const char *value)
 
static void get_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Handle rest request. More...
 
struct GNUNET_CONFIGURATION_Handleset_value (struct GNUNET_CONFIGURATION_Handle *config, const char *section, const char *option, json_t *value)
 
static void set_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Handle REST POST request. More...
 
static void options_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Handle rest request. More...
 
static enum GNUNET_GenericReturnValue rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
 Function processing the REST call. More...
 
void * libgnunet_plugin_rest_config_init (void *cls)
 Entry point for the plugin. More...
 
void * libgnunet_plugin_rest_config_done (void *cls)
 Exit point from the plugin. More...
 

Variables

const struct GNUNET_CONFIGURATION_Handlecfg
 Handle to our configuration. More...
 
static struct RequestHandlerequests_head
 DLL. More...
 
static struct RequestHandlerequests_tail
 DLL. More...
 

Macro Definition Documentation

◆ GNUNET_REST_API_NS_CONFIG

#define GNUNET_REST_API_NS_CONFIG   "/config"

Definition at line 33 of file plugin_rest_config.c.

Function Documentation

◆ cleanup_handle()

static void cleanup_handle ( struct RequestHandle handle)
static

Cleanup request handle.

Parameters
handleHandle to clean up

Definition at line 100 of file plugin_rest_config.c.

101 {
102  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
103  if (NULL != handle->url)
104  GNUNET_free (handle->url);
107  handle);
109 }
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
static struct RequestHandle * requests_head
DLL.
static struct RequestHandle * requests_tail
DLL.

References GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, handle, requests_head, and requests_tail.

Referenced by do_error(), get_cont(), libgnunet_plugin_rest_config_done(), options_cont(), and set_cont().

Here is the caller graph for this function:

◆ do_error()

static void do_error ( void *  cls)
static

Task run on shutdown.

Cleans up everything.

Parameters
clsunused

Definition at line 118 of file plugin_rest_config.c.

119 {
120  struct RequestHandle *handle = cls;
121  struct MHD_Response *resp;
122 
123  resp = GNUNET_REST_create_response (NULL);
124  handle->proc (handle->proc_cls, resp, handle->response_code);
126 }
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:44
static void cleanup_handle(struct RequestHandle *handle)
Cleanup request handle.
The request handle.

References cleanup_handle(), GNUNET_REST_create_response(), and handle.

Referenced by get_cont(), and set_cont().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_sections()

static void add_sections ( void *  cls,
const char *  section,
const char *  option,
const char *  value 
)
static

Definition at line 130 of file plugin_rest_config.c.

134 {
135  json_t *sections_obj = cls;
136  json_t *sec_obj;
137 
138  sec_obj = json_object_get (sections_obj, section);
139  if (NULL != sec_obj)
140  {
141  json_object_set_new (sec_obj, option, json_string (value));
142  return;
143  }
144  sec_obj = json_object ();
145  json_object_set_new (sec_obj, option, json_string (value));
146  json_object_set_new (sections_obj, section, sec_obj);
147 }
static char * value
Value of the record to add/remove.

References value.

Referenced by get_cont().

Here is the caller graph for this function:

◆ add_section_contents()

static void add_section_contents ( void *  cls,
const char *  section,
const char *  option,
const char *  value 
)
static

Definition at line 151 of file plugin_rest_config.c.

155 {
156  json_t *section_obj = cls;
157 
158  json_object_set_new (section_obj, option, json_string (value));
159 }

References value.

Referenced by get_cont().

Here is the caller graph for this function:

◆ get_cont()

static void get_cont ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 
)
static

Handle rest request.

Parameters
handlethe lookup handle

Definition at line 168 of file plugin_rest_config.c.

171 {
172  struct MHD_Response *resp;
173  struct RequestHandle *handle = cls;
174  const char *section;
175  char *response;
176  json_t *result;
177 
178  if (strlen (GNUNET_REST_API_NS_CONFIG) > strlen (handle->url))
179  {
180  handle->response_code = MHD_HTTP_BAD_REQUEST;
182  return;
183  }
184  if (strlen (GNUNET_REST_API_NS_CONFIG) == strlen (handle->url))
185  {
186  result = json_object ();
188  }
189  else
190  {
191  result = json_object ();
192  section = &handle->url[strlen (GNUNET_REST_API_NS_CONFIG) + 1];
194  section,
196  result);
197  }
198  response = json_dumps (result, 0);
200  GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
201  "Content-Type",
202  "application/json"));
203  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
206  json_decref (result);
207 }
static struct MHD_Response * response
Our canonical response.
static int result
Global testing status.
void GNUNET_CONFIGURATION_iterate(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over all options in the configuration.
void GNUNET_CONFIGURATION_iterate_section_values(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over values of a section in the configuration.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
@ MHD_HTTP_BAD_REQUEST
Bad Request [RFC7231, Section 6.5.1].
@ MHD_HTTP_OK
OK [RFC7231, Section 6.3.1].
const struct GNUNET_CONFIGURATION_Handle * cfg
Handle to our configuration.
static void add_section_contents(void *cls, const char *section, const char *option, const char *value)
#define GNUNET_REST_API_NS_CONFIG
static void add_sections(void *cls, const char *section, const char *option, const char *value)
static void do_error(void *cls)
Task run on shutdown.

References add_section_contents(), add_sections(), cfg, cleanup_handle(), do_error(), GNUNET_assert, GNUNET_CONFIGURATION_iterate(), GNUNET_CONFIGURATION_iterate_section_values(), GNUNET_free, GNUNET_REST_API_NS_CONFIG, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), handle, MHD_HTTP_BAD_REQUEST, MHD_HTTP_OK, response, and result.

Here is the call graph for this function:

◆ set_value()

struct GNUNET_CONFIGURATION_Handle* set_value ( struct GNUNET_CONFIGURATION_Handle config,
const char *  section,
const char *  option,
json_t *  value 
)

Definition at line 211 of file plugin_rest_config.c.

215 {
216  if (json_is_string (value))
218  json_string_value (value));
219  else if (json_is_number (value))
221  json_integer_value (value));
222  else if (json_is_null (value))
223  GNUNET_CONFIGURATION_set_value_string (config, section, option, NULL);
224  else if (json_is_true (value))
225  GNUNET_CONFIGURATION_set_value_string (config, section, option, "yes");
226  else if (json_is_false (value))
227  GNUNET_CONFIGURATION_set_value_string (config, section, option, "no");
228  else
229  return NULL;
230  return config; // for error handling (0 -> success, 1 -> error)
231 }
static const struct GNUNET_CONFIGURATION_Handle * config
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
void GNUNET_CONFIGURATION_set_value_number(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long number)
Set a configuration value that should be a number.

References config, GNUNET_CONFIGURATION_set_value_number(), GNUNET_CONFIGURATION_set_value_string(), and value.

Referenced by set_cont().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_cont()

static void set_cont ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 
)
static

Handle REST POST request.

Parameters
handlethe lookup handle

Definition at line 240 of file plugin_rest_config.c.

243 {
244  struct RequestHandle *handle = cls;
245  char term_data[handle->rest_handle->data_size + 1];
247 
248  json_error_t err;
249  json_t *data_json;
250  const char *section;
251  const char *option;
252  json_t *sec_obj;
253  json_t *value;
254  char *cfg_fn;
255 
256  // invalid url
257  if (strlen (GNUNET_REST_API_NS_CONFIG) > strlen (handle->url))
258  {
259  handle->response_code = MHD_HTTP_BAD_REQUEST;
261  return;
262  }
263 
264  // extract data from handle
265  term_data[handle->rest_handle->data_size] = '\0';
266  GNUNET_memcpy (term_data,
267  handle->rest_handle->data,
268  handle->rest_handle->data_size);
269  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
270 
271  if (NULL == data_json)
272  {
274  "Unable to parse JSON Object from %s\n",
275  term_data);
277  return;
278  }
279 
280  // POST /config => {<section> : {<option> : <value>}}
281  if (strlen (GNUNET_REST_API_NS_CONFIG) == strlen (handle->url)) // POST /config
282  {
283  // iterate over sections
284  json_object_foreach (data_json, section, sec_obj)
285  {
286  // iterate over options
287  json_object_foreach (sec_obj, option, value)
288  {
289  out = set_value (out, section, option, value);
290  if (NULL == out)
291  {
292  handle->response_code = MHD_HTTP_BAD_REQUEST;
294  json_decref (data_json);
295  return;
296  }
297  }
298  }
299  }
300  else // POST /config/<section> => {<option> : <value>}
301  {
302  // extract the "<section>" part from the url
303  section = &handle->url[strlen (GNUNET_REST_API_NS_CONFIG) + 1];
304  // iterate over options
305  json_object_foreach (data_json, option, value)
306  {
307  out = set_value (out, section, option, value);
308  if (NULL == out)
309  {
310  handle->response_code = MHD_HTTP_BAD_REQUEST;
312  json_decref (data_json);
313  return;
314  }
315  }
316  }
317  json_decref (data_json);
318 
319 
320  // get cfg file path
321  cfg_fn = NULL;
322  const char *xdg = getenv ("XDG_CONFIG_HOME");
323  if (NULL != xdg)
324  GNUNET_asprintf (&cfg_fn,
325  "%s%s%s",
326  xdg,
329  else
330  cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
331 
332  GNUNET_CONFIGURATION_write (out, cfg_fn);
333  cfg = out;
334  handle->proc (handle->proc_cls,
336  MHD_HTTP_OK);
337  GNUNET_free (cfg_fn);
339 }
char * getenv()
static char * config_file
Set to the name of the config file used.
Definition: gnunet-arm.c:84
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Write configuration file.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_dup(const struct GNUNET_CONFIGURATION_Handle *cfg)
Duplicate an existing configuration object.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_ERROR_TYPE_ERROR
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_get(void)
#define DIR_SEPARATOR_STR
Definition: platform.h:166
struct GNUNET_CONFIGURATION_Handle * set_value(struct GNUNET_CONFIGURATION_Handle *config, const char *section, const char *option, json_t *value)

References cfg, cleanup_handle(), config_file, DIR_SEPARATOR_STR, do_error(), getenv(), GNUNET_asprintf(), GNUNET_CONFIGURATION_dup(), GNUNET_CONFIGURATION_write(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_memcpy, GNUNET_OS_project_data_get(), GNUNET_REST_API_NS_CONFIG, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, MHD_HTTP_BAD_REQUEST, MHD_HTTP_OK, set_value(), and value.

Here is the call graph for this function:

◆ options_cont()

static void options_cont ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 
)
static

Handle rest request.

Parameters
handlethe lookup handle

Definition at line 348 of file plugin_rest_config.c.

351 {
352  struct MHD_Response *resp;
353  struct RequestHandle *handle = cls;
354 
355  resp = GNUNET_REST_create_response (NULL);
356  GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
357  "Access-Control-Allow-Methods",
358  MHD_HTTP_METHOD_GET));
359  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
361 }

References cleanup_handle(), GNUNET_assert, GNUNET_REST_create_response(), handle, and MHD_HTTP_OK.

Here is the call graph for this function:

◆ rest_config_process_request()

static enum GNUNET_GenericReturnValue rest_config_process_request ( struct GNUNET_REST_RequestHandle conndata_handle,
GNUNET_REST_ResultProcessor  proc,
void *  proc_cls 
)
static

Function processing the REST call.

Parameters
methodHTTP method
urlURL of the HTTP request
databody of the HTTP request (optional)
data_sizelength of the body
proccallback function for the result
proc_clsclosure for proc
Returns
GNUNET_OK if request accepted

Definition at line 348 of file plugin_rest_config.c.

379 {
380  static const struct GNUNET_REST_RequestHandler handlers[] = {
381  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CONFIG, &get_cont },
382  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_CONFIG, &set_cont },
383  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CONFIG, &options_cont },
385  };
386  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
388 
389  handle->proc_cls = proc_cls;
390  handle->proc = proc;
391  handle->rest_handle = conndata_handle;
392  handle->url = GNUNET_strdup (conndata_handle->url);
393  if (handle->url[strlen (handle->url) - 1] == '/')
394  handle->url[strlen (handle->url) - 1] = '\0';
397  handle);
398  if (GNUNET_NO ==
399  GNUNET_REST_handle_request (conndata_handle, handlers, &err, handle))
400  {
402  return GNUNET_NO;
403  }
404  return GNUNET_YES;
405 }
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int GNUNET_REST_handle_request(struct GNUNET_REST_RequestHandle *conn, const struct GNUNET_REST_RequestHandler *handlers, struct GNUNET_REST_RequestHandlerError *err, void *cls)
Definition: rest.c:64
#define GNUNET_REST_HANDLER_END
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle rest request.
static void set_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle REST POST request.
static void get_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle rest request.
const char * url
The url as string.

Referenced by libgnunet_plugin_rest_config_init().

Here is the caller graph for this function:

◆ libgnunet_plugin_rest_config_init()

void* libgnunet_plugin_rest_config_init ( void *  cls)

Entry point for the plugin.

Parameters
clsthe "struct GNUNET_NAMESTORE_PluginEnvironment*"
Returns
NULL on error, otherwise the plugin context

Definition at line 415 of file plugin_rest_config.c.

416 {
417  static struct Plugin plugin;
418 
419  cfg = cls;
420  struct GNUNET_REST_Plugin *api;
421 
422  memset (&plugin, 0, sizeof(struct Plugin));
423  plugin.cfg = cfg;
424  api = GNUNET_new (struct GNUNET_REST_Plugin);
425  api->cls = &plugin;
428  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("CONFIG REST API initialized\n"));
429  return api;
430 }
struct TestcasePlugin * plugin
The process handle to the testbed service.
@ GNUNET_ERROR_TYPE_INFO
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
static enum GNUNET_GenericReturnValue rest_config_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
struct returned by the initialization function of the plugin
char * name
Plugin name.
void * cls
The closure of the plugin.
enum GNUNET_GenericReturnValue(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
Handle for a plugin.
Definition: block.c:38

References _, cfg, GNUNET_REST_Plugin::cls, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_new, GNUNET_REST_API_NS_CONFIG, GNUNET_REST_Plugin::name, plugin, GNUNET_REST_Plugin::process_request, and rest_config_process_request().

Here is the call graph for this function:

◆ libgnunet_plugin_rest_config_done()

void* libgnunet_plugin_rest_config_done ( void *  cls)

Exit point from the plugin.

Parameters
clsthe plugin context (as returned by "init")
Returns
always NULL

Definition at line 440 of file plugin_rest_config.c.

441 {
442  struct GNUNET_REST_Plugin *api = cls;
443  struct Plugin *plugin;
444 
445  while (NULL != requests_head)
447  plugin = api->cls;
448  plugin->cfg = NULL;
449  GNUNET_free (api);
450  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONFIG REST plugin is finished\n");
451  return NULL;
452 }
void * cls
Closure for all of the callbacks.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47

References Plugin::api, cleanup_handle(), GNUNET_BLOCK_PluginFunctions::cls, GNUNET_REST_Plugin::cls, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, plugin, and requests_head.

Here is the call graph for this function:

Variable Documentation

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg

Handle to our configuration.

Handle to our configuration.

Definition at line 43 of file plugin_rest_config.c.

Referenced by get_cont(), libgnunet_plugin_rest_config_init(), and set_cont().

◆ requests_head

struct RequestHandle* requests_head
static

DLL.

Definition at line 86 of file plugin_rest_config.c.

Referenced by cleanup_handle(), and libgnunet_plugin_rest_config_done().

◆ requests_tail

struct RequestHandle* requests_tail
static

DLL.

Definition at line 91 of file plugin_rest_config.c.

Referenced by cleanup_handle().