gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: rest: fix #6462


From: gnunet
Subject: [gnunet] branch master updated: rest: fix #6462
Date: Tue, 04 Aug 2020 19:46:38 +0200

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 815ded19f rest: fix #6462
     new 34b1431c1 Merge branch 'master' of ssh://gnunet.org/gnunet
815ded19f is described below

commit 815ded19f106990a37bbacec83546b1b897491f6
Author: Martin Schanzenbach <mschanzenbach@posteo.de>
AuthorDate: Tue Aug 4 19:40:23 2020 +0200

    rest: fix #6462
---
 src/gns/plugin_rest_gns.c                |  65 +++----
 src/identity/plugin_rest_identity.c      | 290 ++++++++++++++----------------
 src/include/gnunet_rest_plugin.h         |   8 +-
 src/namestore/plugin_rest_namestore.c    | 242 ++++++++++++-------------
 src/peerinfo-tool/plugin_rest_peerinfo.c |  66 +++----
 src/reclaim/plugin_rest_openid_connect.c | 241 ++++++++++++-------------
 src/reclaim/plugin_rest_reclaim.c        | 293 ++++++++++++++++---------------
 src/rest/gnunet-rest-server.c            | 120 +++++++------
 src/rest/plugin_rest_config.c            |   7 +-
 src/rest/plugin_rest_copying.c           |  32 +---
 10 files changed, 645 insertions(+), 719 deletions(-)

diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c
index 37313c529..a3006ce23 100644
--- a/src/gns/plugin_rest_gns.c
+++ b/src/gns/plugin_rest_gns.c
@@ -62,6 +62,11 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
  */
 static char *allow_methods;
 
+/**
+ * Connection to GNS
+ */
+static struct GNUNET_GNS_Handle *gns;
+
 /**
  * @brief struct returned by the initialization function of the plugin
  */
@@ -75,11 +80,6 @@ struct Plugin
  */
 struct RequestHandle
 {
-  /**
-   * Connection to GNS
-   */
-  struct GNUNET_GNS_Handle *gns;
-
   /**
    * Active GNS lookup
    */
@@ -153,12 +153,6 @@ cleanup_handle (void *cls)
     GNUNET_GNS_lookup_with_tld_cancel (handle->gns_lookup);
     handle->gns_lookup = NULL;
   }
-  if (NULL != handle->gns)
-  {
-    GNUNET_GNS_disconnect (handle->gns);
-    handle->gns = NULL;
-  }
-
   if (NULL != handle->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (handle->timeout_task);
@@ -318,7 +312,7 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
     handle->record_type = GNUNET_GNSRECORD_TYPE_ANY;
   }
 
-  handle->gns_lookup = GNUNET_GNS_lookup_with_tld (handle->gns,
+  handle->gns_lookup = GNUNET_GNS_lookup_with_tld (gns,
                                                    handle->name,
                                                    handle->record_type,
                                                    GNUNET_GNS_LO_DEFAULT,
@@ -351,29 +345,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
 }
 
 
-/**
- * Handle rest request
- *
- * @param handle the request handle
- */
-static void
-init_cont (struct RequestHandle *handle)
-{
-  struct GNUNET_REST_RequestHandlerError err;
-  static const struct GNUNET_REST_RequestHandler handlers[] =
-  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont },
-    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont },
-    GNUNET_REST_HANDLER_END };
-
-  if (GNUNET_NO ==
-      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
-  {
-    handle->response_code = err.error_code;
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-  }
-}
-
-
 /**
  * Function processing the REST call
  *
@@ -385,12 +356,17 @@ init_cont (struct RequestHandle *handle)
  * @param proc_cls closure for callback function
  * @return GNUNET_OK if request accepted
  */
-static void
+static enum GNUNET_GenericReturnValue
 rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
                       GNUNET_REST_ResultProcessor proc,
                       void *proc_cls)
 {
   struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
+  struct GNUNET_REST_RequestHandlerError err;
+  static const struct GNUNET_REST_RequestHandler handlers[] =
+  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont },
+    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont },
+    GNUNET_REST_HANDLER_END };
 
   handle->response_code = 0;
   handle->timeout =
@@ -402,14 +378,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle 
*rest_handle,
   handle->url = GNUNET_strdup (rest_handle->url);
   if (handle->url[strlen (handle->url) - 1] == '/')
     handle->url[strlen (handle->url) - 1] = '\0';
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
-  handle->gns = GNUNET_GNS_connect (cfg);
-  init_cont (handle);
+  if (GNUNET_NO ==
+      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
+  {
+    cleanup_handle (handle);
+    return GNUNET_NO;
+  }
+
 
   handle->timeout_task =
     GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
+  return GNUNET_YES;
 }
 
 
@@ -441,6 +420,7 @@ libgnunet_plugin_rest_gns_init (void *cls)
                    MHD_HTTP_METHOD_PUT,
                    MHD_HTTP_METHOD_DELETE,
                    MHD_HTTP_METHOD_OPTIONS);
+  gns = GNUNET_GNS_connect (cfg);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Gns REST API initialized\n"));
   return api;
@@ -460,6 +440,9 @@ libgnunet_plugin_rest_gns_done (void *cls)
   struct Plugin *plugin = api->cls;
 
   plugin->cfg = NULL;
+  if (NULL != gns)
+    GNUNET_GNS_disconnect (gns);
+
 
   GNUNET_free (allow_methods);
   GNUNET_free (api);
diff --git a/src/identity/plugin_rest_identity.c 
b/src/identity/plugin_rest_identity.c
index 02e42d03f..6859396d6 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -126,6 +126,26 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
  */
 static char *allow_methods;
 
+/**
+ * Ego list
+ */
+static struct EgoEntry *ego_head;
+
+/**
+ * Ego list
+ */
+static struct EgoEntry *ego_tail;
+
+/**
+ * The processing state
+ */
+static int state;
+
+/**
+ * Handle to Identity service.
+ */
+static struct GNUNET_IDENTITY_Handle *identity_handle;
+
 /**
  * @brief struct returned by the initialization function of the plugin
  */
@@ -185,27 +205,6 @@ struct RequestHandle
    */
   size_t data_size;
 
-
-  /**
-   * Ego list
-   */
-  struct EgoEntry *ego_head;
-
-  /**
-   * Ego list
-   */
-  struct EgoEntry *ego_tail;
-
-  /**
-   * The processing state
-   */
-  int state;
-
-  /**
-   * Handle to Identity service.
-   */
-  struct GNUNET_IDENTITY_Handle *identity_handle;
-
   /**
    * IDENTITY Operation
    */
@@ -260,8 +259,6 @@ static void
 cleanup_handle (void *cls)
 {
   struct RequestHandle *handle = cls;
-  struct EgoEntry *ego_entry;
-  struct EgoEntry *ego_tmp;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
   if (NULL != handle->timeout_task)
@@ -276,17 +273,6 @@ cleanup_handle (void *cls)
     GNUNET_free (handle->emsg);
   if (NULL != handle->name)
     GNUNET_free (handle->name);
-  if (NULL != handle->identity_handle)
-    GNUNET_IDENTITY_disconnect (handle->identity_handle);
-
-  for (ego_entry = handle->ego_head; NULL != ego_entry;)
-  {
-    ego_tmp = ego_entry;
-    ego_entry = ego_entry->next;
-    GNUNET_free (ego_tmp->identifier);
-    GNUNET_free (ego_tmp->keystring);
-    GNUNET_free (ego_tmp);
-  }
 
   GNUNET_free (handle);
 }
