-wip namestore api, changed adding gnsrecord
authorPhil <phil.buschmann@tum.de>
Wed, 25 Jul 2018 19:57:49 +0000 (21:57 +0200)
committerPhil <phil.buschmann@tum.de>
Wed, 25 Jul 2018 19:57:49 +0000 (21:57 +0200)
src/gnsrecord/Makefile.am
src/gnsrecord/gnsrecord.c
src/include/gnunet_gnsrecord_lib.h
src/include/gnunet_json_lib.h
src/json/Makefile.am
src/json/json_parser.c [deleted file]
src/namestore/plugin_rest_namestore.c

index f840a31a47043ab1f4e181f43bc8472d8ac2f92d..47d83169fcd0b236d7ff2a1e167646b70cd87911 100644 (file)
@@ -39,6 +39,7 @@ libgnunetgnsrecord_la_SOURCES = \
   gnsrecord_misc.c
 libgnunetgnsrecord_la_LIBADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
+  -ljansson \
   $(GN_LIBINTL)
 libgnunetgnsrecord_la_LDFLAGS = \
   $(GN_LIB_LDFLAGS) $(WINFLAGS) \
index da34846e76350b9c453afe4c13b6d033887e8771..30a0ffa836e3ec9460ad748d0d72e297bb1b347c 100644 (file)
@@ -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,130 @@ GNUNET_GNSRECORD_number_to_typename (uint32_t type)
   return NULL;
 }
 
+/**
+ * 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 *data;
+  const char *expiration_date;
+  const char *record_type;
+  const char *dummy_value;
+  int flag;
+  void *rdata;
+  size_t rdata_size;
+
+  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!}",
+                            "value", &data,
+                            "type", &record_type,
+                            "expiration_time", &expiration_date,
+                            "flag", &flag,
+                            "label", &dummy_value);
+  GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
+            "{value:%s, type:%s, expire:%s, flag:%i}",
+            data,
+            record_type,
+            expiration_date,
+            flag);
+  if (GNUNET_SYSERR == unpack_state)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
+              "Error json object has a wrong format!\n");
+    return GNUNET_SYSERR;
+  }
+  //TODO test
+  gnsrecord_object = GNUNET_new (struct GNUNET_GNSRECORD_Data);
+  gnsrecord_object->record_type = GNUNET_GNSRECORD_typename_to_number(record_type);
+  if (GNUNET_OK
+      != GNUNET_GNSRECORD_string_to_value (gnsrecord_object->record_type,
+                                          data, &rdata,
+                                          &rdata_size))
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR,"Value invalid for record type");
+    return GNUNET_SYSERR;
+  }
+  gnsrecord_object->data = rdata;
+  gnsrecord_object->data_size = rdata_size;
+
+  if (0 == strcmp (expiration_date, "never"))
+  {
+    gnsrecord_object->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
+  }
+  else if (GNUNET_OK
+      == GNUNET_STRINGS_fancy_time_to_absolute (expiration_date,
+                                               &abs_expiration_time))
+  {
+    gnsrecord_object->expiration_time = abs_expiration_time.abs_value_us;
+  }
+  else
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Value invalid for record type");
+    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;
+}
 
 /* end of gnsrecord.c */
index 20846238b4d8a6e851fdb255cbfd1c1ae0a289d6..2eaa304de04363e985e4409ee091fddc126d6c05 100644 (file)
@@ -447,6 +447,14 @@ GNUNET_GNSRECORD_records_deserialize (size_t len,
                                      unsigned int rd_count,
                                      struct GNUNET_GNSRECORD_Data *dest);
 
+/**
+ * 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);
 
 /* ******* general APIs relating to blocks, records and labels ******** */
 
index 6340d1f41c3a40f889741e1e346d709385adcd2e..4855f21b4b0ed0cef016da47adc2b32eeb3aebf6 100644 (file)
@@ -479,71 +479,6 @@ GNUNET_JSON_getopt (char shortName,
                     const char *description,
                     json_t **json);
 
