gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet] branch master updated (389f49398 -> 08c410658)


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated (389f49398 -> 08c410658)
Date: Thu, 09 Aug 2018 23:57:57 +0200

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

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

    from 389f49398 minor formatting
     new 2c2e76228 -wip remove jsonapi from identity
     new 320c62a4f removed jsonapi structures
     new 4ab30f893 identity rest api - finished and added test_script
     new bd01c6363 -merge branch 'master' of ssh://gnunet.org/gnunet into 
gsoc2018/rest_api
     new f5aae6fb1 cleanup identity rest api, removed jsonapi includes
     new c1062075e -wip error gns
     new 09b6a814e -Merge branch 'master' of ssh://gnunet.org/gnunet into 
gsoc2018/rest_api
     new a006f8260 -wip fix gns
     new 688bd873c -Merge branch 'master' of ssh://gnunet.org/gnunet into 
gsoc2018/rest_api
     new 4e6cb0184 Identity+GNS Rest changed and fixed
     new db8c5cd31 -Merge branch 'master' of ssh://gnunet.org/gnunet into 
gsoc2018/rest_api
     new 6ede545d5 -Merge branch 'master' of ssh://gnunet.org/gnunet into 
gsoc2018/rest_api
     new 6efdf4094 -wip namestore
     new 8b89bb8b0 -Merge branch 'master' of ssh://gnunet.org/gnunet into 
gsoc2018/rest_api
     new 9009fb0aa -fix identity file
     new 4992eacc1 added name search
     new cc577a227 -wip namestore api, changed adding gnsrecord
     new f7ca27a73 change namestore, json handling; fix identity, gns
     new 7d1449573 fix makefiles
     new 83095b7bb -fix json and namestore
     new 791192b0d -wip peerinfo, async call work in progress
     new 894aaa280 fix lowercase identities
     new 36a899058 add peerinfo rest api
     new dc1c69e31 Identity REST API finished
     new 741916af1 GNS REST API finished
     new 65f9785e7 fix gns and identity test script
     new 9eb2df340 -wip namestore
     new 0d2399030 Namestore Rest API finished
     new 995c8c9ce -fix added timeout for gns Rest plugin
     new cffad0ad3 Peerinfo Rest API finished
     new e083dd6ae -Merge branch 'master' into gsoc2018/rest_api
     new 1ad7b6983 style
     new 08c410658 Merge branch 'gsoc2018/rest_api'

The 75 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/gns/plugin_rest_gns.c                   |  674 +++++---------
 src/gns/test_plugin_rest_gns.sh             |   50 ++
 src/gnsrecord/gnsrecord.c                   |    3 +-
 src/identity/Makefile.am                    |    2 -
 src/identity/plugin_rest_identity.c         | 1057 +++++++++++-----------
 src/identity/test_plugin_rest_identity.sh   |  159 ++++
 src/include/gnunet_json_lib.h               |   23 +-
 src/json/Makefile.am                        |    4 +-
 src/json/json_generator.c                   |   35 +
 src/json/json_gnsrecord.c                   |  177 ++++
 src/namestore/Makefile.am                   |    4 +-
 src/namestore/plugin_rest_namestore.c       | 1276 ++++++++++++---------------
 src/namestore/test_plugin_rest_namestore.sh |  208 +++++
 src/peerinfo/Makefile.am                    |   22 +
 src/peerinfo/plugin_rest_peerinfo.c         |  801 +++++++++++++++++
 15 files changed, 2819 insertions(+), 1676 deletions(-)
 create mode 100755 src/gns/test_plugin_rest_gns.sh
 create mode 100755 src/identity/test_plugin_rest_identity.sh
 create mode 100644 src/json/json_gnsrecord.c
 create mode 100755 src/namestore/test_plugin_rest_namestore.sh
 create mode 100644 src/peerinfo/plugin_rest_peerinfo.c

diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c
index e76a5d116..fd2469577 100644
--- a/src/gns/plugin_rest_gns.c
+++ b/src/gns/plugin_rest_gns.c
@@ -11,42 +11,42 @@
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Affero General Public License for more details.
-  
+
    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */
 /**
- * @author Martin Schanzenbach
+ * @author Philippe Buschmann
  * @file gns/plugin_rest_gns.c
- * @brief GNUnet GNS REST plugin
- *
+ * @brief GNUnet Gns REST plugin
  */
 
 #include "platform.h"
 #include "gnunet_rest_plugin.h"
-#include <gnunet_dnsparser_lib.h>
-#include <gnunet_identity_service.h>
-#include <gnunet_gnsrecord_lib.h>
-#include <gnunet_namestore_service.h>
-#include <gnunet_gns_service.h>
-#include <gnunet_rest_lib.h>
-#include <gnunet_jsonapi_lib.h>
-#include <gnunet_jsonapi_util.h>
+#include "gnunet_rest_lib.h"
+#include "gnunet_json_lib.h"
+#include "gnunet_gnsrecord_lib.h"
+#include "gnunet_gns_service.h"
+#include "microhttpd.h"
 #include <jansson.h>
 
 #define GNUNET_REST_API_NS_GNS "/gns"
 
-#define GNUNET_REST_JSONAPI_GNS_RECORD_TYPE "record_type"
-
-#define GNUNET_REST_JSONAPI_GNS_TYPEINFO "gns_name"
 
-#define GNUNET_REST_JSONAPI_GNS_RECORD "records"
+#define GNUNET_REST_GNS_PARAM_NAME "name"
 
-#define GNUNET_REST_JSONAPI_GNS_EGO "ego"
+#define GNUNET_REST_GNS_PARAM_RECORD_TYPE "record_type"
+#define GNUNET_REST_GNS_ERROR_UNKNOWN "Unknown Error"
 
-#define GNUNET_REST_JSONAPI_GNS_PKEY "pkey"
+/**
+ * The configuration handle
+ */
+const struct GNUNET_CONFIGURATION_Handle *cfg;
 
-#define GNUNET_REST_JSONAPI_GNS_OPTIONS "options"
+/**
+ * HTTP methods allows for this plugin
+ */
+static char* allow_methods;
 
 /**
  * @brief struct returned by the initialization function of the plugin
@@ -56,54 +56,44 @@ struct Plugin
   const struct GNUNET_CONFIGURATION_Handle *cfg;
 };
 
-const struct GNUNET_CONFIGURATION_Handle *cfg;
 
-struct LookupHandle
+struct RequestHandle
 {
-  /**
-   * Handle to GNS service.
-   */
-  struct GNUNET_GNS_Handle *gns;
 
   /**
-   * Desired timeout for the lookup (default is no timeout).
+   * Connection to GNS
    */
-  struct GNUNET_TIME_Relative timeout;
+  struct GNUNET_GNS_Handle *gns;
 
   /**
-   * Handle to lookup request
+   * Active GNS lookup
    */
-  struct GNUNET_GNS_LookupRequest *lookup_request;
+  struct GNUNET_GNS_LookupWithTldRequest *gns_lookup;
 
   /**
-   * Handle to rest request
+   * Name to look up
    */
-  struct GNUNET_REST_RequestHandle *rest_handle;
+  char *name;
 
   /**
-   * Lookup an ego with the identity service.
+   * Record type to look up
    */
-  struct GNUNET_IDENTITY_EgoLookup *el;
+  int record_type;
 
   /**
-   * Handle for identity service.
+   * Rest connection
    */
-  struct GNUNET_IDENTITY_Handle *identity;
-
+  struct GNUNET_REST_RequestHandle *rest_handle;
+  
   /**
-   * Active operation on identity service.
+   * Desired timeout for the lookup (default is no timeout).
    */
-  struct GNUNET_IDENTITY_Operation *id_op;
+  struct GNUNET_TIME_Relative timeout;
 
   /**
    * ID of a task associated with the resolution process.
    */
-  struct GNUNET_SCHEDULER_Task * timeout_task;
-
-  /**
-   * The root of the received JSON or NULL
-   */
-  json_t *json_root;
+  struct GNUNET_SCHEDULER_Task *timeout_task;
 
   /**
    * The plugin result processor
@@ -116,49 +106,17 @@ struct LookupHandle
   void *proc_cls;
 
   /**
-   * The name to look up
-   */
-  char *name;
-
-  /**
-   * The ego to use
-   * In string representation from JSON
-   */
-  const char *ego_str;
-
-  /**
-   * The Pkey to use
-   * In string representation from JSON
-   */
-  const char *pkey_str;
-
-  /**
-   * The record type
+   * The url
    */
-  int type;
+  char *url;
 
   /**
-   * The public key of to use for lookup
+   * Error response message
    */
-  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
+  char *emsg;
 
   /**
-   * The public key to use for lookup
-   */
-  struct GNUNET_CRYPTO_EcdsaPublicKey pkeym;
-
-  /**
-   * The resolver options
-   */
-  enum GNUNET_GNS_LocalOptions options;
-
-  /**
-   * the shorten key
-   */
-  struct GNUNET_CRYPTO_EcdsaPrivateKey shorten_key;
-
-  /**
-   * HTTP response code
+   * Reponse code
    */
   int response_code;
 
@@ -166,39 +124,20 @@ struct LookupHandle
 
 
 /**
- * Cleanup lookup handle.
- *
+ * Cleanup lookup handle
  * @param handle Handle to clean up
  */
 static void
-cleanup_handle (struct LookupHandle *handle)
+cleanup_handle (void *cls)
 {
+  struct RequestHandle *handle = cls;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Cleaning up\n");
-  if (NULL != handle->json_root)
-    json_decref (handle->json_root);
 
-  if (NULL != handle->name)
-    GNUNET_free (handle->name);
-  if (NULL != handle->el)
-  {
-    GNUNET_IDENTITY_ego_lookup_cancel (handle->el);
-    handle->el = NULL;
-  }
-  if (NULL != handle->id_op)
-  {
-    GNUNET_IDENTITY_cancel (handle->id_op);
-    handle->id_op = NULL;
-  }
-  if (NULL != handle->lookup_request)
-  {
-    GNUNET_GNS_lookup_cancel (handle->lookup_request);
-    handle->lookup_request = NULL;
-  }
-  if (NULL != handle->identity)
+  if (NULL != handle->gns_lookup)
   {
-    GNUNET_IDENTITY_disconnect (handle->identity);
-    handle->identity = NULL;
+    GNUNET_GNS_lookup_with_tld_cancel (handle->gns_lookup);
+    handle->gns_lookup = NULL;
   }
   if (NULL != handle->gns)
   {
@@ -209,387 +148,181 @@ cleanup_handle (struct LookupHandle *handle)
   if (NULL != handle->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (handle->timeout_task);
+    handle->timeout_task = NULL;
   }
+  if (NULL != handle->url)
+    GNUNET_free (handle->url);
+  if (NULL != handle->name)
+    GNUNET_free (handle->name);
+  if (NULL != handle->emsg)
+    GNUNET_free (handle->emsg);
+  
   GNUNET_free (handle);
 }
 
 
 /**
- * Task run on shutdown.  Cleans up everything.
+ * Task run on errors.  Reports an error and cleans up everything.
  *
- * @param cls unused
- * @param tc scheduler context
+ * @param cls the `struct RequestHandle`
  */
 static void
 do_error (void *cls)
 {
-  struct LookupHandle *handle = cls;
+  struct RequestHandle *handle = cls;
   struct MHD_Response *resp;
+  json_t *json_error = json_object();
+  char *response;
 
-  resp = GNUNET_REST_create_response (NULL);
-  handle->proc (handle->proc_cls, resp, handle->response_code);
-  cleanup_handle (handle);
-}
-
+  if (NULL == handle->emsg)
+    handle->emsg = GNUNET_strdup(GNUNET_REST_GNS_ERROR_UNKNOWN);
 
-/**
- * Create json representation of a GNSRECORD
- *
- * @param rd the GNSRECORD_Data
- */
-static json_t *
-gnsrecord_to_json (const struct GNUNET_GNSRECORD_Data *rd)
-{
-  const char *typename;
-  char *string_val;
-  const char *exp_str;
-  json_t *record_obj;
-
-  typename = GNUNET_GNSRECORD_number_to_typename (rd->record_type);
-  string_val = GNUNET_GNSRECORD_value_to_string (rd->record_type,
-                                                 rd->data,
-                                                 rd->data_size);
+  json_object_set_new(json_error,"error", json_string(handle->emsg));
 
-  if (NULL == string_val)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Record of type %d malformed, skipping\n",
-                (int) rd->record_type);
-    return NULL;
-  }
-  record_obj = json_object ();
-  json_object_set_new (record_obj, "type", json_string (typename));
-  json_object_set_new (record_obj, "value", json_string (string_val));
-  GNUNET_free (string_val);
-
-  if (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd->flags)
-  {
-    struct GNUNET_TIME_Relative time_rel;
-    time_rel.rel_value_us = rd->expiration_time;
-    exp_str = GNUNET_STRINGS_relative_time_to_string (time_rel, 1);
-  }
-  else
-  {
-    struct GNUNET_TIME_Absolute time_abs;
-    time_abs.abs_value_us = rd->expiration_time;
-    exp_str = GNUNET_STRINGS_absolute_time_to_string (time_abs);
-  }
-  json_object_set_new (record_obj, "expiration_time", json_string (exp_str));
-
-  json_object_set_new (record_obj, "expired",
-                       json_boolean (GNUNET_YES == GNUNET_GNSRECORD_is_expired 
(rd)));
-  return record_obj;
-}
-
-
-static void
-do_cleanup (void *cls)
-{
-  struct LookupHandle *handle = cls;
-  cleanup_handle (handle);
+  if (0 == handle->response_code)
+    handle->response_code = MHD_HTTP_OK;
+  response = json_dumps (json_error, 0);
+  resp = GNUNET_REST_create_response (response);
+  handle->proc (handle->proc_cls, resp, handle->response_code);
+  json_decref(json_error);
+  GNUNET_free(response);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 
 /**
- * Function called with the result of a GNS lookup.
+ * Iterator called on obtained result for a GNS lookup.
  *
- * @param cls the 'const char *' name that was resolved
- * @param rd_count number of records returned
- * @param rd array of @a rd_count records with the results
+ * @param cls closure with the object
+ * @param was_gns #GNUNET_NO if name was not a GNS name
+ * @param rd_count number of records in @a rd
+ * @param rd the records in reply
  */
 static void
-process_lookup_result (void *cls, uint32_t rd_count,
-                       const struct GNUNET_GNSRECORD_Data *rd)
+handle_gns_response (void *cls,
+                     int was_gns,
+                     uint32_t rd_count,
+                     const struct GNUNET_GNSRECORD_Data *rd)
 {
-  struct LookupHandle *handle = cls;
+  struct RequestHandle *handle = cls;
   struct MHD_Response *resp;
-  struct GNUNET_JSONAPI_Document *json_document;
-  struct GNUNET_JSONAPI_Resource *json_resource;
-  uint32_t i;
-  char *result;
   json_t *result_array;
   json_t *record_obj;
+  char *result;
+
+  handle->gns_lookup = NULL;
+
+  if (GNUNET_NO == was_gns)
+  {
+    handle->emsg = GNUNET_strdup("Name not found in GNS");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
 
   result_array = json_array();
-  json_document = GNUNET_JSONAPI_document_new ();
-  json_resource = GNUNET_JSONAPI_resource_new 
(GNUNET_REST_JSONAPI_GNS_TYPEINFO, handle->name);
-  handle->lookup_request = NULL;
-  for (i=0; i<rd_count; i++)
+  for (uint32_t i=0;i<rd_count;i++)
   {
-    if ( (rd[i].record_type != handle->type) &&
-         (GNUNET_GNSRECORD_TYPE_ANY != handle->type) )
+    if ((rd[i].record_type != handle->record_type) &&
+        (GNUNET_GNSRECORD_TYPE_ANY != handle->record_type) )
+    {
       continue;
-    record_obj = gnsrecord_to_json (&(rd[i]));
+    }
+
+    record_obj = GNUNET_JSON_from_gns_record(NULL,&rd[i]);
     json_array_append (result_array, record_obj);
     json_decref (record_obj);
   }
-  GNUNET_JSONAPI_resource_add_attr (json_resource,
-                                         GNUNET_REST_JSONAPI_GNS_RECORD,
-                                         result_array);
-  GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
-  GNUNET_JSONAPI_document_serialize (json_document, &result);
+
+  result = json_dumps(result_array, 0);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result);
-  json_decref (result_array);
-  GNUNET_JSONAPI_document_delete (json_document);
   resp = GNUNET_REST_create_response (result);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
   GNUNET_free (result);
-  GNUNET_SCHEDULER_add_now (&do_cleanup, handle);
+  json_decref (result_array);
+  GNUNET_SCHEDULER_add_now(&cleanup_handle, handle);
 }
 
 
 /**
- * Perform the actual resolution, starting with the zone
- * identified by the given public key and the shorten zone.
+ * Handle gns GET request
  *
- * @param pkey public key to use for the zone, can be NULL
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
  */
-static void
-lookup_with_public_key (struct LookupHandle *handle)
+void
+get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
+              const char* url,
+              void *cls)
 {
-  if (UINT32_MAX == handle->type)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Invalid typename specified, assuming `ANY'\n"));
-    handle->type = GNUNET_GNSRECORD_TYPE_ANY;
-  }
-  if (NULL != handle->name)
-  {
-    handle->lookup_request = GNUNET_GNS_lookup (handle->gns,
-                                                handle->name,
-                                                &handle->pkey,
-                                                handle->type,
-                                                handle->options,
-                                                &process_lookup_result,
-                                                handle);
-  }
-  else
+  struct RequestHandle *handle = cls;
+  struct GNUNET_HashCode key;
+  char *record_type;
+  char *name;
+
+  GNUNET_CRYPTO_hash (GNUNET_REST_GNS_PARAM_NAME,
+                      strlen (GNUNET_REST_GNS_PARAM_NAME),
+                      &key);
+  if ( GNUNET_NO
+       == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                  &key))
   {
+    handle->emsg = GNUNET_strdup("Parameter name is missing");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-}
-
-
-/**
- * Method called to with the ego we are to use for the lookup,
- * when the ego is determined by a name.
- *
- * @param cls closure (NULL, unused)
- * @param ego ego handle, NULL if not found
- */
-static void
-identity_zone_cb (void *cls,
-                  const struct GNUNET_IDENTITY_Ego *ego)
-{
-  struct LookupHandle *handle = cls;
-
-  handle->el = NULL;
-  if (NULL == ego)
+  name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,&key);
+  if(0 >= strlen (name))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Ego for not found, cannot perform lookup.\n"));
+    handle->emsg = GNUNET_strdup("Length of parameter name is zero");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  else
-  {
-    GNUNET_IDENTITY_ego_get_public_key (ego, &handle->pkey);
-    lookup_with_public_key (handle);
-  }
-  json_decref(handle->json_root);
-}
-
+  handle->name = GNUNET_strdup(name);
 
-/**
- * Method called to with the ego we are to use for the lookup,
- * when the ego is the one for the default master zone.
- *
- * @param cls closure (NULL, unused)
- * @param ego ego handle, NULL if not found
- * @param ctx context for application to store data for this ego
- *                 (during the lifetime of this process, initially NULL)
- * @param name name 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
-identity_master_cb (void *cls,
-                    struct GNUNET_IDENTITY_Ego *ego,
-                    void **ctx,
-                    const char *name)
-{
-  const char *dot;
-  struct LookupHandle *handle = cls;
-
-  handle->id_op = NULL;
-  if (NULL == ego)
+  handle->record_type = UINT32_MAX;
+  GNUNET_CRYPTO_hash (GNUNET_REST_GNS_PARAM_RECORD_TYPE,
+                      strlen (GNUNET_REST_GNS_PARAM_RECORD_TYPE),
+                      &key);
+  if ( GNUNET_YES
+       == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                  &key))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Ego for `gns-master' not found, cannot perform lookup.  Did 
you run gnunet-gns-import.sh?\n"));
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
+    record_type = GNUNET_CONTAINER_multihashmap_get 
(con_handle->url_param_map, &key);
+    handle->record_type = GNUNET_GNSRECORD_typename_to_number(record_type);
   }
-  GNUNET_IDENTITY_ego_get_public_key (ego,
-                                      &handle->pkey);
-  /* main name is our own master zone, do no look for that in the DHT */
-  handle->options = GNUNET_GNS_LO_LOCAL_MASTER;
-  /* if the name is of the form 'label.gnu', never go to the DHT */
-  dot = NULL;
-  if (NULL != handle->name)
-    dot = strchr (handle->name, '.');
-  if ( (NULL != dot) &&
-       (0 == strcasecmp (dot, ".gnu")) )
-    handle->options = GNUNET_GNS_LO_NO_DHT;
-  lookup_with_public_key (handle);
-}
-
-/**
- * Parse REST uri for name and record type
- *
- * @param url Url to parse
- * @param handle lookup handle to populate
- * @return GNUNET_SYSERR on error
- */
-static int
-parse_url (const char *url, struct LookupHandle *handle)
-{
-  char *name;
-  char tmp_url[strlen(url)+1];
-  char *tok;
-
-  strcpy (tmp_url, url);
-  tok = strtok ((char*)tmp_url, "/");
-  if (NULL == tok)
-    return GNUNET_SYSERR;
-  name = strtok (NULL, "/");
-  if (NULL == name)
-    return GNUNET_SYSERR;
-  GNUNET_asprintf (&handle->name,
-                   "%s",
-                   name);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Got name: %s\n", handle->name);
-  return GNUNET_OK;
-}
-
 