@@ -338,7 +324,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, 
char *name)
 
   if (NULL != pubkey)
   {
-    for (ego_entry = handle->ego_head; NULL != ego_entry;
+    for (ego_entry = ego_head; NULL != ego_entry;
          ego_entry = ego_entry->next)
     {
       if (0 != strcasecmp (pubkey, ego_entry->keystring))
@@ -348,7 +334,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, 
char *name)
   }
   if (NULL != name)
   {
-    for (ego_entry = handle->ego_head; NULL != ego_entry;
+    for (ego_entry = ego_head; NULL != ego_entry;
          ego_entry = ego_entry->next)
     {
       if (0 != strcasecmp (name, ego_entry->identifier))
@@ -438,7 +424,7 @@ ego_get_subsystem (struct GNUNET_REST_RequestHandle 
*con_handle,
   // requested default identity of subsystem
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsystem);
 
-  handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
+  handle->op = GNUNET_IDENTITY_get (identity_handle,
                                     subsystem,
                                     &ego_get_for_subsystem,
                                     handle);
@@ -476,7 +462,7 @@ ego_get_all (struct GNUNET_REST_RequestHandle *con_handle,
 
   json_root = json_array ();
   // Return ego/egos
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
   {
     json_ego = json_object ();
@@ -766,7 +752,7 @@ ego_edit (struct RequestHandle *handle, struct EgoEntry 
*ego_entry)
     json_decref (data_js);
     return;
   }
-  handle->op = GNUNET_IDENTITY_rename (handle->identity_handle,
+  handle->op = GNUNET_IDENTITY_rename (identity_handle,
                                        ego_entry->identifier,
                                        newname,
                                        &do_finished,
@@ -956,7 +942,7 @@ ego_edit_subsystem (struct GNUNET_REST_RequestHandle 
*con_handle,
   }
 
   handle->response_code = MHD_HTTP_NO_CONTENT;
-  handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
+  handle->op = GNUNET_IDENTITY_set (identity_handle,
                                     newsubsys,
                                     ego_entry->ego,
                                     &do_finished,
@@ -1047,7 +1033,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle,
     return;
   }
   GNUNET_STRINGS_utf8_tolower (egoname, egoname);
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
   {
     if (0 == strcasecmp (egoname, ego_entry->identifier))
@@ -1073,7 +1059,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle,
     pk_ptr = NULL;
   json_decref (data_js);
   handle->response_code = MHD_HTTP_CREATED;
-  handle->op = GNUNET_IDENTITY_create (handle->identity_handle,
+  handle->op = GNUNET_IDENTITY_create (identity_handle,
                                        handle->name,
                                        pk_ptr,
                                        &do_finished_create,
@@ -1118,7 +1104,7 @@ ego_delete_pubkey (struct GNUNET_REST_RequestHandle 
*con_handle,
   }
 
   handle->response_code = MHD_HTTP_NO_CONTENT;
-  handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
+  handle->op = GNUNET_IDENTITY_delete (identity_handle,
                                        ego_entry->identifier,
                                        &do_finished,
                                        handle);
@@ -1162,7 +1148,7 @@ ego_delete_name (struct GNUNET_REST_RequestHandle 
*con_handle,
   }
 
   handle->response_code = MHD_HTTP_NO_CONTENT;
-  handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
+  handle->op = GNUNET_IDENTITY_delete (identity_handle,
                                        ego_entry->identifier,
                                        &do_finished,
                                        handle);
@@ -1193,144 +1179,78 @@ options_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
 }
 
 
-/**
- * Handle rest request
- *
- * @param handle the request handle
- */
-static void
-init_cont (struct RequestHandle *handle)
-{
-  struct GNUNET_REST_RequestHandlerError err;
-  static const struct GNUNET_REST_RequestHandler handlers[] =
-  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all },
-    { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY,
-      &ego_get_pubkey },
-    { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name },
-    { MHD_HTTP_METHOD_GET,
-      GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM,
-      &ego_get_subsystem },
-    { MHD_HTTP_METHOD_PUT,
-      GNUNET_REST_API_NS_IDENTITY_PUBKEY,
-      &ego_edit_pubkey },
-    { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name },
-    { MHD_HTTP_METHOD_PUT,
-      GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM,
-      &ego_edit_subsystem },
-    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create },
-    { MHD_HTTP_METHOD_DELETE,
-      GNUNET_REST_API_NS_IDENTITY_PUBKEY,
-      &ego_delete_pubkey },
-    { MHD_HTTP_METHOD_DELETE,
-      GNUNET_REST_API_NS_IDENTITY_NAME,
-      &ego_delete_name },
-    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
-    GNUNET_REST_HANDLER_END };
-
-  if (GNUNET_NO ==
-      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
-  {
-    handle->response_code = err.error_code;
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-  }
-}
-
-
-/**
- * If listing is enabled, prints information about the egos.
- *
- * This function is initially called for all egos and then again
- * whenever a ego's identifier changes or if it is deleted.  At the
- * end of the initial pass over all egos, the function is once called
- * with 'NULL' for 'ego'. That does NOT mean that the callback won't
- * be invoked in the future or that there was an error.
- *
- * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
- * this function is only called ONCE, and 'NULL' being passed in
- * 'ego' does indicate an error (i.e. name is taken or no default
- * value is known).  If 'ego' is non-NULL and if '*ctx'
- * is set in those callbacks, the value WILL be passed to a subsequent
- * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
- * that one was not NULL).
- *
- * When an identity is renamed, this function is called with the
- * (known) ego but the NEW identifier.
- *
- * When an identity is deleted, this function is called with the
- * (known) ego and "NULL" for the 'identifier'.  In this case,
- * the 'ego' is henceforth invalid (and the 'ctx' should also be
- * cleaned up).
- *
- * @param cls closure
- * @param ego ego handle
- * @param ctx context for application to store data for this ego
- *                 (during the lifetime of this process, initially NULL)
- * @param identifier identifier assigned by the user for this ego,
- *                   NULL if the user just deleted the ego and it
- *                   must thus no longer be used
- */
 static void
-init_egos (void *cls,
-           struct GNUNET_IDENTITY_Ego *ego,
-           void **ctx,
-           const char *identifier)
+list_ego (void *cls,
+          struct GNUNET_IDENTITY_Ego *ego,
+          void **ctx,
+          const char *identifier)
 {
-  struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
   struct GNUNET_CRYPTO_EcdsaPublicKey pk;
 
-  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
+  if ((NULL == ego) && (ID_REST_STATE_INIT == state))
   {
-    handle->state = ID_REST_STATE_POST_INIT;
-    init_cont (handle);
+    state = ID_REST_STATE_POST_INIT;
     return;
   }
-  if (ID_REST_STATE_INIT == handle->state)
+  if (ID_REST_STATE_INIT == state)
   {
     ego_entry = GNUNET_new (struct EgoEntry);
     GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
     ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
     ego_entry->ego = ego;
     ego_entry->identifier = GNUNET_strdup (identifier);
-    GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
-                                      handle->ego_tail,
+    GNUNET_CONTAINER_DLL_insert_tail (ego_head,
+                                      ego_tail,
                                       ego_entry);
-    return;
   }
-  // Check if ego exists
-  for (ego_entry = handle->ego_head; NULL != ego_entry;)
+  /* Ego renamed or added */
+  if (identifier != NULL)
   {
-    struct EgoEntry *tmp = ego_entry;
-    ego_entry = ego_entry->next;
-    if (ego != tmp->ego)
-      continue;
-    // Deleted
-    if (NULL == identifier)
+    for (ego_entry = ego_head; NULL != ego_entry;
+         ego_entry = ego_entry->next)
     {
-      GNUNET_CONTAINER_DLL_remove (handle->ego_head,
-                                   handle->ego_tail,
-                                   tmp);
-      GNUNET_free (tmp->keystring);
-      GNUNET_free (tmp->identifier);
-      GNUNET_free (tmp);
+      if (ego_entry->ego == ego)
+      {
+        /* Rename */
+        GNUNET_free (ego_entry->identifier);
+        ego_entry->identifier = GNUNET_strdup (identifier);
+        break;
+      }
     }
-    else
+    if (NULL == ego_entry)
     {
-      // Renamed
-      GNUNET_free (tmp->identifier);
-      tmp->identifier = GNUNET_strdup (identifier);
+      /* Add */
+      ego_entry = GNUNET_new (struct EgoEntry);
+      GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
+      ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
+      ego_entry->ego = ego;
+      ego_entry->identifier = GNUNET_strdup (identifier);
+      GNUNET_CONTAINER_DLL_insert_tail (ego_head,
+                                        ego_tail,
+                                        ego_entry);
     }
+  }
+  else
+  {
+    /* Delete */
+    for (ego_entry = ego_head; NULL != ego_entry;
+         ego_entry = ego_entry->next)
+    {
+      if (ego_entry->ego == ego)
+        break;
+    }
+    if (NULL == ego_entry)
+      return; /* Not found */
+
+    GNUNET_CONTAINER_DLL_remove (ego_head,
+                                 ego_tail,
+                                 ego_entry);
+    GNUNET_free (ego_entry->identifier);
+    GNUNET_free (ego_entry->keystring);
+    GNUNET_free (ego_entry);
     return;
   }
-  // New ego
-  ego_entry = GNUNET_new (struct EgoEntry);
-  GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
-  ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
-  ego_entry->ego = ego;
-  GNUNET_asprintf (&ego_entry->identifier, "%s", identifier);
-  GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
-                                    handle->ego_tail,
-                                    ego_entry);
 
 }
 
@@ -1346,12 +1266,38 @@ init_egos (void *cls,
  * @param proc_cls closure for callback function
  * @return GNUNET_OK if request accepted
  */
-static void
+static enum GNUNET_GenericReturnValue
 rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
                       GNUNET_REST_ResultProcessor proc,
                       void *proc_cls)
 {
   struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
+  struct GNUNET_REST_RequestHandlerError err;
+  static const struct GNUNET_REST_RequestHandler handlers[] =
+  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all },
+    { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY,
+      &ego_get_pubkey },
+    { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name },
+    { MHD_HTTP_METHOD_GET,
+      GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM,
+      &ego_get_subsystem },
+    { MHD_HTTP_METHOD_PUT,
+      GNUNET_REST_API_NS_IDENTITY_PUBKEY,
+      &ego_edit_pubkey },
+    { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name },
+    { MHD_HTTP_METHOD_PUT,
+      GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM,
+      &ego_edit_subsystem },
+    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create },
+    { MHD_HTTP_METHOD_DELETE,
+      GNUNET_REST_API_NS_IDENTITY_PUBKEY,
+      &ego_delete_pubkey },
+    { MHD_HTTP_METHOD_DELETE,
+      GNUNET_REST_API_NS_IDENTITY_NAME,
+      &ego_delete_name },
+    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
+    GNUNET_REST_HANDLER_END };
+
 
   handle->response_code = 0;
   handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -1365,13 +1311,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle 
*rest_handle,
   if (handle->url[strlen (handle->url) - 1] == '/')
     handle->url[strlen (handle->url) - 1] = '\0';
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
-
-  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &init_egos, handle);
+  if (GNUNET_NO ==
+      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
+  {
+    cleanup_handle (handle);
+    return GNUNET_NO;
+  }
 
   handle->timeout_task =
     GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle);
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
+  return GNUNET_YES;
 }
 
 
@@ -1403,6 +1353,7 @@ libgnunet_plugin_rest_identity_init (void *cls)
                    MHD_HTTP_METHOD_PUT,
                    MHD_HTTP_METHOD_DELETE,
                    MHD_HTTP_METHOD_OPTIONS);
+  identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity REST API initialized\n"));
   return api;
@@ -1420,8 +1371,21 @@ libgnunet_plugin_rest_identity_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;
+  struct EgoEntry *ego_entry;
+  struct EgoEntry *ego_tmp;
 
   plugin->cfg = NULL;
+  if (NULL != identity_handle)
+    GNUNET_IDENTITY_disconnect (identity_handle);
+
+  for (ego_entry = ego_head; NULL != ego_entry;)
+  {
+    ego_tmp = ego_entry;
+    ego_entry = ego_entry->next;
+    GNUNET_free (ego_tmp->identifier);
+    GNUNET_free (ego_tmp->keystring);
+    GNUNET_free (ego_tmp);
+  }
 
   GNUNET_free (allow_methods);
   GNUNET_free (api);
diff --git a/src/include/gnunet_rest_plugin.h b/src/include/gnunet_rest_plugin.h
index 770ba66f2..96454f66b 100644
--- a/src/include/gnunet_rest_plugin.h
+++ b/src/include/gnunet_rest_plugin.h
@@ -69,10 +69,12 @@ struct GNUNET_REST_Plugin
    * @param data_size the length of the data
    * @param proc the callback for result
    * @param proc_cls closure for callback
+   * @return GNUNET_YES if the request was processed
    */
-  void (*process_request) (struct GNUNET_REST_RequestHandle *handle,
-                           GNUNET_REST_ResultProcessor proc,
-                           void *proc_cls);
+  enum GNUNET_GenericReturnValue (*process_request)(
+    struct GNUNET_REST_RequestHandle *handle,
+    GNUNET_REST_ResultProcessor proc,
+    void *proc_cls);
 };
 
 
