gnsrecord_misc.c
libgnunetgnsrecord_la_LIBADD = \
$(top_builddir)/src/util/libgnunetutil.la \
+ -ljansson \
$(GN_LIBINTL)
libgnunetgnsrecord_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) $(WINFLAGS) \
#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__)
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 */
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 ******** */
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 */
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 \
+++ /dev/null
-/*
- 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;
-}
-
-
-
-
-
-
-
-
-
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
#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
/**
* 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
* @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;
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)
}
json_decref(handle->resp_object);
}
-
- if (NULL != handle->json_data)
- GNUNET_REST_JSON_free(handle->json_data);
GNUNET_free (handle);
}
{
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);
}
/**
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);
}
/**
}
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);
}
/**
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);
}
&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
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;
}
return GNUNET_OK;
}
-
+*/
/**
* We're storing a new record; this requires
{
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);
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
*
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))
{
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,
"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;
}