-static void
-get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
-              const char* url,
-              void *cls)
-{
-  struct LookupHandle *handle = cls;
-  struct GNUNET_HashCode key;
 
-  //parse name and type from url
-  if (GNUNET_OK != parse_url (url, handle))
+  if(UINT32_MAX == handle->record_type)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing url...\n");
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
+    handle->record_type = GNUNET_GNSRECORD_TYPE_ANY;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Connecting...\n");
+
   handle->gns = GNUNET_GNS_connect (cfg);
-  handle->identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
-  handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
-                                                       &do_error, handle);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Connected\n");
   if (NULL == handle->gns)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Connecting to GNS failed\n");
+    handle->emsg = GNUNET_strdup ("GNS not available");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_OPTIONS,
-                      strlen (GNUNET_REST_JSONAPI_GNS_OPTIONS),
-                      &key);
-  handle->options = GNUNET_GNS_LO_DEFAULT;
-  if ( GNUNET_YES ==
-       GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
-                                               &key) )
-  {
-    handle->options = GNUNET_GNS_LO_DEFAULT;//TODO(char*) 
GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
-    //&key);
-  }
-  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE,
-                      strlen (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE),
-                      &key);
-  if ( GNUNET_YES ==
-       GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
-                                               &key) )
-  {
-    handle->type = GNUNET_GNSRECORD_typename_to_number
-      (GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
-                                          &key));
-  }
-  else
-    handle->type = GNUNET_GNSRECORD_TYPE_ANY;
 
-  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_PKEY,
-                      strlen (GNUNET_REST_JSONAPI_GNS_PKEY),
-                      &key);
-  if ( GNUNET_YES ==
-       GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
-                                               &key) )
-  {
-    handle->pkey_str = GNUNET_CONTAINER_multihashmap_get 
(conndata_handle->url_param_map,
-                                                          &key);
-    GNUNET_assert (NULL != handle->pkey_str);
-    if (GNUNET_OK !=
-        GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->pkey_str,
-                                                    strlen(handle->pkey_str),
-                                                    &(handle->pkey)))
-    {
-      GNUNET_SCHEDULER_add_now (&do_error, handle);
-      return;
-    }
-    lookup_with_public_key (handle);
-    return;
-  }
-  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_EGO,
-                      strlen (GNUNET_REST_JSONAPI_GNS_EGO),
-                      &key);
-  if ( GNUNET_YES ==
-       GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
-                                               &key) )
-  {
-    handle->ego_str = GNUNET_CONTAINER_multihashmap_get 
(conndata_handle->url_param_map,
-                                                         &key);
-    handle->el = GNUNET_IDENTITY_ego_lookup (cfg,
-                                             handle->ego_str,
-                                             &identity_zone_cb,
-                                             handle);
-    return;
-  }
-  if ( (NULL != handle->name) &&
-       (strlen (handle->name) > 4) &&
-       (0 == strcmp (".zkey",
-                     &handle->name[strlen (handle->name) - 4])) )
-  {
-    GNUNET_CRYPTO_ecdsa_key_get_public
-      (GNUNET_CRYPTO_ecdsa_key_get_anonymous (),
-       &(handle->pkey));
-    lookup_with_public_key (handle);
-  }
-  else
-  {
-    GNUNET_break (NULL == handle->id_op);
-    handle->id_op = GNUNET_IDENTITY_get (handle->identity,
-                                         "gns-master",
-                                         &identity_master_cb,
-                                         handle);
-    GNUNET_assert (NULL != handle->id_op);
-  }
+  handle->gns_lookup = GNUNET_GNS_lookup_with_tld (handle->gns,
+                                                   handle->name,
+                                                   handle->record_type,
+                                                   GNUNET_NO,
+                                                   &handle_gns_response,
+                                                   handle);
+  return;
 }
 
+
+
 /**
- * Handle rest request
+ * Respond to OPTIONS request
  *
- * @param handle the lookup handle
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
  */
 static void
 options_cont (struct GNUNET_REST_RequestHandle *con_handle,
@@ -597,53 +330,38 @@ options_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
               void *cls)
 {
   struct MHD_Response *resp;
-  struct LookupHandle *handle = cls;
+  struct RequestHandle *handle = cls;
 
-  //For GNS, independent of path return all options
+  //independent of path return all options
   resp = GNUNET_REST_create_response (NULL);
   MHD_add_response_header (resp,
                            "Access-Control-Allow-Methods",
-                           MHD_HTTP_METHOD_GET);
-  handle->proc (handle->proc_cls,
-               resp,
-               MHD_HTTP_OK);
-  cleanup_handle (handle);
+                           allow_methods);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_SCHEDULER_add_now(&cleanup_handle, handle);
+  return;
 }
 
 
 /**
- * Function processing the REST call
+ * Handle rest request
  *
- * @param method HTTP method
- * @param url URL of the HTTP request
- * @param data body of the HTTP request (optional)
- * @param data_size length of the body
- * @param proc callback function for the result
- * @param proc_cls closure for @a proc
- * @return #GNUNET_OK if request accepted
+ * @param handle the request handle
  */
 static void
-rest_gns_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
-                          GNUNET_REST_ResultProcessor proc,
-                          void *proc_cls)
+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
   };
-  struct LookupHandle *handle = GNUNET_new (struct LookupHandle);
-  struct GNUNET_REST_RequestHandlerError err;
-
-  handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
-  handle->proc_cls = proc_cls;
-  handle->proc = proc;
-  handle->rest_handle = conndata_handle;
 
-  if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle,
-                                                  handlers,
-                                                  &err,
-                                                  handle))
+  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);
@@ -652,18 +370,58 @@ rest_gns_process_request (struct 
GNUNET_REST_RequestHandle *conndata_handle,
 
 
 /**
+ * Function processing the REST call
+ *
+ * @param method HTTP method
+ * @param url URL of the HTTP request
+ * @param data body of the HTTP request (optional)
+ * @param data_size length of the body
+ * @param proc callback function for the result
+ * @param proc_cls closure for callback function
+ * @return GNUNET_OK if request accepted
+ */
+static void
+rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
+                     GNUNET_REST_ResultProcessor proc,
+                     void *proc_cls)
+{
+  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
+
+  handle->response_code = 0;
+  handle->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 
60);
+  handle->proc_cls = proc_cls;
+  handle->proc = proc;
+  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");
+
+  init_cont(handle);
+
+  handle->timeout_task =
+    GNUNET_SCHEDULER_add_delayed (handle->timeout,
+                                  &do_error,
+                                  handle);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
+}
+
+
+/**
  * Entry point for the plugin.
  *
- * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
+ * @param cls Config info
  * @return NULL on error, otherwise the plugin context
  */
 void *
 libgnunet_plugin_rest_gns_init (void *cls)
 {
   static struct Plugin plugin;
-  cfg = cls;
   struct GNUNET_REST_Plugin *api;
 
+  cfg = cls;
   if (NULL != plugin.cfg)
     return NULL;                /* can only initialize once! */
   memset (&plugin, 0, sizeof (struct Plugin));
@@ -671,9 +429,17 @@ libgnunet_plugin_rest_gns_init (void *cls)
   api = GNUNET_new (struct GNUNET_REST_Plugin);
   api->cls = &plugin;
   api->name = GNUNET_REST_API_NS_GNS;
-  api->process_request = &rest_gns_process_request;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("GNS REST API initialized\n"));
+  api->process_request = &rest_process_request;
+  GNUNET_asprintf (&allow_methods,
+                   "%s, %s, %s, %s, %s",
+                   MHD_HTTP_METHOD_GET,
+                   MHD_HTTP_METHOD_POST,
+                   MHD_HTTP_METHOD_PUT,
+                   MHD_HTTP_METHOD_DELETE,
+                   MHD_HTTP_METHOD_OPTIONS);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              _("Gns REST API initialized\n"));
   return api;
 }
 
@@ -689,12 +455,14 @@ libgnunet_plugin_rest_gns_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;
-
   plugin->cfg = NULL;
+
+  GNUNET_free_non_null (allow_methods);
   GNUNET_free (api);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "GNS REST plugin is finished\n");
+              "Gns REST plugin is finished\n");
   return NULL;
 }
 
 /* end of plugin_rest_gns.c */
+
diff --git a/src/gns/test_plugin_rest_gns.sh b/src/gns/test_plugin_rest_gns.sh
new file mode 100755
index 000000000..7ede44501
--- /dev/null
+++ b/src/gns/test_plugin_rest_gns.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/bash
+
+#First, start gnunet-arm and the rest-service.
+#Exit 0 means success, exit 1 means failed test
+
+gns_link="http://localhost:7776/gns";
+wrong_link="http://localhost:7776/gnsandmore";
+
+curl_get () {
+    #$1 is link
+    #$2 is grep
+    cache="$(curl -v "$1" 2>&1 | grep "$2")"
+    #echo $cache
+    if [ "" == "$cache" ]
+    then
+        exit 1
+    fi
+}
+
+gnunet-identity -D "test_plugin_rest_gns" > /dev/null 2>&1
+
+curl_get "$gns_link?name=www.test_plugin_rest_gns" "error"
+
+gnunet-identity -C "test_plugin_rest_gns"
+
+curl_get "$gns_link?name=www.test_plugin_rest_gns" "\[\]"
+
+gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www -e 1d -V 1.1.1.1 -t A
+
+curl_get "$gns_link?name=www.test_plugin_rest_gns" "1.1.1.1"
+
+gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www -e 1d -V 1::1 -t AAAA
+
+curl_get "$gns_link?name=www.test_plugin_rest_gns" "1::1.*1.1.1.1"
+
+gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www -e 1d -V 1.1.1.2 -t A
+
+curl_get "$gns_link?name=www.test_plugin_rest_gns" "1.1.1.2.*1::1.*1.1.1.1"
+curl_get "$gns_link?name=www.test_plugin_rest_gns&record_type=A" 
"1.1.1.2.*1.1.1.1"
+curl_get "$gns_link?name=www.test_plugin_rest_gns&record_type=AAAA" "1::1"
+curl_get "$gns_link?name=www.test_plugin_rest_gns&record_type=WRONG_TYPE" 
"1.1.1.2.*1::1.*1.1.1.1"
+
+gnunet-namestore -z "test_plugin_rest_gns" -p -a -n www1 -e 1d -V 1.1.1.1 -t A
+curl_get "$gns_link?name=www1.test_plugin_rest_gns" "1.1.1.1"
+
+gnunet-identity -D "test_plugin_rest_gns"
+
+curl_get "$gns_link?name=www1.test_plugin_rest_gns" "error"
+
+exit 0
diff --git a/src/gnsrecord/gnsrecord.c b/src/gnsrecord/gnsrecord.c
index da34846e7..b80d86073 100644
--- a/src/gnsrecord/gnsrecord.c
+++ b/src/gnsrecord/gnsrecord.c
@@ -28,7 +28,9 @@
 #include "gnunet_constants.h"
 #include "gnunet_gnsrecord_lib.h"
 #include "gnunet_gnsrecord_plugin.h"
+#include "gnunet_json_lib.h"
 #include "gnunet_tun_lib.h"
+#include <jansson.h>
 
 
 #define LOG(kind,...) GNUNET_log_from (kind, "gnsrecord",__VA_ARGS__)
@@ -245,5 +247,4 @@ GNUNET_GNSRECORD_number_to_typename (uint32_t type)
   return NULL;
 }
 
-
 /* end of gnsrecord.c */
diff --git a/src/identity/Makefile.am b/src/identity/Makefile.am
index b8e70fffb..e7104f0c3 100644
--- a/src/identity/Makefile.am
+++ b/src/identity/Makefile.am
@@ -60,8 +60,6 @@ libgnunet_plugin_rest_identity_la_SOURCES = \
 libgnunet_plugin_rest_identity_la_LIBADD = \
        libgnunetidentity.la \
   $(top_builddir)/src/rest/libgnunetrest.la \
-       $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \
-  $(top_builddir)/src/jsonapi/libgnunetjsonapiutils.la \
   $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
   $(LTLIBINTL) -ljansson -lmicrohttpd
 libgnunet_plugin_rest_identity_la_LDFLAGS = \
diff --git a/src/identity/plugin_rest_identity.c 
b/src/identity/plugin_rest_identity.c
index 355d75fd9..a518a74cc 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -1,6 +1,6 @@
 /*
-   This file is part of GNUnet.
-   Copyright (C) 2012-2015 GNUnet e.V.
+ This file is part of GNUnet.
+ Copyright (C) 2012-2015 GNUnet e.V.
 
    GNUnet is free software: you can redistribute it and/or modify it
    under the terms of the GNU Affero General Public License as published
@@ -11,74 +11,51 @@
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Affero General Public License for more details.
-  
+
    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-   */
+ */
 /**
  * @author Martin Schanzenbach
+ * @author Philippe Buschmann
  * @file identity/plugin_rest_identity.c
- * @brief GNUnet Namestore REST plugin
- *
+ * @brief GNUnet Identity REST plugin
  */
 
 #include "platform.h"
 #include "gnunet_rest_plugin.h"
 #include "gnunet_identity_service.h"
 #include "gnunet_rest_lib.h"
-#include "gnunet_jsonapi_lib.h"
-#include "gnunet_jsonapi_util.h"
 #include "microhttpd.h"
 #include <jansson.h>
-#include "gnunet_signatures.h"
 
-/**
- * REST root namespace
- */
 #define GNUNET_REST_API_NS_IDENTITY "/identity"
 
 /**
- * State while collecting all egos
- */
-#define ID_REST_STATE_INIT 0
-
-/**
- * Done collecting egos
- */
-#define ID_REST_STATE_POST_INIT 1
-
-/**
- * Resource type
- */
-#define GNUNET_REST_JSONAPI_IDENTITY_EGO "ego"
-
-/**
- * Name attribute
- */
-#define GNUNET_REST_JSONAPI_IDENTITY_NAME "name"
-
-/**
- * Attribute to rename "name" TODO we changed id to the pubkey
- * so this can be unified with "name"
- */
-#define GNUNET_REST_JSONAPI_IDENTITY_NEWNAME "newname"
-
-/**
- * URL parameter to change the subsytem for ego
+ * Parameter names
  */
-#define GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM "subsystem"
-
+#define GNUNET_REST_PARAM_PUBKEY "pubkey"
+#define GNUNET_REST_PARAM_SUBSYSTEM "subsystem"
+#define GNUNET_REST_PARAM_NAME "name"
+#define GNUNET_REST_PARAM_NEWNAME "newname"
 
 /**
  * Error messages
  */
+#define GNUNET_REST_IDENTITY_ERROR_UNKNOWN "Unknown Error"
 #define GNUNET_REST_ERROR_RESOURCE_INVALID "Resource location invalid"
 #define GNUNET_REST_ERROR_NO_DATA "No data"
+#define GNUNET_REST_ERROR_DATA_INVALID "Data invalid"
 
 /**
- * GNUid token lifetime
+ * State while collecting all egos
  */
-#define GNUNET_GNUID_TOKEN_EXPIRATION_MICROSECONDS 300000000
+#define ID_REST_STATE_INIT 0
+
+/**
+ * Done collecting egos
+ */
+#define ID_REST_STATE_POST_INIT 1
 
 /**
  * The configuration handle
@@ -129,28 +106,37 @@ struct EgoEntry
   struct GNUNET_IDENTITY_Ego *ego;
 };
 
-
 struct RequestHandle
 {
   /**
-   * Ego list
+   * The data from the REST request
    */
-  struct EgoEntry *ego_head;
+  const char* data;
 
   /**
-   * Ego list
+   * The name to look up
    */
-  struct EgoEntry *ego_tail;
+  char *name;
 
   /**
-   * Handle to the rest connection
+   * the length of the REST data
    */
-  struct GNUNET_REST_RequestHandle *conndata_handle;
+  size_t data_size;
 
   /**
-   * response code
+   * Requested Subsystem
    */
-  int response_code;
+  char *subsystem;
+
+  /**
+   * Ego list
+   */
+  struct EgoEntry *ego_head;
+
+  /**
+   * Ego list
+   */
+  struct EgoEntry *ego_tail;
 
   /**
    * The processing state
@@ -158,7 +144,7 @@ struct RequestHandle
   int state;
 
   /**
-   * Handle to GNS service.
+   * Handle to Identity service.
    */
   struct GNUNET_IDENTITY_Handle *identity_handle;
 
@@ -168,6 +154,11 @@ struct RequestHandle
   struct GNUNET_IDENTITY_Operation *op;
 
   /**
+   * Rest connection
+   */
+  struct GNUNET_REST_RequestHandle *rest_handle;
+
+  /**
    * Desired timeout for the lookup (default is no timeout).
    */
   struct GNUNET_TIME_Relative timeout;
@@ -175,7 +166,7 @@ struct RequestHandle
   /**
    * ID of a task associated with the resolution process.
    */
-  struct GNUNET_SCHEDULER_Task * timeout_task;
+  struct GNUNET_SCHEDULER_Task *timeout_task;
 
   /**
    * The plugin result processor
@@ -188,81 +179,63 @@ struct RequestHandle
   void *proc_cls;
 
   /**
-   * The name to look up
-   */
-  char *name;
-
-  /**
-   * The subsystem set from REST
-   */
-  char *subsys;
-
-  /**
    * The url
    */
   char *url;
 
   /**
-   * The data from the REST request
-   */
-  const char* data;
-
-  /**
-   * the length of the REST data
-   */
-  size_t data_size;
-
-  /**
-   * HTTP method
+   * Error response message
    */
-  const char* method;
+  char *emsg;
 
   /**
-   * Error response message
+   * Reponse code
    */
-  char *emsg;
+  int response_code;
 
 };
 
-
 /**
  * Cleanup lookup handle
  * @param handle Handle to clean up
  */
 static void
-cleanup_handle (struct RequestHandle *handle)
+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->name)
-    GNUNET_free (handle->name);
+
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
   if (NULL != handle->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (handle->timeout_task);
     handle->timeout_task = NULL;
   }
-  if (NULL != handle->identity_handle)
-    GNUNET_IDENTITY_disconnect (handle->identity_handle);
-  if (NULL != handle->subsys)
-    GNUNET_free (handle->subsys);
+
+  if (NULL != handle->subsystem)
+    GNUNET_free(handle->subsystem);
   if (NULL != handle->url)
-    GNUNET_free (handle->url);
+    GNUNET_free(handle->url);
   if (NULL != handle->emsg)
-    GNUNET_free (handle->emsg);
+    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;)
+  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(ego_tmp->identifier);
+    GNUNET_free(ego_tmp->keystring);
+    GNUNET_free(ego_tmp);
   }
-  GNUNET_free (handle);
-}
 