diff --git a/src/namestore/plugin_rest_namestore.c 
b/src/namestore/plugin_rest_namestore.c
index f1cbfb38b..c993518ea 100644
--- a/src/namestore/plugin_rest_namestore.c
+++ b/src/namestore/plugin_rest_namestore.c
@@ -84,6 +84,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
  */
 static char *allow_methods;
 
+/**
+ * Ego list
+ */
+static struct EgoEntry *ego_head;
+
+/**
+ * Ego list
+ */
+static struct EgoEntry *ego_tail;
+
+/**
+ * The processing state
+ */
+static int state;
+
+/**
+ * Handle to NAMESTORE
+ */
+static struct GNUNET_NAMESTORE_Handle *ns_handle;
+
+/**
+ * Handle to Identity service.
+ */
+static struct GNUNET_IDENTITY_Handle *identity_handle;
+
 /**
  * @brief struct returned by the initialization function of the plugin
  */
@@ -170,15 +195,6 @@ struct RequestHandle
    */
   json_t *resp_object;
 
-  /**
-   * The processing state
-   */
-  int state;
-
-  /**
-   * Handle to NAMESTORE
-   */
-  struct GNUNET_NAMESTORE_Handle *ns_handle;
 
   /**
    * Handle to NAMESTORE it
@@ -195,26 +211,11 @@ struct RequestHandle
    */
   struct EgoEntry *ego_entry;
 
-  /**
-   * Ego list
-   */
-  struct EgoEntry *ego_head;
-
-  /**
-   * Ego list
-   */
-  struct EgoEntry *ego_tail;
-
   /**
    * IDENTITY Operation
    */
   struct GNUNET_IDENTITY_Operation *op;
 
-  /**
-   * Handle to Identity service.
-   */
-  struct GNUNET_IDENTITY_Handle *identity_handle;
-
   /**
    * Rest connection
    */
@@ -264,8 +265,6 @@ static void
 cleanup_handle (void *cls)
 {
   struct RequestHandle *handle = cls;
-  struct EgoEntry *ego_entry;
-  struct EgoEntry *ego_tmp;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
   if (NULL != handle->timeout_task)
@@ -294,21 +293,6 @@ cleanup_handle (void *cls)
     GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it);
   if (NULL != handle->ns_qe)
     GNUNET_NAMESTORE_cancel (handle->ns_qe);
-  if (NULL != handle->identity_handle)
-    GNUNET_IDENTITY_disconnect (handle->identity_handle);
-  if (NULL != handle->ns_handle)
-  {
-    GNUNET_NAMESTORE_disconnect (handle->ns_handle);
-  }
-
-  for (ego_entry = handle->ego_head; NULL != ego_entry;)
-  {
-    ego_tmp = ego_entry;
-    ego_entry = ego_entry->next;
-    GNUNET_free (ego_tmp->identifier);
-    GNUNET_free (ego_tmp->keystring);
-    GNUNET_free (ego_tmp);
-  }
 
   if (NULL != handle->resp_object)
   {
@@ -368,7 +352,7 @@ get_egoentry_namestore (struct RequestHandle *handle, char 
*name)
   if (NULL == name)
     return NULL;
   tmp = strtok (copy, "/");
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
   {
     if (0 != strcasecmp (tmp, ego_entry->identifier))
@@ -647,7 +631,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
   if (1 >= strlen (labelname))
   {
     handle->list_it =
-      GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
+      GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
                                              handle->zone_pkey,
                                              &namestore_iteration_error,
                                              handle,
@@ -664,7 +648,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
     return;
   }
   handle->record_name = GNUNET_strdup (labelname + 1);
-  handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
+  handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
                                                    handle->zone_pkey,
                                                    handle->record_name,
                                                    &ns_lookup_error_cb,
@@ -699,7 +683,7 @@ ns_lookup_cb (void *cls,
   }
   for (j = 0; j < handle->rd_count; j++)
     rd_new[i + j] = handle->rd[j];
-  handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
+  handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
                                                   handle->zone_pkey,
                                                   handle->record_name,
                                                   i + j,
@@ -791,7 +775,7 @@ namestore_add_or_update (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
   handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
-  handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
+  handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
                                                    handle->zone_pkey,
                                                    handle->record_name,
                                                    &ns_lookup_error_cb,
@@ -892,7 +876,7 @@ namestore_delete (struct GNUNET_REST_RequestHandle 
*con_handle,
   }
 
   handle->record_name = GNUNET_strdup (labelname + 1);
-  handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
+  handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
                                                   handle->zone_pkey,
                                                   handle->record_name,
                                                   0,
@@ -932,90 +916,79 @@ options_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
 }
 
 
-/**
- * Handle rest request
- *
- * @param handle the request handle
- */
-static void
-init_cont (struct RequestHandle *handle)
-{
-  struct GNUNET_REST_RequestHandlerError err;
-  static const struct GNUNET_REST_RequestHandler handlers[] =
-  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get },
-    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add },
-    { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update },
-    { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete 
},
-    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont },
-    GNUNET_REST_HANDLER_END };
-
-  if (GNUNET_NO ==
-      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
-  {
-    handle->response_code = err.error_code;
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-  }
-}
-
-
-/**
- * This function is initially called for all egos and then again
- * whenever a ego's identifier changes or if it is deleted.  At the
- * end of the initial pass over all egos, the function is once called
- * with 'NULL' for 'ego'. That does NOT mean that the callback won't
- * be invoked in the future or that there was an error.
- *
- * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
- * this function is only called ONCE, and 'NULL' being passed in
- * 'ego' does indicate an error (i.e. name is taken or no default
- * value is known).  If 'ego' is non-NULL and if '*ctx'
- * is set in those callbacks, the value WILL be passed to a subsequent
- * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
- * that one was not NULL).
- *
- * When an identity is renamed, this function is called with the
- * (known) ego but the NEW identifier.
- *
- * When an identity is deleted, this function is called with the
- * (known) ego and "NULL" for the 'identifier'.  In this case,
- * the 'ego' is henceforth invalid (and the 'ctx' should also be
- * cleaned up).
- *
- * @param cls closure
- * @param ego ego handle
- * @param ctx context for application to store data for this ego
- *                 (during the lifetime of this process, initially NULL)
- * @param name identifier assigned by the user for this ego,
- *                   NULL if the user just deleted the ego and it
- *                   must thus no longer be used
- */
 static void
-id_connect_cb (void *cls,
-               struct GNUNET_IDENTITY_Ego *ego,
-               void **ctx,
-               const char *name)
+list_ego (void *cls,
+          struct GNUNET_IDENTITY_Ego *ego,
+          void **ctx,
+          const char *identifier)
 {
-  struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
   struct GNUNET_CRYPTO_EcdsaPublicKey pk;
 
-  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
+  if ((NULL == ego) && (ID_REST_STATE_INIT == state))
   {
-    handle->state = ID_REST_STATE_POST_INIT;
-    init_cont (handle);
+    state = ID_REST_STATE_POST_INIT;
     return;
   }
-  if (ID_REST_STATE_INIT == handle->state)
+  if (ID_REST_STATE_INIT == state)
   {
     ego_entry = GNUNET_new (struct EgoEntry);
     GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
     ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
     ego_entry->ego = ego;
-    GNUNET_asprintf (&ego_entry->identifier, "%s", name);
-    GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
-                                      handle->ego_tail,
+    ego_entry->identifier = GNUNET_strdup (identifier);
+    GNUNET_CONTAINER_DLL_insert_tail (ego_head,
+                                      ego_tail,
                                       ego_entry);
   }
+  /* Ego renamed or added */
+  if (identifier != NULL)
+  {
+    for (ego_entry = ego_head; NULL != ego_entry;
+         ego_entry = ego_entry->next)
+    {
+      if (ego_entry->ego == ego)
+      {
+        /* Rename */
+        GNUNET_free (ego_entry->identifier);
+        ego_entry->identifier = GNUNET_strdup (identifier);
+        break;
+      }
+    }
+    if (NULL == ego_entry)
+    {
+      /* Add */
+      ego_entry = GNUNET_new (struct EgoEntry);
+      GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
+      ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
+      ego_entry->ego = ego;
+      ego_entry->identifier = GNUNET_strdup (identifier);
+      GNUNET_CONTAINER_DLL_insert_tail (ego_head,
+                                        ego_tail,
+                                        ego_entry);
+    }
+  }
+  else
+  {
+    /* Delete */
+    for (ego_entry = ego_head; NULL != ego_entry;
+         ego_entry = ego_entry->next)
+    {
+      if (ego_entry->ego == ego)
+        break;
+    }
+    if (NULL == ego_entry)
+      return; /* Not found */
+
+    GNUNET_CONTAINER_DLL_remove (ego_head,
+                                 ego_tail,
+                                 ego_entry);
+    GNUNET_free (ego_entry->identifier);
+    GNUNET_free (ego_entry->keystring);
+    GNUNET_free (ego_entry);
+    return;
+  }
+
 }
 
 