-/* ****************** GETOPT JSON parser ******************* */
-
-struct GNUNET_REST_JSON_Data
-{
-  /**
-   * Public key of an identity
-   */
-  char *pubkey;
-
-  /**
-   * Name
-   */
-  char *name;
-
-  /**
-   * Nickname
-   */
-  char *nickname;
-
-  /**
-   * New name
-   */
-  char *new_name;
-
-  /**
-   * Name of subsystem
-   */
-  char *subsystem;
-
-  /**
-   * Should data be handled as public (GNUNET_YES or GNUNET_NO)
-   */
-  int is_public;
-
-  /**
-   * Expiration date of data
-   */
-  char *expiration_time;
-
-  /**
-   * Type of data
-   */
-  char *type;
-
-  /**
-   * Value of data
-   */
-  char *value;
-
-  /**
-   * Zone
-   */
-  char *zone;
-};
-/*
- * Test
- */
-int
-GNUNET_REST_JSON_parse (struct GNUNET_REST_JSON_Data** rest_json_data,
-                       json_t *json_data);
-
-int
-GNUNET_REST_JSON_free (struct GNUNET_REST_JSON_Data* rest_json_data);
-
-
 #endif
 
 /* end of gnunet_json_lib.h */
index 5aac23654515d950268843c0094cff96c455897c..16c0450d956c5a7508a9885dfb4c45104ff51294 100644 (file)
@@ -16,8 +16,7 @@ libgnunetjson_la_SOURCES = \
   json.c \
   json_mhd.c \
   json_generator.c \
-  json_helper.c \
-  json_parser.c
+  json_helper.c 
 libgnunetjson_la_LIBADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
   -ljansson \
