aboutsummaryrefslogtreecommitdiff
path: root/src/gns/plugin_rest_gns.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2015-03-26 18:22:20 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2015-03-26 18:22:20 +0000
commitddbe636f3a013cde33ce94ecb9435bfd39f6355f (patch)
tree40a4ac88070e677ffd434b01a36978cb33ac063f /src/gns/plugin_rest_gns.c
parent45d2452b677a6432ca076a9010ebeccd610d80c5 (diff)
downloadgnunet-ddbe636f3a013cde33ce94ecb9435bfd39f6355f.tar.gz
gnunet-ddbe636f3a013cde33ce94ecb9435bfd39f6355f.zip
-gns rest
Diffstat (limited to 'src/gns/plugin_rest_gns.c')
-rw-r--r--src/gns/plugin_rest_gns.c194
1 files changed, 66 insertions, 128 deletions
diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c
index 60ccb23c0..1859a76e1 100644
--- a/src/gns/plugin_rest_gns.c
+++ b/src/gns/plugin_rest_gns.c
@@ -31,17 +31,21 @@
31#include <gnunet_gnsrecord_lib.h> 31#include <gnunet_gnsrecord_lib.h>
32#include <gnunet_namestore_service.h> 32#include <gnunet_namestore_service.h>
33#include <gnunet_gns_service.h> 33#include <gnunet_gns_service.h>
34#include <gnunet_rest_lib.h>
34#include <jansson.h> 35#include <jansson.h>
35 36
36#define API_NAMESPACE "/gns" 37#define API_NAMESPACE "/gns"
37 38
38#define GNUNET_REST_JSON_ATTR_ID "id"
39 39
40#define GNUNET_REST_JSON_ATTR_TYPE "type" 40#define GNUNET_REST_JSONAPI_GNS_RECORD_TYPE "type"
41 41
42#define GNUNET_GNS_JSON_RECORD_TYPE "rtype" 42#define GNUNET_REST_JSONAPI_GNS_RECORD "records"
43 43
44#define GNUNET_REST_JSON_ATTR_DATA "data" 44#define GNUNET_REST_JSONAPI_GNS_EGO "ego"
45
46#define GNUNET_REST_JSONAPI_GNS_PKEY "pkey"
47
48#define GNUNET_REST_JSONAPI_GNS_OPTIONS "options"
45 49
46/** 50/**
47 * @brief struct returned by the initialization function of the plugin 51 * @brief struct returned by the initialization function of the plugin
@@ -118,12 +122,12 @@ struct LookupHandle
118 122
119 /** 123 /**
120 * The Pkey to use 124 * The Pkey to use
121 * In stirng representation from JSON 125 * In string representation from JSON
122 */ 126 */
123 const char *pkey_str; 127 const char *pkey_str;
124 128
125 /** 129 /**
126 * The record type to look up 130 * The record type
127 */ 131 */
128 int type; 132 int type;
129 133
@@ -200,28 +204,6 @@ cleanup_handle (struct LookupHandle *handle)
200 204
201 205
202/** 206/**
203 * Create s JSON Response for MHD
204 * TODO move to lib
205 * @param data the JSON to return (can be NULL)
206 * @return a MHD_Response handle
207 */
208struct MHD_Response*
209create_json_response (const char *data)
210{
211 size_t len;
212 if (NULL == data)
213 len = 0;
214 else
215 len = strlen (data);
216 struct MHD_Response *resp = MHD_create_response_from_buffer (len,
217 (void*)data,
218 MHD_RESPMEM_MUST_COPY);
219 MHD_add_response_header (resp,MHD_HTTP_HEADER_CONTENT_TYPE,"application/json");
220 return resp;
221}
222
223
224/**
225 * Task run on shutdown. Cleans up everything. 207 * Task run on shutdown. Cleans up everything.
226 * 208 *
227 * @param cls unused 209 * @param cls unused
@@ -232,7 +214,7 @@ do_error (void *cls,
232 const struct GNUNET_SCHEDULER_TaskContext *tc) 214 const struct GNUNET_SCHEDULER_TaskContext *tc)
233{ 215{
234 struct LookupHandle *handle = cls; 216 struct LookupHandle *handle = cls;
235 struct MHD_Response *resp = create_json_response (NULL); 217 struct MHD_Response *resp = GNUNET_REST_create_json_response (NULL);
236 handle->proc (handle->proc_cls, resp, GNUNET_SYSERR); 218 handle->proc (handle->proc_cls, resp, GNUNET_SYSERR);
237 cleanup_handle (handle); 219 cleanup_handle (handle);
238} 220}
@@ -300,39 +282,35 @@ process_lookup_result (void *cls, uint32_t rd_count,
300{ 282{
301 struct LookupHandle *handle = cls; 283 struct LookupHandle *handle = cls;
302 struct MHD_Response *resp; 284 struct MHD_Response *resp;
285 struct JsonApiObject *json_object;
286 struct JsonApiResource *json_resource;
303 uint32_t i; 287 uint32_t i;
304 char *result; 288 char *result;
305 json_t *result_root;
306 json_t *result_data;
307 json_t *result_array; 289 json_t *result_array;
308 json_t *record_obj; 290 json_t *record_obj;
309 291
310 result_root = json_object();
311 result_array = json_array(); 292 result_array = json_array();
312 result_data = json_object(); 293 json_object = GNUNET_REST_jsonapi_object_new ();
313 json_object_set_new (result_root, GNUNET_REST_JSON_ATTR_ID, json_string (handle->name)); 294 json_resource = GNUNET_REST_jsonapi_resource_new (GNUNET_REST_JSONAPI_GNS_RECORD, handle->name);
314 json_object_set (result_root,
315 GNUNET_REST_JSON_ATTR_TYPE,
316 json_string (GNUNET_GNS_JSON_RECORD_TYPE));
317 handle->lookup_request = NULL; 295 handle->lookup_request = NULL;
318 for (i=0; i<rd_count; i++) 296 for (i=0; i<rd_count; i++)
319 { 297 {
320 if ( (rd[i].record_type != handle->type) && 298 if ( (rd[i].record_type != handle->type) &&
321 (GNUNET_GNSRECORD_TYPE_ANY != handle->type) ) 299 (GNUNET_GNSRECORD_TYPE_ANY != handle->type) )
322 continue; 300 continue;
323
324 record_obj = gnsrecord_to_json (&(rd[i])); 301 record_obj = gnsrecord_to_json (&(rd[i]));
325 json_array_append (result_array, record_obj); 302 json_array_append (result_array, record_obj);
326 json_decref (record_obj); 303 json_decref (record_obj);
327 } 304 }
328 json_object_set (result_root, GNUNET_REST_JSON_ATTR_DATA, result_data); 305 GNUNET_REST_jsonapi_resource_add_attr (json_resource,
329 json_decref (result_data); 306 GNUNET_REST_JSONAPI_GNS_RECORD,
330 json_object_set (result_data, "query_result", result_array); 307 result_array);
331 json_decref (result_array); 308 GNUNET_REST_jsonapi_object_resource_add (json_object, json_resource);
332 result = json_dumps (result_root, JSON_COMPACT); 309 GNUNET_REST_jsonapi_data_serialize (json_object, &result);
333 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result); 310 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result);
334 json_decref (result_root); 311 json_decref (result_array);
335 resp = create_json_response (result); 312 GNUNET_REST_jsonapi_object_delete (json_object);
313 resp = GNUNET_REST_create_json_response (result);
336 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 314 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
337 GNUNET_free (result); 315 GNUNET_free (result);
338 cleanup_handle (handle); 316 cleanup_handle (handle);
@@ -505,7 +483,6 @@ int
505parse_url (const char *url, struct LookupHandle *handle) 483parse_url (const char *url, struct LookupHandle *handle)
506{ 484{
507 char *name; 485 char *name;
508 char *type;
509 char tmp_url[strlen(url)+1]; 486 char tmp_url[strlen(url)+1];
510 char *tok; 487 char *tok;
511 488
@@ -521,75 +498,9 @@ parse_url (const char *url, struct LookupHandle *handle)
521 name); 498 name);
522 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
523 "Got name: %s\n", handle->name); 500 "Got name: %s\n", handle->name);
524 type = strtok (NULL, "/");
525 if (NULL == type)
526 {
527 handle->type = GNUNET_GNSRECORD_TYPE_ANY;
528 return GNUNET_OK;
529 }
530 handle->type = GNUNET_GNSRECORD_typename_to_number (type);
531 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
532 "Got type: %s\n", type);
533 return GNUNET_OK;
534}
535
536/**
537 * Parse json from REST request
538 * TODO 1. this leaks 2. Rework JSON API. This is confusing
539 *
540 * @param data REST data
541 * @param data_size data size
542 * @param handle Handle to populate
543 * @return GNUNET_SYSERR on error
544 */
545int
546parse_json (const char *data, size_t data_size, struct LookupHandle *handle)
547{
548 json_error_t error;
549 json_t *pkey_json;
550 json_t *ego_json;
551 json_t *options_json;
552
553 char term_data[data_size+1];
554 term_data[data_size] = '\0';
555
556 memcpy (term_data, data, data_size);
557
558 handle->json_root = json_loads (term_data, 0, &error);
559
560 if (NULL == handle->json_root)
561 {
562 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, error.text);
563 return GNUNET_SYSERR;
564 }
565
566 if(!json_is_object(handle->json_root))
567 {
568 return GNUNET_SYSERR;
569 }
570
571 ego_json = json_object_get (handle->json_root, "ego");
572
573 if(json_is_string(ego_json))
574 {
575 handle->ego_str = json_string_value (ego_json);
576 }
577
578 pkey_json = json_object_get (handle->json_root, "pkey");
579 if(json_is_string(pkey_json))
580 {
581 handle->pkey_str = json_string_value (pkey_json);
582 }
583
584 options_json = json_object_get (handle->json_root, "options");
585 if(json_is_integer (options_json))
586 {
587 handle->options = json_integer_value (options_json);
588 }
589 return GNUNET_OK; 501 return GNUNET_OK;
590} 502}
591 503
592
593/** 504/**
594 * Function processing the REST call 505 * Function processing the REST call
595 * 506 *
@@ -607,8 +518,9 @@ rest_gns_process_request(struct RestConnectionDataHandle *conndata_handle,
607 void *proc_cls) 518 void *proc_cls)
608{ 519{
609 struct LookupHandle *handle = GNUNET_new (struct LookupHandle); 520 struct LookupHandle *handle = GNUNET_new (struct LookupHandle);
610 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 521 struct GNUNET_HashCode key;
611 522
523 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
612 //parse name and type from url 524 //parse name and type from url
613 if (GNUNET_OK != parse_url (conndata_handle->url, handle)) 525 if (GNUNET_OK != parse_url (conndata_handle->url, handle))
614 { 526 {
@@ -616,18 +528,8 @@ rest_gns_process_request(struct RestConnectionDataHandle *conndata_handle,
616 GNUNET_SCHEDULER_add_now (&do_error, handle); 528 GNUNET_SCHEDULER_add_now (&do_error, handle);
617 return; 529 return;
618 } 530 }
619
620 handle->proc_cls = proc_cls; 531 handle->proc_cls = proc_cls;
621 handle->proc = proc; 532 handle->proc = proc;
622 if (0 < conndata_handle->data_size)
623 {
624 if (GNUNET_OK != parse_json (conndata_handle->data, conndata_handle->data_size, handle))
625 {
626 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing json...\n");
627 GNUNET_SCHEDULER_add_now (&do_error, handle);
628 return;
629 }
630 }
631 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
632 "Connecting...\n"); 534 "Connecting...\n");
633 handle->gns = GNUNET_GNS_connect (cfg); 535 handle->gns = GNUNET_GNS_connect (cfg);
@@ -636,7 +538,6 @@ rest_gns_process_request(struct RestConnectionDataHandle *conndata_handle,
636 &do_error, handle); 538 &do_error, handle);
637 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
638 "Connected\n"); 540 "Connected\n");
639
640 if (NULL == handle->gns) 541 if (NULL == handle->gns)
641 { 542 {
642 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 543 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -644,9 +545,40 @@ rest_gns_process_request(struct RestConnectionDataHandle *conndata_handle,
644 GNUNET_SCHEDULER_add_now (&do_error, handle); 545 GNUNET_SCHEDULER_add_now (&do_error, handle);
645 return; 546 return;
646 } 547 }
548 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_OPTIONS,
549 strlen (GNUNET_REST_JSONAPI_GNS_OPTIONS),
550 &key);
551 handle->options = GNUNET_GNS_LO_DEFAULT;
552 if ( GNUNET_YES ==
553 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
554 &key) )
555 {
556 handle->options = GNUNET_GNS_LO_DEFAULT;//TODO(char*) GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
557 //&key);
558 }
559 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE,
560 strlen (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE),
561 &key);
562 if ( GNUNET_YES ==
563 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
564 &key) )
565 {
566 handle->type = GNUNET_GNSRECORD_typename_to_number
567 (GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
568 &key));
569 }
570 else
571 handle->type = GNUNET_GNSRECORD_TYPE_ANY;
647 572
648 if (NULL != handle->pkey_str) 573 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_PKEY,
574 strlen (GNUNET_REST_JSONAPI_GNS_PKEY),
575 &key);
576 if ( GNUNET_YES ==
577 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
578 &key) )
649 { 579 {
580 handle->pkey_str = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
581 &key);
650 if (GNUNET_OK != 582 if (GNUNET_OK !=
651 GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->pkey_str, 583 GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->pkey_str,
652 strlen(handle->pkey_str), 584 strlen(handle->pkey_str),
@@ -656,10 +588,17 @@ rest_gns_process_request(struct RestConnectionDataHandle *conndata_handle,
656 return; 588 return;
657 } 589 }
658 lookup_with_public_key (handle); 590 lookup_with_public_key (handle);
659 591 return;
660 } 592 }
661 if (NULL != handle->ego_str) 593 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_EGO,
594 strlen (GNUNET_REST_JSONAPI_GNS_EGO),
595 &key);
596 if ( GNUNET_YES ==
597 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
598 &key) )
662 { 599 {
600 handle->ego_str = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
601 &key);
663 handle->el = GNUNET_IDENTITY_ego_lookup (cfg, 602 handle->el = GNUNET_IDENTITY_ego_lookup (cfg,
664 handle->ego_str, 603 handle->ego_str,
665 &identity_zone_cb, 604 &identity_zone_cb,
@@ -671,7 +610,6 @@ rest_gns_process_request(struct RestConnectionDataHandle *conndata_handle,
671 (0 == strcmp (".zkey", 610 (0 == strcmp (".zkey",
672 &handle->name[strlen (handle->name) - 4])) ) 611 &handle->name[strlen (handle->name) - 4])) )
673 { 612 {
674 /* no zone required, use 'anonymous' zone */
675 GNUNET_CRYPTO_ecdsa_key_get_public 613 GNUNET_CRYPTO_ecdsa_key_get_public
676 (GNUNET_CRYPTO_ecdsa_key_get_anonymous (), 614 (GNUNET_CRYPTO_ecdsa_key_get_anonymous (),
677 &(handle->pkey)); 615 &(handle->pkey));