@@ -1030,12 +1003,20 @@ id_connect_cb (void *cls,
  * @param proc_cls closure for callback function
  * @return GNUNET_OK if request accepted
  */
-static void
+static enum GNUNET_GenericReturnValue
 rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
                       GNUNET_REST_ResultProcessor proc,
                       void *proc_cls)
 {
   struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
+  struct GNUNET_REST_RequestHandlerError err;
+  static const struct GNUNET_REST_RequestHandler handlers[] =
+  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get },
+    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add },
+    { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update },
+    { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete 
},
+    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont },
+    GNUNET_REST_HANDLER_END };
 
   handle->response_code = 0;
   handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -1048,14 +1029,18 @@ rest_process_request (struct GNUNET_REST_RequestHandle 
*rest_handle,
   if (handle->url[strlen (handle->url) - 1] == '/')
     handle->url[strlen (handle->url) - 1] = '\0';
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
+  if (GNUNET_NO ==
+      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
+  {
+    cleanup_handle (handle);
+    return GNUNET_NO;
+  }
 
-  handle->ns_handle = GNUNET_NAMESTORE_connect (cfg);
-  handle->identity_handle =
-    GNUNET_IDENTITY_connect (cfg, &id_connect_cb, handle);
   handle->timeout_task =
     GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
+  return GNUNET_YES;
 }
 
 
@@ -1087,6 +1072,8 @@ libgnunet_plugin_rest_namestore_init (void *cls)
                    MHD_HTTP_METHOD_PUT,
                    MHD_HTTP_METHOD_DELETE,
                    MHD_HTTP_METHOD_OPTIONS);
+  ns_handle = GNUNET_NAMESTORE_connect (cfg);
+  identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n"));
   return api;
@@ -1104,8 +1091,23 @@ libgnunet_plugin_rest_namestore_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;
+  struct EgoEntry *ego_entry;
+  struct EgoEntry *ego_tmp;
 
   plugin->cfg = NULL;
+  if (NULL != identity_handle)
+    GNUNET_IDENTITY_disconnect (identity_handle);
+  if (NULL != ns_handle)
+    GNUNET_NAMESTORE_disconnect (ns_handle);
+
+  for (ego_entry = ego_head; NULL != ego_entry;)
+  {
+    ego_tmp = ego_entry;
+    ego_entry = ego_entry->next;
+    GNUNET_free (ego_tmp->identifier);
+    GNUNET_free (ego_tmp->keystring);
+    GNUNET_free (ego_tmp);
+  }
 
   GNUNET_free (allow_methods);
   GNUNET_free (api);
diff --git a/src/peerinfo-tool/plugin_rest_peerinfo.c 
b/src/peerinfo-tool/plugin_rest_peerinfo.c
index 1ab6d6f75..1d7461b1a 100644
--- a/src/peerinfo-tool/plugin_rest_peerinfo.c
+++ b/src/peerinfo-tool/plugin_rest_peerinfo.c
@@ -70,7 +70,12 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
 /**
  * HTTP methods allows for this plugin
  */
-static char*allow_methods;
+static char *allow_methods;
+
+/**
+ * Handle to PEERINFO
+ */
+static struct GNUNET_PEERINFO_Handle *peerinfo_handle;
 
 /**
  * @brief struct returned by the initialization function of the plugin
@@ -204,10 +209,6 @@ struct RequestHandle
    */
   struct GNUNET_PEERINFO_IteratorContext *list_it;
 
-  /**
-   * Handle to PEERINFO
-   */
-  struct GNUNET_PEERINFO_Handle *peerinfo_handle;
 
   /**
    * Rest connection
@@ -294,10 +295,10 @@ cleanup_handle (void *cls)
     GNUNET_PEERINFO_iterate_cancel (handle->list_it);
     handle->list_it = NULL;
   }
-  if (NULL != handle->peerinfo_handle)
+  if (NULL != peerinfo_handle)
   {
-    GNUNET_PEERINFO_disconnect (handle->peerinfo_handle);
-    handle->peerinfo_handle = NULL;
+    GNUNET_PEERINFO_disconnect (peerinfo_handle);
+    peerinfo_handle = NULL;
   }
 
   GNUNET_free (handle);
@@ -664,7 +665,7 @@ peerinfo_get (struct GNUNET_REST_RequestHandle *con_handle,
     // specific_peer = GNUNET_PEER_resolve2(peer_id);
   }
 
-  handle->list_it = GNUNET_PEERINFO_iterate (handle->peerinfo_handle,
+  handle->list_it = GNUNET_PEERINFO_iterate (peerinfo_handle,
                                              include_friend_only,
                                              specific_peer,
                                              &peerinfo_list_iteration,
@@ -698,32 +699,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
 }
 
 
-/**
- * Handle rest request
- *
- * @param handle the request handle
- */
-static void
-init_cont (struct RequestHandle *handle)
-{
-  struct GNUNET_REST_RequestHandlerError err;
-  static const struct GNUNET_REST_RequestHandler handlers[] = {
-    { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get },
-    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont },
-    GNUNET_REST_HANDLER_END
-  };
-
-  if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle,
-                                               handlers,
-                                               &err,
-                                               handle))
-  {
-    handle->response_code = err.error_code;
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-  }
-}
-
-
 /**
  * Function processing the REST call
  *
@@ -735,12 +710,18 @@ init_cont (struct RequestHandle *handle)
  * @param proc_cls closure for callback function
  * @return GNUNET_OK if request accepted
  */
-static void
+static enum GNUNET_GenericReturnValue
 rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
                       GNUNET_REST_ResultProcessor proc,
                       void *proc_cls)
 {
   struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
+  struct GNUNET_REST_RequestHandlerError err;
+  static const struct GNUNET_REST_RequestHandler handlers[] = {
+    { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get },
+    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont },
+    GNUNET_REST_HANDLER_END
+  };
 
   handle->response_code = 0;
   handle->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
@@ -753,14 +734,20 @@ rest_process_request (struct GNUNET_REST_RequestHandle 
*rest_handle,
   if (handle->url[strlen (handle->url) - 1] == '/')
     handle->url[strlen (handle->url) - 1] = '\0';
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
-  handle->peerinfo_handle = GNUNET_PEERINFO_connect (cfg);
-  init_cont (handle);
+  if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle,
+                                               handlers,
+                                               &err,
+                                               handle))
+  {
+    cleanup_handle (handle);
+    return GNUNET_NO;
+  }
   handle->timeout_task =
     GNUNET_SCHEDULER_add_delayed (handle->timeout,
                                   &do_error,
                                   handle);
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
+  return GNUNET_YES;
 }
 
 
@@ -792,6 +779,7 @@ libgnunet_plugin_rest_peerinfo_init (void *cls)
                    MHD_HTTP_METHOD_PUT,
                    MHD_HTTP_METHOD_DELETE,
                    MHD_HTTP_METHOD_OPTIONS);
+  peerinfo_handle = GNUNET_PEERINFO_connect (cfg);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               _ ("Peerinfo REST API initialized\n"));
diff --git a/src/reclaim/plugin_rest_openid_connect.c 
b/src/reclaim/plugin_rest_openid_connect.c
index eb602a08f..64782fb72 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -248,6 +248,36 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
  */
 static char *allow_methods;
 
+/**
+ * Ego list
+ */
+static struct EgoEntry *ego_head;
+
+/**
+ * Ego list
+ */
+static struct EgoEntry *ego_tail;
+
+/**
+ * The processing state
+ */
+static int state;
+
+/**
+ * Handle to Identity service.
+  */
+static struct GNUNET_IDENTITY_Handle *identity_handle;
+
+/**
+ * GNS handle
+ */
+static struct GNUNET_GNS_Handle *gns_handle;
+
+/**
+ * Identity Provider
+ */
+static struct GNUNET_RECLAIM_Handle *idp;
+
 /**
  * @brief struct returned by the initialization function of the plugin
  */