+  GNUNET_free(handle);
+}
 
 /**
  * Task run on errors.  Reports an error and cleans up everything.
@@ -274,23 +247,67 @@ do_error (void *cls)
 {
   struct RequestHandle *handle = cls;
   struct MHD_Response *resp;
-  char *json_error;
-
-  GNUNET_asprintf (&json_error,
-                   "{Error while processing request: %s}",
-                   &handle->emsg);
-
-  resp = GNUNET_REST_create_response (json_error);
-  handle->proc (handle->proc_cls,
-               resp,
-               handle->response_code);
-  cleanup_handle (handle);
-  GNUNET_free (json_error);
+  json_t *json_error = json_object();
+  char *response;
+
+  if (NULL == handle->emsg)
+    handle->emsg = GNUNET_strdup(GNUNET_REST_IDENTITY_ERROR_UNKNOWN);
+
+  json_object_set_new(json_error,"error", json_string(handle->emsg));
+
+  if (0 == handle->response_code)
+    handle->response_code = MHD_HTTP_OK;
+  response = json_dumps (json_error, 0);
+  resp = GNUNET_REST_create_response (response);
+  handle->proc (handle->proc_cls, resp, handle->response_code);
+  json_decref(json_error);
+  GNUNET_free(response);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 
+
 /**
- * Callback for IDENTITY_get()
+ * Get EgoEntry from list with either a public key or a name
+ * If public key and name are not NULL, it returns the public key result first
+ *
+ * @param handle the RequestHandle
+ * @param pubkey the public key of an identity (only one can be NULL)
+ * @param name the name of an identity (only one can be NULL)
+ * @return EgoEntry or NULL if not found
+ */
+struct EgoEntry*
+get_egoentry(struct RequestHandle *handle, char* pubkey, char *name)
+{
+  struct EgoEntry *ego_entry;
+  if (NULL != pubkey)
+  {
+    for (ego_entry = handle->ego_head;
+       NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    {
+      if (0 != strcasecmp (pubkey, ego_entry->keystring))
+       continue;
+      return ego_entry;
+    }
+  }
+  if (NULL != name)
+  {
+    for (ego_entry = handle->ego_head;
+       NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    {
+      if (0 != strcasecmp (name, ego_entry->identifier))
+       continue;
+      return ego_entry;
+    }
+  }
+  return NULL;
+}
+
+
+/**
+ * Callback for GET Request with subsystem
  *
  * @param cls the RequestHandle
  * @param ego the Ego found
@@ -298,153 +315,177 @@ do_error (void *cls)
  * @param name the id of the ego
  */
 static void
-get_ego_for_subsys (void *cls,
-                    struct GNUNET_IDENTITY_Ego *ego,
-                    void **ctx,
-                    const char *name)
+ego_get_for_subsystem (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx,
+                      const char *name)
 {
   struct RequestHandle *handle = cls;
-  struct GNUNET_JSONAPI_Document *json_document;
-  struct GNUNET_JSONAPI_Resource *json_resource;
-  struct EgoEntry *ego_entry;
   struct MHD_Response *resp;
-  json_t *name_json;
+  struct GNUNET_CRYPTO_EcdsaPublicKey public_key;
+  json_t *json_root;
   char *result_str;
+  char *public_key_string;
 
-  json_document = GNUNET_JSONAPI_document_new ();
-
-  for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
+  if(NULL == ego)
   {
-    if ( (NULL != name) && (0 != strcmp (name, ego_entry->identifier)) )
-      continue;
-    if (NULL == name)
-      continue;
-    json_resource = GNUNET_JSONAPI_resource_new
-      (GNUNET_REST_JSONAPI_IDENTITY_EGO, ego_entry->keystring);
-    name_json = json_string (ego_entry->identifier);
-    GNUNET_JSONAPI_resource_add_attr (json_resource,
-                                           GNUNET_REST_JSONAPI_IDENTITY_NAME,
-                                           name_json);
-    json_decref (name_json);
-    GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
-    break;
-  }
-  if (0 == GNUNET_JSONAPI_document_resource_count (json_document))
-  {
-    GNUNET_JSONAPI_document_delete (json_document);
-    handle->emsg = GNUNET_strdup("No identity matches results!");
+    handle->emsg = GNUNET_strdup("No identity found for subsystem");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_JSONAPI_document_serialize (json_document, &result_str);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
+
+  GNUNET_IDENTITY_ego_get_public_key(ego,&public_key);
+  public_key_string = GNUNET_CRYPTO_ecdsa_public_key_to_string(&public_key);
+
+  // create json with subsystem identity
+  json_root = json_object ();
+  json_object_set_new (json_root, GNUNET_REST_PARAM_PUBKEY, 
json_string(public_key_string));
+  json_object_set_new (json_root, GNUNET_REST_PARAM_NAME, json_string(name));
+
+  result_str = json_dumps (json_root, 0);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
   resp = GNUNET_REST_create_response (result_str);
-  GNUNET_JSONAPI_document_delete (json_document);
+
+  json_decref (json_root);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  GNUNET_free (result_str);
-  cleanup_handle (handle);
+  GNUNET_free(result_str);
+  GNUNET_free(public_key_string);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 /**
- * Create a response with requested ego(s)
+ * Handle identity GET request
  *
- * @param con the Rest handle
- * @param url the requested url
- * @param cls the request handle
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
  */
-static void
-ego_info_response (struct GNUNET_REST_RequestHandle *con,
-                   const char *url,
-                   void *cls)
+void
+ego_get (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
+        void *cls)
 {
-  const char *egoname;
-  char *result_str;
-  char *subsys_val;
-  char *keystring;
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
   struct GNUNET_HashCode key;
   struct MHD_Response *resp;
-  struct GNUNET_JSONAPI_Document *json_document;
-  struct GNUNET_JSONAPI_Resource *json_resource;
-  json_t *name_str;
+  char *keystring;
+  char *egoname;
+  json_t *json_root;
+  json_t *json_ego;
+  char *result_str;
 
-  if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url, 
GNUNET_REST_API_NS_IDENTITY))
+  //requested default identity of subsystem
+  GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_SUBSYSTEM,
+                     strlen (GNUNET_REST_PARAM_SUBSYSTEM), &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (
+         handle->rest_handle->url_param_map, &key))
   {
-    resp = GNUNET_REST_create_response (NULL);
-    handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
-    cleanup_handle (handle);
+    handle->subsystem = GNUNET_strdup(
+       GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
+                                          &key));
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n",
+              handle->subsystem);
+
+    handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
+                                     handle->subsystem,
+                                     &ego_get_for_subsystem,
+                                     handle);
+    if (NULL == handle->op)
+    {
+      handle->emsg = GNUNET_strdup("No identity found for subsystem");
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
     return;
   }
   egoname = NULL;
   keystring = NULL;
-  if (strlen (GNUNET_REST_API_NS_IDENTITY) < strlen (handle->url))
+
+  //one identity requested with key
+  GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_PUBKEY,
+                     strlen (GNUNET_REST_PARAM_PUBKEY),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (
+         handle->rest_handle->url_param_map, &key))
   {
-    keystring = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY)+1];
-    //Return all egos
-    for (ego_entry = handle->ego_head;
-         NULL != ego_entry;
-         ego_entry = ego_entry->next)
+    keystring = GNUNET_CONTAINER_multihashmap_get (
+       handle->rest_handle->url_param_map, &key);
+
+    ego_entry = get_egoentry(handle, keystring, NULL);
+    if (NULL == ego_entry)
     {
-      if ( (NULL != keystring) && (0 != strcmp (keystring, 
ego_entry->keystring)) )
-        continue;
-      egoname = ego_entry->identifier;
+      handle->emsg = GNUNET_strdup("No identity found for public key");
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
     }
+    egoname = ego_entry->identifier;
   }
 
-  if ( NULL == egoname ) {
-    GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM,
-                        strlen (GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM),
-                        &key);
-    if ( GNUNET_YES ==
-         GNUNET_CONTAINER_multihashmap_contains 
(handle->conndata_handle->url_param_map,
-                                                 &key) )
+  //one identity requested with name
+  if (NULL == egoname)
+  {
+    GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_NAME,
+                       strlen (GNUNET_REST_PARAM_NAME),
+                       &key);
+    if ( GNUNET_YES
+       == GNUNET_CONTAINER_multihashmap_contains (
+           handle->rest_handle->url_param_map, &key))
     {
-      subsys_val = GNUNET_CONTAINER_multihashmap_get 
(handle->conndata_handle->url_param_map,
-                                                      &key);
-      if (NULL != subsys_val)
+      egoname = GNUNET_CONTAINER_multihashmap_get (
+         handle->rest_handle->url_param_map, &key);
+      if (0 >= strlen(egoname))
       {
-        GNUNET_asprintf (&handle->subsys, "%s", subsys_val);
-        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", 
subsys_val);
-        handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
-                                          handle->subsys,
-                                          &get_ego_for_subsys,
-                                          handle);
+        handle->emsg = GNUNET_strdup("No identity found for name");
+        GNUNET_SCHEDULER_add_now (&do_error, handle);
         return;
       }
+      //LOWERCASE ego names?
+      GNUNET_STRINGS_utf8_tolower(egoname, egoname);
     }
   }
 
-  json_document = GNUNET_JSONAPI_document_new ();
-
-  //Return all egos
+  json_root = json_array ();
+  //Return ego/egos
   for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
+  NULL != ego_entry; ego_entry = ego_entry->next)
   {
-    if ( (NULL != egoname) && (0 != strcmp (egoname, ego_entry->identifier)) )
-      continue;
-    json_resource = GNUNET_JSONAPI_resource_new 
(GNUNET_REST_JSONAPI_IDENTITY_EGO,
-                                                      ego_entry->keystring);
-    name_str = json_string (ego_entry->identifier);
-    GNUNET_JSONAPI_resource_add_attr (
-                                           json_resource,
-                                           GNUNET_REST_JSONAPI_IDENTITY_NAME,
-                                           name_str);
-    json_decref (name_str);
-    GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
+    //if only one ego requested
+    if ((NULL != egoname)){
+      if(0 != strcmp (egoname, ego_entry->identifier)){
+       continue;
+      }
+    }
+
+    json_ego = json_object ();
+    json_object_set_new (json_ego,
+                        GNUNET_REST_PARAM_PUBKEY,
+                        json_string (ego_entry->keystring));
+    json_object_set_new (json_ego,
+                        GNUNET_REST_PARAM_NAME,
+                        json_string (ego_entry->identifier));
+    json_array_append (json_root, json_ego);
+    json_decref (json_ego);
+  }
+
+  if ((size_t) 0 == json_array_size (json_root))
+  {
+    json_decref (json_root);
+    handle->emsg = GNUNET_strdup("No identities found!");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
   }
-  GNUNET_JSONAPI_document_serialize (json_document, &result_str);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
+
+  result_str = json_dumps (json_root, 0);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
   resp = GNUNET_REST_create_response (result_str);
-  GNUNET_JSONAPI_document_delete (json_document);
+
+  json_decref (json_root);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  GNUNET_free (result_str);
-  cleanup_handle (handle);
+  GNUNET_free(result_str);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
+
 /**
  * Processing finished
  *
@@ -460,311 +501,363 @@ do_finished (void *cls, const char *emsg)
   handle->op = NULL;
   if (NULL != emsg)
   {
-    handle->emsg = GNUNET_strdup (emsg);
+    handle->emsg = GNUNET_strdup(emsg);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
   resp = GNUNET_REST_create_response (NULL);
-  handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT);
-  cleanup_handle (handle);
+  handle->proc (handle->proc_cls, resp, handle->response_code);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
+
 /**
- * Create a new ego
+ * Handle identity PUT request
  *
- * @param con rest handle
- * @param url url
- * @param cls request handle
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
  */
-static void
-ego_create_cont (struct GNUNET_REST_RequestHandle *con,
-                 const char *url,
-                 void *cls)
+void
+ego_edit (struct GNUNET_REST_RequestHandle *con_handle,
+         const char* url,
+         void *cls)
 {
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
+  struct EgoEntry *ego_entry_tmp;
   struct MHD_Response *resp;
-  struct GNUNET_JSONAPI_Document *json_obj;
-  struct GNUNET_JSONAPI_Resource *json_res;
-  json_t *egoname_json;
+  int json_state;
   json_t *data_js;
   json_error_t err;
-  const char* egoname;
-  char term_data[handle->data_size+1];
-  struct GNUNET_JSON_Specification docspec[] = {
-    GNUNET_JSON_spec_jsonapi_document (&json_obj),
-    GNUNET_JSON_spec_end()
-  };
-  if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url))
-  {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
-  }
+  char *pubkey;
+  char *name;
+  char *newsubsys;
+  char *newname;
+  char term_data[handle->data_size + 1];
+
+  //if no data
   if (0 >= handle->data_size)
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
+  //if not json
   term_data[handle->data_size] = '\0';
-  GNUNET_memcpy (term_data, handle->data, handle->data_size);
-  data_js = json_loads (term_data,
-                        JSON_DECODE_ANY,
-                        &err);
-  GNUNET_assert (NULL != data_js);
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_JSON_parse (data_js, docspec,
-                                    NULL, NULL));
+  GNUNET_memcpy(term_data, handle->data, handle->data_size);
+  data_js = json_loads (term_data,JSON_DECODE_ANY,&err);
 
-  json_decref (data_js);
-
-  if (NULL == json_obj)
+  if (NULL == data_js)
   {
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
-  {
-    GNUNET_JSONAPI_document_delete (json_obj);
-    handle->emsg = GNUNET_strdup ("Provided resource count invalid");
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
-  }
-  json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
-  if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, 
GNUNET_REST_JSONAPI_IDENTITY_EGO))
-  {
-    GNUNET_JSONAPI_document_delete (json_obj);
-    resp = GNUNET_REST_create_response (NULL);
-    handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
-    cleanup_handle (handle);
-    return;
-  }
-  egoname_json = GNUNET_JSONAPI_resource_read_attr (json_res, 
GNUNET_REST_JSONAPI_IDENTITY_NAME);
-  if (!json_is_string (egoname_json))
+
+  ego_entry = NULL;
+  pubkey = NULL;
+  name = NULL;
+  newname = NULL;
+  //NEW NAME
+  json_state = 0;
+  json_state = json_unpack(data_js,
+                          "{s:s,s?:s,s?:s}",
+                          GNUNET_REST_PARAM_NEWNAME,
+                          &newname,
+                          GNUNET_REST_PARAM_PUBKEY,
+                          &pubkey,
+                          GNUNET_REST_PARAM_NAME,
+                          &name);
+  //Change name with pubkey or name identifier
+  if (0 == json_state)
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
-    handle->emsg = GNUNET_strdup ("No name provided");
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    if (NULL == newname)
+    {
+      handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      json_decref (data_js);
+      return;
+    }
+
+    if (0 >= strlen(newname))
+    {
+      handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      json_decref (data_js);
+      return;
+    }
+    //lower case name
+    GNUNET_STRINGS_utf8_tolower(newname,newname);
+
+    ego_entry = get_egoentry(handle,pubkey,name);
+
+    if (NULL == ego_entry)
+    {
+      resp = GNUNET_REST_create_response (NULL);
+      handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
+      GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
+      json_decref (data_js);
+      return;
+    }
+
+    for (ego_entry_tmp = handle->ego_head;
+    NULL != ego_entry_tmp; ego_entry_tmp = ego_entry_tmp->next)
+    {
+      if (0 == strcasecmp (newname, ego_entry_tmp->identifier))
+      {
+        //Ego with same name not allowed
+        resp = GNUNET_REST_create_response (NULL);
+        handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
+        GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
+        json_decref (data_js);
+        return;
+      }
+    }
+    handle->response_code = MHD_HTTP_NO_CONTENT;
+    handle->op = GNUNET_IDENTITY_rename (handle->identity_handle,
+                                      ego_entry->identifier, newname,
+                                      &do_finished, handle);
+    json_decref (data_js);
     return;
   }
-  egoname = json_string_value (egoname_json);
-  for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
+
+  newsubsys = NULL;
+  //SUBSYSTEM
+  json_state = 0;
+  json_state = json_unpack(data_js,
+                          "{s:s,s?:s,s?:s}",
+                          GNUNET_REST_PARAM_SUBSYSTEM,
+                          &newsubsys,
+                          GNUNET_REST_PARAM_PUBKEY,
+                          &pubkey,
+                          GNUNET_REST_PARAM_NAME,
+                          &name);
+  //Change subsystem with pubkey or name identifier
+  if (0 == json_state)
   {
-    if (0 == strcasecmp (egoname, ego_entry->identifier))
+    if (NULL == newsubsys || (NULL == pubkey && NULL == name))
     {
-      GNUNET_JSONAPI_document_delete (json_obj);
-      resp = GNUNET_REST_create_response (NULL);
-      handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
-      cleanup_handle (handle);
+      handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      json_decref (data_js);
+      return;
+    }
+
+    if (0 >= strlen(newsubsys))
+    {
+      handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      json_decref (data_js);
       return;
     }
+
+    ego_entry = get_egoentry(handle, pubkey, name);
+
+    if (NULL == ego_entry)
+    {
+      handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      json_decref (data_js);
+      return;
+    }
+
+    handle->response_code = MHD_HTTP_NO_CONTENT;
+    handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
+                                     newsubsys,
+                                     ego_entry->ego,
+                                     &do_finished,
+                                     handle);
+    json_decref (data_js);
+    return;
   }
-  GNUNET_asprintf (&handle->name, "%s", egoname);
-  GNUNET_JSONAPI_document_delete (json_obj);
-  handle->op = GNUNET_IDENTITY_create (handle->identity_handle,
-                                       handle->name,
-                                       &do_finished,
-                                       handle);
-}
 
+  handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
+  GNUNET_SCHEDULER_add_now (&do_error, handle);
+  json_decref (data_js);
+  return;
+}
 
 /**
- * Handle ego edit request
+ * Handle identity POST request
  *
- * @param con rest connection handle
- * @param url the url that is requested
+ * @param con_handle the connection handle
+ * @param url the url
  * @param cls the RequestHandle
  */
-static void
-ego_edit_cont (struct GNUNET_REST_RequestHandle *con,
-               const char *url,
-               void *cls)
+void
+ego_create (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
+           void *cls)
 {
-  struct GNUNET_JSONAPI_Document *json_obj;
-  struct GNUNET_JSONAPI_Resource *json_res;
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
-  struct EgoEntry *ego_entry_tmp;
   struct MHD_Response *resp;
-  json_t *subsys_json;
-  json_t *name_json;
   json_t *data_js;
   json_error_t err;
-  const char *keystring;
-  const char *subsys;
-  const char *newname;
-  char term_data[handle->data_size+1];
-  int ego_exists = GNUNET_NO;
-  struct GNUNET_JSON_Specification docspec[] = {
-    GNUNET_JSON_spec_jsonapi_document (&json_obj),
-    GNUNET_JSON_spec_end()
-  };
+  char* egoname;
+  int json_unpack_state;
+  char term_data[handle->data_size + 1];
 
-  if (strlen (GNUNET_REST_API_NS_IDENTITY) > strlen (handle->url))
+  if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url))
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_RESOURCE_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
-  keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY)+1];
-
-  for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
-  {
-    if (0 != strcasecmp (keystring, ego_entry->keystring))
-      continue;
-    ego_exists = GNUNET_YES;
-    break;
-  }
-
-  if (GNUNET_NO == ego_exists)
-  {
-    resp = GNUNET_REST_create_response (NULL);
-    handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
-    cleanup_handle (handle);
-    return;
-  }
-
   if (0 >= handle->data_size)
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-
   term_data[handle->data_size] = '\0';
-  GNUNET_memcpy (term_data, handle->data, handle->data_size);
+  GNUNET_memcpy(term_data, handle->data, handle->data_size);
   data_js = json_loads (term_data,
-                        JSON_DECODE_ANY,
-                        &err);
-  GNUNET_assert (NULL != data_js);
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_JSON_parse (data_js, docspec,
-                                    NULL, NULL));
-
-  json_decref (data_js);
-
-  if (NULL == json_obj)
+                       JSON_DECODE_ANY,
+                       &err);
+  if (NULL == data_js)
   {
-    handle->emsg = GNUNET_strdup ("Data invalid");
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
+    json_decref (data_js);
     return;
   }
-
-  if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
+  json_unpack_state = 0;
+  json_unpack_state = json_unpack(data_js,
+                                 "{s:s!}",
+                                 GNUNET_REST_PARAM_NAME,
+                                 &egoname);
+  if (0 != json_unpack_state)
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
-    handle->emsg = GNUNET_strdup ("Resource amount invalid");
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
+    json_decref (data_js);
     return;
   }
-  json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
 
-  if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, 
GNUNET_REST_JSONAPI_IDENTITY_EGO))
+  if (NULL == egoname)
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
-    handle->emsg = GNUNET_strdup ("Resource type invalid");
+    handle->emsg = GNUNET_strdup("No name provided");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
+    json_decref (data_js);
     return;
   }
-
-  //This is a rename
-  name_json = GNUNET_JSONAPI_resource_read_attr (json_res,
-                                                 
GNUNET_REST_JSONAPI_IDENTITY_NEWNAME);
-  if ((NULL != name_json) && json_is_string (name_json))
+  if (0 >= strlen (egoname))
   {
-    newname = json_string_value (name_json);
-    for (ego_entry_tmp = handle->ego_head;
-         NULL != ego_entry_tmp;
-         ego_entry_tmp = ego_entry_tmp->next)
-    {
-      if (0 == strcasecmp (newname, ego_entry_tmp->identifier) &&
-          0 != strcasecmp (keystring, ego_entry_tmp->keystring))
-      {
-        //Ego with same name not allowed
-        GNUNET_JSONAPI_document_delete (json_obj);
-        resp = GNUNET_REST_create_response (NULL);
-        handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
-        cleanup_handle (handle);
-        return;
-      }
-    }
-    handle->op = GNUNET_IDENTITY_rename (handle->identity_handle,
-                                         ego_entry->identifier,
-                                         newname,
-                                         &do_finished,
-                                         handle);
-    GNUNET_JSONAPI_document_delete (json_obj);
+    json_decref (data_js);
+    handle->emsg = GNUNET_strdup("No name provided");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-
-  //Set subsystem
-  subsys_json = GNUNET_JSONAPI_resource_read_attr (json_res, 
GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM);
-  if ( (NULL != subsys_json) && json_is_string (subsys_json))
+  GNUNET_STRINGS_utf8_tolower(egoname, egoname);
+  for (ego_entry = handle->ego_head;
+  NULL != ego_entry; ego_entry = ego_entry->next)
   {
-    subsys = json_string_value (subsys_json);
-    GNUNET_asprintf (&handle->subsys, "%s", subsys);
-    GNUNET_JSONAPI_document_delete (json_obj);
-    handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
-                                      handle->subsys,
-                                      ego_entry->ego,
-                                      &do_finished,
-                                      handle);
-    return;
+    if (0 == strcasecmp (egoname, ego_entry->identifier))
+    {
+      resp = GNUNET_REST_create_response (NULL);
+      handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
+      GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
+      json_decref (data_js);
+      return;
+    }
   }
