*/
#include "platform.h"
#include "gnunet_json_lib.h"
-
-#define GNUNET_JSONAPI_KEY_DATA "data"
-
-#define GNUNET_JSONAPI_KEY_ID "id"
-
-#define GNUNET_JSONAPI_KEY_TYPE "type"
-
-struct GNUNET_JSONAPI_Resource
-{
- /**
- * DLL
- */
- struct GNUNET_JSONAPI_Resource *next;
-
- /**
- * DLL
- */
- struct GNUNET_JSONAPI_Resource *prev;
-
- /**
- * Resource content
- */
- json_t *res_obj;
-};
-
-
-struct GNUNET_JSONAPI_Object
-{
- /**
- * DLL Resource
- */
- struct GNUNET_JSONAPI_Resource *res_list_head;
-
- /**
- * DLL Resource
- */
- struct GNUNET_JSONAPI_Resource *res_list_tail;
-
- /**
- * num resources
- */
- int res_count;
-};
-
+#include "gnunet_rest_lib.h"
/**
- * JSON API
- */
-
-
-/**
- * Create a JSON API resource
- *
- * @param type the JSON API resource type
- * @param id the JSON API resource id
- * @return a new JSON API resource or NULL on error.
+ * TODO move this to jsonapi-utils
*/
-struct GNUNET_JSONAPI_Resource*
-GNUNET_JSONAPI_resource_new (const char *type, const char *id)
-{
- struct GNUNET_JSONAPI_Resource *res;
-
- if ( (NULL == type) || (0 == strlen (type)) )
- return NULL;
- if ( (NULL == id) || (0 == strlen (id)) )
- return NULL;
-
- res = GNUNET_new (struct GNUNET_JSONAPI_Resource);
- res->prev = NULL;
- res->next = NULL;
-
- res->res_obj = json_object ();
-
- json_object_set_new (res->res_obj, GNUNET_JSONAPI_KEY_ID, json_string (id));
- json_object_set_new (res->res_obj, GNUNET_JSONAPI_KEY_TYPE, json_string (type));
-
- return res;
-}
-
-
/**
- * Add a JSON API attribute
+ * Check rest request for validity
*
- * @param res the JSON resource
- * @param key the key for the attribute
- * @param json the json_t attribute to add
- * @return #GNUNET_OK if added successfully
- * #GNUNET_SYSERR if not
+ * @param req handle to the request
+ * @return GNUNET_OK if valid
*/
int
-GNUNET_JSONAPI_resource_add_attr (const struct GNUNET_JSONAPI_Resource *resource,
- const char* key,
- json_t *json)
+GNUNET_JSONAPI_check_request_acceptable (struct GNUNET_REST_RequestHandle *req)
{
- if ( (NULL == resource) ||
- (NULL == key) ||
- (NULL == json) )
- return GNUNET_SYSERR;
- json_object_set (resource->res_obj, key, json);
+ //TODO
return GNUNET_OK;
}
/**
- * Read a JSON API attribute
+ * Check rest request for validity
*
- * @param res the JSON resource
- * @param key the key for the attribute
- * @return the json_t object
+ * @param req handle to the request
+ * @return GNUNET_OK if valid
*/
-json_t*
-GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resource,
- const char* key)
-{
- if ( (NULL == resource) ||
- (NULL == key))
- return NULL;
- return json_object_get (resource->res_obj, key);
-}
-
int
-check_resource_attr_str (const struct GNUNET_JSONAPI_Resource *resource,
- const char* key,
- const char* attr)
+GNUNET_JSONAPI_check_request_supported (struct GNUNET_REST_RequestHandle *req)
{
- json_t *value;
- if ( (NULL == resource) ||
- (NULL == key) ||
- (NULL == attr))
- return GNUNET_NO;
- value = json_object_get (resource->res_obj, key);
- if (NULL == value)
- return GNUNET_NO;
- if (!json_is_string (value) ||
- (0 != strcmp (attr, json_string_value(value))))
- {
- return GNUNET_NO;
- }
- return GNUNET_YES;
-}
-
-/**
- * Check a JSON API resource id
- *
- * @param res the JSON resource
- * @param id the expected id
- * @return GNUNET_YES if id matches
- */
-int
-GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource,
- const char* id)
-{
- return check_resource_attr_str (resource, GNUNET_JSONAPI_KEY_ID, id);
-}
-
-/**
- * Check a JSON API resource id
- *
- * @param res the JSON resource
- * @return the resource id
- */
-json_t*
-GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource)
-{
- return GNUNET_JSONAPI_resource_read_attr (resource, GNUNET_JSONAPI_KEY_ID);
-}
-
-/**
- * Check a JSON API resource type
- *
- * @param res the JSON resource
- * @param type the expected type
- * @return GNUNET_YES if id matches
- */
-int
-GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resource,
- const char* type)
-{
- return check_resource_attr_str (resource, GNUNET_JSONAPI_KEY_TYPE, type);
+ //TODO
+ return GNUNET_OK;
}
/**
- * Get a JSON API object resource count
+ * Handle jsonapi rest request. Checks request headers for jsonapi compliance
*
- * @param resp the JSON API object
- * @return the number of resources
+ * @param req rest request handle
+ * @param handler rest request handlers
+ * @param cls closure
+ * @return GNUNET_OK if successful
*/
int
-GNUNET_JSONAPI_object_resource_count (struct GNUNET_JSONAPI_Object *resp)
-{
- return resp->res_count;
-}
-
-/**
- * Get a JSON API object resource by index
- *
- * @param resp the JSON API object
- * @param num the number of the resource
- * @return the resource
- */
-struct GNUNET_JSONAPI_Resource*
-GNUNET_JSONAPI_object_get_resource (struct GNUNET_JSONAPI_Object *resp,
- int num)
-{
- struct GNUNET_JSONAPI_Resource *res;
- int i;
-
- if ((0 == resp->res_count) ||
- (num >= resp->res_count))
- return NULL;
- res = resp->res_list_head;
- for (i = 0; i < num; i++)
- {
- res = res->next;
- }
- return res;
-}
-
-/**
- * Delete a JSON API resource
- *
- * @param res the JSON resource
- * @param result Pointer where the resource should be stored
- */
-void
-GNUNET_JSONAPI_resource_delete (struct GNUNET_JSONAPI_Resource *resource)
-{
- json_decref (resource->res_obj);
- GNUNET_free (resource);
- resource = NULL;
-}
-
-/**
- * Delete a JSON API primary data
- *
- * @param type the JSON API resource type
- * @param id the JSON API resource id
- * @return a new JSON API resource or NULL on error.
- */
-void
-GNUNET_JSONAPI_object_delete (struct GNUNET_JSONAPI_Object *resp)
-{
- struct GNUNET_JSONAPI_Resource *res;
- struct GNUNET_JSONAPI_Resource *res_next;
-
- for (res = resp->res_list_head;
- res != NULL;)
- {
- res_next = res->next;
- GNUNET_CONTAINER_DLL_remove (resp->res_list_head,
- resp->res_list_tail,
- res);
- GNUNET_JSONAPI_resource_delete (res);
- res = res_next;
- }
- GNUNET_free (resp);
- resp = NULL;
-}
-
-/**
- * Create a JSON API primary data
- *
- * @return a new JSON API resource or NULL on error.
- */
-struct GNUNET_JSONAPI_Object*
-GNUNET_JSONAPI_object_new ()
-{
- struct GNUNET_JSONAPI_Object *result;
-
- result = GNUNET_new (struct GNUNET_JSONAPI_Object);
- result->res_count = 0;
- return result;
-}
-
-/**
- * Add a JSON API object to primary data
- *
- * @param data The JSON API data to add to
- * @param res the JSON API resource to add
- * @return the new number of resources
- */
-void
-GNUNET_JSONAPI_object_resource_add (struct GNUNET_JSONAPI_Object *resp,
- struct GNUNET_JSONAPI_Resource *res)
-{
- GNUNET_CONTAINER_DLL_insert (resp->res_list_head,
- resp->res_list_tail,
- res);
-
- resp->res_count++;
-}
-
-static void
-add_json_resource (struct GNUNET_JSONAPI_Object *obj,
- const json_t *res_json)
-{
- struct GNUNET_JSONAPI_Resource *res;
- const char *type_json;
-
- struct GNUNET_JSON_Specification dspec[] = {
- GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_TYPE, &type_json),
- GNUNET_JSON_spec_end()
- };
-
- GNUNET_assert (GNUNET_OK ==
- GNUNET_JSON_parse (res_json, dspec,
- NULL, NULL));
- GNUNET_JSON_parse_free (dspec);
- res = GNUNET_new (struct GNUNET_JSONAPI_Resource);
- res->next = NULL;
- res->prev = NULL;
- res->res_obj = json_deep_copy (res_json);
- GNUNET_JSONAPI_object_resource_add (obj, res);
-}
-
-/**
- * Parse given JSON object to RSA public key.
- *
- * @param cls closure, NULL
- * @param root the json object representing data
- * @param[out] spec where to write the data
- * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
- */
-static int
-parse_jsonapiobject (void *cls,
- json_t *root,
- struct GNUNET_JSON_Specification *spec)
+GNUNET_JSONAPI_handle_request (struct GNUNET_REST_RequestHandle *handle,
+ const struct GNUNET_REST_RequestHandler *handlers,
+ struct GNUNET_REST_RequestHandlerError *err,
+ void *cls)
{
- struct GNUNET_JSONAPI_Object *result;
- json_t *data_json;
- int res_count = 0;
- int i;
-
- struct GNUNET_JSON_Specification jsonapispec[] = {
- GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_DATA, &data_json),
- GNUNET_JSON_spec_end()
- };
- if (GNUNET_OK !=
- GNUNET_JSON_parse (root, jsonapispec,
- NULL, NULL) || (NULL == data_json))
+ if (GNUNET_OK != GNUNET_JSONAPI_check_request_acceptable (handle))
{
+ err->error_code = MHD_HTTP_NOT_ACCEPTABLE;
return GNUNET_SYSERR;
}
-
- result = GNUNET_new (struct GNUNET_JSONAPI_Object);
- result->res_count = 0;
- if (json_is_object (data_json))
- add_json_resource (result, data_json);
- else if (json_is_array (data_json))
- {
- res_count = json_array_size (data_json);
- for (i = 0; i < res_count; i++)
- add_json_resource (result, json_array_get (data_json, i));
- }
- if (0 == result->res_count)
+ if (GNUNET_OK != GNUNET_JSONAPI_check_request_supported (handle))
{
- GNUNET_free (result);
- GNUNET_JSON_parse_free (jsonapispec);
+ err->error_code = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE;
return GNUNET_SYSERR;
}
- *(struct GNUNET_JSONAPI_Object **) spec->ptr = result;
- GNUNET_JSON_parse_free (jsonapispec);
- 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_jsonapiobject (void *cls,
- struct GNUNET_JSON_Specification *spec)
-{
- struct GNUNET_JSONAPI_Object **jsonapi_obj;
- jsonapi_obj = (struct GNUNET_JSONAPI_Object **) spec->ptr;
- if (NULL != *jsonapi_obj)
- {
- GNUNET_JSONAPI_object_delete (*jsonapi_obj);
- *jsonapi_obj = NULL;
- }
-}
-
-/**
- * Add a JSON API resource to primary data
- *
- * @param data The JSON API data to add to
- * @param res the JSON API resource to add
- * @return the new number of resources
- */
-void
-GNUNET_JSONAPI_data_resource_remove (struct GNUNET_JSONAPI_Object *resp,
- struct GNUNET_JSONAPI_Resource *res)
-{
- GNUNET_CONTAINER_DLL_remove (resp->res_list_head,
- resp->res_list_tail,
- res);
- resp->res_count--;
-}
-
-/**
- * String serialze jsonapi primary data
- *
- * @param data the JSON API primary data
- * @param result where to store the result
- * @return GNUNET_SYSERR on error else GNUNET_OK
- */
-int
-GNUNET_JSONAPI_data_serialize (const struct GNUNET_JSONAPI_Object *resp,
- char **result)
-{
- struct GNUNET_JSONAPI_Resource *res;
- json_t *root_json;
- json_t *res_arr;
-
- if ((NULL == resp))
- return GNUNET_SYSERR;
-
- root_json = json_object ();
- res_arr = json_array ();
- for (res = resp->res_list_head;
- res != NULL;
- res = res->next)
- {
- json_array_append (res_arr, res->res_obj);
- }
- json_object_set (root_json, GNUNET_JSONAPI_KEY_DATA, res_arr);
- *result = json_dumps (root_json, JSON_INDENT(2));
- json_decref (root_json);
- json_decref (res_arr);
- return GNUNET_OK;
-}
-
-/**
- * JSON object.
- *
- * @param name name of the JSON field
- * @param[out] jsonp where to store the JSON found under @a name
- */
-struct GNUNET_JSON_Specification
-GNUNET_JSON_spec_jsonapi (struct GNUNET_JSONAPI_Object **jsonapi_object)
-{
- struct GNUNET_JSON_Specification ret = {
- .parser = &parse_jsonapiobject,
- .cleaner = &clean_jsonapiobject,
- .cls = NULL,
- .field = NULL,
- .ptr = jsonapi_object,
- .ptr_size = 0,
- .size_ptr = NULL
- };
- *jsonapi_object = NULL;
- return ret;
+ return GNUNET_REST_handle_request (handle, handlers, err, cls);
}