@@ -361,15 +391,6 @@ struct EgoEntry
 
 struct RequestHandle
 {
-  /**
-   * Ego list
-   */
-  struct EgoEntry *ego_head;
-
-  /**
-   * Ego list
-   */
-  struct EgoEntry *ego_tail;
 
   /**
    * Selected ego
@@ -386,40 +407,15 @@ struct RequestHandle
    */
   struct OIDC_Variables *oidc;
 
-  /**
-   * The processing state
-   */
-  int state;
-
-  /**
-   * Handle to Identity service.
-   */
-  struct GNUNET_IDENTITY_Handle *identity_handle;
-
-  /**
-   * Rest connection
-   */
-  struct GNUNET_REST_RequestHandle *rest_handle;
-
-  /**
-   * GNS handle
-   */
-  struct GNUNET_GNS_Handle *gns_handle;
-
   /**
    * GNS lookup op
    */
   struct GNUNET_GNS_LookupRequest *gns_op;
 
   /**
-   * Handle to NAMESTORE
-   */
-  struct GNUNET_NAMESTORE_Handle *namestore_handle;
-
-  /**
-   * Iterator for NAMESTORE
+   * Rest connection
    */
-  struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it;
+  struct GNUNET_REST_RequestHandle *rest_handle;
 
   /**
    * Attribute claim list for id_token
@@ -442,10 +438,6 @@ struct RequestHandle
    */
   struct GNUNET_IDENTITY_Operation *op;
 
-  /**
-   * Identity Provider
-   */
-  struct GNUNET_RECLAIM_Handle *idp;
 
   /**
    * Idp Operation
@@ -529,6 +521,7 @@ struct RequestHandle
   int response_code;
 };
 
+
 /**
  * Cleanup lookup handle
  * @param handle Handle to clean up
@@ -536,13 +529,10 @@ struct RequestHandle
 static void
 cleanup_handle (struct RequestHandle *handle)
 {
-  struct EgoEntry *ego_entry;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
   if (NULL != handle->timeout_task)
     GNUNET_SCHEDULER_cancel (handle->timeout_task);
-  if (NULL != handle->identity_handle)
-    GNUNET_IDENTITY_disconnect (handle->identity_handle);
   if (NULL != handle->attr_it)
     GNUNET_RECLAIM_get_attributes_stop (handle->attr_it);
   if (NULL != handle->attest_it)
@@ -551,8 +541,6 @@ cleanup_handle (struct RequestHandle *handle)
     GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it);
   if (NULL != handle->idp_op)
     GNUNET_RECLAIM_cancel (handle->idp_op);
-  if (NULL != handle->idp)
-    GNUNET_RECLAIM_disconnect (handle->idp);
   GNUNET_free (handle->url);
   GNUNET_free (handle->tld);
   GNUNET_free (handle->redirect_prefix);
@@ -561,11 +549,6 @@ cleanup_handle (struct RequestHandle *handle)
   GNUNET_free (handle->edesc);
   if (NULL != handle->gns_op)
     GNUNET_GNS_lookup_cancel (handle->gns_op);
-  if (NULL != handle->gns_handle)
-    GNUNET_GNS_disconnect (handle->gns_handle);
-
-  if (NULL != handle->namestore_handle)
-    GNUNET_NAMESTORE_disconnect (handle->namestore_handle);
   if (NULL != handle->oidc)
   {
     GNUNET_free (handle->oidc->client_id);
@@ -585,15 +568,6 @@ cleanup_handle (struct RequestHandle *handle)
   if (NULL!=handle->attests_list)
     GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list);
 
-  while (NULL != (ego_entry = handle->ego_head))
-  {
-    GNUNET_CONTAINER_DLL_remove (handle->ego_head,
-                                 handle->ego_tail,
-                                 ego_entry);
-    GNUNET_free (ego_entry->identifier);
-    GNUNET_free (ego_entry->keystring);
-    GNUNET_free (ego_entry);
-  }
   GNUNET_free (handle);
 }
 
@@ -993,7 +967,8 @@ oidc_ticket_issue_cb (void *cls, const struct 
GNUNET_RECLAIM_Ticket *ticket)
                      handle->redirect_prefix,
                      handle->tld,
                      handle->redirect_suffix,
-                     (NULL == strchr(handle->redirect_suffix, '?') ? "?" : 
"&"),
+                     (NULL == strchr (handle->redirect_suffix, '?') ? "?" :
+                      "&"),
                      handle->oidc->response_type,
                      code_string,
                      handle->oidc->state);
@@ -1003,7 +978,8 @@ oidc_ticket_issue_cb (void *cls, const struct 
GNUNET_RECLAIM_Ticket *ticket)
     GNUNET_asprintf (&redirect_uri,
                      "%s%s%s=%s&state=%s",
                      handle->oidc->redirect_uri,
-                     (NULL == strchr(handle->oidc->redirect_uri, '?') ? "?" : 
"&"),
+                     (NULL == strchr (handle->oidc->redirect_uri, '?') ? "?" :
+                      "&"),
                      handle->oidc->response_type,
                      code_string,
                      handle->oidc->state);
@@ -1082,7 +1058,7 @@ oidc_attest_collect_finished_cb (void *cls)
   handle->attest_it = NULL;
   merged_list = attribute_list_merge (handle->attr_idtoken_list,
                                       handle->attr_userinfo_list);
-  handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp,
+  handle->idp_op = GNUNET_RECLAIM_ticket_issue (idp,
                                                 &handle->priv_key,
                                                 &handle->oidc->client_pkey,
                                                 merged_list,
@@ -1149,7 +1125,7 @@ oidc_attr_collect_finished_cb (void *cls)
   }
   handle->attests_list = GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
   handle->attest_it =
-    GNUNET_RECLAIM_get_attestations_start (handle->idp,
+    GNUNET_RECLAIM_get_attestations_start (idp,
                                            &handle->priv_key,
                                            &oidc_iteration_error,
                                            handle,
@@ -1315,7 +1291,7 @@ code_redirect (void *cls)
         return;
       }
       // iterate over egos and compare their public key
-      for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
+      for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
            handle->ego_entry = handle->ego_entry->next)
       {
         GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey);
@@ -1323,13 +1299,12 @@ code_redirect (void *cls)
         {
           handle->priv_key =
             *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
-          handle->idp = GNUNET_RECLAIM_connect (cfg);
           handle->attr_idtoken_list =
             GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
           handle->attr_userinfo_list =
             GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
           handle->attr_it =
-            GNUNET_RECLAIM_get_attributes_start (handle->idp,
+            GNUNET_RECLAIM_get_attributes_start (idp,
                                                  &handle->priv_key,
                                                  &oidc_iteration_error,
                                                  handle,
@@ -1474,7 +1449,7 @@ client_redirect (void *cls)
 
   /* Lookup client redirect uri to verify request */
   handle->gns_op =
-    GNUNET_GNS_lookup (handle->gns_handle,
+    GNUNET_GNS_lookup (gns_handle,
                        GNUNET_GNS_EMPTY_LABEL_AT,
                        &handle->oidc->client_pkey,
                        GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT,
@@ -1700,14 +1675,14 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle 
*con_handle,
 
   // If we know this identity, translated the corresponding TLD
   // TODO: We might want to have a reverse lookup functionality for TLDs?
-  for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
+  for (tmp_ego = ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
   {
     priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
     GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &pkey);
     if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
     {
       handle->tld = GNUNET_strdup (tmp_ego->identifier);
-      handle->ego_entry = handle->ego_tail;
+      handle->ego_entry = ego_tail;
     }
   }
   handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
@@ -1790,6 +1765,7 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle,
   GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
 }
 
+
 static int
 parse_credentials_basic_auth (struct RequestHandle *handle,
                               char **client_id,
@@ -1847,8 +1823,8 @@ parse_credentials_basic_auth (struct RequestHandle 
*handle,
 
 static int
 parse_credentials_post_body (struct RequestHandle *handle,
-                              char **client_id,
-                              char **client_secret)
+                             char **client_id,
+                             char **client_secret)
 {
   struct GNUNET_HashCode cache_key;
   char *client_id_tmp;
@@ -1861,8 +1837,9 @@ parse_credentials_post_body (struct RequestHandle *handle,
                                                            ->url_param_map,
                                                            &cache_key))
     return GNUNET_SYSERR;
-  client_id_tmp = GNUNET_CONTAINER_multihashmap_get 
(handle->rest_handle->url_param_map,
-                                                     &cache_key);
+  client_id_tmp = GNUNET_CONTAINER_multihashmap_get (
+    handle->rest_handle->url_param_map,
+    &cache_key);
   if (NULL == client_id_tmp)
     return GNUNET_SYSERR;
   *client_id = strdup (client_id_tmp);
@@ -1896,13 +1873,16 @@ check_authorization (struct RequestHandle *handle,
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Received client credentials in HTTP AuthZ header\n");
-  } else if (GNUNET_OK == parse_credentials_post_body (handle,
-                                                       &received_cid,
-                                                       &received_cpw))
+  }
+  else if (GNUNET_OK == parse_credentials_post_body (handle,
+                                                     &received_cid,
+                                                     &received_cpw))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Received client credentials in POST body\n");
-  } else {
+  }
+  else
+  {
     handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
     handle->response_code = MHD_HTTP_UNAUTHORIZED;
     return GNUNET_SYSERR;
@@ -1931,7 +1911,7 @@ check_authorization (struct RequestHandle *handle,
     return GNUNET_SYSERR;
   }
   // check client_id
-  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
+  for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
        handle->ego_entry = handle->ego_entry->next)
   {
     if (0 == strcmp (handle->ego_entry->keystring, received_cid))
@@ -1963,7 +1943,7 @@ find_ego (struct RequestHandle *handle,
   struct EgoEntry *ego_entry;
   struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
 
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
   {
     GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
@@ -2321,14 +2301,13 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
 
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
   handle->oidc->response = json_object ();
   json_object_set_new (handle->oidc->response,
                        "sub",
                        json_string (iss_ego->keystring));
   privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego);
 
-  handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
+  handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp,
                                                   privkey,
                                                   ticket,
                                                   consume_ticket,
@@ -2337,36 +2316,6 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle 
*con_handle,
 }
 
 
-/**
- * Handle rest request
- *
- * @param handle the request handle
- */
-static void
-init_cont (struct RequestHandle *handle)
-{
-  struct GNUNET_REST_RequestHandlerError err;
-  static const struct GNUNET_REST_RequestHandler handlers[] =
-  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
-    { MHD_HTTP_METHOD_POST,
-      GNUNET_REST_API_NS_AUTHORIZE,
-      &authorize_endpoint },   // url-encoded
-    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
-    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
-    { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
-    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
-    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
-    GNUNET_REST_HANDLER_END };
-
-  if (GNUNET_NO ==
-      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
-  {
-    handle->response_code = err.error_code;
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-  }
-}
-
-
 /**
  * If listing is enabled, prints information about the egos.
  *
@@ -2406,18 +2355,16 @@ list_ego (void *cls,
           void **ctx,
           const char *identifier)
 {
-  struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
   struct GNUNET_CRYPTO_EcdsaPublicKey pk;
 
-  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
+  if ((NULL == ego) && (ID_REST_STATE_INIT == state))
   {
-    handle->state = ID_REST_STATE_POST_INIT;
-    init_cont (handle);
+    state = ID_REST_STATE_POST_INIT;
     return;
   }
   GNUNET_assert (NULL != ego);
-  if (ID_REST_STATE_INIT == handle->state)
+  if (ID_REST_STATE_INIT == state)
 
   {
     ego_entry = GNUNET_new (struct EgoEntry);
@@ -2425,15 +2372,15 @@ list_ego (void *cls,
     ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
     ego_entry->ego = ego;
     ego_entry->identifier = GNUNET_strdup (identifier);
-    GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
-                                      handle->ego_tail,
+    GNUNET_CONTAINER_DLL_insert_tail (ego_head,
+                                      ego_tail,
                                       ego_entry);
     return;
   }
   /* Ego renamed or added */
   if (identifier != NULL)
   {
-    for (ego_entry = handle->ego_head; NULL != ego_entry;
+    for (ego_entry = ego_head; NULL != ego_entry;
          ego_entry = ego_entry->next)
     {
       if (ego_entry->ego == ego)
@@ -2452,15 +2399,15 @@ list_ego (void *cls,
       ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
       ego_entry->ego = ego;
       ego_entry->identifier = GNUNET_strdup (identifier);
-      GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
-                                        handle->ego_tail,
+      GNUNET_CONTAINER_DLL_insert_tail (ego_head,
+                                        ego_tail,
                                         ego_entry);
     }
   }
   else
   {
     /* Delete */
-    for (ego_entry = handle->ego_head; NULL != ego_entry;
+    for (ego_entry = ego_head; NULL != ego_entry;
          ego_entry = ego_entry->next)
     {
       if (ego_entry->ego == ego)
@@ -2469,8 +2416,8 @@ list_ego (void *cls,
     if (NULL == ego_entry)
       return; /* Not found */
 
-    GNUNET_CONTAINER_DLL_remove (handle->ego_head,
-                                 handle->ego_tail,
+    GNUNET_CONTAINER_DLL_remove (ego_head,
+                                 ego_tail,
                                  ego_entry);
     GNUNET_free (ego_entry->identifier);
     GNUNET_free (ego_entry->keystring);
@@ -2480,12 +2427,23 @@ list_ego (void *cls,
 }
 
 
-static void
+static enum GNUNET_GenericReturnValue
 rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
                                GNUNET_REST_ResultProcessor proc,
                                void *proc_cls)
 {
   struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
+  struct GNUNET_REST_RequestHandlerError err;
+  static const struct GNUNET_REST_RequestHandler handlers[] =
+  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
+    { MHD_HTTP_METHOD_POST,
+      GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },   // url-encoded
+    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
+    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
+    { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
+    { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
+    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
+    GNUNET_REST_HANDLER_END };
 
   handle->oidc = GNUNET_new (struct OIDC_Variables);
   if (NULL == OIDC_cookie_jar_map)
@@ -2495,19 +2453,17 @@ rest_identity_process_request (struct 
GNUNET_REST_RequestHandle *rest_handle,
   handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
   handle->proc_cls = proc_cls;
   handle->proc = proc;
-  handle->state = ID_REST_STATE_INIT;
   handle->rest_handle = rest_handle;
-
   handle->url = GNUNET_strdup (rest_handle->url);
   if (handle->url[strlen (handle->url) - 1] == '/')
     handle->url[strlen (handle->url) - 1] = '\0';
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
-  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle);
-  handle->gns_handle = GNUNET_GNS_connect (cfg);
-  handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg);
+  if (GNUNET_NO ==
+      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
+    return GNUNET_NO;
+
   handle->timeout_task =
     GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
+  return GNUNET_YES;
 }
 
 
@@ -2532,6 +2488,11 @@ libgnunet_plugin_rest_openid_connect_init (void *cls)
   api->cls = &plugin;
   api->name = GNUNET_REST_API_NS_OIDC;
   api->process_request = &rest_identity_process_request;
+  identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
+  gns_handle = GNUNET_GNS_connect (cfg);
+  idp = GNUNET_RECLAIM_connect (cfg);
+
+  state = ID_REST_STATE_INIT;
   GNUNET_asprintf (&allow_methods,
                    "%s, %s, %s, %s, %s",
                    MHD_HTTP_METHOD_GET,
@@ -2557,6 +2518,7 @@ libgnunet_plugin_rest_openid_connect_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;
+  struct EgoEntry *ego_entry;
 
   plugin->cfg = NULL;
 
@@ -2573,6 +2535,21 @@ libgnunet_plugin_rest_openid_connect_done (void *cls)
 
   GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it);
   GNUNET_free (allow_methods);
+  if (NULL != gns_handle)
+    GNUNET_GNS_disconnect (gns_handle);
+  if (NULL != identity_handle)
+    GNUNET_IDENTITY_disconnect (identity_handle);
+  if (NULL != idp)
+    GNUNET_RECLAIM_disconnect (idp);
+  while (NULL != (ego_entry = ego_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (ego_head,
+                                 ego_tail,
+                                 ego_entry);
+    GNUNET_free (ego_entry->identifier);
+    GNUNET_free (ego_entry->keystring);
+    GNUNET_free (ego_entry);
+  }
   GNUNET_free (api);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "OpenID Connect REST plugin is finished\n");
diff --git a/src/reclaim/plugin_rest_reclaim.c 
b/src/reclaim/plugin_rest_reclaim.c
index 10ee2f801..eb442bc3b 100644
--- a/src/reclaim/plugin_rest_reclaim.c
+++ b/src/reclaim/plugin_rest_reclaim.c
@@ -87,6 +87,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
  */
 static char *allow_methods;
 
+/**
+ * Ego list
+ */
+static struct EgoEntry *ego_head;
+
+/**
+ * Ego list
+ */
+static struct EgoEntry *ego_tail;
+
+/**
+ * The processing state
+ */
+static int state;
+
+/**
+ * Handle to Identity service.
+ */
+static struct GNUNET_IDENTITY_Handle *identity_handle;
+
+/**
+ * Identity Provider
+ */
+static struct GNUNET_RECLAIM_Handle *idp;
+
 /**
  * @brief struct returned by the initialization function of the plugin
  */
@@ -129,15 +154,6 @@ struct EgoEntry
 
 struct RequestHandle
 {
-  /**
-   * Ego list
-   */
-  struct EgoEntry *ego_head;
-
-  /**
-   * Ego list
-   */
-  struct EgoEntry *ego_tail;
 
   /**
    * Selected ego
@@ -149,16 +165,6 @@ struct RequestHandle
    */
   struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key;
 
-  /**
-   * The processing state
-   */
-  int state;
-
-  /**
-   * Handle to Identity service.
-   */
-  struct GNUNET_IDENTITY_Handle *identity_handle;
-
   /**
    * Rest connection
    */
@@ -174,11 +180,6 @@ struct RequestHandle
    */
   struct GNUNET_IDENTITY_Operation *op;
 
-  /**
-   * Identity Provider
-   */
-  struct GNUNET_RECLAIM_Handle *idp;
-
   /**
    * Idp Operation
    */
@@ -194,7 +195,6 @@ struct RequestHandle
    */
   struct GNUNET_RECLAIM_AttestationIterator *attest_it;
 
-
   /**
    * Ticket iterator
    */
@@ -251,51 +251,31 @@ struct RequestHandle
  * @param handle Handle to clean up
  */
 static void
-cleanup_handle (struct RequestHandle *handle)
+cleanup_handle (void *cls)
 {
-  struct EgoEntry *ego_entry;
-  struct EgoEntry *ego_tmp;
+  struct RequestHandle *handle = cls;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
   if (NULL != handle->resp_object)
     json_decref (handle->resp_object);
   if (NULL != handle->timeout_task)
     GNUNET_SCHEDULER_cancel (handle->timeout_task);
-  if (NULL != handle->identity_handle)
-    GNUNET_IDENTITY_disconnect (handle->identity_handle);
   if (NULL != handle->attr_it)
     GNUNET_RECLAIM_get_attributes_stop (handle->attr_it);
   if (NULL != handle->attest_it)
     GNUNET_RECLAIM_get_attestations_stop (handle->attest_it);
   if (NULL != handle->ticket_it)
     GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it);
-  if (NULL != handle->idp)
-    GNUNET_RECLAIM_disconnect (handle->idp);
   if (NULL != handle->url)
     GNUNET_free (handle->url);
   if (NULL != handle->emsg)
     GNUNET_free (handle->emsg);
   if (NULL != handle->attr_list)
     GNUNET_RECLAIM_attribute_list_destroy (handle->attr_list);
-  for (ego_entry = handle->ego_head; NULL != ego_entry;)
-  {
-    ego_tmp = ego_entry;
-    ego_entry = ego_entry->next;
-    GNUNET_free (ego_tmp->identifier);
-    GNUNET_free (ego_tmp->keystring);
-    GNUNET_free (ego_tmp);
-  }
   GNUNET_free (handle);
 }
 
 
-static void
-cleanup_handle_delayed (void *cls)
-{
-  cleanup_handle (cls);
-}
-
-
 /**
  * Task run on error, sends error message.  Cleans up everything.
  *
@@ -316,7 +296,7 @@ do_error (void *cls)
   resp = GNUNET_REST_create_response (json_error);
   MHD_add_response_header (resp, "Content-Type", "application/json");
   handle->proc (handle->proc_cls, resp, handle->response_code);
-  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
   GNUNET_free (json_error);
 }
 
@@ -339,9 +319,7 @@ do_timeout (void *cls)
 static void
 collect_error_cb (void *cls)
 {
-  struct RequestHandle *handle = cls;
-
-  do_error (handle);
+  do_error (cls);
 }
 
 
@@ -359,7 +337,7 @@ finished_cont (void *cls, int32_t success, const char *emsg)
     return;
   }
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 
@@ -376,7 +354,7 @@ delete_finished_cb (void *cls, int32_t success, const char 
*emsg)
     return;
   }
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 
@@ -485,7 +463,7 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   identity = handle->url + strlen (
     GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1;
 
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
@@ -523,9 +501,8 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
    */
   if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id))
     GNUNET_RECLAIM_id_generate (&attribute->id);
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
   exp = GNUNET_TIME_UNIT_HOURS;
-  handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp,
+  handle->idp_op = GNUNET_RECLAIM_attestation_store (idp,
                                                      identity_priv,
                                                      attribute,
                                                      &exp,
@@ -644,7 +621,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   identity = handle->url + strlen (
     GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1;
 
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
@@ -659,8 +636,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
   priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
-  handle->attest_it = GNUNET_RECLAIM_get_attestations_start (handle->idp,
+  handle->attest_it = GNUNET_RECLAIM_get_attestations_start (idp,
                                                              priv_key,
                                                              &collect_error_cb,
                                                              handle,
@@ -713,7 +689,7 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
 
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
@@ -727,11 +703,10 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
   priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
   memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attestation));
   GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id));
   attr.name = "";
-  handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp,
+  handle->idp_op = GNUNET_RECLAIM_attestation_delete (idp,
                                                       priv_key,
                                                       &attr,
                                                       &delete_finished_cb,
@@ -768,7 +743,7 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   }
   identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
 
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
@@ -782,9 +757,8 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
   priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
   handle->ticket_it =
-    GNUNET_RECLAIM_ticket_iteration_start (handle->idp,
+    GNUNET_RECLAIM_ticket_iteration_start (idp,
                                            priv_key,
                                            &collect_error_cb,
                                            handle,
@@ -823,7 +797,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   }
   identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
 
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
@@ -862,9 +836,8 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
    */
   if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id))
     GNUNET_RECLAIM_id_generate (&attribute->id);
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
   exp = GNUNET_TIME_UNIT_HOURS;
-  handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
+  handle->idp_op = GNUNET_RECLAIM_attribute_store (idp,
                                                    identity_priv,
                                                    attribute,
                                                    &exp,
@@ -1012,7 +985,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   }
   identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
 
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
@@ -1027,8 +1000,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
   priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
-  handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
+  handle->attr_it = GNUNET_RECLAIM_get_attributes_start (idp,
                                                          priv_key,
                                                          &collect_error_cb,
                                                          handle,
@@ -1078,7 +1050,7 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
 
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
     if (0 == strcmp (identity, ego_entry->identifier))
       break;
@@ -1092,11 +1064,10 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
   priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
   memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attribute));
   GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id));
   attr.name = "";
-  handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp,
+  handle->idp_op = GNUNET_RECLAIM_attribute_delete (idp,
                                                     priv_key,
                                                     &attr,
                                                     &delete_finished_cb,
@@ -1152,7 +1123,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
     return;
   }
 
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
   {
     GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk);
@@ -1169,8 +1140,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   }
   identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
 
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
-  handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp,
+  handle->idp_op = GNUNET_RECLAIM_ticket_revoke (idp,
                                                  identity_priv,
                                                  ticket,
                                                  &finished_cont,
@@ -1256,7 +1226,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
     json_decref (data_json);
     return;
   }
-  for (ego_entry = handle->ego_head; NULL != ego_entry;
+  for (ego_entry = ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
   {
     GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk);
@@ -1273,8 +1243,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   }
   identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
   handle->resp_object = json_object ();
-  handle->idp = GNUNET_RECLAIM_connect (cfg);
-  handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
+  handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp,
                                                   identity_priv,
                                                   ticket,
                                                   &consume_cont,
@@ -1307,55 +1276,6 @@ options_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
 }
 
 
-/**
- * Handle rest request
- *
- * @param handle the request handle
- */
-static void
-init_cont (struct RequestHandle *handle)
-{
-  struct GNUNET_REST_RequestHandlerError err;
-  static const struct GNUNET_REST_RequestHandler handlers[] =
-  { { MHD_HTTP_METHOD_GET,
-      GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
-      &list_attribute_cont },
-    { MHD_HTTP_METHOD_POST,
-      GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
-      &add_attribute_cont },
-    { MHD_HTTP_METHOD_DELETE,
-      GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
-      &delete_attribute_cont },
-    { MHD_HTTP_METHOD_GET,
-      GNUNET_REST_API_NS_RECLAIM_ATTESTATION,
-      &list_attestation_cont },
-    { MHD_HTTP_METHOD_POST,
-      GNUNET_REST_API_NS_RECLAIM_ATTESTATION,
-      &add_attestation_cont },
-    { MHD_HTTP_METHOD_DELETE,
-      GNUNET_REST_API_NS_RECLAIM_ATTESTATION,
-      &delete_attestation_cont },
-    { MHD_HTTP_METHOD_GET,
-      GNUNET_REST_API_NS_IDENTITY_TICKETS,
-      &list_tickets_cont },
-    { MHD_HTTP_METHOD_POST,
-      GNUNET_REST_API_NS_IDENTITY_REVOKE,
-      &revoke_ticket_cont },
-    { MHD_HTTP_METHOD_POST,
-      GNUNET_REST_API_NS_IDENTITY_CONSUME,
-      &consume_ticket_cont },
-    { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont },
-    GNUNET_REST_HANDLER_END };
-
-  if (GNUNET_NO ==
-      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
-  {
-    handle->response_code = err.error_code;
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-  }
-}
-
-
 /**
  * If listing is enabled, prints information about the egos.
  *
@@ -1395,52 +1315,126 @@ list_ego (void *cls,
           void **ctx,
           const char *identifier)
 {
-  struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
   struct GNUNET_CRYPTO_EcdsaPublicKey pk;
 
-  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
+  if ((NULL == ego) && (ID_REST_STATE_INIT == state))
   {
-    handle->state = ID_REST_STATE_POST_INIT;
-    init_cont (handle);
+    state = ID_REST_STATE_POST_INIT;
     return;
   }
-  if (ID_REST_STATE_INIT == handle->state)
+  if (ID_REST_STATE_INIT == state)
   {
     ego_entry = GNUNET_new (struct EgoEntry);
     GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
     ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
     ego_entry->ego = ego;
     ego_entry->identifier = GNUNET_strdup (identifier);
-    GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
-                                      handle->ego_tail,
+    GNUNET_CONTAINER_DLL_insert_tail (ego_head,
+                                      ego_tail,
                                       ego_entry);
   }
+  /* Ego renamed or added */
+  if (identifier != NULL)
+  {
+    for (ego_entry = ego_head; NULL != ego_entry;
+         ego_entry = ego_entry->next)
+    {
+      if (ego_entry->ego == ego)
+      {
+        /* Rename */
+        GNUNET_free (ego_entry->identifier);
+        ego_entry->identifier = GNUNET_strdup (identifier);
+        break;
+      }
+    }
+    if (NULL == ego_entry)
+    {
+      /* Add */
+      ego_entry = GNUNET_new (struct EgoEntry);
+      GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
+      ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
+      ego_entry->ego = ego;
+      ego_entry->identifier = GNUNET_strdup (identifier);
+      GNUNET_CONTAINER_DLL_insert_tail (ego_head,
+                                        ego_tail,
+                                        ego_entry);
+    }
+  }
+  else
+  {
+    /* Delete */
+    for (ego_entry = ego_head; NULL != ego_entry;
+         ego_entry = ego_entry->next)
+    {
+      if (ego_entry->ego == ego)
+        break;
+    }
+    if (NULL == ego_entry)
+      return; /* Not found */
+
+    GNUNET_CONTAINER_DLL_remove (ego_head,
+                                 ego_tail,
+                                 ego_entry);
+    GNUNET_free (ego_entry->identifier);
+    GNUNET_free (ego_entry->keystring);
+    GNUNET_free (ego_entry);
+    return;
+  }
+
 }
 
 
-static void
+static enum GNUNET_GenericReturnValue
 rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
                                GNUNET_REST_ResultProcessor proc,
                                void *proc_cls)
 {
   struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
+  struct GNUNET_REST_RequestHandlerError err;
+  static const struct GNUNET_REST_RequestHandler handlers[] =
+  { { MHD_HTTP_METHOD_GET,
+      GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont },
+  { MHD_HTTP_METHOD_POST,
+    GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont },
+  { MHD_HTTP_METHOD_DELETE,
+    GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &delete_attribute_cont },
+  { MHD_HTTP_METHOD_GET,
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &list_attestation_cont },
+  { MHD_HTTP_METHOD_POST,
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &add_attestation_cont },
+  { MHD_HTTP_METHOD_DELETE,
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &delete_attestation_cont },
+  { MHD_HTTP_METHOD_GET,
+    GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont },
+  { MHD_HTTP_METHOD_POST,
+    GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont },
+  { MHD_HTTP_METHOD_POST,
+    GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont },
+  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont },
+  GNUNET_REST_HANDLER_END
+  };
 
   handle->response_code = 0;
   handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
   handle->proc_cls = proc_cls;
   handle->proc = proc;
-  handle->state = ID_REST_STATE_INIT;
+  state = ID_REST_STATE_INIT;
   handle->rest_handle = rest_handle;
 
   handle->url = GNUNET_strdup (rest_handle->url);
   if (handle->url[strlen (handle->url) - 1] == '/')
     handle->url[strlen (handle->url) - 1] = '\0';
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
-  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle);
+  if (GNUNET_NO ==
+      GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
+  {
+    cleanup_handle (handle);
+    return GNUNET_NO;
+  }
+
   handle->timeout_task =
     GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
+  return GNUNET_YES;
 }
 
 
@@ -1472,7 +1466,8 @@ libgnunet_plugin_rest_reclaim_init (void *cls)
                    MHD_HTTP_METHOD_PUT,
                    MHD_HTTP_METHOD_DELETE,
                    MHD_HTTP_METHOD_OPTIONS);