-  GNUNET_JSONAPI_document_delete (json_obj);
-  handle->emsg = GNUNET_strdup ("Subsystem not provided");
-  GNUNET_SCHEDULER_add_now (&do_error, handle);
+  handle->name = GNUNET_strdup(egoname);
+  json_decref (data_js);
+  handle->response_code = MHD_HTTP_CREATED;
+  handle->op = GNUNET_IDENTITY_create (handle->identity_handle, handle->name,
+                                      &do_finished, handle);
 }
 
+/**
+ * Handle identity DELETE request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
 void
-ego_delete_cont (struct GNUNET_REST_RequestHandle *con_handle,
-                 const char* url,
-                 void *cls)
+ego_delete (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
+           void *cls)
 {
-  const char *keystring;
+  struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
+  struct GNUNET_HashCode key;
   struct MHD_Response *resp;
-  struct RequestHandle *handle = cls;
+  const char *keystring;
+  char *egoname;
   int ego_exists = GNUNET_NO;
 
-  if (strlen (GNUNET_REST_API_NS_IDENTITY) >= strlen (handle->url))
+  keystring = NULL;
+  egoname = NULL;
+
+  //delete with pubkey
+  GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_PUBKEY,
+                     strlen (GNUNET_REST_PARAM_PUBKEY), &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (
+         handle->rest_handle->url_param_map, &key))
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
+    keystring = GNUNET_CONTAINER_multihashmap_get (
+        handle->rest_handle->url_param_map,&key);
   }
 
-  keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY)+1];
-  for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
+  GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_NAME,
+                     strlen (GNUNET_REST_PARAM_NAME), &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (
+         handle->rest_handle->url_param_map, &key))
   {
-    if (0 != strcasecmp (keystring, ego_entry->keystring))
-      continue;
-    ego_exists = GNUNET_YES;
-    break;
+    egoname = GNUNET_CONTAINER_multihashmap_get (
+       handle->rest_handle->url_param_map, &key);
+    //LOWERCASE ego names?
+    //GNUNET_STRINGS_utf8_tolower(egoname, egoname);
   }
+
+  if (NULL != keystring)
+  {
+    for (ego_entry = handle->ego_head;
+    NULL != ego_entry; ego_entry = ego_entry->next)
+    {
+      if (0 != strcasecmp (keystring, ego_entry->keystring))
+        continue;
+      ego_exists = GNUNET_YES;
+      break;
+    }
+  }
+  else if (NULL != egoname)
+  {
+    for (ego_entry = handle->ego_head;
+    NULL != ego_entry; ego_entry = ego_entry->next)
+    {
+      if (0 != strcmp (egoname, ego_entry->identifier))
+        continue;
+      ego_exists = GNUNET_YES;
+      break;
+    }
+  }
+  else
+  {
+    handle->emsg = GNUNET_strdup("Missing parameter pubkey or name");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
   if (GNUNET_NO == ego_exists)
   {
     resp = GNUNET_REST_create_response (NULL);
     handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
-    cleanup_handle (handle);
+    GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
     return;
   }
+  handle->response_code = MHD_HTTP_NO_CONTENT;
   handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
-                                       ego_entry->identifier,
-                                       &do_finished,
-                                       handle);
+                                      ego_entry->identifier, &do_finished,
+                                      handle);
 
 }
 
-
 /**
  * Respond to OPTIONS request
  *
@@ -773,20 +866,17 @@ ego_delete_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
  * @param cls the RequestHandle
  */
 static void
-options_cont (struct GNUNET_REST_RequestHandle *con_handle,
-              const char* url,
-              void *cls)
+options_cont (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
+             void *cls)
 {
   struct MHD_Response *resp;
   struct RequestHandle *handle = cls;
 
   //For now, independent of path return all options
   resp = GNUNET_REST_create_response (NULL);
-  MHD_add_response_header (resp,
-                           "Access-Control-Allow-Methods",
-                           allow_methods);
+  MHD_add_response_header (resp, "Access-Control-Allow-Methods", 
allow_methods);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  cleanup_handle (handle);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
   return;
 }
 
@@ -800,18 +890,17 @@ 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_info_response},
-    {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create_cont},
-    {MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY, &ego_edit_cont},
-    {MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_IDENTITY, &ego_delete_cont},
-    {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont},
-    GNUNET_REST_HANDLER_END
+      { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get },
+      { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY, &ego_edit },
+      { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create },
+      { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_IDENTITY, &ego_delete },
+      { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
+      GNUNET_REST_HANDLER_END
   };
 
-  if (GNUNET_NO == GNUNET_JSONAPI_handle_request (handle->conndata_handle,
-                                                  handlers,
-                                                  &err,
-                                                  handle))
+  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);
@@ -852,10 +941,8 @@ init_cont (struct RequestHandle *handle)
  *                   must thus no longer be used
  */
 static void
-list_ego (void *cls,
-          struct GNUNET_IDENTITY_Ego *ego,
-          void **ctx,
-          const char *identifier)
+init_egos (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx,
+          const char *identifier)
 {
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
@@ -867,16 +954,16 @@ list_ego (void *cls,
     init_cont (handle);
     return;
   }
-  if (ID_REST_STATE_INIT == handle->state) {
-    ego_entry = GNUNET_new (struct EgoEntry);
+  if (ID_REST_STATE_INIT == handle->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->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);
+    GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head, handle->ego_tail,
+                                    ego_entry);
   }
-
 }
 
 /**
@@ -891,39 +978,30 @@ list_ego (void *cls,
  * @return GNUNET_OK if request accepted
  */
 static void
-rest_identity_process_request(struct GNUNET_REST_RequestHandle 
*conndata_handle,
-                              GNUNET_REST_ResultProcessor proc,
-                              void *proc_cls)
+rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
+                     GNUNET_REST_ResultProcessor proc, void *proc_cls)
 {
-  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
-
-
+  struct RequestHandle *handle = GNUNET_new(struct RequestHandle);
 
+  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;
-  handle->conndata_handle = conndata_handle;
-  handle->data = conndata_handle->data;
-  handle->data_size = conndata_handle->data_size;
-  handle->method = conndata_handle->method;
-  GNUNET_asprintf (&handle->url, "%s", conndata_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->timeout_task =
-    GNUNET_SCHEDULER_add_delayed (handle->timeout,
-                                  &do_error,
-                                  handle);
-
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Connected\n");
+  handle->rest_handle = rest_handle;
+  handle->data = rest_handle->data;
+  handle->data_size = rest_handle->data_size;
+
+  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, &init_egos, handle);
+
+  handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
+                                                      &do_error, handle);
+
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
 }
 
 /**
@@ -940,27 +1018,24 @@ libgnunet_plugin_rest_identity_init (void *cls)
 
   cfg = cls;
   if (NULL != plugin.cfg)
-    return NULL;                /* can only initialize once! */
-  memset (&plugin, 0, sizeof (struct Plugin));
+    return NULL; /* can only initialize once! */
+  memset (&plugin, 0, sizeof(struct Plugin));
   plugin.cfg = cfg;
-  api = GNUNET_new (struct GNUNET_REST_Plugin);
+  api = GNUNET_new(struct GNUNET_REST_Plugin);
   api->cls = &plugin;
   api->name = GNUNET_REST_API_NS_IDENTITY;
-  api->process_request = &rest_identity_process_request;
-  GNUNET_asprintf (&allow_methods,
-                   "%s, %s, %s, %s, %s",
-                   MHD_HTTP_METHOD_GET,
-                   MHD_HTTP_METHOD_POST,
-                   MHD_HTTP_METHOD_PUT,
-                   MHD_HTTP_METHOD_DELETE,
-                   MHD_HTTP_METHOD_OPTIONS);
-
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("Identity REST API initialized\n"));
+  api->process_request = &rest_process_request;
+  GNUNET_asprintf (&allow_methods, "%s, %s, %s, %s, %s",
+                  MHD_HTTP_METHOD_GET,
+                  MHD_HTTP_METHOD_POST,
+                  MHD_HTTP_METHOD_PUT,
+                  MHD_HTTP_METHOD_DELETE,
+                  MHD_HTTP_METHOD_OPTIONS);
+
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, _("Identity REST API initialized\n"));
   return api;
 }
 
-
 /**
  * Exit point from the plugin.
  *
@@ -972,13 +1047,13 @@ libgnunet_plugin_rest_identity_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;
-
   plugin->cfg = NULL;
-  GNUNET_free_non_null (allow_methods);
-  GNUNET_free (api);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Identity REST plugin is finished\n");
+
+  GNUNET_free_non_null(allow_methods);
+  GNUNET_free(api);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Identity REST plugin is finished\n");
   return NULL;
 }
 
-/* end of plugin_rest_gns.c */
+/* end of plugin_rest_identity.c */
+
diff --git a/src/identity/test_plugin_rest_identity.sh 
b/src/identity/test_plugin_rest_identity.sh
new file mode 100755
index 000000000..d9377500e
--- /dev/null
+++ b/src/identity/test_plugin_rest_identity.sh
@@ -0,0 +1,159 @@
+#!/usr/bin/bash
+
+#First, start gnunet-arm and the rest-service.
+#Exit 0 means success, exit 1 means failed test
+
+identity_link="http://localhost:7776/identity";
+wrong_link="http://localhost:7776/identityandmore";
+
+
+curl_get () {
+    #$1 is link
+    #$2 is grep
+    cache="$(curl -v "$1" 2>&1 | grep "$2")"
+    #echo $cache
+    if [ "" == "$cache" ]
+    then
+        exit 1
+    fi
+}
+
+curl_post () {
+    #$1 is link
+    #$2 is data
+    #$3 is grep
+    cache="$(curl -v -X "POST" "$1" --data "$2" 2>&1 | grep "$3")"
+    #echo $cache
+    if [ "" == "$cache" ]
+    then
+        exit 1
+    fi
+}
+
+curl_delete () {
+    #$1 is link
+    #$2 is grep
+    cache="$(curl -v -X "DELETE" "$1" 2>&1 | grep "$2")"
+    #echo $cache
+    if [ "" == "$cache" ]
+    then
+        exit 1
+    fi
+}
+
+curl_put () {
+    #$1 is link
+    #$2 is data
+    #$3 is grep
+    cache="$(curl -v -X "PUT" "$1" --data "$2" 2>&1 | grep "$3")"
+    #echo $cache
+    if [ "" == "$cache" ]
+    then
+        exit 1
+    fi
+}
+
+#Test GET
+test="$(gnunet-identity -d)"
+#if no identity exists
+if [ "" == "$test" ]
+then
+    curl_get "$identity_link" "error"
+    gnunet-identity -C "test_plugin_rest_identity"
+    name="$(gnunet-identity -d | awk 'NR==1{print $1}')"
+    public="$(gnunet-identity -d | awk 'NR==1{print $3}')"
+    
+    curl_get "${identity_link}?name=$name" "$public"
+    curl_get "${identity_link}?name=" "error"
+    curl_get "${identity_link}?name=$public" "error"
+    
+    curl_get "${identity_link}?pubkey=$public" "$name"
+    curl_get "${identity_link}?pubkey=$name" "error"
+    curl_get "${identity_link}?pubkey=" "error"
+    
+    gnunet-identity -D "test_plugin_rest_identity"
+else
+    name="$(gnunet-identity -d | awk 'NR==1{print $1}')"
+    public="$(gnunet-identity -d | awk 'NR==1{print $3}')"
+    
+    curl_get "${identity_link}?name=$name" "$public"
+    curl_get "${identity_link}?name=" "error"
+    curl_get "${identity_link}?name=$public" "error"
+    
+    curl_get "${identity_link}?pubkey=$public" "$name"
+    curl_get "${identity_link}?pubkey=$name" "error"
+    curl_get "${identity_link}?pubkey=" "error"
+fi
+
+#Test POST
+gnunet-identity -D "test_plugin_rest_identity" > /dev/null 2>&1
+gnunet-identity -D "test_plugin_rest_identity1" > /dev/null 2>&1
+
+curl_post "${identity_link}" '{"name":"test_plugin_rest_identity"}' "HTTP/1.1 
201 Created"
+curl_post "${identity_link}" '{"name":"test_plugin_rest_identity"}' "HTTP/1.1 
409"
+curl_post "${identity_link}" '{"name":"Test_plugin_rest_identity"}' "HTTP/1.1 
409"
+curl_post "${identity_link}" '{}' "error"
+curl_post "${identity_link}" '' "error"
+curl_post "${identity_link}" '{"name":""}' "error"
+curl_post "${identity_link}" '{"name":123}' "error"
+curl_post "${identity_link}" '{"name":[]}' "error"
+curl_post "${identity_link}" '{"name1":"test_plugin_rest_identity"}' "error"
+curl_post "${identity_link}" '{"other":""}' "error"
+curl_post "${identity_link}" '{"name":"test_plugin_rest_identity1", 
"other":"test_plugin_rest_identity2"}' "error"
+
+#Test PUT
+name="$(gnunet-identity -d | grep "test_plugin_rest_identity" | awk 
'NR==1{print $1}')"
+public="$(gnunet-identity -d | grep "test_plugin_rest_identity" | awk 
'NR==1{print $3}')"
+
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity1","pubkey":"'$public'"}' "HTTP/1.1 204"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity1","pubkey":"'$public'"}' "HTTP/1.1 409"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity1","pubkey":"'$public'xx"}' "HTTP/1.1 404"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity1","pubkey":""}' "HTTP/1.1 404"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity1","pubke":""}' "HTTP/1.1 404"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity1","pubke":"","other":"sdfdsf"}' 
"HTTP/1.1 404"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity1","pubke":"","name":"sdfdsf"}' "HTTP/1.1 
404"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity","pubke":"","name":"test_plugin_rest_identity1"}'
 "HTTP/1.1 204"
+curl_put "${identity_link}" 
'{"newnam":"test_plugin_rest_identity","pubkey":"'$public'"}' "error"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity1","name":"test_plugin_rest_identity"}' 
"HTTP/1.1 204"
+curl_put "${identity_link}" 
'{"newname":"TEST_plugin_rest_identity1","name":"test_plugin_rest_identity1"}' 
"HTTP/1.1 409"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity1","name":"test_plugin_rest_identity1"}' 
"HTTP/1.1 409"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity","name":"test_plugin_rest_identityxxx"}' 
"HTTP/1.1 404"
+curl_put "${identity_link}" 
'{"newname":"test_plugin_rest_identity","name":"test_plugin_rest_identity1"}' 
"HTTP/1.1 204"
+curl_put "${identity_link}" 
'{"newnam":"test_plugin_rest_identityfail","name":"test_plugin_rest_identity"}' 
"error"
+
+
+#Test subsystem
+curl_put "${identity_link}" 
'{"subsystem":"namestore","name":"test_plugin_rest_identity"}' "HTTP/1.1 204"
+curl_put "${identity_link}" 
'{"subsystem":"namestore","name":"test_plugin_rest_identity"}' "HTTP/1.1 204"
+curl_get "${identity_link}?subsystem=namestore" "test_plugin_rest_identity"
+curl_post "${identity_link}" '{"name":"test_plugin_rest_identity1"}' "HTTP/1.1 
201 Created"
+public="$(gnunet-identity -d | grep "test_plugin_rest_identity" | awk 
'NR==1{print $3}')"
+curl_put "${identity_link}" '{"subsystem":"namestore","pubkey":"'"$public"'"}' 
"HTTP/1.1 204"
+curl_get "${identity_link}?subsystem=namestore" "test_plugin_rest_identity1"
+curl_get "${identity_link}?subsystem=test_plugin_rest_identity_no_subsystem" 
"error"
+curl_put "${identity_link}" 
'{"subsystem":"test_plugin_rest_identity_no_subsystem","name":"test_plugin_rest_identity1"}'
 "HTTP/1.1 204"
+curl_get "${identity_link}?subsystem=test_plugin_rest_identity_no_subsystem" 
"test_plugin_rest_identity1"
+
+curl_put "${identity_link}" 
'{"subsyste":"test_plugin_rest_identity_no_subsystem","name":"test_plugin_rest_identity1"}'
 "error"
+curl_put "${identity_link}" 
'{"subsystem":"test_plugin_rest_identity_no_subsystem","name":"Test_plugin_rest_identity1"}'
 "HTTP/1.1 204"
+
+#Test DELETE
+curl_delete "${identity_link}?name=test_plugin_rest_identity" "HTTP/1.1 204"
+curl_get "${identity_link}?name=test_plugin_rest_identity" "error"
+curl_delete "${identity_link}?name=TEST_plugin_rest_identity1" "HTTP/1.1 404"
+curl_delete "${identity_link}?name=test_plugin_rest_identity1" "HTTP/1.1 204"
+curl_get "${identity_link}?name=test_plugin_rest_identity1" "error"
+curl_delete "${identity_link}?name=test_plugin_rest_identity_not_found" 
"HTTP/1.1 404"
+curl_post "${identity_link}" '{"name":"test_plugin_rest_identity1"}' "HTTP/1.1 
201 Created"
+public="$(gnunet-identity -d | grep "test_plugin_rest_identity1" | awk 
'NR==1{print $3}')"
+curl_delete "${identity_link}?pubkey=$public" "HTTP/1.1 204"
+curl_delete "${identity_link}?pubke=$public" "error"
+curl_delete "${identity_link}?pubkey=$public&other=232" "HTTP/1.1 404"
+
+#Test wrong_link
+curl_get "$wrong_link" "HTTP/1.1 404"
+curl_post "$wrong_link" '{"name":"test_plugin_rest_identity"}' "HTTP/1.1 404"
+curl_put "$wrong_link" 
'{"newname":"test_plugin_rest_identity1","name":"test_plugin_rest_identity"}' 
"HTTP/1.1 404"
+curl_delete "$wrong_link?name=test_plugin_rest_identity1" "HTTP/1.1 404"
+
+exit 0;
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h
index 06749590c..781d5698b 100644
--- a/src/include/gnunet_json_lib.h
+++ b/src/include/gnunet_json_lib.h
@@ -26,6 +26,7 @@
 #define GNUNET_JSON_LIB_H
 
 #include "gnunet_util_lib.h"
+#include "gnunet_gnsrecord_lib.h"
 #include <jansson.h>
 
 
@@ -318,6 +319,17 @@ GNUNET_JSON_spec_rsa_signature (const char *name,
                                 struct GNUNET_CRYPTO_RsaSignature **sig);
 
 
+
+/**
+ * JSON Specification for GNS Records.
+ *
+ * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill
+ * @return JSON Specification
+ */
+struct GNUNET_JSON_Specification
+GNUNET_JSON_spec_gnsrecord_data (struct GNUNET_GNSRECORD_Data 
**gnsrecord_object);
+
+
 /* ****************** Generic generator interface ******************* */
 
 
@@ -393,6 +405,16 @@ GNUNET_JSON_from_rsa_public_key (const struct 
GNUNET_CRYPTO_RsaPublicKey *pk);
 json_t *
 GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig);
 
+/**
+ * Convert Gns record to JSON.
+ *
+ * @param rname name of record
+ * @param rd record data
+ * @return corresponding JSON encoding
+ */
+json_t *
+GNUNET_JSON_from_gns_record (const char* rname,
+                               const struct GNUNET_GNSRECORD_Data *rd);
 
 /* ******************* Helpers for MHD upload handling ******************* */
 
@@ -479,7 +501,6 @@ GNUNET_JSON_getopt (char shortName,
                     const char *description,
                     json_t **json);
 
-
 #endif
 
 /* end of gnunet_json_lib.h */
diff --git a/src/json/Makefile.am b/src/json/Makefile.am
index da19e7955..f3fa28d69 100644
--- a/src/json/Makefile.am
+++ b/src/json/Makefile.am
@@ -16,9 +16,11 @@ libgnunetjson_la_SOURCES = \
   json.c \
   json_mhd.c \
   json_generator.c \
-  json_helper.c
+  json_helper.c \
+  json_gnsrecord.c
 libgnunetjson_la_LIBADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
+  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   -ljansson \
   $(XLIB)
 