diff --git a/src/json/json_parser.c b/src/json/json_parser.c
deleted file mode 100644 (file)
index cfe553b..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-  This file is part of GNUnet
-  Copyright (C) 2014, 2015, 2016 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_helper.c
- * @brief functions for REST JSON parsing
- * @author Philippe Buschmann
- */
-
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_json_lib.h"
-
-#define GNUNET_REST_JSON_PUBKEY_ENTRY "pubkey"
-#define GNUNET_REST_JSON_NAME_ENTRY "name"
-#define GNUNET_REST_JSON_NICKNAME_ENTRY "nickname"
-#define GNUNET_REST_JSON_NEWNAME_ENTRY "newname"
-#define GNUNET_REST_JSON_SUBSYSTEM_ENTRY "subsystem"
-#define GNUNET_REST_JSON_IS_PUBLIC_ENTRY "is_public"
-#define GNUNET_REST_JSON_EXPIRATION_DATE_ENTRY "expiration_time"
-#define GNUNET_REST_JSON_TYPE_ENTRY "type"
-#define GNUNET_REST_JSON_VALUE_ENTRY "value"
-#define GNUNET_REST_JSON_ZONE_ENTRY "zone"
-
-
-int
-GNUNET_REST_JSON_parse (struct GNUNET_REST_JSON_Data** output_data ,json_t *json_data)
-{
-  struct GNUNET_REST_JSON_Data *rest_json_data;
-  json_t *cache;
-
-  rest_json_data = GNUNET_malloc(sizeof(struct GNUNET_REST_JSON_Data));
-
-  cache = json_object_get (json_data, GNUNET_REST_JSON_EXPIRATION_DATE_ENTRY);
-  rest_json_data->expiration_time = NULL;
-  if (NULL != cache)
-  {
-    if (json_is_string(cache))
-    {
-      rest_json_data->expiration_time = GNUNET_strdup(json_string_value(cache));
-    }
-  }
-  cache = json_object_get (json_data, GNUNET_REST_JSON_NAME_ENTRY);
-  rest_json_data->name = NULL;
-  if (NULL != cache)
-  {
-    if (json_is_string(cache))
-    {
-      rest_json_data->name = GNUNET_strdup(json_string_value(cache));
-    }
-  }
-  cache = json_object_get (json_data, GNUNET_REST_JSON_NEWNAME_ENTRY);
-  rest_json_data->new_name = NULL;
-  if (NULL != cache)
-  {
-    if (json_is_string(cache))
-    {
-      rest_json_data->new_name = GNUNET_strdup(json_string_value(cache));
-    }
-  }
-  cache = json_object_get (json_data, GNUNET_REST_JSON_NICKNAME_ENTRY);
-  rest_json_data->nickname = NULL;
-  if (NULL != cache)
-  {
-    if (json_is_string(cache))
-    {
-      rest_json_data->nickname = GNUNET_strdup(json_string_value(cache));
-    }
-  }
-  cache = json_object_get (json_data, GNUNET_REST_JSON_PUBKEY_ENTRY);
-  rest_json_data->pubkey = NULL;
-  if (NULL != cache)
-  {
-    if (json_is_string(cache))
-    {
-      rest_json_data->pubkey = GNUNET_strdup(json_string_value(cache));
-    }
-  }
-  cache = json_object_get (json_data, GNUNET_REST_JSON_SUBSYSTEM_ENTRY);
-  rest_json_data->subsystem = NULL;
-  if (NULL != cache)
-  {
-    if (json_is_string(cache))
-    {
-      rest_json_data->subsystem = GNUNET_strdup(json_string_value(cache));
-    }
-  }
-  cache = json_object_get (json_data, GNUNET_REST_JSON_TYPE_ENTRY);
-  rest_json_data->type = NULL;
-  if (NULL != cache)
-  {
-    if (json_is_string(cache))
-    {
-      rest_json_data->type = GNUNET_strdup(json_string_value(cache));
-    }
-  }
-  cache = json_object_get (json_data, GNUNET_REST_JSON_VALUE_ENTRY);
-  rest_json_data->value = NULL;
-  if (NULL != cache)
-  {
-    if (json_is_string(cache))
-    {
-      rest_json_data->value = GNUNET_strdup(json_string_value(cache));
-    }
-  }
-  cache = json_object_get (json_data, GNUNET_REST_JSON_ZONE_ENTRY);
-  rest_json_data->zone = NULL;
-  if (NULL != cache)
-  {
-    if (json_is_string(cache))
-    {
-      rest_json_data->zone = GNUNET_strdup(json_string_value(cache));
-    }
-  }
-  cache = json_object_get (json_data, GNUNET_REST_JSON_IS_PUBLIC_ENTRY);
-  if (NULL != cache)
-  {
-    if (json_is_integer(cache))
-    {
-      rest_json_data->is_public = json_integer_value(cache);
-    }
-  }
-  *output_data = rest_json_data;
-  return GNUNET_OK;
-}
-
-
-
-int
-GNUNET_REST_JSON_free (struct GNUNET_REST_JSON_Data* rest_json_data)
-{
-  if (rest_json_data != NULL)
-  {
-    GNUNET_free_non_null(rest_json_data->expiration_time);
-    GNUNET_free_non_null(rest_json_data->name);
-    GNUNET_free_non_null(rest_json_data->new_name);
-    GNUNET_free_non_null(rest_json_data->nickname);
-    GNUNET_free_non_null(rest_json_data->pubkey);
-    GNUNET_free_non_null(rest_json_data->subsystem);
-    GNUNET_free_non_null(rest_json_data->type);
-    GNUNET_free_non_null(rest_json_data->value);
-    GNUNET_free_non_null(rest_json_data->zone);
-  }
-  GNUNET_free_non_null(rest_json_data);
-  return GNUNET_OK;
-}
-
-
-
-
-
-
-
-
-
index ab490c04f1394fa37cb4d8e2693162d3d56122de..afe010b79dadae332fd8e7266ee80881c0b27d5c 100644 (file)
@@ -2,20 +2,18 @@
    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 General Public License as published