-
+  identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
+  idp = GNUNET_RECLAIM_connect (cfg);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               _ ("Identity Provider REST API initialized\n"));
   return api;
@@ -1490,8 +1485,22 @@ libgnunet_plugin_rest_reclaim_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;
+  struct EgoEntry *ego_entry;
+  struct EgoEntry *ego_tmp;
 
   plugin->cfg = NULL;
+  if (NULL != idp)
+    GNUNET_RECLAIM_disconnect (idp);
+  if (NULL != identity_handle)
+    GNUNET_IDENTITY_disconnect (identity_handle);
+  for (ego_entry = ego_head; NULL != ego_entry;)
+  {
+    ego_tmp = ego_entry;
+    ego_entry = ego_entry->next;
+    GNUNET_free (ego_tmp->identifier);
+    GNUNET_free (ego_tmp->keystring);
+    GNUNET_free (ego_tmp);
+  }
 
   GNUNET_free (allow_methods);
   GNUNET_free (api);
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c
index 519a27515..44d4f345e 100644
--- a/src/rest/gnunet-rest-server.c
+++ b/src/rest/gnunet-rest-server.c
@@ -114,11 +114,6 @@ static struct MHD_Response *failure_response;
  */
 static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
-/**
- * Map of loaded plugins.
- */
-static struct GNUNET_CONTAINER_MultiHashMap *plugin_map;
-
 /**
  * Echo request Origin in CORS
  */
