aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/plugin_rest_namestore.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2015-09-11 15:56:39 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2015-09-11 15:56:39 +0000
commitc8aace43c41d50e03bd28b6e696b33c1da8b6c4c (patch)
tree375181e89bd4f099e0a2039ed0962bf7cfd48131 /src/namestore/plugin_rest_namestore.c
parenta12f20bd4c621a7b5e88ca52830ad1bb74a8e2d8 (diff)
- move rest plugins into rest directory where they belong
Diffstat (limited to 'src/namestore/plugin_rest_namestore.c')
-rw-r--r--src/namestore/plugin_rest_namestore.c1063
1 files changed, 0 insertions, 1063 deletions
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c
deleted file mode 100644
index 9b6b5c57c2..0000000000
--- a/src/namestore/plugin_rest_namestore.c
+++ /dev/null
@@ -1,1063 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2012-2015 Christian Grothoff (and other contributing authors)
-
- 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 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.
-
- 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.
- */
-/**
- * @author Martin Schanzenbach
- * @file namestore/plugin_rest_namestore.c
- * @brief GNUnet Namestore REST plugin
- *
- */
-
-#include "platform.h"
-#include "gnunet_rest_plugin.h"
-#include "gnunet_namestore_service.h"
-#include "gnunet_identity_service.h"
-#include "gnunet_rest_lib.h"
-#include "microhttpd.h"
-#include <jansson.h>
-
-#define GNUNET_REST_API_NS_NAMESTORE "/names"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO "record"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_RECORD GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE "record_type"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_VALUE "value"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_PUBLIC "public"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_SHADOW "shadow"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_PKEY "pkey"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_EXPIRATION "expiration"
-
-#define GNUNET_REST_JSONAPI_NAMESTORE_EGO "ego"
-
-/**
- * @brief struct returned by the initialization function of the plugin
- */
-struct Plugin
-{
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-};
-
-const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-struct RecordEntry
-{
- /**
- * DLL
- */
- struct RecordEntry *next;
-
- /**
- * DLL
- */
- struct RecordEntry *prev;
-
-};
-
-struct RequestHandle
-{
- /**
- * Ego list
- */
- struct RecordEntry *record_head;
-
- /**
- * Ego list
- */
- struct record_entry *record_tail;
-
- /**
- * JSON response object
- */
- struct JsonApiObject *resp_object;
-
- /**
- * Rest connection
- */
- struct RestConnectionDataHandle *conndata_handle;
-
- /**
- * Handle to GNS service.
- */
- struct GNUNET_IDENTITY_Handle *identity_handle;
-
- /**
- * Handle to NAMESTORE
- */
- struct GNUNET_NAMESTORE_Handle *ns_handle;
-
- /**
- * Handle to NAMESTORE it
- */
- struct GNUNET_NAMESTORE_ZoneIterator *list_it;
-
- /**
- * Private key for the zone
- */
- struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey;
-
- /**
- * Handle to identity lookup
- */
- struct GNUNET_IDENTITY_EgoLookup *ego_lookup;
-
- /**
- * Default Ego operation
- */
- struct GNUNET_IDENTITY_Operation *get_default;
-
- /**
- * Name of the ego
- */
- char *ego_name;
-
- /**
- * Record is public
- */
- int is_public;
-
- /**
- * Shadow record
- */
- int is_shadow;
-
- /**
- * Name of the record to modify
- */
- char *name;
-
- /**
- * Value of the record
- */
- char *value;
-
- /**
- * record type
- */
- uint32_t type;
-
- /**
- * Records to store
- */
- struct GNUNET_GNSRECORD_Data *rd;
-
- /**
- * record count
- */
- unsigned int rd_count;
-
- /**
- * NAMESTORE Operation
- */
- struct GNUNET_NAMESTORE_QueueEntry *add_qe;
-
- /**
- * 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;
-
- /**
- * The data from the REST request
- */
- const char* data;
-
- /**
- * the length of the REST data
- */
- size_t data_size;
-
- /**
- * Cfg
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-};
-
-
-/**
- * Cleanup lookup handle
- * @param handle Handle to clean up
- */
-static void
-cleanup_handle (struct RequestHandle *handle)
-{
- struct RecordEntry *record_entry;
- struct RecordEntry *record_tmp;
- int i;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Cleaning up\n");
- 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);
- if (NULL != handle->list_it)
- GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it);
- if (NULL != handle->add_qe)
- GNUNET_NAMESTORE_cancel (handle->add_qe);
- if (NULL != 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 (i = 0; i < handle->rd_count; i++)
- {
- if (NULL != handle->rd[i].data)
- GNUNET_free ((void*)handle->rd[i].data);
- }
- GNUNET_free (handle->rd);
- }
- if (NULL != handle->ego_name)
- GNUNET_free (handle->ego_name);
- for (record_entry = handle->record_head;
- NULL != record_entry;)
- {
- record_tmp = record_entry;
- record_entry = record_entry->next;
- GNUNET_free (record_tmp);
- }
- GNUNET_free (handle);
-}
-
-/**
- * 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);
-
- 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)
- {
- 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, 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;
-}
-
-
-/**
- * Task run on shutdown. Cleans up everything.
- *
- * @param cls unused
- * @param tc scheduler context
- */
-static void
-do_error (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct RequestHandle *handle = cls;
- struct MHD_Response *resp = GNUNET_REST_create_json_response (NULL);
- handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
- cleanup_handle (handle);
-}
-
-static void
-cleanup_handle_delayed (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- cleanup_handle (cls);
-}
-
-/**
- * Create a response with requested records
- *
- * @param handle the RequestHandle
- */
-static void
-namestore_list_response (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 JsonApiResource *json_resource;
- struct MHD_Response *resp;
- json_t *result_array;
- json_t *record_obj;
- int i;
- char *result;
-
- if (NULL == handle->resp_object)
- handle->resp_object = GNUNET_REST_jsonapi_object_new ();
-
- if (NULL == rname)
- {
- handle->list_it = NULL;
- //Handle response
- if (GNUNET_SYSERR == GNUNET_REST_jsonapi_data_serialize (handle->resp_object, &result))
- {
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- GNUNET_REST_jsonapi_object_delete (handle->resp_object);
- resp = GNUNET_REST_create_json_response (result);
- handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
- GNUNET_free (result);
- GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
- return;
- }
-
- if ( (NULL != handle->name) &&
- (0 != strcmp (handle->name, rname)) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%s does not match %s\n", rname, handle->name);
- GNUNET_NAMESTORE_zone_iterator_next (handle->list_it);
- return;
- }
-
- result_array = json_array ();
- for (i=0; i<rd_len; i++)
- {
- if ( (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
- (0 != strcmp (rname, "+")) )
- continue;
-
- if ( (rd[i].record_type != handle->type) &&
- (GNUNET_GNSRECORD_TYPE_ANY != handle->type) )
- continue;
- record_obj = gnsrecord_to_json (&(rd[i]));
- json_array_append (result_array, record_obj);
- json_decref (record_obj);
- }
-
- json_resource = GNUNET_REST_jsonapi_resource_new (GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO,
- rname);
- GNUNET_REST_jsonapi_resource_add_attr (json_resource,
- GNUNET_REST_JSONAPI_NAMESTORE_RECORD,
- result_array);
- GNUNET_REST_jsonapi_object_resource_add (handle->resp_object, json_resource);
-
- json_decref (result_array);
- GNUNET_NAMESTORE_zone_iterator_next (handle->list_it);
-}
-
-static void
-create_finished (void *cls, int32_t success, const char *emsg)
-{
- struct RequestHandle *handle = cls;
- struct MHD_Response *resp;
-
- handle->add_qe = NULL;
- if (GNUNET_YES != success)
- {
- 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;
- }
- resp = GNUNET_REST_create_json_response (NULL);
- handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT);
- GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
-}
-
-
-/**
- * We're storing a new record; this requires
- * that no record already exists
- *
- * @param cls closure, unused
- * @param zone_key private key of the zone
- * @param rec_name name that is being mapped (at most 255 characters long)
- * @param rd_count number of entries in @a rd array
- * @param rd array of records with data to store
- */
-static void
-create_new_record_cont (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
- const char *rec_name,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
-{
- struct RequestHandle *handle = cls;
-
- handle->add_qe = NULL;
- if ( (NULL != zone_key) &&
- (0 != strcmp (rec_name, handle->name)) )
- {
- GNUNET_break (0);
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Received %u records for name `%s'\n",
- rd_count, rec_name);
- if (0 != rd_count)
- {
- handle->proc (handle->proc_cls,
- GNUNET_REST_create_json_response (NULL),
- MHD_HTTP_CONFLICT);
- GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, 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->rd,
- &create_finished,
- handle);
-}
-
-static void
-del_finished (void *cls,
- int32_t success,
- const char *emsg)
-{
- struct RequestHandle *handle = cls;
-
- handle->add_qe = NULL;
- if (GNUNET_NO == success)
- {
- 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
- return;
- }
- if (GNUNET_SYSERR == success)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Deleting record failed%s%s\n"),
- (NULL != emsg) ? ": " : "",
- (NULL != emsg) ? emsg : "");
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- handle->proc (handle->proc_cls,
- GNUNET_REST_create_json_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;
-
- if (0 == rd_count)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("There are no records under label `%s' that could be deleted.\n"),
- label);
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
-
- 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 RestConnectionDataHandle *con,
- const char *url,
- void *cls)
-{
- struct RequestHandle *handle = cls;
-
- if (NULL == handle->name)
- {
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
-
- handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
- &handle->zone_pkey,
- handle->name,
- &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;
- int i;
- 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_malloc (sizeof (struct GNUNET_GNSRECORD_Data) * *rd_count);
- for (i = 0; i < *rd_count; i++)
- {
- 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;
- }
- GNUNET_asprintf (&value, "%s", 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 RestConnectionDataHandle *con,
- const char *url,
- void *cls)
-{
- struct RequestHandle *handle = cls;
- struct MHD_Response *resp;
- struct JsonApiObject *json_obj;
- struct JsonApiResource *json_res;
- json_t *name_json;
- json_t *records_json;
- char term_data[handle->data_size+1];
-
- if (strlen (GNUNET_REST_API_NS_NAMESTORE) != strlen (handle->url))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Cannot create under %s\n", handle->url);
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- if (0 >= handle->data_size)
- {
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- term_data[handle->data_size] = '\0';
- memcpy (term_data, handle->data, handle->data_size);
- json_obj = GNUNET_REST_jsonapi_object_parse (term_data);
- if (NULL == json_obj)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unable to parse JSONAPI Object from %s\n",
- term_data);
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- if (1 != GNUNET_REST_jsonapi_object_resource_count (json_obj))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Cannot create more than 1 resource! (Got %d)\n",
- GNUNET_REST_jsonapi_object_resource_count (json_obj));
- GNUNET_REST_jsonapi_object_delete (json_obj);
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- json_res = GNUNET_REST_jsonapi_object_get_resource (json_obj, 0);
- if (GNUNET_NO == GNUNET_REST_jsonapi_resource_check_type (json_res,
- GNUNET_REST_JSONAPI_NAMESTORE_RECORD))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unsupported JSON data type\n");
- GNUNET_REST_jsonapi_object_delete (json_obj);
- resp = GNUNET_REST_create_json_response (NULL);
- handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
- cleanup_handle (handle);
- return;
- }
- name_json = GNUNET_REST_jsonapi_resource_read_attr (json_res, GNUNET_REST_JSONAPI_KEY_ID);
- if (!json_is_string (name_json))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Name property is no string\n");
- GNUNET_REST_jsonapi_object_delete (json_obj);
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- GNUNET_asprintf (&handle->name, "%s", json_string_value (name_json));
- records_json = GNUNET_REST_jsonapi_resource_read_attr (json_res,
- GNUNET_REST_JSONAPI_NAMESTORE_RECORD);
- if (NULL == records_json)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No records given\n");
- GNUNET_REST_jsonapi_object_delete (json_obj);
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- if (GNUNET_SYSERR == json_to_gnsrecord (records_json, &handle->rd, &handle->rd_count))
- {
- GNUNET_REST_jsonapi_object_delete (json_obj);
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- GNUNET_REST_jsonapi_object_delete (json_obj);
-
- handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
- &handle->zone_pkey,
- handle->name,
- &create_new_record_cont, handle );
-}
-
-
-
-
-
-static void
-namestore_info_cont (struct RestConnectionDataHandle *con,
- const char *url,
- void *cls)
-{
- struct RequestHandle *handle = cls;
- handle->list_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
- &handle->zone_pkey,
- &namestore_list_response,
- 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;
-}
-
-/**
- * Function called with the result from the check if the namestore
- * service is actually running. If it is, we start the actual
- * operation.
- *
- * @param cls closure with our configuration
- * @param result #GNUNET_YES if the namestore service is running
- */
-static void
-testservice_task (void *cls,
- int result)
-{
- struct RequestHandle *handle = cls;
- static const struct GNUNET_REST_RestConnectionHandler handlers[] = {
- {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
- GNUNET_REST_HANDLER_END
- };
-
- if (GNUNET_YES != result)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Service `%s' is not running\n"),
- "namestore");
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- 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_NO == GNUNET_REST_handle_request (handle->conndata_handle, handlers, handle))
- GNUNET_SCHEDULER_add_now (&do_error, (void*) handle);
-
-}
-
-/**
- * Callback invoked from identity service with ego information.
- * An @a ego of NULL means the ego was not found.
- *
- * @param cls closure with the configuration
- * @param ego an ego known to identity service, or NULL
- */
-static void
-identity_cb (void *cls,
- const struct GNUNET_IDENTITY_Ego *ego)
-{
- struct RequestHandle *handle = cls;
- struct MHD_Response *resp;
-
- 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_json_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);
- GNUNET_CLIENT_service_test ("namestore", handle->cfg,
- GNUNET_TIME_UNIT_SECONDS,
- &testservice_task,
- (void *) handle);
-}
-
-static void
-default_ego_cb (void *cls,
- struct GNUNET_IDENTITY_Ego *ego,
- void **ctx,
- const char *name)
-{
- 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_json_response (NULL);
- handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
- cleanup_handle (handle);
- return;
- }
- else
- {
- identity_cb (cls, ego);
- }
-}
-
-static void
-id_connect_cb (void *cls,
- struct GNUNET_IDENTITY_Ego *ego,
- void **ctx,
- const char *name)
-{
- struct RequestHandle *handle = cls;
- if (NULL == ego)
- {
- handle->get_default = GNUNET_IDENTITY_get (handle->identity_handle,
- "namestore",
- &default_ego_cb, handle);
- }
-}
-
-static void
-testservice_id_task (void *cls, int result)
-{
- struct RequestHandle *handle = cls;
- struct MHD_Response *resp;
- struct GNUNET_HashCode key;
- char *ego;
- char *name;
- char *type;
-
- if (result != GNUNET_YES)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Identity service is not running\n"));
- resp = GNUNET_REST_create_json_response (NULL);
- handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
- cleanup_handle (handle);
- return;
- }
- 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->conndata_handle->url_param_map,
- &key) )
- {
- ego = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
- &key);
- }
-
- 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->conndata_handle->url_param_map,
- &key) )
- {
- type = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
- &key);
- }
- handle->type = GNUNET_GNSRECORD_typename_to_number (type);
- name = get_name_from_url (handle->url);
- if (NULL != ego)
- GNUNET_asprintf (&handle->ego_name, "%s", ego);
- if (NULL != name)
- GNUNET_asprintf (&handle->name, "%s", name);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", handle->ego_name);
- if (NULL == handle->ego_name)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", 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_json_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);
-}
-
-/**
- * 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_identity_process_request(struct RestConnectionDataHandle *conndata_handle,
- GNUNET_REST_ResultProcessor proc,
- void *proc_cls)
-{
- struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
-
- handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
- handle->proc_cls = proc_cls;
- handle->proc = proc;
- handle->conndata_handle = conndata_handle;
- handle->data = conndata_handle->data;
- handle->data_size = conndata_handle->data_size;
- 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->cfg = cfg;
- GNUNET_CLIENT_service_test ("identity",
- cfg,
- GNUNET_TIME_UNIT_SECONDS,
- &testservice_id_task,
- handle);
- handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
- &do_error,
- handle);
-
-
-}
-
-/**
- * Entry point for the plugin.
- *
- * @param cls Config info
- * @return NULL on error, otherwise the plugin context
- */
-void *
-libgnunet_plugin_rest_namestore_init (void *cls)
-{
- static struct Plugin plugin;
- cfg = cls;
- struct GNUNET_REST_Plugin *api;
-
- 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_NAMESTORE;
- api->process_request = &rest_identity_process_request;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Namestore 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_namestore_done (void *cls)
-{
- struct GNUNET_REST_Plugin *api = cls;
- struct Plugin *plugin = api->cls;
-
- plugin->cfg = NULL;
- GNUNET_free (api);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Namestore REST plugin is finished\n");
- return NULL;
-}
-
-/* end of plugin_rest_namestore.c */