diff --git a/src/json/json_generator.c b/src/json/json_generator.c
index dd6df4f74..d8c82bc86 100644
--- a/src/json/json_generator.c
+++ b/src/json/json_generator.c
@@ -157,5 +157,40 @@ GNUNET_JSON_from_rsa_signature (const struct 
GNUNET_CRYPTO_RsaSignature *sig)
   return ret;
 }
 
+/**
+ * Convert Gns record to JSON.
+ *
+ * @param rname name of record
+ * @param rd record data
+ * @return corresponding JSON encoding
+ */
+json_t *
+GNUNET_JSON_from_gns_record (const char* rname,
+                            const struct GNUNET_GNSRECORD_Data *rd)
+{
+  struct GNUNET_TIME_Absolute expiration_time;
+  const char *expiration_time_str;
+  const char *record_type_str;
+  char *value_str;
+  json_t *ret;
+  int flags;
+
+  value_str = 
GNUNET_GNSRECORD_value_to_string(rd->record_type,rd->data,rd->data_size);
+  expiration_time = GNUNET_GNSRECORD_record_get_expiration_time(1, rd);
+  expiration_time_str = 
GNUNET_STRINGS_absolute_time_to_string(expiration_time);
+  flags = (int)rd->flags; //maybe necessary
+  record_type_str = GNUNET_GNSRECORD_number_to_typename(rd->record_type);
+
+  // ? for possible NULL values
+  ret = json_pack("{s:s?,s:s?,s:s?,s:i,s:s?}",
+                 "value", value_str,
+                 "type", record_type_str,
+                 "expiration_time", expiration_time_str,
+                 "flag", flags,
+                 "label", rname);
+  GNUNET_free_non_null(value_str);
+  return ret;
+}
+
 
 /* End of json/json_generator.c */
diff --git a/src/json/json_gnsrecord.c b/src/json/json_gnsrecord.c
new file mode 100644
index 000000000..7bdf97f06
--- /dev/null
+++ b/src/json/json_gnsrecord.c
@@ -0,0 +1,177 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2009-2013 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Affero General Public License for more details.
+
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file json/json_gnsrecord.c
+ * @brief JSON handling of GNS record data
+ * @author Philippe Buschmann
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_json_lib.h"
+
+#define GNUNET_JSON_GNSRECORD_VALUE "value"
+#define GNUNET_JSON_GNSRECORD_TYPE "type"
+#define GNUNET_JSON_GNSRECORD_EXPIRATION_TIME "expiration_time"
+#define GNUNET_JSON_GNSRECORD_FLAG "flag"
+#define GNUNET_JSON_GNSRECORD_LABEL "label"
+#define GNUNET_JSON_GNSRECORD_NEVER "never"
+
+
+/**
+ * Parse given JSON object to gns record
+ *
+ * @param cls closure, NULL
+ * @param root the json object representing data
+ * @param spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static int
+parse_gnsrecordobject (void *cls,
+                      json_t *root,
+                      struct GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_GNSRECORD_Data *gnsrecord_object;
+  struct GNUNET_TIME_Absolute abs_expiration_time;
+  int unpack_state=0;
+  const char *value;
+  const char *expiration_time;
+  const char *record_type;
+  const char *label;
+  int flag;
+  void *rdata = NULL;
+  size_t rdata_size;
+
+  GNUNET_assert(NULL != root);
+  if(!json_is_object(root))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               "Error json is not array nor object!\n");
+    return GNUNET_SYSERR;
+  }
+  //interpret single gns record
+  unpack_state = json_unpack(root,
+                            "{s:s, s:s, s:s, s?:i, s:s!}",
+                            GNUNET_JSON_GNSRECORD_VALUE, &value,
+                            GNUNET_JSON_GNSRECORD_TYPE, &record_type,
+                            GNUNET_JSON_GNSRECORD_EXPIRATION_TIME, 
&expiration_time,
+                            GNUNET_JSON_GNSRECORD_FLAG, &flag,
+                            GNUNET_JSON_GNSRECORD_LABEL, &label);
+  if (0 != unpack_state)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+              "Error json object has a wrong format!\n");
+    return GNUNET_SYSERR;
+  }
+  gnsrecord_object = GNUNET_new (struct GNUNET_GNSRECORD_Data);
+  gnsrecord_object->record_type = 
GNUNET_GNSRECORD_typename_to_number(record_type);
+  if (UINT32_MAX == gnsrecord_object->record_type)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Unsupported type\n");
+    GNUNET_free(gnsrecord_object);
+    return GNUNET_SYSERR;
+  }
+  if (GNUNET_OK
+      != GNUNET_GNSRECORD_string_to_value (gnsrecord_object->record_type,
+                                          value,
+                                          &rdata,
+                                          &rdata_size))
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Value invalid for record type\n");
+    GNUNET_free(gnsrecord_object);
+    return GNUNET_SYSERR;
+  }
+
+  gnsrecord_object->data = rdata;
+  gnsrecord_object->data_size = rdata_size;
+
+  if (0 == strcmp (expiration_time, GNUNET_JSON_GNSRECORD_NEVER))
+  {
+    gnsrecord_object->expiration_time = 
GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
+  }
+  else if (GNUNET_OK
+      == GNUNET_STRINGS_fancy_time_to_absolute (expiration_time,
+                                               &abs_expiration_time))
+  {
+    gnsrecord_object->expiration_time = abs_expiration_time.abs_value_us;
+  }
+  else
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Expiration time invalid\n");
+    GNUNET_free_non_null(rdata);
+    GNUNET_free(gnsrecord_object);
+    return GNUNET_SYSERR;
+  }
+  // check if flag is a valid enum value
+  if ((GNUNET_GNSRECORD_RF_NONE != flag)
+      && (GNUNET_GNSRECORD_RF_PRIVATE != flag)
+      && (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION != flag)
+      && (GNUNET_GNSRECORD_RF_SHADOW_RECORD) != flag)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Flag invalid\n");
+    GNUNET_free_non_null(rdata);
+    GNUNET_free(gnsrecord_object);
+    return GNUNET_SYSERR;
+  }
+  gnsrecord_object->flags = (enum GNUNET_GNSRECORD_Flags)flag;
+  *(struct GNUNET_GNSRECORD_Data **) spec->ptr = gnsrecord_object;
+  return GNUNET_OK;
+}
+
+/**
+ * Cleanup data left from parsing RSA public key.
+ *
+ * @param cls closure, NULL
+ * @param[out] spec where to free the data
+ */
+static void
+clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_GNSRECORD_Data **gnsrecord_object;
+  gnsrecord_object = (struct GNUNET_GNSRECORD_Data **) spec->ptr;
+  if (NULL != *gnsrecord_object)
+  {
+    if (NULL != (*gnsrecord_object)->data)
+      GNUNET_free((char*)(*gnsrecord_object)->data);
+
+    GNUNET_free(*gnsrecord_object);
+    *gnsrecord_object = NULL;
+  }
+}
+
+/**
+ * JSON Specification for GNS Records.
+ *
+ * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill
+ * @return JSON Specification
+ */
+struct GNUNET_JSON_Specification
+GNUNET_JSON_spec_gnsrecord_data (struct GNUNET_GNSRECORD_Data 
**gnsrecord_object)
+{
+  struct GNUNET_JSON_Specification ret = {
+    .parser = &parse_gnsrecordobject,
+    .cleaner = &clean_gnsrecordobject,
+    .cls = NULL,
+    .field = NULL,
+    .ptr = gnsrecord_object,
+    .ptr_size = 0,
+    .size_ptr = NULL
+  };
+  *gnsrecord_object = NULL;
+  return ret;
+}
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index 777e722c2..7f44c2a71 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -230,8 +230,8 @@ libgnunet_plugin_rest_namestore_la_LIBADD = \
   libgnunetnamestore.la \
   $(top_builddir)/src/rest/libgnunetrest.la \
   $(top_builddir)/src/identity/libgnunetidentity.la \
-       $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \
-  $(top_builddir)/src/jsonapi/libgnunetjsonapiutils.la \
+  $(top_builddir)/src/json/libgnunetjson.la \
+  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
   $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
   $(LTLIBINTL) -ljansson -lmicrohttpd
 libgnunet_plugin_rest_namestore_la_LDFLAGS = \
diff --git a/src/namestore/plugin_rest_namestore.c 
b/src/namestore/plugin_rest_namestore.c
index ec44046e0..f14707cce 100644
--- a/src/namestore/plugin_rest_namestore.c
+++ b/src/namestore/plugin_rest_namestore.c
@@ -11,15 +11,15 @@
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Affero General Public License for more details.
-  
+
    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */
 /**
  * @author Martin Schanzenbach
+ * @author Philippe Buschmann
  * @file namestore/plugin_rest_namestore.c
  * @brief GNUnet Namestore REST plugin
- *
  */
 
 #include "platform.h"
@@ -28,38 +28,45 @@
 #include "gnunet_namestore_service.h"
 #include "gnunet_identity_service.h"
 #include "gnunet_rest_lib.h"
-#include "gnunet_jsonapi_lib.h"
-#include "gnunet_jsonapi_util.h"
+#include "gnunet_json_lib.h"
 #include "microhttpd.h"
 #include <jansson.h>
 
-#define GNUNET_REST_API_NS_NAMESTORE "/names"
-
-#define GNUNET_REST_API_NS_NAMESTORE_ZKEY "/names/zkey"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO "record"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_NAME "name"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_REVINFO "revinfo"
 
-#define GNUNET_REST_JSONAPI_NAMESTORE_RECORD 
GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO
+#define GNUNET_REST_API_NS_NAMESTORE "/namestore"
+#define GNUNET_REST_SUBSYSTEM_NAMESTORE "namestore"
 
-#define GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE "record_type"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_VALUE "value"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_PUBLIC "public"
+/**
+ * Parameter names
+ */
+#define GNUNET_REST_API_PARAM_PUBKEY "pubkey"
+#define GNUNET_REST_API_PARAM_NAME "name"
 
-#define GNUNET_REST_JSONAPI_NAMESTORE_SHADOW "shadow"
+/**
+ * Error messages
+ */
+#define GNUNET_REST_NAMESTORE_ERROR_UNKNOWN "Unknown Error"
 
-#define GNUNET_REST_JSONAPI_NAMESTORE_PKEY "pkey"
+#define GNUNET_REST_NAMESTORE_RD_COUNT 1
 
-#define GNUNET_REST_JSONAPI_NAMESTORE_ZKEY "zkey"
+/**
+ * State while collecting all egos
+ */
+#define ID_REST_STATE_INIT 0
 
-#define GNUNET_REST_JSONAPI_NAMESTORE_EXPIRATION "expiration"
+/**
+ * Done collecting egos
+ */
+#define ID_REST_STATE_POST_INIT 1
+/**
+ * The configuration handle
+ */
+const struct GNUNET_CONFIGURATION_Handle *cfg;
 
-#define GNUNET_REST_JSONAPI_NAMESTORE_EGO "ego"
+/**
+ * HTTP methods allows for this plugin
+ */
+static char* allow_methods;
 
 /**
  * @brief struct returned by the initialization function of the plugin
@@ -69,135 +76,110 @@ struct Plugin
   const struct GNUNET_CONFIGURATION_Handle *cfg;
 };
 
-
 /**
- * HTTP methods allows for this plugin
+ * The default namestore ego
  */
-static char* allow_methods;
-
-const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-struct RecordEntry
+struct EgoEntry
 {
   /**
    * DLL
    */
-  struct RecordEntry *next;
+  struct EgoEntry *next;
 
   /**
    * DLL
    */
-  struct RecordEntry *prev;
-
-};
-
-struct RequestHandle
-{
-  /**
-   * Ego list
-   */
-  struct RecordEntry *record_head;
-
-  /**
-   * Ego list
-   */
-  struct record_entry *record_tail;
+  struct EgoEntry *prev;
 
   /**
-   * JSON response object
+   * Ego Identifier
    */
-  struct GNUNET_JSONAPI_Document *resp_object;
+  char *identifier;
 
   /**
-   * Rest connection
+   * Public key string
    */
-  struct GNUNET_REST_RequestHandle *rest_handle;
+  char *keystring;
 
   /**
-   * Handle to GNS service.
-   */
-  struct GNUNET_IDENTITY_Handle *identity_handle;
-
-  /**
-   * Handle to NAMESTORE
+   * The Ego
    */
-  struct GNUNET_NAMESTORE_Handle *ns_handle;
+  struct GNUNET_IDENTITY_Ego *ego;
+};
 
-  /**
-   * Handle to NAMESTORE it
-   */
-  struct GNUNET_NAMESTORE_ZoneIterator *list_it;
 
+struct RequestHandle
+{
   /**
-   * Private key for the zone
+   * Records to store
    */
-  struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey;
+  char *label_name;
 
   /**
-   * Handle to identity lookup
+   * Records to store
    */
-  struct GNUNET_IDENTITY_EgoLookup *ego_lookup;
+  struct GNUNET_GNSRECORD_Data *rd;
 
   /**
-   * Default Ego operation
+   * NAMESTORE Operation
    */
-  struct GNUNET_IDENTITY_Operation *get_default;
+  struct GNUNET_NAMESTORE_QueueEntry *add_qe;
 
   /**
-   * Name of the ego
+   * Response object
    */
-  char *ego_name;
+  json_t *resp_object;
 
   /**
-   * Record is public
+   * The processing state
    */
-  int is_public;
+  int state;
 
   /**
-   * Shadow record
+   * Handle to NAMESTORE
    */
-  int is_shadow;
+  struct GNUNET_NAMESTORE_Handle *ns_handle;
 
   /**
-   * Name of the record to modify
+   * Handle to NAMESTORE it
    */
-  char *name;
+  struct GNUNET_NAMESTORE_ZoneIterator *list_it;
 
   /**
-   * Value of the record
+   * Private key for the zone
    */
-  char *value;
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_pkey;
 
   /**
-   * Zkey string
+   * IDENTITY Operation
    */
-  const char* zkey_str;
+  struct EgoEntry *ego_entry;
 
   /**
-   * record type
+   * Ego list
    */
-  uint32_t type;
+  struct EgoEntry *ego_head;
 
   /**
-   * Records to store
+   * Ego list
    */
-  struct GNUNET_GNSRECORD_Data *rd;
+  struct EgoEntry *ego_tail;
 
   /**
-   * record count
+   * IDENTITY Operation
    */
-  unsigned int rd_count;
+  struct GNUNET_IDENTITY_Operation *op;
 
   /**
-   * NAMESTORE Operation
+   * Handle to Identity service.
    */
-  struct GNUNET_NAMESTORE_QueueEntry *add_qe;
+  struct GNUNET_IDENTITY_Handle *identity_handle;
 
   /**
-   * NAMESTORE Operation
+   * Rest connection
    */
-  struct GNUNET_NAMESTORE_QueueEntry *reverse_qe;
-
+  struct GNUNET_REST_RequestHandle *rest_handle;
+  
   /**
    * Desired timeout for the lookup (default is no timeout).
    */
@@ -206,7 +188,7 @@ struct RequestHandle
   /**
    * ID of a task associated with the resolution process.
    */
-  struct GNUNET_SCHEDULER_Task * timeout_task;
+  struct GNUNET_SCHEDULER_Task *timeout_task;
 
   /**
    * The plugin result processor
@@ -224,164 +206,201 @@ struct RequestHandle
   char *url;
 
   /**
-   * Cfg
+   * Error response message
    */
-  const struct GNUNET_CONFIGURATION_Handle *cfg;
+  char *emsg;
 
   /**
-   * HTTP response code
+   * Reponse code
    */
   int response_code;
 
 };
 
-
 /**
  * Cleanup lookup handle
- *
  * @param handle Handle to clean up
  */
 static void
-cleanup_handle (struct RequestHandle *handle)
+cleanup_handle (void *cls)
 {
-  struct RecordEntry *record_entry;
-  struct RecordEntry *record_tmp;
+  struct RequestHandle *handle = cls;
+  struct EgoEntry *ego_entry;
+  struct EgoEntry *ego_tmp;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Cleaning up\n");
-  if (NULL != handle->resp_object)
-    GNUNET_JSONAPI_document_delete (handle->resp_object);
-  if (NULL != handle->name)
-    GNUNET_free (handle->name);
   if (NULL != handle->timeout_task)
+  {
     GNUNET_SCHEDULER_cancel (handle->timeout_task);
-  if (NULL != handle->ego_lookup)
-    GNUNET_IDENTITY_ego_lookup_cancel (handle->ego_lookup);
-  if (NULL != handle->get_default)
-    GNUNET_IDENTITY_cancel (handle->get_default);
+    handle->timeout_task = NULL;
+  }
+  if (NULL != handle->label_name)
+    GNUNET_free(handle->label_name);
+  if (NULL != handle->url)
+    GNUNET_free(handle->url);
+  if (NULL != handle->emsg)
+    GNUNET_free(handle->emsg);
+  if (NULL != handle->rd)
+  {
+    if (NULL != handle->rd->data)
+      GNUNET_free((void*)handle->rd->data);
+    GNUNET_free(handle->rd);
+  }
+  if (NULL != handle->timeout_task)
+    GNUNET_SCHEDULER_cancel(handle->timeout_task);
   if (NULL != handle->list_it)
-    GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it);
+    GNUNET_NAMESTORE_zone_iteration_stop(handle->list_it);
   if (NULL != handle->add_qe)
-    GNUNET_NAMESTORE_cancel (handle->add_qe);
+    GNUNET_NAMESTORE_cancel(handle->add_qe);
   if (NULL != handle->identity_handle)
-    GNUNET_IDENTITY_disconnect (handle->identity_handle);
+    GNUNET_IDENTITY_disconnect(handle->identity_handle);
   if (NULL != handle->ns_handle)
-    GNUNET_NAMESTORE_disconnect (handle->ns_handle);
-  if (NULL != handle->url)
-    GNUNET_free (handle->url);
-  if (NULL != handle->value)
-    GNUNET_free (handle->value);
-  if (NULL != handle->rd)
   {
-    for (unsigned int i = 0; i < handle->rd_count; i++)
-    {
-      if (NULL != handle->rd[i].data)
-        GNUNET_free ((void*)handle->rd[i].data);
-    }
-    GNUNET_free (handle->rd);
+    GNUNET_NAMESTORE_disconnect(handle->ns_handle);
   }
-  if (NULL != handle->ego_name)
-    GNUNET_free (handle->ego_name);
-  for (record_entry = handle->record_head;
-       NULL != record_entry;)
+
+  for (ego_entry = handle->ego_head;
+  NULL != ego_entry;)
   {
-    record_tmp = record_entry;
-    record_entry = record_entry->next;
-    GNUNET_free (record_tmp);
+    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)
+  {
+    json_decref(handle->resp_object);
+  }
+
   GNUNET_free (handle);
 }
 
 
 /**
- * Create json representation of a GNSRECORD
+ * Task run on errors.  Reports an error and cleans up everything.
  *
- * @param rd the GNSRECORD_Data
+ * @param cls the `struct RequestHandle`
  */
-static json_t *
-gnsrecord_to_json (const struct GNUNET_GNSRECORD_Data *rd)
+static void
+do_error (void *cls)
 {
-  const char *typename;
-  char *string_val;
-  const char *exp_str;
-  json_t *record_obj;
+  struct RequestHandle *handle = cls;
+  struct MHD_Response *resp;
+  json_t *json_error = json_object();
+  char *response;
 
-  typename = GNUNET_GNSRECORD_number_to_typename (rd->record_type);
-  string_val = GNUNET_GNSRECORD_value_to_string (rd->record_type,
-                                                 rd->data,
-                                                 rd->data_size);
+  if (NULL == handle->emsg)
+    handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_ERROR_UNKNOWN);
 