@@ -139,6 +134,38 @@ static char *allow_headers;
  */
 static char *allow_credentials;
 
+/**
+ * Plugin list head
+ */
+static struct PluginListEntry *plugins_head;
+
+/**
+ * Plugin list tail
+ */
+static struct PluginListEntry *plugins_tail;
+
+/**
+ * A plugin list entry
+ */
+struct PluginListEntry
+{
+  /* DLL */
+  struct PluginListEntry *next;
+
+  /* DLL */
+  struct PluginListEntry *prev;
+
+  /**
+   * libname (to cleanup)
+   */
+  char *libname;
+
+  /**
+   * The plugin
+   */
+  struct GNUNET_REST_Plugin *plugin;
+};
+
 /**
  * MHD Connection handle
  */
@@ -148,8 +175,6 @@ struct MhdConnectionHandle
 
   struct MHD_Response *response;
 
-  struct GNUNET_REST_Plugin *plugin;
-
   struct GNUNET_REST_RequestHandle *data_handle;
 
   struct MHD_PostProcessor *pp;
@@ -322,15 +347,15 @@ post_data_iter (void *cls,
 
   GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
   val = GNUNET_CONTAINER_multihashmap_get (handle->url_param_map,
-                  &hkey);
+                                           &hkey);
   if (NULL == val)
   {
     val = GNUNET_malloc (65536);
     if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (
-        handle->url_param_map,
-        &hkey,
-        val,
-        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
+          handle->url_param_map,
+          &hkey,
+          val,
+          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "Could not add url param '%s'\n",
@@ -378,39 +403,21 @@ create_response (void *cls,
                  size_t *upload_data_size,
                  void **con_cls)
 {
-  char *plugin_name;
   char *origin;
   struct GNUNET_HashCode key;
   struct MhdConnectionHandle *con_handle;
   struct GNUNET_REST_RequestHandle *rest_conndata_handle;
+  struct PluginListEntry *ple;
 
   con_handle = *con_cls;
 
   if (NULL == *con_cls)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url);
-    char tmp_url[strlen (url) + 1];
-    strcpy (tmp_url, url);
     con_handle = GNUNET_new (struct MhdConnectionHandle);
     con_handle->con = con;
     con_handle->state = GN_REST_STATE_INIT;
     *con_cls = con_handle;
-
-    plugin_name = strtok (tmp_url, "/");
-
-    if (NULL != plugin_name)
-    {
-      GNUNET_CRYPTO_hash (plugin_name, strlen (plugin_name), &key);
-
-      con_handle->plugin = GNUNET_CONTAINER_multihashmap_get (plugin_map, 
&key);
-    }
-    if (NULL == con_handle->plugin)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing response with MHD\n");
-      GNUNET_free (con_handle);
-      return MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response);
-    }
-
     return MHD_YES;
   }
   if (GN_REST_STATE_INIT == con_handle->state)