-   by the Free Software Foundation; either version 3, or (at your
-   option) any later version.
+   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
-   General Public License for more details.
+   Affero General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with GNUnet; see the file COPYING.  If not, write to the
-   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.
+   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
@@ -42,6 +40,7 @@
 #define GNUNET_REST_JSON_NAMESTORE_VALUE "value"
 #define GNUNET_REST_JSON_NAMESTORE_EXPIRATION "expiration"
 #define GNUNET_REST_JSON_NAMESTORE_EXPIRED "expired"
+#define GNUNET_REST_ERROR_UNKNOWN "Unknown Error"
 
 #define GNUNET_REST_NAMESTORE_RD_COUNT 1
 
@@ -96,17 +95,17 @@ struct RequestHandle
   /**
    * Records to store
    */
-  struct GNUNET_GNSRECORD_Data *rd;
+  char *label_name;
 
   /**
-   * NAMESTORE Operation
+   * Records to store
    */
-  struct GNUNET_NAMESTORE_QueueEntry *add_qe;
+  struct GNUNET_GNSRECORD_Data *rd;
 
   /**
-   * JSON data parser
+   * NAMESTORE Operation
    */
-  struct GNUNET_REST_JSON_Data *json_data;
+  struct GNUNET_NAMESTORE_QueueEntry *add_qe;
 
   /**
    * Response object
@@ -192,8 +191,9 @@ struct RequestHandle
  * @param handle Handle to clean up
  */
 static void
-cleanup_handle (struct RequestHandle *handle)
+cleanup_handle (void *cls)
 {
+  struct RequestHandle *handle = cls;
   size_t index;
   json_t *json_ego;
 
@@ -204,6 +204,8 @@ cleanup_handle (struct RequestHandle *handle)
     GNUNET_SCHEDULER_cancel (handle->timeout_task);
     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)
@@ -243,9 +245,6 @@ cleanup_handle (struct RequestHandle *handle)
     }
     json_decref(handle->resp_object);
   }
-  
-  if (NULL != handle->json_data)
-    GNUNET_REST_JSON_free(handle->json_data);
 
   GNUNET_free (handle);
 }
@@ -261,20 +260,22 @@ do_error (void *cls)
 {
   struct RequestHandle *handle = cls;
   struct MHD_Response *resp;
-  char *json_error;
+  json_t *json_error = json_object();
+  char *response;
 
   if (NULL == handle->emsg)
-    handle->emsg = GNUNET_strdup("Unknown Error");
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_UNKNOWN);
+
+  json_object_set_new(json_error,"error", json_string(handle->emsg));
 
-  GNUNET_asprintf (&json_error, "{\"error\": \"%s\"}", handle->emsg);
-  
   if (0 == handle->response_code)
     handle->response_code = MHD_HTTP_OK;
-
-  resp = GNUNET_REST_create_response (json_error);
+  response = json_dumps (json_error, 0);
+  resp = GNUNET_REST_create_response (response);
   handle->proc (handle->proc_cls, resp, handle->response_code);