-  if (NULL == string_val)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Record of type %d malformed, skipping\n",
-                (int) rd->record_type);
-    return NULL;
-  }
-  record_obj = json_object();
-  json_object_set_new (record_obj,
-                       GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE,
-                       json_string (typename));
-  json_object_set_new (record_obj,
-                       GNUNET_REST_JSONAPI_NAMESTORE_VALUE,
-                       json_string (string_val));
-  GNUNET_free (string_val);
-
-  if (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd->flags)
+  json_object_set_new(json_error,"error", json_string(handle->emsg));
+
+  if (0 == handle->response_code)
+    handle->response_code = MHD_HTTP_OK;
+  response = json_dumps (json_error, 0);
+  resp = GNUNET_REST_create_response (response);
+  handle->proc (handle->proc_cls, resp, handle->response_code);
+  json_decref(json_error);
+  GNUNET_free(response);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
+}
+
+
+/**
+ * Get EgoEntry from list with either a public key or a name
+ * If public key and name are not NULL, it returns the public key result first
+ *
+ * @param handle the RequestHandle
+ * @param pubkey the public key of an identity (only one can be NULL)
+ * @param name the name of an identity (only one can be NULL)
+ * @return EgoEntry or NULL if not found
+ */
+struct EgoEntry*
+get_egoentry(struct RequestHandle *handle, char* pubkey, char *name)
+{
+  struct EgoEntry *ego_entry;
+  if (NULL != pubkey)
   {
-    struct GNUNET_TIME_Relative time_rel;
-    time_rel.rel_value_us = rd->expiration_time;
-    exp_str = GNUNET_STRINGS_relative_time_to_string (time_rel, 1);
+    for (ego_entry = handle->ego_head;
+       NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    {
+      if (0 != strcasecmp (pubkey, ego_entry->keystring))
+       continue;
+      return ego_entry;
+    }
   }
-  else
+  if (NULL != name)
   {
-    struct GNUNET_TIME_Absolute time_abs;
-    time_abs.abs_value_us = rd->expiration_time;
-    exp_str = GNUNET_STRINGS_absolute_time_to_string (time_abs);
+    for (ego_entry = handle->ego_head;
+       NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    {
+      if (0 != strcasecmp (name, ego_entry->identifier))
+       continue;
+      return ego_entry;
+    }
   }
-  json_object_set_new (record_obj, GNUNET_REST_JSONAPI_NAMESTORE_EXPIRATION, 
json_string (exp_str));
-
-  json_object_set_new (record_obj, "expired",
-                       json_boolean (GNUNET_YES == GNUNET_GNSRECORD_is_expired 
(rd)));
-  return record_obj;
+  return NULL;
 }
 
 
 /**
- * Task run on error.  Generates error response and cleans up.
- *
- * @param cls the request to generate an error response for
+ * Does internal server error when iteration failed.
  */
 static void
-do_error (void *cls)
+namestore_iteration_error (void *cls)
 {
   struct RequestHandle *handle = cls;
   struct MHD_Response *resp = GNUNET_REST_create_response (NULL);
-
-  handle->proc (handle->proc_cls, resp, handle->response_code);
-  cleanup_handle (handle);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_INTERNAL_SERVER_ERROR);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 
-/**
- * Task run on timeout.
- *
- * @param cls the request to time out
- */
 static void
-do_timeout (void *cls)
+create_finished (void *cls, int32_t success, const char *emsg)
 {
   struct RequestHandle *handle = cls;
+  struct MHD_Response *resp;
 
-  handle->timeout_task = NULL;
-  do_error (handle);
+  handle->add_qe = NULL;
+  if (GNUNET_YES != success)
+  {
+    handle->emsg = GNUNET_strdup("Error storing records");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  resp = GNUNET_REST_create_response (NULL);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 
 static void
-cleanup_handle_delayed (void *cls)
+del_finished (void *cls, int32_t success, const char *emsg)
 {
-  cleanup_handle (cls);
+  struct RequestHandle *handle = cls;
+
+  handle->add_qe = NULL;
+  if (GNUNET_NO == success)
+  {
+    handle->emsg = GNUNET_strdup("Deleting record failed. Record does not 
exist");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  if (GNUNET_SYSERR == success)
+  {
+    handle->emsg = GNUNET_strdup("Deleting record failed");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  handle->proc (handle->proc_cls,
+                GNUNET_REST_create_response (NULL),
+                MHD_HTTP_NO_CONTENT);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 
@@ -395,31 +414,24 @@ static void
 namestore_list_finished (void *cls)
 {
   struct RequestHandle *handle = cls;
-  char *result;
+  char *result_str;
   struct MHD_Response *resp;
 
   handle->list_it = NULL;
-  if (NULL == handle->resp_object)
-    handle->resp_object = GNUNET_JSONAPI_document_new ();
 
-  if (GNUNET_SYSERR ==
-      GNUNET_JSONAPI_document_serialize (handle->resp_object,
-                                         &result))
+  if (NULL == handle->resp_object)
   {
-    handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
-    GNUNET_SCHEDULER_add_now (&do_error,
-                              handle);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  resp = GNUNET_REST_create_response (result);
-  handle->proc (handle->proc_cls,
-                resp,
-                MHD_HTTP_OK);
-  GNUNET_free_non_null (result);
-  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed,
-                            handle);
-}
 
+  result_str = json_dumps (handle->resp_object, 0);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
+  resp = GNUNET_REST_create_response (result_str);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_free_non_null (result_str);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
+}
 
 
 /**
@@ -428,84 +440,111 @@ namestore_list_finished (void *cls)
  * @param handle the RequestHandle
  */
 static void
-namestore_list_response (void *cls,
+namestore_list_iteration (void *cls,
                          const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
                          const char *rname,
                          unsigned int rd_len,
                          const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct RequestHandle *handle = cls;
-  struct GNUNET_JSONAPI_Resource *json_resource;
-  json_t *result_array;
   json_t *record_obj;
 
   if (NULL == handle->resp_object)
-    handle->resp_object = GNUNET_JSONAPI_document_new ();
+    handle->resp_object = json_array();
 
-  if ( (NULL != handle->name) &&
-       (0 != strcmp (handle->name,
+  /*if ( (NULL != handle->ego_entry->identifier) &&
+       (0 != strcmp (handle->ego_entry->identifier,
                     rname)) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "%s does not match %s\n",
-               rname,
-               handle->name);
-    GNUNET_NAMESTORE_zone_iterator_next (handle->list_it,
-                                         1);
+                "%s does not match %s\n", rname,
+              handle->ego_entry->identifier);
+    GNUNET_NAMESTORE_zone_iterator_next (handle->list_it, 1);
     return;
-  }
+  }*/
 
-  result_array = json_array ();
-  for (unsigned int i=0; i<rd_len; i++)
+  for (unsigned int i = 0; i < rd_len; i++)
   {
     if ( (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
          (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT)) )
       continue;
 
-    if ( (rd[i].record_type != handle->type) &&
-         (GNUNET_GNSRECORD_TYPE_ANY != handle->type) )
+    record_obj = GNUNET_JSON_from_gns_record(rname,rd);
+
+    if(NULL == record_obj)
       continue;
-    record_obj = gnsrecord_to_json (&rd[i]);
-    json_array_append (result_array,
-                      record_obj);
-    json_decref (record_obj);
-  }
 
-  if (0 < json_array_size(result_array))
-  {
-    json_resource = GNUNET_JSONAPI_resource_new 
(GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO,
-                                                 rname);
-    GNUNET_JSONAPI_resource_add_attr (json_resource,
-                                      GNUNET_REST_JSONAPI_NAMESTORE_RECORD,
-                                      result_array);
-    GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource);
+    json_array_append (handle->resp_object, record_obj);
+    json_decref (record_obj);
   }
 
-  json_decref (result_array);
-  GNUNET_NAMESTORE_zone_iterator_next (handle->list_it,
-                                       1);
+  GNUNET_NAMESTORE_zone_iterator_next (handle->list_it, 1);
 }
 
 
-static void
-create_finished (void *cls, int32_t success, const char *emsg)
+/**
+ * Handle namestore GET request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+void
+namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
+                 const char* url,
+                 void *cls)
 {
   struct RequestHandle *handle = cls;
-  struct MHD_Response *resp;
+  struct EgoEntry *ego_entry = NULL;
+  struct GNUNET_HashCode key;
+  char *pubkey = NULL;
+  char *name = NULL;
+
+  //change zone if pubkey or name specified
+  GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_PUBKEY,
+                     strlen (GNUNET_REST_API_PARAM_PUBKEY),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                &key))
+  {
+    pubkey = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
+                                               &key);
+  }
+  GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_NAME,
+                     strlen (GNUNET_REST_API_PARAM_NAME),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                &key))
+  {
+    name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
+                                             &key);
+  }
 
-  handle->add_qe = NULL;
-  if (GNUNET_YES != success)
+  ego_entry = get_egoentry(handle,pubkey,name);
+  if (NULL == ego_entry)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Error storing records%s%s\n",
-                (NULL == emsg) ? "" : ": ",
-                (NULL == emsg) ? "" : emsg);
-    GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
-    return;
+    if (NULL != pubkey || NULL != name)
+    {
+      handle->emsg = GNUNET_strdup("Invalid identity");
+      handle->response_code = MHD_HTTP_NOT_FOUND;
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
   }
-  resp = GNUNET_REST_create_response (NULL);
-  handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT);
-  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
+  if ( NULL != ego_entry )
+  {
+    handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
+  }
+  handle->list_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
+                                                           handle->zone_pkey,
+                                                           
&namestore_iteration_error,
+                                                           handle,
+                                                           
&namestore_list_iteration,
+                                                           handle,
+                                                           
&namestore_list_finished,
+                                                           handle);
 }
 
 
@@ -529,10 +568,10 @@ create_new_record_cont (void *cls,
   struct RequestHandle *handle = cls;
 
   handle->add_qe = NULL;
-  if (0 != strcmp (rec_name, handle->name))
+  if (0 != strcmp (rec_name, handle->label_name))
   {
     GNUNET_break (0);
-    do_error (handle);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
@@ -541,426 +580,262 @@ create_new_record_cont (void *cls,
     handle->proc (handle->proc_cls,
                   GNUNET_REST_create_response (NULL),
                   MHD_HTTP_CONFLICT);
-    GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
+    GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
     return;
   }
-
-  GNUNET_assert (NULL != handle->name);
   handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
-                                                   &handle->zone_pkey,
-                                                   handle->name,
-                                                   handle->rd_count,
+                                                   handle->zone_pkey,
+                                                   handle->label_name,
+                                                   
GNUNET_REST_NAMESTORE_RD_COUNT,
                                                    handle->rd,
                                                    &create_finished,
                                                    handle);
 }
 
-
-static void
-del_finished (void *cls,
-              int32_t success,
-              const char *emsg)
+/**
+ * Handle namestore POST request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+void
+namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
+               const char* url,
+              void *cls)
 {
   struct RequestHandle *handle = cls;
+  struct GNUNET_GNSRECORD_Data *gns_record;
+  json_t *data_js;
+  json_t *name_json;
+  json_error_t err;
 
-  handle->add_qe = NULL;
-  if (GNUNET_NO == success)
+  struct EgoEntry *ego_entry = NULL;
+  struct GNUNET_HashCode key;
+  char *pubkey = NULL;
+  char *name = NULL;
+
+  char term_data[handle->rest_handle->data_size + 1];
+  struct GNUNET_JSON_Specification gnsspec[] = {
+    GNUNET_JSON_spec_gnsrecord_data(&gns_record),
+    GNUNET_JSON_spec_end ()
+  };
+
+  if (strlen (GNUNET_REST_API_NS_NAMESTORE) != strlen (handle->url))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Deleting record failed, record does not exist%s%s\n"),
-                (NULL != emsg) ? ": " : "",
-                (NULL != emsg) ? emsg : "");
-    GNUNET_SCHEDULER_add_now (&do_error, handle); //do_not_found TODO
+    handle->emsg = GNUNET_strdup("Wrong URL");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  if (GNUNET_SYSERR == success)
+  if (0 >= handle->rest_handle->data_size)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Deleting record failed%s%s\n"),
-                (NULL != emsg) ? ": " : "",
-                (NULL != emsg) ? emsg : "");
+    handle->emsg = GNUNET_strdup("No data");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  handle->proc (handle->proc_cls,
-                GNUNET_REST_create_response (NULL),
-                MHD_HTTP_NO_CONTENT);
-  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
-}
-
-
-static void
-del_cont (void *cls,
-          const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
-          const char *label,
-          unsigned int rd_count,
-          const struct GNUNET_GNSRECORD_Data *rd)
-{
-  struct RequestHandle *handle = cls;
-
-  handle->add_qe = NULL;
-  if (0 == rd_count)
+  term_data[handle->rest_handle->data_size] = '\0';
+  GNUNET_memcpy(term_data, handle->rest_handle->data,
+               handle->rest_handle->data_size);
+  data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
+  if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("There are no records under label `%s' that could be 
deleted.\n"),
-                label);
-    do_error (handle);
+    handle->emsg = GNUNET_strdup("Invalid data");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    GNUNET_JSON_parse_free(gnsspec);
+    json_decref (data_js);
     return;
   }
+  handle->rd = gns_record;
 
-  handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
-                                                   &handle->zone_pkey,
-                                                   handle->name,
-                                                   0, NULL,
-                                                   &del_finished,
-                                                   handle);
-}
-
-
-static void
-namestore_delete_cont (struct GNUNET_REST_RequestHandle *con,
-                       const char *url,
-                       void *cls)
-{
-  struct RequestHandle *handle = cls;
-
-  if (NULL == handle->name)
+  name_json = json_object_get(data_js, "label");
+  if (!json_is_string(name_json))
   {
+    handle->emsg = GNUNET_strdup("Missing name");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
+    json_decref (data_js);
     return;
   }
-
-  handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
-                                                    &handle->zone_pkey,
-                                                    handle->name,
-                                                    &do_error,
-                                                    handle,
-                                                    &del_cont,
-                                                    handle);
-}
-
-
-static int
-json_to_gnsrecord (const json_t *records_json,
-                   struct GNUNET_GNSRECORD_Data **rd,
-                   unsigned int *rd_count)
-{
-  struct GNUNET_TIME_Relative etime_rel;
-  struct GNUNET_TIME_Absolute etime_abs;
-  char *value;
-  void *rdata;
-  size_t rdata_size;
-  const char *typestring;
-  const char *expirationstring;
-  json_t *type_json;
-  json_t *value_json;
-  json_t *record_json;
-  json_t *exp_json;
-
-  *rd_count = json_array_size (records_json);
-  *rd = GNUNET_new_array (*rd_count,
-                          struct GNUNET_GNSRECORD_Data);
-  for (unsigned int i = 0; i < *rd_count; i++)
+  handle->label_name = GNUNET_strdup(json_string_value(name_json));
+  if(NULL == handle->label_name)
   {
-    memset (&(*rd)[i],
-           0,
-           sizeof (struct GNUNET_GNSRECORD_Data));
-    record_json = json_array_get (records_json,
-                                 i);
-    type_json = json_object_get (record_json,
-                                 GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE);
-    if (! json_is_string (type_json))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Type property is no string\n");
-      return GNUNET_SYSERR;
-    }
-    typestring = json_string_value (type_json);
-    (*rd)[i].record_type = GNUNET_GNSRECORD_typename_to_number (typestring);
-    if (UINT32_MAX == (*rd)[i].record_type)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unsupported type `%s'\n"),
-                  json_string_value (type_json));
-      return GNUNET_SYSERR;
-    }
-    value_json = json_object_get (record_json,
-                                  GNUNET_REST_JSONAPI_NAMESTORE_VALUE);
-    if (! json_is_string (value_json))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Value property is no string\n");
-      return GNUNET_SYSERR;
-    }
-    value = GNUNET_strdup (json_string_value (value_json));
-    if (GNUNET_OK !=
-       GNUNET_GNSRECORD_string_to_value ((*rd)[i].record_type,
-                                         value,
-                                         &rdata,
-                                         &rdata_size))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 _("Value `%s' invalid for record type `%s'\n"),
-                  value,
-                 typestring);
-      return GNUNET_SYSERR;
-    }
-    (*rd)[i].data = rdata;
-    (*rd)[i].data_size = rdata_size;
-    /**TODO
-     * if (1 == handle->is_shadow)
-     rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
-     if (1 != handle->is_public)
-     rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
-     */
-    exp_json = json_object_get (record_json,
-                                GNUNET_REST_JSONAPI_NAMESTORE_EXPIRATION);
-    if (! json_is_string (exp_json))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Expiration property is no string\n");
-      return GNUNET_SYSERR;
-    }
-    expirationstring = json_string_value (exp_json);
-    if (0 == strcmp (expirationstring, "never"))
-    {
-      (*rd)[i].expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
-    }
-    else if (GNUNET_OK ==
-             GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
-                                                    &etime_rel))
-    {
-      (*rd)[i].expiration_time = etime_rel.rel_value_us;
-      (*rd)[i].flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
-    }
-    else if (GNUNET_OK ==
-             GNUNET_STRINGS_fancy_time_to_absolute (expirationstring,
-                                                    &etime_abs))
-    {
-      (*rd)[i].expiration_time = etime_abs.abs_value_us;
-    }
-    else
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 _("Value `%s' invalid for record type `%s'\n"),
-                  value,
-                 typestring);
-      return GNUNET_SYSERR;
-    }
-  }
-  return GNUNET_OK;
-}
-
-
-static void
-namestore_create_cont (struct GNUNET_REST_RequestHandle *con,
-                       const char *url,
-                       void *cls)
-{
-  struct RequestHandle *handle = cls;
-  struct MHD_Response *resp;
-  struct GNUNET_JSONAPI_Document *json_obj;
-  struct GNUNET_JSONAPI_Resource *json_res;
-  json_t *records_json;
-  json_t *data_js;
-  json_error_t err;
-  char term_data[handle->rest_handle->data_size+1];
-  struct GNUNET_JSON_Specification docspec[] = {
-    GNUNET_JSON_spec_jsonapi_document (&json_obj),
-    GNUNET_JSON_spec_end()
-  };
-
-  if (strlen (GNUNET_REST_API_NS_NAMESTORE) != strlen (handle->url))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Cannot create under %s\n", handle->url);
+    handle->emsg = GNUNET_strdup("Missing name");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
+    json_decref (data_js);
     return;
   }
-  if (0 >= handle->rest_handle->data_size)
+  if (0 >= strlen(handle->label_name))
   {
+    handle->emsg = GNUNET_strdup("Missing name");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
+    json_decref (data_js);
     return;
   }
-  term_data[handle->rest_handle->data_size] = '\0';
-  GNUNET_memcpy (term_data,
-                 handle->rest_handle->data,
-                 handle->rest_handle->data_size);
-  data_js = json_loads (term_data,
-                        JSON_DECODE_ANY,
-                        &err);
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_JSON_parse (data_js, docspec,
-                                    NULL, NULL));
   json_decref (data_js);
-  if (NULL == json_obj)
+
+  //change zone if pubkey or name specified
+  GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_PUBKEY,
+                     strlen (GNUNET_REST_API_PARAM_PUBKEY),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                &key))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unable to parse JSONAPI Object from %s\n",
-                term_data);
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
+    pubkey = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
+                                               &key);
   }
-  if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
+  GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_NAME,
+                     strlen (GNUNET_REST_API_PARAM_NAME),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                &key))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Cannot create more than 1 resource! (Got %d)\n",
-                GNUNET_JSONAPI_document_resource_count (json_obj));
-    GNUNET_JSONAPI_document_delete (json_obj);
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
+    name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
+                                             &key);
   }
-  json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
-  if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res,
-                                                       
GNUNET_REST_JSONAPI_NAMESTORE_RECORD))
+
+  ego_entry = get_egoentry(handle,pubkey,name);
+  if (NULL == ego_entry)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unsupported JSON data type\n");
-    GNUNET_JSONAPI_document_delete (json_obj);
-    resp = GNUNET_REST_create_response (NULL);
-    handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
-    cleanup_handle (handle);
-    return;
+    if (NULL != pubkey || NULL != name)
+    {
+      handle->emsg = GNUNET_strdup("Invalid identity");
+      handle->response_code = MHD_HTTP_NOT_FOUND;
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
   }
-  handle->name = GNUNET_strdup (GNUNET_JSONAPI_resource_get_id (json_res));
-  records_json = GNUNET_JSONAPI_resource_read_attr (json_res,
-                                                    
GNUNET_REST_JSONAPI_NAMESTORE_RECORD);
-  if (NULL == records_json)
+  if ( NULL != ego_entry )
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "No records given\n");
-    GNUNET_JSONAPI_document_delete (json_obj);
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
+    handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
   }
-  if (GNUNET_SYSERR == json_to_gnsrecord (records_json, &handle->rd, 
&handle->rd_count))
+  if (NULL == handle->zone_pkey)
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
+    handle->emsg = GNUNET_strdup("No default identity for namestore");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_JSONAPI_document_delete (json_obj);
-
   handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
-                                                    &handle->zone_pkey,
-                                                    handle->name,
-                                                    &do_error,
-                                                    handle,
-                                                    &create_new_record_cont,
-                                                    handle);
+                                                   handle->zone_pkey,
+                                                   handle->label_name,
+                                                   &do_error,
+                                                   handle,
+                                                   &create_new_record_cont,
+                                                   handle);
 }
 
 
 static void
