diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2015-03-26 14:57:05 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2015-03-26 14:57:05 +0000 |
commit | b68a1cacd29fb91dee84f736085c48db4ea5acaf (patch) | |
tree | 16b343e23754b0eec27f927e877e0f457955c105 /src | |
parent | 496e08d0b3e7719b4bf63eb9e0a3e0f8f19d6569 (diff) | |
download | gnunet-b68a1cacd29fb91dee84f736085c48db4ea5acaf.tar.gz gnunet-b68a1cacd29fb91dee84f736085c48db4ea5acaf.zip |
-more REST
Diffstat (limited to 'src')
-rw-r--r-- | src/identity/plugin_rest_identity.c | 130 | ||||
-rw-r--r-- | src/include/gnunet_rest_lib.h | 79 | ||||
-rw-r--r-- | src/rest/rest.c | 199 |
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 | */ |
93 | struct JsonApiResponse; | 93 | struct JsonApiObject; |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * Create a JSON API resource | 96 | * Create a JSON API resource |
@@ -124,18 +124,64 @@ int | |||
124 | GNUNET_REST_jsonapi_resource_add_attr (const struct JsonApiResource *resource, | 124 | GNUNET_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 | */ | ||
134 | json_t* | ||
135 | GNUNET_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 | */ | ||
146 | int | ||
147 | GNUNET_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 | */ | ||
158 | int | ||
159 | GNUNET_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 | */ |
135 | struct JsonApiResponse* | 170 | struct JsonApiObject* |
136 | GNUNET_REST_jsonapi_response_new (); | 171 | GNUNET_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 | */ | ||
180 | struct JsonApiObject* | ||
181 | GNUNET_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 | */ |
145 | void | 191 | void |
146 | GNUNET_REST_jsonapi_response_delete (struct JsonApiResponse *resp); | 192 | GNUNET_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 | */ |
155 | void | 201 | void |
156 | GNUNET_REST_jsonapi_response_resource_add (struct JsonApiResponse *resp, | 202 | GNUNET_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 | */ | ||
210 | int | ||
211 | GNUNET_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 | */ | ||
220 | struct JsonApiResource* | ||
221 | GNUNET_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 | */ |
166 | void | 231 | void |
167 | GNUNET_REST_jsonapi_data_resource_remove (struct JsonApiResponse *resp, | 232 | GNUNET_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 | */ |
177 | int | 242 | int |
178 | GNUNET_REST_jsonapi_data_serialize (const struct JsonApiResponse *resp, | 243 | GNUNET_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 | ||
53 | struct JsonApiResponse | 53 | struct 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 | */ | ||
145 | json_t* | ||
146 | GNUNET_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 | |||
155 | int | ||
156 | check_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 | */ | ||
185 | int | ||
186 | GNUNET_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 | */ | ||
200 | int | ||
201 | GNUNET_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 | */ |
148 | struct JsonApiResponse* | 213 | struct JsonApiObject* |
149 | GNUNET_REST_jsonapi_response_new () | 214 | GNUNET_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 | |||
224 | static void | ||
225 | add_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 | */ | ||
249 | struct JsonApiObject* | ||
250 | GNUNET_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 | */ |
165 | void | 302 | void |
166 | GNUNET_REST_jsonapi_response_delete (struct JsonApiResponse *resp) | 303 | GNUNET_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 | */ |
184 | void | 321 | void |
185 | GNUNET_REST_jsonapi_response_resource_add (struct JsonApiResponse *resp, | 322 | GNUNET_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 | */ | ||
339 | int | ||
340 | GNUNET_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 | */ | ||
352 | struct JsonApiResource* | ||
353 | GNUNET_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 | */ |
202 | void | 377 | void |
203 | GNUNET_REST_jsonapi_data_resource_remove (struct JsonApiResponse *resp, | 378 | GNUNET_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 | */ |
219 | int | 394 | int |
220 | GNUNET_REST_jsonapi_data_serialize (const struct JsonApiResponse *resp, | 395 | GNUNET_REST_jsonapi_data_serialize (const struct JsonApiObject *resp, |
221 | char **result) | 396 | char **result) |
222 | { | 397 | { |
223 | struct JsonApiResource *res; | 398 | struct JsonApiResource *res; |