-  cleanup_handle (handle);
-  GNUNET_free(json_error);
+  json_decref(json_error);
+  GNUNET_free(response);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 /**
@@ -287,7 +288,7 @@ namestore_iteration_error (void *cls)
   struct MHD_Response *resp = GNUNET_REST_create_response (NULL);
   handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
   handle->proc (handle->proc_cls, resp, handle->response_code);
-  cleanup_handle (handle);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 /**
@@ -360,7 +361,7 @@ create_finished (void *cls, int32_t success, const char *emsg)
   }
   resp = GNUNET_REST_create_response (NULL);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT);
-  cleanup_handle(handle);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 /**
@@ -391,7 +392,7 @@ namestore_list_finished (void *cls)
   resp = GNUNET_REST_create_response (result_str);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
   GNUNET_free_non_null (result_str);
-  cleanup_handle(handle);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
 }
 
 
@@ -476,34 +477,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
                                                            &namestore_list_finished,
                                                            handle);
 }
-
-int
-check_needed_data(struct RequestHandle *handle){
-  if(NULL == handle->json_data->name)
-  {
-    handle->emsg = GNUNET_strdup("Missing JSON parameter: name");
-    return GNUNET_SYSERR;
-  }
-
-  if(NULL == handle->json_data->type)
-  {
-    handle->emsg = GNUNET_strdup("Missing JSON parameter: type");
-    return GNUNET_SYSERR;
-  }
-
-  if(NULL == handle->json_data->value)
-  {
-    handle->emsg = GNUNET_strdup("Missing JSON parameter: value");
-    return GNUNET_SYSERR;
-  }
-
-  if(NULL == handle->json_data->expiration_time)
-  {
-    handle->emsg = GNUNET_strdup("Missing JSON parameter: expiration time");
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
+/*
 
 //TODO filter input
 static int
@@ -544,7 +518,7 @@ json_to_gnsrecord (struct RequestHandle *handle)
    rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
    if (1 != handle->is_public)
    rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
-   */
+   *
   if (0 == strcmp (handle->json_data->expiration_time, "never"))
   {
     (*handle->rd).expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
@@ -569,7 +543,7 @@ json_to_gnsrecord (struct RequestHandle *handle)
   }
   return GNUNET_OK;
 }
-
+*/
 
 /**
  * We're storing a new record; this requires
@@ -590,8 +564,9 @@ create_new_record_cont (void *cls,
 {
   struct RequestHandle *handle = cls;
 
+
   handle->add_qe = NULL;
-  if (0 != strcmp (rec_name, handle->json_data->name))
+  if (0 != strcmp (rec_name, handle->label_name))
   {
     GNUNET_break (0);
     do_error (handle);
@@ -603,19 +578,18 @@ create_new_record_cont (void *cls,
     handle->proc (handle->proc_cls,
                   GNUNET_REST_create_response (NULL),
                   MHD_HTTP_CONFLICT);
-    cleanup_handle(handle);
+    GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
     return;
   }
   handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
                                                    &handle->zone_pkey,
-                                                   handle->json_data->name,
+                                                   handle->label_name,
                                                    GNUNET_REST_NAMESTORE_RD_COUNT,
                                                    handle->rd,
                                                    &create_finished,
                                                    handle);
 }
 
-
 /**
  * Handle namestore POST request
  *
@@ -629,9 +603,15 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
               void *cls)
 {
   struct RequestHandle *handle = cls;
+  struct GNUNET_GNSRECORD_Data *gns_record;
   json_t *data_js;
+  json_t *name_json;
   json_error_t err;
   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))
   {
@@ -649,24 +629,26 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
   GNUNET_memcpy(term_data, handle->rest_handle->data,
                handle->rest_handle->data_size);
   data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
-  GNUNET_REST_JSON_parse(&handle->json_data, data_js);
-  if(NULL == handle->json_data)
+  GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL));
+  name_json = json_object_get(data_js, "label");
+  if (!json_is_string(name_json))
   {
-    handle->emsg = GNUNET_strdup("Wrong data");
+    handle->emsg = GNUNET_strdup("Missing name");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  if(GNUNET_SYSERR == check_needed_data(handle))
+  handle->label_name = GNUNET_strdup(json_string_value(name_json));
+  if(NULL == handle->label_name)
   {
-    json_decref (data_js);
+    handle->emsg = GNUNET_strdup("Missing name");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
   json_decref (data_js);
-  json_to_gnsrecord (handle);
+  handle->rd = gns_record;
   handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
                                                    &handle->zone_pkey,
-                                                   handle->json_data->name,
+                                                   handle->label_name,
                                                    &do_error,
                                                    handle,
                                                    &create_new_record_cont,
@@ -718,7 +700,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
                            "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;
 }