-namestore_zkey_response (void *cls,
-                         const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
-                         const char *label,
-                         unsigned int rd_count,
-                         const struct GNUNET_GNSRECORD_Data *rd)
+del_cont (void *cls,
+          const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+          const char *label,
+          unsigned int rd_count,
+          const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct RequestHandle *handle = cls;
-  struct MHD_Response *resp;
-  struct GNUNET_JSONAPI_Document *json_obj;
-  struct GNUNET_JSONAPI_Resource *json_res;
-  json_t *name_json;
-  char* result;
 
-  handle->reverse_qe = NULL;
-  json_obj = GNUNET_JSONAPI_document_new ();
-  if (NULL != label)
-  {
-    name_json = json_string (label);
-    json_res = GNUNET_JSONAPI_resource_new 
(GNUNET_REST_JSONAPI_NAMESTORE_REVINFO,
-                                            handle->zkey_str);
-    GNUNET_JSONAPI_resource_add_attr (json_res,
-                                      GNUNET_REST_JSONAPI_NAMESTORE_NAME,
-                                      name_json);
-    GNUNET_JSONAPI_document_resource_add (json_obj, json_res);
-    json_decref (name_json);
-  }
-  //Handle response
-  if (GNUNET_SYSERR == GNUNET_JSONAPI_document_serialize (json_obj, &result))
+  handle->add_qe = NULL;
+  if (0 == rd_count)
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
+    handle->emsg = GNUNET_strdup("Record not found");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  resp = GNUNET_REST_create_response (result);
-  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  GNUNET_JSONAPI_document_delete (json_obj);
-  GNUNET_free (result);
-  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
-}
 
+  handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
+                                                   handle->zone_pkey,
+                                                   handle->label_name,
+                                                   0, NULL,
+                                                   &del_finished,
+                                                   handle);
+}
 
-static void
-namestore_zkey_cont (struct GNUNET_REST_RequestHandle *con,
-                     const char *url,
-                     void *cls)
+/**
+ * Handle namestore DELETE request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+void
+namestore_delete (struct GNUNET_REST_RequestHandle *con_handle,
+                 const char* url,
+                 void *cls)
 {
   struct RequestHandle *handle = cls;
   struct GNUNET_HashCode key;
-  struct GNUNET_CRYPTO_EcdsaPublicKey pubkey;
-
-  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_NAMESTORE_ZKEY,
-                      strlen (GNUNET_REST_JSONAPI_NAMESTORE_ZKEY),
-                      &key);
-  if ( GNUNET_NO ==
-       GNUNET_CONTAINER_multihashmap_contains 
(handle->rest_handle->url_param_map,
-                                               &key) )
+  struct EgoEntry *ego_entry = NULL;
+  char *pubkey = NULL;
+  char *name = NULL;
+
+  //change zone if pubkey or name specified
+  GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_PUBKEY,
+                     strlen (GNUNET_REST_API_PARAM_PUBKEY),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                &key))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "No zkey given %s\n", handle->url);
+    pubkey = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
+                                               &key);
+  }
+  GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_NAME,
+                     strlen (GNUNET_REST_API_PARAM_NAME),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                &key))
+  {
+    name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
+                                             &key);
+  }
+
+  ego_entry = get_egoentry(handle,pubkey,name);
+  if (NULL == ego_entry)
+  {
+    if (NULL != pubkey || NULL != name)
+    {
+      handle->emsg = GNUNET_strdup("Invalid identity");
+      handle->response_code = MHD_HTTP_NOT_FOUND;
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
+  }
+  if ( NULL != ego_entry )
+  {
+    handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
+  }
+
+  GNUNET_CRYPTO_hash ("label", strlen ("label"), &key);
+  if ( GNUNET_NO
+      == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                &key))
+  {
+    handle->emsg = GNUNET_strdup("Missing name");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  handle->zkey_str = GNUNET_CONTAINER_multihashmap_get 
(handle->rest_handle->url_param_map,
-                                                        &key);
-  if ((NULL == handle->zkey_str) ||
-      (GNUNET_OK !=
-       GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->zkey_str,
-                                                   strlen (handle->zkey_str),
-                                                   &pubkey)))
+  handle->label_name = GNUNET_strdup(
+      GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key));
+
+  if (NULL == handle->zone_pkey)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Zkey invalid %s\n", handle->zkey_str);
+    handle->emsg = GNUNET_strdup("No default identity for namestore");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  handle->reverse_qe = GNUNET_NAMESTORE_zone_to_name (handle->ns_handle,
-                                                      &handle->zone_pkey,
-                                                      &pubkey,
-                                                      &do_error,
-                                                      handle,
-                                                      &namestore_zkey_response,
-                                                      handle);
-}
-
 
-static void
-namestore_info_cont (struct GNUNET_REST_RequestHandle *con,
-                     const char *url,
-                     void *cls)
-{
-  struct RequestHandle *handle = cls;
+  handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
+                                                    handle->zone_pkey,
+                                                    handle->label_name,
+                                                    &do_error,
+                                                    handle,
+                                                    &del_cont,
+                                                    handle);
 
-  handle->list_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
-                                                           &handle->zone_pkey,
-                                                           &do_error,
-                                                           handle,
-                                                           
&namestore_list_response,
-                                                           handle,
-                                                           
&namestore_list_finished,
-                                                           handle);
 }
 
 
-static char*
-get_name_from_url (const char* url)
-{
-  if (strlen (url) <= strlen (GNUNET_REST_API_NS_NAMESTORE))
-    return NULL;
-  return (char*)url + strlen (GNUNET_REST_API_NS_NAMESTORE) + 1;
-}
 
 /**
  * Respond to OPTIONS request
@@ -977,101 +852,72 @@ options_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   struct MHD_Response *resp;
   struct RequestHandle *handle = cls;
 
-  //For now, independent of path return all options
+  //independent of path return all options
   resp = GNUNET_REST_create_response (NULL);
   MHD_add_response_header (resp,
                            "Access-Control-Allow-Methods",
                            allow_methods);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  cleanup_handle (handle);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
+  return;
 }
 
 
 /**
- * Callback invoked from identity service with ego information.
- * An @a ego of NULL means the ego was not found.
+ * Handle rest request
  *
- * @param cls closure with the configuration
- * @param ego an ego known to identity service, or NULL
+ * @param handle the request handle
  */
 static void
-identity_cb (void *cls,
-             const struct GNUNET_IDENTITY_Ego *ego)
+init_cont (struct RequestHandle *handle)
 {
-  struct RequestHandle *handle = cls;
-  struct MHD_Response *resp;
   struct GNUNET_REST_RequestHandlerError err;
   static const struct GNUNET_REST_RequestHandler handlers[] = {
-    {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE_ZKEY, 
&namestore_zkey_cont}, //reverse
-    {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_info_cont}, 
//list
-    {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, 
&namestore_create_cont}, //create
-    //    {MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, 
&namestore_edit_cont}, //update. TODO this shoul be PATCH
-    {MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, 
&namestore_delete_cont}, //delete
+    {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_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete},
     {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont},
     GNUNET_REST_HANDLER_END
   };
 
-  handle->ego_lookup = NULL;
-  if (NULL == ego)
-  {
-    if (NULL != handle->ego_name)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("Ego `%s' not known to identity service\n"),
-                  handle->ego_name);
-    }
-    resp = GNUNET_REST_create_response (NULL);
-    handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
-    cleanup_handle (handle);
-    return;
-  }
-  handle->zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
-  handle->ns_handle = GNUNET_NAMESTORE_connect (cfg);
-  if (NULL == handle->ns_handle)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Failed to connect to namestore\n"));
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
-  }
-
-  if (GNUNET_OK !=
-      GNUNET_JSONAPI_handle_request (handle->rest_handle,
-                                     handlers,
-                                     &err,
-                                     handle))
+  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,
-                              (void *) handle);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
   }
 }
 
-
+/**
+ * @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
 default_ego_cb (void *cls,
                 struct GNUNET_IDENTITY_Ego *ego,
                 void **ctx,
-                const char *name)
+                const char *identifier)
 {
   struct RequestHandle *handle = cls;
-  struct MHD_Response *resp;
-  handle->get_default = NULL;
-  if (NULL == ego)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("No default ego configured in identity service\n"));
-    resp = GNUNET_REST_create_response (NULL);
-    handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
-    cleanup_handle (handle);
-    return;
-  }
-  else
+  handle->op = NULL;
+
+  if (ego != NULL)
   {
-    identity_cb (cls, ego);
+    handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
   }
 }
 
+
+/**
+ * Connect to identity callback
+ */
 static void
 id_connect_cb (void *cls,
                struct GNUNET_IDENTITY_Ego *ego,
@@ -1079,12 +925,33 @@ id_connect_cb (void *cls,
                const char *name)
 {
   struct RequestHandle *handle = cls;
-  if (NULL == ego)
+  struct EgoEntry *ego_entry;
+  struct GNUNET_CRYPTO_EcdsaPublicKey pk;
+
+  if ((NULL == ego) && (NULL == handle->zone_pkey))
+  {
+    handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
+                                     GNUNET_REST_SUBSYSTEM_NAMESTORE,
+                                     &default_ego_cb,
+                                     handle);
+  }
+  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
+  {
+    handle->state = ID_REST_STATE_POST_INIT;
+    init_cont (handle);
+    return;
+  }
+  if (ID_REST_STATE_INIT == handle->state)
   {
-    handle->get_default = GNUNET_IDENTITY_get (handle->identity_handle,
-                                               "namestore",
-                                               &default_ego_cb, handle);
+    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);
   }
+
 }
 
 
@@ -1097,81 +964,38 @@ id_connect_cb (void *cls,
  * @param data_size length of the body
  * @param proc callback function for the result
  * @param proc_cls closure for callback function
- * @return #GNUNET_OK if request accepted
+ * @return GNUNET_OK if request accepted
  */
 static void
-rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
+rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
                               GNUNET_REST_ResultProcessor proc,
                               void *proc_cls)
 {
   struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
-  struct MHD_Response *resp;
-  struct GNUNET_HashCode key;
-  char *ego;
-  char *name;
-  char *type;
-
+  
+  handle->response_code = 0;
   handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
   handle->proc_cls = proc_cls;
   handle->proc = proc;
   handle->rest_handle = rest_handle;
+  handle->zone_pkey = NULL;
+  
   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->cfg = cfg;
-  ego = NULL;
-  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_NAMESTORE_EGO,
-                      strlen (GNUNET_REST_JSONAPI_NAMESTORE_EGO),
-                      &key);
-  if ( GNUNET_YES ==
-       GNUNET_CONTAINER_multihashmap_contains 
(handle->rest_handle->url_param_map,
-                                               &key) )
-  {
-    ego = GNUNET_CONTAINER_multihashmap_get 
(handle->rest_handle->url_param_map,
-                                             &key);
-  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
 
-  handle->type = GNUNET_GNSRECORD_TYPE_ANY;
-  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE,
-                      strlen (GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE),
-                      &key);
-  if ( GNUNET_YES ==
-       GNUNET_CONTAINER_multihashmap_contains 
(handle->rest_handle->url_param_map,
-                                               &key) )
-  {
-    type = GNUNET_CONTAINER_multihashmap_get 
(handle->rest_handle->url_param_map,
-                                              &key);
-    if (NULL != type)
-      handle->type = GNUNET_GNSRECORD_typename_to_number (type);
-  }
-  name = get_name_from_url (handle->url);
-  if (NULL != ego)
-    handle->ego_name = GNUNET_strdup (ego);
-  if (NULL != name)
-    handle->name = GNUNET_strdup (name);
-  if (NULL == handle->ego_name)
-  {
-    handle->identity_handle = GNUNET_IDENTITY_connect (handle->cfg, 
&id_connect_cb, handle);
-    if (NULL == handle->identity_handle)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Cannot connect to identity 
service\n"));
-      resp = GNUNET_REST_create_response (NULL);
-      handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
-      cleanup_handle (handle);
-    }
-    return;
-  }
-  handle->ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg,
-                                                   handle->ego_name,
-                                                   &identity_cb,
-                                                   handle);
-  handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
-                                                       &do_timeout,
-                                                       handle);
+  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, 
handle);
+  handle->ns_handle = GNUNET_NAMESTORE_connect (cfg);
+  handle->timeout_task =
+    GNUNET_SCHEDULER_add_delayed (handle->timeout,
+                                  &do_error,
+                                  handle);
+  
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
 }
 
+
 /**
  * Entry point for the plugin.
  *
@@ -1182,9 +1006,9 @@ void *
 libgnunet_plugin_rest_namestore_init (void *cls)
 {
   static struct Plugin plugin;
-  cfg = cls;
   struct GNUNET_REST_Plugin *api;
 
+  cfg = cls;
   if (NULL != plugin.cfg)
     return NULL;                /* can only initialize once! */
   memset (&plugin, 0, sizeof (struct Plugin));
@@ -1192,7 +1016,7 @@ libgnunet_plugin_rest_namestore_init (void *cls)
   api = GNUNET_new (struct GNUNET_REST_Plugin);
   api->cls = &plugin;
   api->name = GNUNET_REST_API_NS_NAMESTORE;
-  api->process_request = &rest_identity_process_request;
+  api->process_request = &rest_process_request;
   GNUNET_asprintf (&allow_methods,
                    "%s, %s, %s, %s, %s",
                    MHD_HTTP_METHOD_GET,
@@ -1200,7 +1024,8 @@ libgnunet_plugin_rest_namestore_init (void *cls)
                    MHD_HTTP_METHOD_PUT,
                    MHD_HTTP_METHOD_DELETE,
                    MHD_HTTP_METHOD_OPTIONS);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               _("Namestore REST API initialized\n"));
   return api;
 }
@@ -1217,13 +1042,14 @@ libgnunet_plugin_rest_namestore_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;
-
   plugin->cfg = NULL;
-  GNUNET_free (api);
+
   GNUNET_free_non_null (allow_methods);
+  GNUNET_free (api);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Namestore REST plugin is finished\n");
   return NULL;
 }
 
 /* end of plugin_rest_namestore.c */
+
diff --git a/src/namestore/test_plugin_rest_namestore.sh 
b/src/namestore/test_plugin_rest_namestore.sh
new file mode 100755
index 000000000..de02dfafc
--- /dev/null
+++ b/src/namestore/test_plugin_rest_namestore.sh
@@ -0,0 +1,208 @@
+#!/usr/bin/bash
+
+#First, start gnunet-arm and the rest-service.
+#Exit 0 means success, exit 1 means failed test
+
+namestore_link="http://localhost:7776/namestore";
+wrong_link="http://localhost:7776/namestoreandmore";
+
+
+curl_get () {
+    #$1 is link
+    #$2 is grep
+    cache="$(curl -v "$1" 2>&1 | grep "$2")"
+    #echo $cache
+    if [ "" == "$cache" ]
+    then
+        exit 1
+    fi
+}
+
+curl_post () {
+    #$1 is link
+    #$2 is data
+    #$3 is grep
+    cache="$(curl -v -X "POST" "$1" --data "$2" 2>&1 | grep "$3")"
+    #echo $cache
+    if [ "" == "$cache" ]
+    then
+        exit 1
+    fi
+}
+
+curl_delete () {
+    #$1 is link
+    #$2 is grep
+    cache="$(curl -v -X "DELETE" "$1" 2>&1 | grep "$2")"
+    #echo $cache
+    if [ "" == "$cache" ]
+    then
+        exit 1
+    fi
+}
+
+# curl_put () {
+#     #$1 is link
+#     #$2 is data
+#     #$3 is grep
+#     cache="$(curl -v -X "PUT" "$1" --data "$2" 2>&1 | grep "$3")"
+#     #echo $cache
+#     if [ "" == "$cache" ]
+#     then
+#         exit 1
+#     fi
+# }
+
+#Test subsystem default identity
+
+#Test GET
+gnunet-identity -D "test_plugin_rest_namestore"
+gnunet-identity -C "test_plugin_rest_namestore"
+test="$(gnunet-namestore -D -z "test_plugin_rest_namestore")"
+name="test_plugin_rest_namestore"
+public="$(gnunet-identity -d | grep "test_plugin_rest_namestore" | awk 
'NR==1{print $3}')"
+if [ "" == "$test" ]
+then
+    #if no entries for test_plugin_rest_namestore
+    curl_get "${namestore_link}?name=$name" "error"
+    curl_get "${namestore_link}?name=" "error"
+    curl_get "${namestore_link}?name=$public" "error"
+    
+    curl_get "${namestore_link}?pubkey=$public" "error"
+    curl_get "${namestore_link}?pubkey=$name" "error"
+    curl_get "${namestore_link}?pubkey=" "error"
+else
+    #if entries exists (that should not be possible)
+    curl_get "${namestore_link}" "HTTP/1.1 200 OK"
+    curl_get "${namestore_link}?name=$name" "HTTP/1.1 200 OK"
+    curl_get "${namestore_link}?name=" "error"
+    curl_get "${namestore_link}?name=$public" "error"
+    
+    curl_get "${namestore_link}?pubkey=$public" "HTTP/1.1 200 OK"
+    curl_get "${namestore_link}?pubkey=$name" "error"
+    curl_get "${namestore_link}?pubkey=" "error"
+fi
+gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V 
"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY"
+curl_get "${namestore_link}" "HTTP/1.1 200 OK"
+curl_get "${namestore_link}?name=$name" "HTTP/1.1 200 OK"
+curl_get "${namestore_link}?name=" "error"
+curl_get "${namestore_link}?name=$public" "error"
+curl_get "${namestore_link}?pubkey=$public" "HTTP/1.1 200 OK"
+curl_get "${namestore_link}?pubkey=$name" "error"
+curl_get "${namestore_link}?pubkey=" "error"
+gnunet-namestore -z $name -d -n "test_entry"
+
+#Test POST with NAME
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+#value
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" '{"value":"", "type":"PKEY", 
"expiration_time":"1d","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value_missing":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+#time
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"0d","flag":0,"label":"test_entry"}' "HTTP/1.1 
204"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"10000d","flag":0,"label":"test_entry"}' 
"HTTP/1.1 204"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"now","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time_missing":"1d","flag":0,"label":"test_entry"}' 
"error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+#flag
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":2,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":8,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":16,"label":"test_entry"}' 
"HTTP/1.1 204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":-1,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":"Test","label":"test_entry"}' 
"error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag_missing":0,"label":"test_entry"}' 
"error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+#label
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "HTTP/1.1 
409"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":""}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?name=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label_missing":"test_entry"}' 
"error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+
+#Test POST with PUBKEY
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+#value
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" '{"value":"", "type":"PKEY", 
"expiration_time":"1d","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value_missing":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRGxxx", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+#time
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"0d","flag":0,"label":"test_entry"}' "HTTP/1.1 
204"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"10000d","flag":0,"label":"test_entry"}' 
"HTTP/1.1 204"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"now","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time_missing":"1d","flag":0,"label":"test_entry"}' 
"error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+#flag
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":2,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":8,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":16,"label":"test_entry"}' 
"HTTP/1.1 204 No Content"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":-1,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":"Test","label":"test_entry"}' 
"error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag_missing":0,"label":"test_entry"}' 
"error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+#label
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "HTTP/1.1 
204 No Content"
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "HTTP/1.1 
409"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":""}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label_missing":"test_entry"}' 
"error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+
+#wrong zone
+curl_post "${namestore_link}?name=$public" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+curl_post "${namestore_link}?pubkey=$name" 
'{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", 
"type":"PKEY", "expiration_time":"1d","flag":0,"label":"test_entry"}' "error"
+gnunet-namestore -z $name -d -n "test_entry" > /dev/null 2>&1
+
+#Test DELETE
+gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V 
"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY"
+curl_delete "${namestore_link}?label=test_entry&name=$name" "HTTP/1.1 204" 
+gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V 
"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY"
+curl_delete "${namestore_link}?label=test_entry&pubkey=$public" "HTTP/1.1 204" 
+gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V 
"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY"
+curl_delete "${namestore_link}?label=test_entry&pubkey=$name" "HTTP/1.1 404" 
+
+
+#Test default identity
+#not possible without defining 
+
+exit 0;
+
diff --git a/src/peerinfo/Makefile.am b/src/peerinfo/Makefile.am
index eeb5ee54e..5e96250b1 100644
--- a/src/peerinfo/Makefile.am
+++ b/src/peerinfo/Makefile.am
@@ -5,6 +5,8 @@ pkgcfgdir= $(pkgdatadir)/config.d/
 
 libexecdir= $(pkglibdir)/libexec/
 
+plugindir = $(libdir)/gnunet
+
 pkgcfg_DATA = \
   peerinfo.conf
 
@@ -25,6 +27,8 @@ libgnunetpeerinfo_la_SOURCES = \
 libgnunetpeerinfo_la_LIBADD = \
   $(top_builddir)/src/hello/libgnunethello.la \
   $(top_builddir)/src/util/libgnunetutil.la \
+  $(top_builddir)/src/json/libgnunetjson.la \
+  $(top_builddir)/src/transport/libgnunettransport.la \
   $(XLIB) \
   $(LTLIBINTL)
 libgnunetpeerinfo_la_LDFLAGS = \
@@ -35,12 +39,30 @@ libgnunetpeerinfo_la_LDFLAGS = \
 libexec_PROGRAMS = \
  gnunet-service-peerinfo
 