@@ -445,9 +452,18 @@ create_response (void *cls,
     MHD_destroy_post_processor (con_handle->pp);
 
     con_handle->state = GN_REST_STATE_PROCESSING;
-    con_handle->plugin->process_request (rest_conndata_handle,
-                                         &plugin_callback,
-                                         con_handle);
+    for (ple = plugins_head; NULL != ple; ple = ple->next)
+    {
+      if (GNUNET_YES == ple->plugin->process_request (rest_conndata_handle,
+                                                      &plugin_callback,
+                                                      con_handle))
+        break; /* Request handled */
+    }
+    if (NULL == ple)
+    {
+      /** Request not handled **/
+      MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response);
+    }
     *upload_data_size = 0;
     run_mhd_now ();
     return MHD_YES;
@@ -732,6 +748,18 @@ do_accept (void *cls)
 static void
 do_shutdown (void *cls)
 {
+  struct PluginListEntry *ple;
+
+  while (NULL != plugins_head)
+  {
+    ple = plugins_head;
+    GNUNET_CONTAINER_DLL_remove (plugins_head,
+                                 plugins_tail,
+                                 ple);
+    GNUNET_PLUGIN_unload (ple->libname, NULL);
+    GNUNET_free (ple->libname);
+    GNUNET_free (ple);
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
   kill_httpd ();
   GNUNET_free (allow_credentials);
@@ -820,7 +848,7 @@ static void
 load_plugin (void *cls, const char *libname, void *lib_ret)
 {
   struct GNUNET_REST_Plugin *plugin = lib_ret;
-  struct GNUNET_HashCode key;
+  struct PluginListEntry *ple;
 
   if (NULL == lib_ret)
   {
@@ -831,18 +859,12 @@ load_plugin (void *cls, const char *libname, void 
*lib_ret)
   }
   GNUNET_assert (1 < strlen (plugin->name));
   GNUNET_assert ('/' == *plugin->name);
-  GNUNET_CRYPTO_hash (plugin->name + 1, strlen (plugin->name + 1), &key);
-  if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (
-        plugin_map,
-        &key,
-        plugin,
-        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Could not load add plugin `%s'\n",
-                libname);
-    return;
-  }
+  ple = GNUNET_new (struct PluginListEntry);
+  ple->libname = GNUNET_strdup (libname);
+  ple->plugin = plugin;
+  GNUNET_CONTAINER_DLL_insert (plugins_head,
+                               plugins_tail,
+                               ple);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname);
 }
 
@@ -864,8 +886,8 @@ run (void *cls,
   char *addr_str;
 
   cfg = c;
-  plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
-
+  plugins_head = NULL;
+  plugins_tail = NULL;
   /* Get port to bind to */
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port))
diff --git a/src/rest/plugin_rest_config.c b/src/rest/plugin_rest_config.c
index 43dea1b9f..d9ae57acd 100644
--- a/src/rest/plugin_rest_config.c
+++ b/src/rest/plugin_rest_config.c
@@ -347,7 +347,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
  * @param proc_cls closure for @a proc
  * @return #GNUNET_OK if request accepted
  */
-static void
+static enum GNUNET_GenericReturnValue
 rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
                              GNUNET_REST_ResultProcessor proc,
                              void *proc_cls)
@@ -371,9 +371,10 @@ rest_config_process_request (struct 
GNUNET_REST_RequestHandle *conndata_handle,
   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);
+    cleanup_handle (handle);
+    return GNUNET_NO;
   }
+  return GNUNET_YES;
 }
 
 
diff --git a/src/rest/plugin_rest_copying.c b/src/rest/plugin_rest_copying.c
index e601e505e..1649da3bb 100644
--- a/src/rest/plugin_rest_copying.c
+++ b/src/rest/plugin_rest_copying.c
@@ -81,24 +81,6 @@ cleanup_handle (struct RequestHandle *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);
-}
-
-
 /**
  * Handle rest request
  *
@@ -155,7 +137,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
  * @param proc_cls closure for @a proc
  * @return #GNUNET_OK if request accepted
  */
-static void
+static enum GNUNET_GenericReturnValue
 rest_copying_process_request (struct GNUNET_REST_RequestHandle 
*conndata_handle,
                               GNUNET_REST_ResultProcessor proc,
                               void *proc_cls)
@@ -172,14 +154,10 @@ rest_copying_process_request (struct 
GNUNET_REST_RequestHandle *conndata_handle,
   handle->proc = proc;
   handle->rest_handle = conndata_handle;
 
-  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);
-  }
+  return GNUNET_REST_handle_request (conndata_handle,
+                                     handlers,
+                                     &err,
+                                     handle);
 }
 
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]