aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2015-03-26 14:57:05 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2015-03-26 14:57:05 +0000
commitb68a1cacd29fb91dee84f736085c48db4ea5acaf (patch)
tree16b343e23754b0eec27f927e877e0f457955c105 /src
parent496e08d0b3e7719b4bf63eb9e0a3e0f8f19d6569 (diff)
downloadgnunet-b68a1cacd29fb91dee84f736085c48db4ea5acaf.tar.gz
gnunet-b68a1cacd29fb91dee84f736085c48db4ea5acaf.zip
-more REST
Diffstat (limited to 'src')
-rw-r--r--src/identity/plugin_rest_identity.c130
-rw-r--r--src/include/gnunet_rest_lib.h79
-rw-r--r--src/rest/rest.c199
3 files changed, 315 insertions, 93 deletions
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c
index 75c65466c..d62e56db2 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -45,6 +45,8 @@
45 45
46#define GNUNET_REST_JSONAPI_IDENTITY_KEY "key" 46#define GNUNET_REST_JSONAPI_IDENTITY_KEY "key"
47 47
48#define GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM "subsystem"
49
48/** 50/**
49 * @brief struct returned by the initialization function of the plugin 51 * @brief struct returned by the initialization function of the plugin
50 */ 52 */
@@ -236,16 +238,16 @@ get_ego_for_subsys (void *cls,
236 const char *name) 238 const char *name)
237{ 239{
238 struct RequestHandle *handle = cls; 240 struct RequestHandle *handle = cls;
241 struct JsonApiObject *json_object;
242 struct JsonApiResource *json_resource;
239 struct EgoEntry *ego_entry; 243 struct EgoEntry *ego_entry;
240 struct MHD_Response *resp; 244 struct MHD_Response *resp;
245 json_t *key_json;
241 char *result_str; 246 char *result_str;
242 char *keystring; 247 char *keystring;
243 json_t *ego_json;
244 json_t *root_json;
245
246 root_json = json_object ();
247 248
248 //Return all egos 249 json_object = GNUNET_REST_jsonapi_object_new ();
250
249 for (ego_entry = handle->ego_head; 251 for (ego_entry = handle->ego_head;
250 NULL != ego_entry; 252 NULL != ego_entry;
251 ego_entry = ego_entry->next) 253 ego_entry = ego_entry->next)
@@ -254,26 +256,25 @@ get_ego_for_subsys (void *cls,
254 continue; 256 continue;
255 if (NULL == name) 257 if (NULL == name)
256 continue; 258 continue;
257 ego_json = json_object (); 259 json_resource = GNUNET_REST_jsonapi_resource_new (GNUNET_REST_JSONAPI_IDENTITY_EGO, ego_entry->identifier);
258 keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&ego_entry->pk); 260 keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&ego_entry->pk);
259 json_object_set_new (ego_json, "id", json_string (ego_entry->identifier)); 261 key_json = json_string (keystring);
260 json_object_set_new (ego_json, "type", json_string (GNUNET_REST_JSONAPI_IDENTITY_EGO)); 262 GNUNET_REST_jsonapi_resource_add_attr (json_resource, GNUNET_REST_JSONAPI_IDENTITY_KEY, key_json);
261 json_object_set_new (ego_json, "key", json_string (keystring)); 263 json_decref (key_json);
262 GNUNET_free (keystring); 264 GNUNET_free (keystring);
265 GNUNET_REST_jsonapi_object_resource_add (json_object, json_resource);
263 break; 266 break;
264 } 267 }
265 if (NULL == ego_json) 268 if (0 == GNUNET_REST_jsonapi_object_resource_count (json_object))
266 { 269 {
267 json_decref (root_json); 270 GNUNET_REST_jsonapi_object_delete (json_object);
268 GNUNET_SCHEDULER_add_now (&do_error, handle); 271 GNUNET_SCHEDULER_add_now (&do_error, handle);
269 return; 272 return;
270 } 273 }
271 json_object_set (root_json, GNUNET_REST_JSONAPI_KEY_DATA, ego_json); 274 GNUNET_REST_jsonapi_data_serialize (json_object, &result_str);
272 result_str = json_dumps (root_json, JSON_COMPACT);
273 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
274 json_decref (ego_json);
275 json_decref (root_json);
276 resp = GNUNET_REST_create_json_response (result_str); 276 resp = GNUNET_REST_create_json_response (result_str);
277 GNUNET_REST_jsonapi_object_delete (json_object);
277 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 278 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
278 GNUNET_free (result_str); 279 GNUNET_free (result_str);
279 cleanup_handle (handle); 280 cleanup_handle (handle);
@@ -297,7 +298,7 @@ ego_info_response (struct RestConnectionDataHandle *con,
297 struct EgoEntry *ego_entry; 298 struct EgoEntry *ego_entry;
298 struct GNUNET_HashCode key; 299 struct GNUNET_HashCode key;
299 struct MHD_Response *resp; 300 struct MHD_Response *resp;
300 struct JsonApiResponse *json_response; 301 struct JsonApiObject *json_object;
301 struct JsonApiResource *json_resource; 302 struct JsonApiResource *json_resource;
302 json_t *key_str; 303 json_t *key_str;
303 304
@@ -309,7 +310,6 @@ ego_info_response (struct RestConnectionDataHandle *con,
309 GNUNET_break (0); 310 GNUNET_break (0);
310 return; 311 return;
311 } 312 }
312 json_response = GNUNET_REST_jsonapi_response_new ();
313 if ( (strlen (EGO_NAMESPACE) == strlen (handle->url) )) { 313 if ( (strlen (EGO_NAMESPACE) == strlen (handle->url) )) {
314 GNUNET_CRYPTO_hash (URL_PARAM_SUBSYS, strlen (URL_PARAM_SUBSYS), &key); 314 GNUNET_CRYPTO_hash (URL_PARAM_SUBSYS, strlen (URL_PARAM_SUBSYS), &key);
315 if ( GNUNET_YES == 315 if ( GNUNET_YES ==
@@ -330,7 +330,7 @@ ego_info_response (struct RestConnectionDataHandle *con,
330 } 330 }
331 } 331 }
332 } 332 }
333 json_response = GNUNET_REST_jsonapi_response_new (); 333 json_object = GNUNET_REST_jsonapi_object_new ();
334 egoname = &handle->url[strlen (EGO_NAMESPACE)+1]; 334 egoname = &handle->url[strlen (EGO_NAMESPACE)+1];
335 335
336 if (strlen (EGO_NAMESPACE) == strlen (handle->url)) 336 if (strlen (EGO_NAMESPACE) == strlen (handle->url))
@@ -353,13 +353,13 @@ ego_info_response (struct RestConnectionDataHandle *con,
353 key_str); 353 key_str);
354 json_decref (key_str); 354 json_decref (key_str);
355 GNUNET_free (keystring); 355 GNUNET_free (keystring);
356 GNUNET_REST_jsonapi_response_resource_add (json_response, json_resource); 356 GNUNET_REST_jsonapi_object_resource_add (json_object, json_resource);
357 } 357 }
358 358
359 GNUNET_REST_jsonapi_data_serialize (json_response, &result_str); 359 GNUNET_REST_jsonapi_data_serialize (json_object, &result_str);
360
361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 360 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
362 resp = GNUNET_REST_create_json_response (result_str); 361 resp = GNUNET_REST_create_json_response (result_str);
362 GNUNET_REST_jsonapi_object_delete (json_object);
363 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 363 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
364 GNUNET_free (result_str); 364 GNUNET_free (result_str);
365 cleanup_handle (handle); 365 cleanup_handle (handle);
@@ -421,16 +421,14 @@ ego_create_cont (struct RestConnectionDataHandle *con,
421 const char *url, 421 const char *url,
422 void *cls) 422 void *cls)
423{ 423{
424 const char* egoname;
425 struct RequestHandle *handle = cls; 424 struct RequestHandle *handle = cls;
426 char term_data[handle->data_size+1];
427 struct EgoEntry *ego_entry; 425 struct EgoEntry *ego_entry;
428 struct MHD_Response *resp; 426 struct MHD_Response *resp;
429 json_t *root_json; 427 struct JsonApiObject *json_obj;
430 json_t *data_json; 428 struct JsonApiResource *json_res;
431 json_t *type_json;
432 json_t *egoname_json; 429 json_t *egoname_json;
433 json_error_t error; 430 char term_data[handle->data_size+1];
431 const char* egoname;
434 432
435 if (strlen (API_NAMESPACE) != strlen (handle->url)) 433 if (strlen (API_NAMESPACE) != strlen (handle->url))
436 { 434 {
@@ -442,43 +440,39 @@ ego_create_cont (struct RestConnectionDataHandle *con,
442 GNUNET_SCHEDULER_add_now (&do_error, handle); 440 GNUNET_SCHEDULER_add_now (&do_error, handle);
443 return; 441 return;
444 } 442 }
445
446 term_data[handle->data_size] = '\0'; 443 term_data[handle->data_size] = '\0';
447 memcpy (term_data, handle->data, handle->data_size); 444 memcpy (term_data, handle->data, handle->data_size);
448 root_json = json_loads (term_data, 0, &error); 445 json_obj = GNUNET_REST_jsonapi_object_parse (term_data);
449 446
450 if ((NULL == root_json) || !json_is_object (root_json)) 447 if (NULL == json_obj)
451 { 448 {
452 GNUNET_SCHEDULER_add_now (&do_error, handle); 449 GNUNET_SCHEDULER_add_now (&do_error, handle);
453 return; 450 return;
454 } 451 }
455 data_json = json_object_get (root_json, GNUNET_REST_JSONAPI_KEY_DATA); 452 if (1 != GNUNET_REST_jsonapi_object_resource_count (json_obj))
456 if ((NULL == data_json) || !json_is_object (data_json))
457 { 453 {
454 GNUNET_REST_jsonapi_object_delete (json_obj);
458 GNUNET_SCHEDULER_add_now (&do_error, handle); 455 GNUNET_SCHEDULER_add_now (&do_error, handle);
459 return; 456 return;
460 } 457 }
461 type_json = json_object_get (data_json, "type"); 458
462 if (!json_is_string (type_json) || 459 json_res = GNUNET_REST_jsonapi_object_get_resource (json_obj, 0);
463 (0 != strcmp (GNUNET_REST_JSONAPI_IDENTITY_EGO, json_string_value (type_json)))) 460 if (GNUNET_NO == GNUNET_REST_jsonapi_resource_check_type (json_res, GNUNET_REST_JSONAPI_IDENTITY_EGO))
464 { 461 {
465 json_decref (data_json); 462 GNUNET_REST_jsonapi_object_delete (json_obj);
466 json_decref (root_json);
467 resp = GNUNET_REST_create_json_response (NULL); 463 resp = GNUNET_REST_create_json_response (NULL);
468 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); 464 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
469 cleanup_handle (handle); 465 cleanup_handle (handle);
470 return; 466 return;
471 } 467 }
472 json_decref (type_json); 468
473 egoname_json = json_object_get (data_json, "id"); 469 egoname_json = GNUNET_REST_jsonapi_resource_read_attr (json_res, GNUNET_REST_JSONAPI_KEY_ID);
474 if (!json_is_string (egoname_json)) 470 if (!json_is_string (egoname_json))
475 { 471 {
476 json_decref (data_json); 472 GNUNET_REST_jsonapi_object_delete (json_obj);
477 json_decref (root_json);
478 GNUNET_SCHEDULER_add_now (&do_error, handle); 473 GNUNET_SCHEDULER_add_now (&do_error, handle);
479 return; 474 return;
480 } 475 }
481
482 egoname = json_string_value (egoname_json); 476 egoname = json_string_value (egoname_json);
483 for (ego_entry = handle->ego_head; 477 for (ego_entry = handle->ego_head;
484 NULL != ego_entry; 478 NULL != ego_entry;
@@ -487,8 +481,7 @@ ego_create_cont (struct RestConnectionDataHandle *con,
487 if (0 == strcasecmp (egoname, ego_entry->identifier)) 481 if (0 == strcasecmp (egoname, ego_entry->identifier))
488 { 482 {
489 json_decref (egoname_json); 483 json_decref (egoname_json);
490 json_decref (data_json); 484 GNUNET_REST_jsonapi_object_delete (json_obj);
491 json_decref (root_json);
492 resp = GNUNET_REST_create_json_response (NULL); 485 resp = GNUNET_REST_create_json_response (NULL);
493 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); 486 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
494 cleanup_handle (handle); 487 cleanup_handle (handle);
@@ -497,8 +490,7 @@ ego_create_cont (struct RestConnectionDataHandle *con,
497 } 490 }
498 GNUNET_asprintf (&handle->name, "%s", egoname); 491 GNUNET_asprintf (&handle->name, "%s", egoname);
499 json_decref (egoname_json); 492 json_decref (egoname_json);
500 json_decref (data_json); 493 GNUNET_REST_jsonapi_object_delete (json_obj);
501 json_decref (root_json);
502 handle->op = GNUNET_IDENTITY_create (handle->identity_handle, 494 handle->op = GNUNET_IDENTITY_create (handle->identity_handle,
503 handle->name, 495 handle->name,
504 &create_finished, 496 &create_finished,
@@ -510,6 +502,8 @@ subsys_set_cont (struct RestConnectionDataHandle *con,
510 const char *url, 502 const char *url,
511 void *cls) 503 void *cls)
512{ 504{
505 struct JsonApiObject *json_obj;
506 struct JsonApiResource *json_res;
513 const char *egoname; 507 const char *egoname;
514 const char *subsys; 508 const char *subsys;
515 struct RequestHandle *handle = cls; 509 struct RequestHandle *handle = cls;
@@ -517,13 +511,8 @@ subsys_set_cont (struct RestConnectionDataHandle *con,
517 struct EgoEntry *ego_entry; 511 struct EgoEntry *ego_entry;
518 struct MHD_Response *resp; 512 struct MHD_Response *resp;
519 int ego_exists = GNUNET_NO; 513 int ego_exists = GNUNET_NO;
520 json_t *root_json;
521 json_t *data_json;
522 json_t *type_json;
523 json_t *id_json;
524 json_t *subsys_json; 514 json_t *subsys_json;
525 json_error_t error; 515
526
527 if (strlen (API_NAMESPACE) > strlen (handle->url)) 516 if (strlen (API_NAMESPACE) > strlen (handle->url))
528 { 517 {
529 GNUNET_SCHEDULER_add_now (&do_error, handle); 518 GNUNET_SCHEDULER_add_now (&do_error, handle);
@@ -557,54 +546,47 @@ subsys_set_cont (struct RestConnectionDataHandle *con,
557 546
558 term_data[handle->data_size] = '\0'; 547 term_data[handle->data_size] = '\0';
559 memcpy (term_data, handle->data, handle->data_size); 548 memcpy (term_data, handle->data, handle->data_size);
560 root_json = json_loads (term_data, 0, &error); 549 json_obj = GNUNET_REST_jsonapi_object_parse (term_data);
561 550
562 if ((NULL == root_json) || !json_is_object (root_json)) 551 if (NULL == json_obj)
563 { 552 {
564 GNUNET_SCHEDULER_add_now (&do_error, handle); 553 GNUNET_SCHEDULER_add_now (&do_error, handle);
565 return; 554 return;
566 } 555 }
567 data_json = json_object_get (root_json, "data"); 556 if (1 != GNUNET_REST_jsonapi_object_resource_count (json_obj))
568 if (!json_is_object (data_json))
569 { 557 {
570 json_decref (root_json); 558 GNUNET_REST_jsonapi_object_delete (json_obj);
571 GNUNET_SCHEDULER_add_now (&do_error, handle); 559 GNUNET_SCHEDULER_add_now (&do_error, handle);
572 return; 560 return;
573 } 561 }
574 id_json = json_object_get (data_json, "id"); 562
575 if (!json_is_string (id_json) || 563 json_res = GNUNET_REST_jsonapi_object_get_resource (json_obj, 0);
576 (0 != strcmp (egoname, json_string_value (id_json)))) 564 if (GNUNET_NO == GNUNET_REST_jsonapi_resource_check_id (json_res, egoname))
577 { 565 {
578 json_decref (root_json); 566 GNUNET_REST_jsonapi_object_delete (json_obj);
579 json_decref (data_json);
580 GNUNET_SCHEDULER_add_now (&do_error, handle); 567 GNUNET_SCHEDULER_add_now (&do_error, handle);
581 return; 568 return;
582 } 569 }
583 json_decref (id_json); 570
584 571 if (GNUNET_NO == GNUNET_REST_jsonapi_resource_check_id (json_res, GNUNET_REST_JSONAPI_IDENTITY_EGO))
585 type_json = json_object_get (data_json, "type");
586 if (!json_is_string (type_json) ||
587 (0 != strcmp (GNUNET_REST_JSONAPI_IDENTITY_EGO, json_string_value (type_json))))
588 { 572 {
589 json_decref (root_json); 573 GNUNET_REST_jsonapi_object_delete (json_obj);
590 json_decref (data_json);
591 GNUNET_SCHEDULER_add_now (&do_error, handle); 574 GNUNET_SCHEDULER_add_now (&do_error, handle);
592 return; 575 return;
593 } 576 }
594 json_decref (type_json);
595 577
596 subsys_json = json_object_get (data_json, "subsystem"); 578 subsys_json = GNUNET_REST_jsonapi_resource_read_attr (json_res, GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM);
597 if (!json_is_string (subsys_json)) 579 if (!json_is_string (subsys_json))
598 { 580 {
599 json_decref (root_json); 581 json_decref (subsys_json);
600 json_decref (data_json); 582 GNUNET_REST_jsonapi_object_delete (json_obj);
601 GNUNET_SCHEDULER_add_now (&do_error, handle); 583 GNUNET_SCHEDULER_add_now (&do_error, handle);
602 return; 584 return;
603 } 585 }
604 subsys = json_string_value (subsys_json); 586 subsys = json_string_value (subsys_json);
605 GNUNET_asprintf (&handle->subsys, "%s", subsys); 587 GNUNET_asprintf (&handle->subsys, "%s", subsys);
606 json_decref (subsys_json); 588 json_decref (subsys_json);
607 json_decref (root_json); 589 GNUNET_REST_jsonapi_object_delete (json_obj);
608 handle->op = GNUNET_IDENTITY_set (handle->identity_handle, 590 handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
609 handle->subsys, 591 handle->subsys,
610 ego_entry->ego, 592 ego_entry->ego,
diff --git a/src/include/gnunet_rest_lib.h b/src/include/gnunet_rest_lib.h
index cc02f01d0..398cbfdbe 100644
--- a/src/include/gnunet_rest_lib.h
+++ b/src/include/gnunet_rest_lib.h
@@ -90,7 +90,7 @@ struct JsonApiResource;
90/** 90/**
91 * Responses for JSON API 91 * Responses for JSON API
92 */ 92 */
93struct JsonApiResponse; 93struct JsonApiObject;
94 94
95/** 95/**
96 * Create a JSON API resource 96 * Create a JSON API resource
@@ -124,18 +124,64 @@ int
124GNUNET_REST_jsonapi_resource_add_attr (const struct JsonApiResource *resource, 124GNUNET_REST_jsonapi_resource_add_attr (const struct JsonApiResource *resource,
125 const char* key, 125 const char* key,
126 json_t *json); 126 json_t *json);
127/**
128 * Read a JSON API attribute
129 *
130 * @param res the JSON resource
131 * @param key the key for the attribute
132 * @return the json attr
133 */
134json_t*
135GNUNET_REST_jsonapi_resource_read_attr (const struct JsonApiResource *resource,
136 const char* key);
137
138
139/**
140 * Check a JSON API resource id
141 *
142 * @param res the JSON resource
143 * @param id the expected id
144 * @return GNUNET_YES if id matches
145 */
146int
147GNUNET_REST_jsonapi_resource_check_id (const struct JsonApiResource *resource,
148 const char* id);
149
127 150
128/** 151/**
152 * Check a JSON API resource type
153 *
154 * @param res the JSON resource
155 * @param type the expected type
156 * @return GNUNET_YES if id matches
157 */
158int
159GNUNET_REST_jsonapi_resource_check_type (const struct JsonApiResource *resource,
160 const char* type);
161
162
163/**
129 * Create a JSON API primary data 164 * Create a JSON API primary data
130 * 165 *
131 * @param type the JSON API resource type 166 * @param type the JSON API resource type
132 * @param id the JSON API resource id 167 * @param id the JSON API resource id
133 * @return a new JSON API resource or NULL on error. 168 * @return a new JSON API resource or NULL on error.
134 */ 169 */
135struct JsonApiResponse* 170struct JsonApiObject*
136GNUNET_REST_jsonapi_response_new (); 171GNUNET_REST_jsonapi_object_new ();
172
137 173
138/** 174/**
175 * Create a JSON API primary data from a string
176 *
177 * @param data the string of the JSON API data
178 * @return a new JSON API resource or NULL on error.
179 */
180struct JsonApiObject*
181GNUNET_REST_jsonapi_object_parse (const char* data);
182
183
184/**
139 * Delete a JSON API primary data 185 * Delete a JSON API primary data
140 * 186 *
141 * @param type the JSON API resource type 187 * @param type the JSON API resource type
@@ -143,7 +189,7 @@ GNUNET_REST_jsonapi_response_new ();
143 * @return a new JSON API resource or NULL on error. 189 * @return a new JSON API resource or NULL on error.
144 */ 190 */
145void 191void
146GNUNET_REST_jsonapi_response_delete (struct JsonApiResponse *resp); 192GNUNET_REST_jsonapi_object_delete (struct JsonApiObject *resp);
147 193
148/** 194/**
149 * Add a JSON API resource to primary data 195 * Add a JSON API resource to primary data
@@ -153,8 +199,27 @@ GNUNET_REST_jsonapi_response_delete (struct JsonApiResponse *resp);
153 * @return the new number of resources 199 * @return the new number of resources
154 */ 200 */
155void 201void
156GNUNET_REST_jsonapi_response_resource_add (struct JsonApiResponse *resp, 202GNUNET_REST_jsonapi_object_resource_add (struct JsonApiObject *resp,
157 struct JsonApiResource *res); 203 struct JsonApiResource *res);
204/**
205 * Get a JSON API object resource count
206 *
207 * @param resp the JSON API object
208 * @return the number of resources
209 */
210int
211GNUNET_REST_jsonapi_object_resource_count (struct JsonApiObject *resp);
212
213/**
214 * Get a JSON API object resource #num
215 *
216 * @param resp the JSON API object
217 * @param num the number of the resource
218 * @return the resource
219 */
220struct JsonApiResource*
221GNUNET_REST_jsonapi_object_get_resource (struct JsonApiObject *resp, int num);
222
158 223
159/** 224/**
160 * Add a JSON API resource to primary data 225 * Add a JSON API resource to primary data
@@ -164,7 +229,7 @@ GNUNET_REST_jsonapi_response_resource_add (struct JsonApiResponse *resp,
164 * @return the new number of resources 229 * @return the new number of resources
165 */ 230 */
166void 231void
167GNUNET_REST_jsonapi_data_resource_remove (struct JsonApiResponse *resp, 232GNUNET_REST_jsonapi_data_resource_remove (struct JsonApiObject *resp,
168 struct JsonApiResource *res); 233 struct JsonApiResource *res);
169 234
170/** 235/**
@@ -175,7 +240,7 @@ GNUNET_REST_jsonapi_data_resource_remove (struct JsonApiResponse *resp,
175 * @return GNUNET_SYSERR on error else GNUNET_OK 240 * @return GNUNET_SYSERR on error else GNUNET_OK
176 */ 241 */
177int 242int
178GNUNET_REST_jsonapi_data_serialize (const struct JsonApiResponse *resp, 243GNUNET_REST_jsonapi_data_serialize (const struct JsonApiObject *resp,
179 char **result); 244 char **result);
180 245
181/** 246/**
diff --git a/src/rest/rest.c b/src/rest/rest.c
index ec46e1273..d6fb8a2f3 100644
--- a/src/rest/rest.c
+++ b/src/rest/rest.c
@@ -50,7 +50,7 @@ struct JsonApiResource
50}; 50};
51 51
52 52
53struct JsonApiResponse 53struct JsonApiObject
54{ 54{
55 /** 55 /**
56 * DLL Resource 56 * DLL Resource
@@ -135,26 +135,163 @@ GNUNET_REST_jsonapi_resource_add_attr (const struct JsonApiResource *resource,
135 return GNUNET_OK; 135 return GNUNET_OK;
136} 136}
137 137
138/**
139 * Read a JSON API attribute
140 *
141 * @param res the JSON resource
142 * @param key the key for the attribute
143 * @return the json_t object
144 */
145json_t*
146GNUNET_REST_jsonapi_resource_read_attr (const struct JsonApiResource *resource,
147 const char* key)
148{
149 if ( (NULL == resource) ||
150 (NULL == key))
151 return NULL;
152 return json_object_get (resource->res_obj, key);
153}
154
155int
156check_resource_attr_str (const struct JsonApiResource *resource,
157 const char* key,
158 const char* attr)
159{
160 json_t *value;
161 if ( (NULL == resource) ||
162 (NULL == key) ||
163 (NULL == attr))
164 return GNUNET_NO;
165 value = json_object_get (resource->res_obj, key);
166 if (NULL == value)
167 return GNUNET_NO;
168 if (!json_is_string (value) ||
169 (0 != strcmp (attr, json_string_value(value))))
170 {
171 json_decref (value);
172 return GNUNET_NO;
173 }
174 json_decref (value);
175 return GNUNET_YES;
176}
177
178/**
179 * Check a JSON API resource id
180 *
181 * @param res the JSON resource
182 * @param id the expected id
183 * @return GNUNET_YES if id matches
184 */
185int
186GNUNET_REST_jsonapi_resource_check_id (const struct JsonApiResource *resource,
187 const char* id)
188{
189 return check_resource_attr_str (resource, id, GNUNET_REST_JSONAPI_KEY_ID);
190}
138 191
139 192
193/**
194 * Check a JSON API resource type
195 *
196 * @param res the JSON resource
197 * @param type the expected type
198 * @return GNUNET_YES if id matches
199 */
200int
201GNUNET_REST_jsonapi_resource_check_type (const struct JsonApiResource *resource,
202 const char* type)
203{
204 return check_resource_attr_str (resource, type, GNUNET_REST_JSONAPI_KEY_TYPE);
205}
206
140 207
141/** 208/**
142 * Create a JSON API primary data 209 * Create a JSON API primary data
143 * 210 *
144 * @param type the JSON API resource type
145 * @param id the JSON API resource id
146 * @return a new JSON API resource or NULL on error. 211 * @return a new JSON API resource or NULL on error.
147 */ 212 */
148struct JsonApiResponse* 213struct JsonApiObject*
149GNUNET_REST_jsonapi_response_new () 214GNUNET_REST_jsonapi_object_new ()
150{ 215{
151 struct JsonApiResponse *result; 216 struct JsonApiObject *result;
152 217
153 result = GNUNET_new (struct JsonApiResponse); 218 result = GNUNET_new (struct JsonApiObject);
154 result->res_count = 0; 219 result->res_count = 0;
155 return result; 220 return result;
156} 221}
157 222
223
224static void
225add_json_resource (struct JsonApiObject *obj,
226 const json_t *res_json)
227{
228 struct JsonApiResource *res;
229 json_t *type_json;
230 json_t *id_json;
231
232 id_json = json_object_get (res_json, GNUNET_REST_JSONAPI_KEY_ID);
233 type_json = json_object_get (res_json, GNUNET_REST_JSONAPI_KEY_TYPE);
234
235 if (!json_is_string (id_json) || !json_is_string (type_json))
236 return;
237
238 res = GNUNET_new (struct JsonApiResource);
239 res->res_obj = json_deep_copy (res_json);
240 GNUNET_REST_jsonapi_object_resource_add (obj, res);
241}
242
243/**
244 * Create a JSON API primary data from a string
245 *
246 * @param data the string of the JSON API data
247 * @return a new JSON API resource or NULL on error.
248 */
249struct JsonApiObject*
250GNUNET_REST_jsonapi_object_parse (const char* data)
251{
252 struct JsonApiObject *result;
253 json_t *root_json;
254 json_t *data_json;
255 json_error_t error;
256 int res_count = 0;
257 int i;
258
259 if (NULL == data)
260 return NULL;
261 root_json = json_loads (data, 0, &error);
262
263 if ( (NULL == root_json) || !json_is_object (root_json))
264 {
265 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "json error: %s", error.text);
266 return NULL;
267 }
268 data_json = json_object_get (root_json, GNUNET_REST_JSONAPI_KEY_DATA);
269 if (NULL == data_json)
270 {
271 json_decref (root_json);
272 return NULL;
273 }
274
275 result = GNUNET_new (struct JsonApiObject);
276 result->res_count = 0;
277 if (json_is_object (data_json))
278 add_json_resource (result, data_json);
279 else if (json_is_array (data_json))
280 {
281 res_count = json_array_size (data_json);
282 for (i = 0; i < res_count; i++)
283 add_json_resource (result, json_array_get (data_json, i));
284 }
285 json_decref (root_json);
286 if (0 == res_count)
287 {
288 GNUNET_free (result);
289 result = NULL;
290 }
291 return result;
292}
293
294
158/** 295/**
159 * Delete a JSON API primary data 296 * Delete a JSON API primary data
160 * 297 *
@@ -163,7 +300,7 @@ GNUNET_REST_jsonapi_response_new ()
163 * @return a new JSON API resource or NULL on error. 300 * @return a new JSON API resource or NULL on error.
164 */ 301 */
165void 302void
166GNUNET_REST_jsonapi_response_delete (struct JsonApiResponse *resp) 303GNUNET_REST_jsonapi_object_delete (struct JsonApiObject *resp)
167{ 304{
168 struct JsonApiResource *res; 305 struct JsonApiResource *res;
169 306
@@ -175,14 +312,14 @@ GNUNET_REST_jsonapi_response_delete (struct JsonApiResponse *resp)
175} 312}
176 313
177/** 314/**
178 * Add a JSON API resource to primary data 315 * Add a JSON API object to primary data
179 * 316 *
180 * @param data The JSON API data to add to 317 * @param data The JSON API data to add to
181 * @param res the JSON API resource to add 318 * @param res the JSON API resource to add
182 * @return the new number of resources 319 * @return the new number of resources
183 */ 320 */
184void 321void
185GNUNET_REST_jsonapi_response_resource_add (struct JsonApiResponse *resp, 322GNUNET_REST_jsonapi_object_resource_add (struct JsonApiObject *resp,
186 struct JsonApiResource *res) 323 struct JsonApiResource *res)
187{ 324{
188 GNUNET_CONTAINER_DLL_insert (resp->res_list_head, 325 GNUNET_CONTAINER_DLL_insert (resp->res_list_head,
@@ -192,6 +329,44 @@ GNUNET_REST_jsonapi_response_resource_add (struct JsonApiResponse *resp,
192 resp->res_count++; 329 resp->res_count++;
193} 330}
194 331
332
333/**
334 * Get a JSON API object resource count
335 *
336 * @param resp the JSON API object
337 * @return the number of resources
338 */
339int
340GNUNET_REST_jsonapi_object_resource_count (struct JsonApiObject *resp)
341{
342 return resp->res_count++;
343}
344
345/**
346 * Get a JSON API object resource #num
347 *
348 * @param resp the JSON API object
349 * @param num the number of the resource
350 * @return the resource
351 */
352struct JsonApiResource*
353GNUNET_REST_jsonapi_object_get_resource (struct JsonApiObject *resp, int num)
354{
355 struct JsonApiResource *res;
356 int i;
357
358 if ((0 < resp->res_count) &&
359 (num < resp->res_count))
360 return NULL;
361 res = resp->res_list_head;
362 for (i = 0; i < num; i++)
363 {
364 res = res->next;
365 }
366 return res;
367}
368
369
195/** 370/**
196 * Add a JSON API resource to primary data 371 * Add a JSON API resource to primary data
197 * 372 *
@@ -200,7 +375,7 @@ GNUNET_REST_jsonapi_response_resource_add (struct JsonApiResponse *resp,
200 * @return the new number of resources 375 * @return the new number of resources
201 */ 376 */
202void 377void
203GNUNET_REST_jsonapi_data_resource_remove (struct JsonApiResponse *resp, 378GNUNET_REST_jsonapi_data_resource_remove (struct JsonApiObject *resp,
204 struct JsonApiResource *res) 379 struct JsonApiResource *res)
205{ 380{
206 GNUNET_CONTAINER_DLL_remove (resp->res_list_head, 381 GNUNET_CONTAINER_DLL_remove (resp->res_list_head,
@@ -217,7 +392,7 @@ GNUNET_REST_jsonapi_data_resource_remove (struct JsonApiResponse *resp,
217 * @return GNUNET_SYSERR on error else GNUNET_OK 392 * @return GNUNET_SYSERR on error else GNUNET_OK
218 */ 393 */
219int 394int
220GNUNET_REST_jsonapi_data_serialize (const struct JsonApiResponse *resp, 395GNUNET_REST_jsonapi_data_serialize (const struct JsonApiObject *resp,
221 char **result) 396 char **result)
222{ 397{
223 struct JsonApiResource *res; 398 struct JsonApiResource *res;