+if HAVE_MHD
+if HAVE_JSON
+plugin_LTLIBRARIES = \
+  libgnunet_plugin_rest_peerinfo.la 
+endif
+endif
+
 gnunet_service_peerinfo_SOURCES = \
  gnunet-service-peerinfo.c
 gnunet_service_peerinfo_LDADD = \
   $(top_builddir)/src/hello/libgnunethello.la \
   $(top_builddir)/src/statistics/libgnunetstatistics.la \
   $(top_builddir)/src/util/libgnunetutil.la
+  
+
+libgnunet_plugin_rest_peerinfo_la_SOURCES = \
+  plugin_rest_peerinfo.c
+libgnunet_plugin_rest_peerinfo_la_LIBADD = \
+       libgnunetpeerinfo.la \
+  $(top_builddir)/src/rest/libgnunetrest.la \
+  $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
+  $(LTLIBINTL) -ljansson -lmicrohttpd
+libgnunet_plugin_rest_peerinfo_la_LDFLAGS = \
+ $(GN_PLUGIN_LDFLAGS)
 
 if HAVE_BENCHMARKS
  PEERINFO_BENCHMARKS = \
diff --git a/src/peerinfo/plugin_rest_peerinfo.c 
b/src/peerinfo/plugin_rest_peerinfo.c
new file mode 100644
index 000000000..97c473e36
--- /dev/null
+++ b/src/peerinfo/plugin_rest_peerinfo.c
@@ -0,0 +1,801 @@
+/*
+   This file is part of GNUnet.
+   Copyright (C) 2012-2015 GNUnet e.V.
+
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   GNUnet is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Affero General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+   */
+/**
+ * @author Martin Schanzenbach
+ * @author Philippe Buschmann
+ * @file peerinfo/plugin_rest_peerinfo.c
+ * @brief GNUnet Peerinfo REST plugin
+ */
+
+#include "platform.h"
+#include "gnunet_rest_plugin.h"
+#include "gnunet_peerinfo_service.h"
+#include "gnunet_transport_service.h"
+#include "gnunet_rest_lib.h"
+#include "gnunet_json_lib.h"
+#include "microhttpd.h"
+#include <jansson.h>
+
+#define GNUNET_REST_API_NS_PEERINFO "/peerinfo"
+
+#define GNUNET_REST_API_PEERINFO_PEER "peer"
+#define GNUNET_REST_API_PEERINFO_FRIEND "friend"
+#define GNUNET_REST_API_PEERINFO_ARRAY "array"
+
+#define GNUNET_REST_ERROR_UNKNOWN "Unkown Error"
+
+/**
+ * How long until we time out during address lookup?
+ */
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+/**
+ * The configuration handle
+ */
+const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * HTTP methods allows for this plugin
+ */
+static char* allow_methods;
+
+/**
+ * @brief struct returned by the initialization function of the plugin
+ */
+struct Plugin
+{
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+};
+
+
+/**
+ * Record we keep for each printable address.
+ */
+struct AddressRecord
+{
+  /**
+   * Current address-to-string context (if active, otherwise NULL).
+   */
+  struct GNUNET_TRANSPORT_AddressToStringContext *atsc;
+
+  /**
+   * Address expiration time
+   */
+  struct GNUNET_TIME_Absolute expiration;
+
+  /**
+   * Printable address.
+   */
+  char *result;
+
+  /**
+   * Print context this address record belongs to.
+   */
+  struct PrintContext *pc;
+};
+
+
+/**
+ * Structure we use to collect printable address information.
+ */
+struct PrintContext
+{
+
+  /**
+   * Kept in DLL.
+   */
+  struct PrintContext *next;
+
+  /**
+   * Kept in DLL.
+   */
+  struct PrintContext *prev;
+
+  /**
+   * Identity of the peer.
+   */
+  struct GNUNET_PeerIdentity peer;
+
+  /**
+   * List of printable addresses.
+   */
+  struct AddressRecord *address_list;
+
+  /**
+   * Number of completed addresses in @e address_list.
+   */
+  unsigned int num_addresses;
+
+  /**
+   * Number of addresses allocated in @e address_list.
+   */
+  unsigned int address_list_size;
+
+  /**
+   * Current offset in @e address_list (counted down).
+   */
+  unsigned int off;
+
+  /**
+   * Hello was friend only, #GNUNET_YES or #GNUNET_NO
+   */
+  int friend_only;
+
+  /**
+   * RequestHandle
+   */
+  struct RequestHandle *handle;
+
+};
+
+/**
+ * Head of list of print contexts.
+ */
+static struct PrintContext *pc_head;
+
+/**
+ * Tail of list of print contexts.
+ */
+static struct PrintContext *pc_tail;
+
+struct RequestHandle
+{
+  /**
+   * JSON temporary array
+   */
+  json_t *temp_array;
+
+  /**
+   * Expiration time string
+   */
+  char *expiration_str;
+
+  /**
+   * Address string
+   */
+  const char *address;
+
+  /**
+   * Iteration peer public key
+   */
+  char *pubkey;
+
+  /**
+   * JSON response
+   */
+  json_t *response;
+
+  /**
+   * Handle to PEERINFO it
+   */
+  struct GNUNET_PEERINFO_IteratorContext *list_it;
+
+  /**
+   * Handle to PEERINFO
+   */
+  struct GNUNET_PEERINFO_Handle *peerinfo_handle;
+
+  /**
+   * Rest connection
+   */
+  struct GNUNET_REST_RequestHandle *rest_handle;
+  
+  /**
+   * Desired timeout for the lookup (default is no timeout).
+   */
+  struct GNUNET_TIME_Relative timeout;
+
+  /**
+   * ID of a task associated with the resolution process.
+   */
+  struct GNUNET_SCHEDULER_Task *timeout_task;
+
+  /**
+   * The plugin result processor
+   */
+  GNUNET_REST_ResultProcessor proc;
+
+  /**
+   * The closure of the result processor
+   */
+  void *proc_cls;
+
+  /**
+   * The url
+   */
+  char *url;
+
+  /**
+   * Error response message
+   */
+  char *emsg;
+
+  /**
+   * Reponse code
+   */
+  int response_code;
+
+};
+
+
+/**
+ * Cleanup lookup handle
+ * @param handle Handle to clean up
+ */
+static void
+cleanup_handle (void *cls)
+{
+  struct RequestHandle *handle = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Cleaning up\n");
+  if (NULL != handle->timeout_task)
+  {
+    GNUNET_SCHEDULER_cancel (handle->timeout_task);
+    handle->timeout_task = NULL;
+  }
+  if (NULL != handle->url)
+    GNUNET_free (handle->url);
+  if (NULL != handle->emsg)
+    GNUNET_free (handle->emsg);
+  if (NULL != handle->address)
+    GNUNET_free ((char*)handle->address);
+  if (NULL != handle->expiration_str)
+    GNUNET_free (handle->expiration_str);
+  if (NULL != handle->pubkey)
+    GNUNET_free (handle->pubkey);
+
+  if (NULL != handle->temp_array)
+  {
+    json_decref(handle->temp_array);
+    handle->temp_array = NULL;
+  }
+  if (NULL != handle->response)
+  {
+    json_decref(handle->response);
+    handle->response = NULL;
+  }
+
+  if (NULL != handle->list_it)
+  {
+    GNUNET_PEERINFO_iterate_cancel(handle->list_it);
+    handle->list_it = NULL;
+  }
+  if (NULL != handle->peerinfo_handle)
+  {
+    GNUNET_PEERINFO_disconnect(handle->peerinfo_handle);
+    handle->peerinfo_handle = NULL;
+  }
+  
+  GNUNET_free (handle);
+}
+
+
+/**
+ * Task run on errors.  Reports an error and cleans up everything.
+ *
+ * @param cls the `struct RequestHandle`
+ */
+static void
+do_error (void *cls)
+{
+  struct RequestHandle *handle = cls;
+  struct MHD_Response *resp;
+  json_t *json_error = json_object();
+  char *response;
+
+  if (NULL == handle->emsg)
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_UNKNOWN);
+
+  json_object_set_new(json_error,"error", json_string(handle->emsg));
+
+  if (0 == handle->response_code)
+    handle->response_code = MHD_HTTP_OK;
+  response = json_dumps (json_error, 0);
+  resp = GNUNET_REST_create_response (response);
+  handle->proc (handle->proc_cls, resp, handle->response_code);
+  json_decref(json_error);
+  GNUNET_free(response);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
+}
+
+
+/**
+ * Function that assembles our response.
+ */
+static void
+peerinfo_list_finished (void *cls)
+{
+  struct RequestHandle *handle = cls;
+  char *result_str;
+  struct MHD_Response *resp;
+
+  if (NULL == handle->response)
+  {
+    handle->emsg = GNUNET_strdup ("No peers found");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  result_str = json_dumps (handle->response, 0);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
+  resp = GNUNET_REST_create_response (result_str);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_free_non_null (result_str);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
+}
+
+
+/**
+ * Iterator callback to go over all addresses and count them.
+ *
+ * @param cls `struct PrintContext *` with `off` to increment
+ * @param address the address
+ * @param expiration expiration time
+ * @return #GNUNET_OK to keep the address and continue
+ */
+static int
+count_address (void *cls,
+               const struct GNUNET_HELLO_Address *address,
+               struct GNUNET_TIME_Absolute expiration)
+{
+  struct PrintContext *pc = cls;
+
+  if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
+  {
+    return GNUNET_OK;          /* ignore expired address */
+  }
+
+  pc->off++;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Print the collected address information to the console and free @a pc.
+ *
+ * @param pc printing context
+ */
+static void
+dump_pc (struct PrintContext *pc)
+{
+  struct RequestHandle *handle;
+  unsigned int i;
+  json_t *response_entry;
+  json_t *temp_array;
+  json_t *object;
+  json_t *address;
+  json_t *expires;
+  json_t *friend_and_peer_json;
+  char *friend_and_peer;
+
+  temp_array = json_array();
+  response_entry = json_object();
+
+//  printf (_("%sPeer `%s'\n"),
+//       (GNUNET_YES == pc->friend_only) ? "F2F: " : "",
+//       GNUNET_i2s_full (&pc->peer));
+  for (i = 0; i < pc->num_addresses; i++)
+  {
+    if (NULL != pc->address_list[i].result)
+    {
+      object = json_object ();
+      address = json_string(pc->address_list[i].result);
+      expires = json_string(
+         GNUNET_STRINGS_absolute_time_to_string 
(pc->address_list[i].expiration));
+      json_object_set (object, "address", address);
+      json_object_set (object, "expires", expires);
+
+      json_decref(address);
+      json_decref(expires);
+
+      json_array_append(temp_array, object);
+      json_decref(object);
+      GNUNET_free (pc->address_list[i].result);
+    }
+  }
+
+  if (0 < json_array_size(temp_array))
+  {
+    GNUNET_asprintf(&friend_and_peer,
+                   "%s%s",
+                   (GNUNET_YES == pc->friend_only) ? "F2F:" : "",
+                   GNUNET_i2s_full (&pc->peer));
+    friend_and_peer_json = json_string(friend_and_peer);
+    json_object_set(response_entry,
+                   GNUNET_REST_API_PEERINFO_PEER,
+                   friend_and_peer_json);
+    json_object_set(response_entry,
+                   GNUNET_REST_API_PEERINFO_ARRAY,
+                   temp_array);
+    json_array_append(pc->handle->response, response_entry);
+    json_decref(friend_and_peer_json);
+    GNUNET_free(friend_and_peer);
+  }
+
+  json_decref (temp_array);
+  json_decref(response_entry);
+
+  GNUNET_free_non_null (pc->address_list);
+  GNUNET_CONTAINER_DLL_remove (pc_head,
+                              pc_tail,
+                              pc);
+  handle = pc->handle;
+  GNUNET_free (pc);
+
+  if ( (NULL == pc_head) &&
+       (NULL == handle->list_it) )
+  {
+    GNUNET_SCHEDULER_add_now (&peerinfo_list_finished, handle);
+  }
+
+}
+
+
+/**
+ * Function to call with a human-readable format of an address
+ *
+ * @param cls closure
+ * @param address NULL on error, otherwise 0-terminated printable UTF-8 string
+ * @param res result of the address to string conversion:
+ *        if #GNUNET_OK: address was valid (conversion to
+ *                       string might still have failed)
+ *        if #GNUNET_SYSERR: address is invalid
+ */
+static void
+process_resolved_address (void *cls,
+                          const char *address,
+                          int res)
+{
+  struct AddressRecord *ar = cls;
+  struct PrintContext *pc = ar->pc;
+
+  if (NULL != address)
+  {
+    if (0 != strlen (address))
+    {
+      if (NULL != ar->result)
+        GNUNET_free (ar->result);
+      ar->result = GNUNET_strdup (address);
+    }
+    return;
+  }
+  ar->atsc = NULL;
+  if (GNUNET_SYSERR == res)
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Failure: Cannot convert address to string for peer `%s'\n"),
+                GNUNET_i2s (&ar->pc->peer));
+  pc->num_addresses++;
+  if (pc->num_addresses == pc->address_list_size)
+    dump_pc (ar->pc);
+}
+
+
+/**
+ * Iterator callback to go over all addresses.
+ *
+ * @param cls closure
+ * @param address the address
+ * @param expiration expiration time
+ * @return #GNUNET_OK to keep the address and continue
+ */
+static int
+print_address (void *cls,
+               const struct GNUNET_HELLO_Address *address,
+               struct GNUNET_TIME_Absolute expiration)
+{
+  struct PrintContext *pc = cls;
+  struct AddressRecord *ar;
+
+  if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
+  {
+    return GNUNET_OK;          /* ignore expired address */
+  }
+
+  GNUNET_assert (0 < pc->off);
+  ar = &pc->address_list[--pc->off];
+  ar->pc = pc;
+  ar->expiration = expiration;
+  GNUNET_asprintf (&ar->result,
+                   "%s:%u:%u",
+                   address->transport_name,
+                   address->address_length,
+                   address->local_info);
+  ar->atsc = GNUNET_TRANSPORT_address_to_string (cfg,
+                                                 address,
+                                                GNUNET_NO,
+                                                TIMEOUT,
+                                                &process_resolved_address,
+                                                ar);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Callback that processes each of the known HELLOs for the
+ * iteration response construction.
+ *
+ * @param cls closure, NULL
+ * @param peer id of the peer, NULL for last call
+ * @param hello hello message for the peer (can be NULL)
+ * @param err_msg message
+ */
+void
+peerinfo_list_iteration(void *cls,
+                       const struct GNUNET_PeerIdentity *peer,
+                       const struct GNUNET_HELLO_Message *hello,
+                       const char *err_msg)
+{
+  struct RequestHandle *handle = cls;
+  struct PrintContext *pc;
+  int friend_only;
+
+  if (NULL == handle->response)
+  {
+    handle->response = json_array();
+  }
+
+  if (NULL == peer)
+  {
+    handle->list_it = NULL;
+    handle->emsg = GNUNET_strdup ("Error in communication with peerinfo");
+    if (NULL != err_msg)
+    {
+      GNUNET_free(handle->emsg);
+      handle->emsg = GNUNET_strdup (err_msg);
+      handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
+    }
+    if (NULL == pc_head)
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  if (NULL == hello)
+    return;
+
+  friend_only = GNUNET_NO;
+  if (NULL != hello)
+    friend_only = GNUNET_HELLO_is_friend_only (hello);
+
+  pc = GNUNET_new(struct PrintContext);
+  GNUNET_CONTAINER_DLL_insert (pc_head,
+                              pc_tail,
+                              pc);
+  pc->peer = *peer;
+  pc->friend_only = friend_only;
+  pc->handle = handle;
+  GNUNET_HELLO_iterate_addresses (hello,
+                                 GNUNET_NO,
+                                 &count_address,
+                                 pc);
+  if (0 == pc->off)
+  {
+    dump_pc (pc);
+    return;
+  }
+  pc->address_list_size = pc->off;
+  pc->address_list = GNUNET_malloc(
+      sizeof(struct AddressRecord) * pc->off);
+  GNUNET_HELLO_iterate_addresses (hello,
+                                 GNUNET_NO,
+                                 &print_address,
+                                 pc);
+}
+
+/**
+ * Handle peerinfo GET request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+void
+peerinfo_get (struct GNUNET_REST_RequestHandle *con_handle,
+                 const char* url,
+                 void *cls)
+{
+  struct RequestHandle *handle = cls;
+  struct GNUNET_HashCode key;
+  const struct GNUNET_PeerIdentity *specific_peer;
+  GNUNET_PEER_Id peer_id;
+  int include_friend_only;
+  char* include_friend_only_str;
+
+  include_friend_only = GNUNET_NO;
+  GNUNET_CRYPTO_hash (GNUNET_REST_API_PEERINFO_FRIEND,
+                     strlen (GNUNET_REST_API_PEERINFO_FRIEND),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                &key))
+  {
+    include_friend_only_str = GNUNET_CONTAINER_multihashmap_get (
+             con_handle->url_param_map, &key);
+    if (0 == strcmp(include_friend_only_str, "yes"))
+    {
+      include_friend_only = GNUNET_YES;
+    }
+  }
+
+  specific_peer = NULL;
+  GNUNET_CRYPTO_hash (GNUNET_REST_API_PEERINFO_PEER,
+                     strlen (GNUNET_REST_API_PEERINFO_PEER),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
+                                                &key))
+  {
+    peer_id = *(unsigned int*)GNUNET_CONTAINER_multihashmap_get 
(con_handle->url_param_map, &key);
+    specific_peer = GNUNET_PEER_resolve2(peer_id);
+  }
+
+  handle->list_it = GNUNET_PEERINFO_iterate(handle->peerinfo_handle,
+                                           include_friend_only,
+                                           specific_peer,
+                                           &peerinfo_list_iteration,
+                                           handle);
+}
+
+
+
+/**
+ * Respond to OPTIONS request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+options_cont (struct GNUNET_REST_RequestHandle *con_handle,
+              const char* url,
+              void *cls)
+{
+  struct MHD_Response *resp;
+  struct RequestHandle *handle = cls;
+
+  //independent of path return all options
+  resp = GNUNET_REST_create_response (NULL);
+  MHD_add_response_header (resp,
+                           "Access-Control-Allow-Methods",
+                           allow_methods);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
+  return;
+}
+
+
+/**
+ * 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
+ *
+ * @param method HTTP method
+ * @param url URL of the HTTP request
+ * @param data body of the HTTP request (optional)
+ * @param data_size length of the body
+ * @param proc callback function for the result
+ * @param proc_cls closure for callback function
+ * @return GNUNET_OK if request accepted
+ */
+static void
+rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
+                              GNUNET_REST_ResultProcessor proc,
+                              void *proc_cls)
+{
+  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
+  
+  handle->response_code = 0;
+  handle->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 
60);
+  handle->proc_cls = proc_cls;
+  handle->proc = proc;
+  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->peerinfo_handle = GNUNET_PEERINFO_connect(cfg);
+  init_cont(handle);
+  handle->timeout_task =
+    GNUNET_SCHEDULER_add_delayed (handle->timeout,
+                                  &do_error,
+                                  handle);
+  
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
+}
+
+
+/**
+ * Entry point for the plugin.
+ *
+ * @param cls Config info
+ * @return NULL on error, otherwise the plugin context
+ */
+void *
+libgnunet_plugin_rest_peerinfo_init (void *cls)
+{
+  static struct Plugin plugin;
+  struct GNUNET_REST_Plugin *api;
+
+  cfg = cls;
+  if (NULL != plugin.cfg)
+    return NULL;                /* can only initialize once! */
+  memset (&plugin, 0, sizeof (struct Plugin));
+  plugin.cfg = cfg;
+  api = GNUNET_new (struct GNUNET_REST_Plugin);
+  api->cls = &plugin;
+  api->name = GNUNET_REST_API_NS_PEERINFO;
+  api->process_request = &rest_process_request;
+  GNUNET_asprintf (&allow_methods,
+                   "%s, %s, %s, %s, %s",
+                   MHD_HTTP_METHOD_GET,
+                   MHD_HTTP_METHOD_POST,
+                   MHD_HTTP_METHOD_PUT,
+                   MHD_HTTP_METHOD_DELETE,
+                   MHD_HTTP_METHOD_OPTIONS);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              _("Peerinfo REST API initialized\n"));
+  return api;
+}
+
+
+/**
+ * Exit point from the plugin.
+ *
+ * @param cls the plugin context (as returned by "init")
+ * @return always NULL
+ */
+void *
+libgnunet_plugin_rest_peerinfo_done (void *cls)
+{
+  struct GNUNET_REST_Plugin *api = cls;
+  struct Plugin *plugin = api->cls;
+  plugin->cfg = NULL;
+
+  GNUNET_free_non_null (allow_methods);
+  GNUNET_free (api);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Peerinfo REST plugin is finished\n");
+  return NULL;
+}
+
+/* end of plugin_rest_peerinfo.c */
+

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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