aboutsummaryrefslogtreecommitdiff
path: root/src/gns/plugin_rest_gns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/plugin_rest_gns.c')
-rw-r--r--src/gns/plugin_rest_gns.c188
1 files changed, 107 insertions, 81 deletions
diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c
index 2b729db54..82d62744c 100644
--- a/src/gns/plugin_rest_gns.c
+++ b/src/gns/plugin_rest_gns.c
@@ -17,6 +17,7 @@
17 */ 17 */
18/** 18/**
19 * @author Martin Schanzenbach 19 * @author Martin Schanzenbach
20 * @author Philippe Buschmann
20 * @file gns/plugin_rest_gns.c 21 * @file gns/plugin_rest_gns.c
21 * @brief GNUnet GNS REST plugin 22 * @brief GNUnet GNS REST plugin
22 * 23 *
@@ -38,6 +39,8 @@
38 39
39#define GNUNET_REST_JSONAPI_GNS_RECORD_TYPE "record_type" 40#define GNUNET_REST_JSONAPI_GNS_RECORD_TYPE "record_type"
40 41
42#define GNUNET_REST_PARAMETER_GNS_NAME "name"
43
41#define GNUNET_REST_JSONAPI_GNS_TYPEINFO "gns_name" 44#define GNUNET_REST_JSONAPI_GNS_TYPEINFO "gns_name"
42 45
43#define GNUNET_REST_JSONAPI_GNS_RECORD "records" 46#define GNUNET_REST_JSONAPI_GNS_RECORD "records"
@@ -162,6 +165,11 @@ struct LookupHandle
162 */ 165 */
163 int response_code; 166 int response_code;
164 167
168 /**
169 * HTTP response code
170 */
171 char* emsg;
172
165}; 173};
166 174
167 175
@@ -180,6 +188,8 @@ cleanup_handle (struct LookupHandle *handle)
180 188
181 if (NULL != handle->name) 189 if (NULL != handle->name)
182 GNUNET_free (handle->name); 190 GNUNET_free (handle->name);
191 if (NULL != handle->emsg)
192 GNUNET_free (handle->emsg);
183 if (NULL != handle->el) 193 if (NULL != handle->el)
184 { 194 {
185 GNUNET_IDENTITY_ego_lookup_cancel (handle->el); 195 GNUNET_IDENTITY_ego_lookup_cancel (handle->el);
@@ -225,10 +235,18 @@ do_error (void *cls)
225{ 235{
226 struct LookupHandle *handle = cls; 236 struct LookupHandle *handle = cls;
227 struct MHD_Response *resp; 237 struct MHD_Response *resp;
238 char *json_error;
228 239
229 resp = GNUNET_REST_create_response (NULL); 240 if (NULL == handle->emsg)
241 handle->emsg = GNUNET_strdup("Unknown Error");
242
243 GNUNET_asprintf (&json_error, "{\"error\": \"%s\"}", handle->emsg);
244 handle->response_code = MHD_HTTP_OK;
245
246 resp = GNUNET_REST_create_response (json_error);
230 handle->proc (handle->proc_cls, resp, handle->response_code); 247 handle->proc (handle->proc_cls, resp, handle->response_code);
231 cleanup_handle (handle); 248 cleanup_handle (handle);
249 GNUNET_free(json_error);
232} 250}
233 251
234 252
@@ -294,16 +312,12 @@ process_lookup_result (void *cls, uint32_t rd_count,
294{ 312{
295 struct LookupHandle *handle = cls; 313 struct LookupHandle *handle = cls;
296 struct MHD_Response *resp; 314 struct MHD_Response *resp;
297 struct GNUNET_JSONAPI_Document *json_document;
298 struct GNUNET_JSONAPI_Resource *json_resource;
299 uint32_t i; 315 uint32_t i;
300 char *result; 316 char *result;
301 json_t *result_array; 317 json_t *result_array;
302 json_t *record_obj; 318 json_t *record_obj;
303 319
304 result_array = json_array(); 320 result_array = json_array();
305 json_document = GNUNET_JSONAPI_document_new ();
306 json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_GNS_TYPEINFO, handle->name);
307 handle->lookup_request = NULL; 321 handle->lookup_request = NULL;
308 for (i=0; i<rd_count; i++) 322 for (i=0; i<rd_count; i++)
309 { 323 {
@@ -314,17 +328,12 @@ process_lookup_result (void *cls, uint32_t rd_count,
314 json_array_append (result_array, record_obj); 328 json_array_append (result_array, record_obj);
315 json_decref (record_obj); 329 json_decref (record_obj);
316 } 330 }
317 GNUNET_JSONAPI_resource_add_attr (json_resource, 331 result = json_dumps(result_array, 0);
318 GNUNET_REST_JSONAPI_GNS_RECORD,
319 result_array);
320 GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
321 GNUNET_JSONAPI_document_serialize (json_document, &result);
322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result); 332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result);
323 json_decref (result_array);
324 GNUNET_JSONAPI_document_delete (json_document);
325 resp = GNUNET_REST_create_response (result); 333 resp = GNUNET_REST_create_response (result);
326 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 334 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
327 GNUNET_free (result); 335 GNUNET_free (result);
336 json_decref (result_array);
328 cleanup_handle (handle); 337 cleanup_handle (handle);
329} 338}
330 339
@@ -356,6 +365,7 @@ lookup_with_public_key (struct LookupHandle *handle)
356 } 365 }
357 else 366 else
358 { 367 {
368 handle->emsg = GNUNET_strdup("Parameter name is missing");
359 GNUNET_SCHEDULER_add_now (&do_error, handle); 369 GNUNET_SCHEDULER_add_now (&do_error, handle);
360 return; 370 return;
361 } 371 }
@@ -380,6 +390,7 @@ identity_zone_cb (void *cls,
380 { 390 {
381 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 391 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
382 _("Ego for not found, cannot perform lookup.\n")); 392 _("Ego for not found, cannot perform lookup.\n"));
393 handle->emsg = GNUNET_strdup ("Ego for not found, cannot perform lookup.");
383 GNUNET_SCHEDULER_add_now (&do_error, handle); 394 GNUNET_SCHEDULER_add_now (&do_error, handle);
384 return; 395 return;
385 } 396 }
@@ -418,6 +429,7 @@ identity_master_cb (void *cls,
418 { 429 {
419 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 430 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
420 _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n")); 431 _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n"));
432 handle->emsg = GNUNET_strdup("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?");
421 GNUNET_SCHEDULER_add_now (&do_error, handle); 433 GNUNET_SCHEDULER_add_now (&do_error, handle);
422 return; 434 return;
423 } 435 }
@@ -436,35 +448,10 @@ identity_master_cb (void *cls,
436} 448}
437 449
438/** 450/**
439 * Parse REST uri for name and record type 451 * Handle get request
440 * 452 *
441 * @param url Url to parse 453 * @param handle the lookup handle
442 * @param handle lookup handle to populate
443 * @return GNUNET_SYSERR on error
444 */ 454 */
445static int
446parse_url (const char *url, struct LookupHandle *handle)
447{
448 char *name;
449 char tmp_url[strlen(url)+1];
450 char *tok;
451
452 strcpy (tmp_url, url);
453 tok = strtok ((char*)tmp_url, "/");
454 if (NULL == tok)
455 return GNUNET_SYSERR;
456 name = strtok (NULL, "/");
457 if (NULL == name)
458 return GNUNET_SYSERR;
459 GNUNET_asprintf (&handle->name,
460 "%s",
461 name);
462 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
463 "Got name: %s\n", handle->name);
464 return GNUNET_OK;
465}
466
467
468static void 455static void
469get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle, 456get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
470 const char* url, 457 const char* url,
@@ -472,40 +459,48 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
472{ 459{
473 struct LookupHandle *handle = cls; 460 struct LookupHandle *handle = cls;
474 struct GNUNET_HashCode key; 461 struct GNUNET_HashCode key;
462 long int enum_test;
463 char *temp_val;
475 464
476 //parse name and type from url 465 //check for /gns otherwise 404
477 if (GNUNET_OK != parse_url (url, handle)) 466 if (strlen (GNUNET_REST_API_NS_GNS) > strlen (url))
478 { 467 {
479 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing url...\n"); 468 handle->emsg = GNUNET_strdup("Wrong URL");
480 GNUNET_SCHEDULER_add_now (&do_error, handle); 469 GNUNET_SCHEDULER_add_now (&do_error, handle);
481 return; 470 return;
482 } 471 }
483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 472
484 "Connecting...\n"); 473 //connect to gns
474 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
485 handle->gns = GNUNET_GNS_connect (cfg); 475 handle->gns = GNUNET_GNS_connect (cfg);
486 handle->identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL); 476 handle->identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
487 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, 477 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
488 &do_error, handle); 478 &do_error, handle);
489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 479 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
490 "Connected\n");
491 if (NULL == handle->gns) 480 if (NULL == handle->gns)
492 { 481 {
493 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 482 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Connecting to GNS failed\n");
494 "Connecting to GNS failed\n"); 483 handle->emsg = GNUNET_strdup("Connecting to GNS failed");
495 GNUNET_SCHEDULER_add_now (&do_error, handle); 484 GNUNET_SCHEDULER_add_now (&do_error, handle);
496 return; 485 return;
497 } 486 }
498 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_OPTIONS, 487
499 strlen (GNUNET_REST_JSONAPI_GNS_OPTIONS), 488 //check parameter name -> BAD_REQUEST
500 &key); 489 GNUNET_CRYPTO_hash (GNUNET_REST_PARAMETER_GNS_NAME,
501 handle->options = GNUNET_GNS_LO_DEFAULT; 490 strlen (GNUNET_REST_PARAMETER_GNS_NAME),
502 if ( GNUNET_YES == 491 &key);
503 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, 492 if ( GNUNET_NO
504 &key) ) 493 == GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
494 &key))
505 { 495 {
506 handle->options = GNUNET_GNS_LO_DEFAULT;//TODO(char*) GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, 496 handle->emsg = GNUNET_strdup("Parameter name is missing");
507 //&key); 497 GNUNET_SCHEDULER_add_now (&do_error, handle);
498 return;
508 } 499 }
500 handle->name = GNUNET_strdup(GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
501 &key));
502
503 //check parameter record_type, optional
509 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE, 504 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE,
510 strlen (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE), 505 strlen (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE),
511 &key); 506 &key);
@@ -513,34 +508,66 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
513 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, 508 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
514 &key) ) 509 &key) )
515 { 510 {
516 handle->type = GNUNET_GNSRECORD_typename_to_number 511 handle->type = GNUNET_GNSRECORD_typename_to_number(
517 (GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, 512 GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
518 &key)); 513 &key));
519 } 514 }
520 else 515 else
516 {
521 handle->type = GNUNET_GNSRECORD_TYPE_ANY; 517 handle->type = GNUNET_GNSRECORD_TYPE_ANY;
518 }
522 519
520 //check parameter options, optional
521 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_OPTIONS,
522 strlen (GNUNET_REST_JSONAPI_GNS_OPTIONS),
523 &key);
524 handle->options = GNUNET_GNS_LO_DEFAULT;
525 if ( GNUNET_YES
526 == GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
527 &key))
528 {
529 temp_val = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, &key);
530 if (1 < strlen(temp_val))
531 {
532 handle->options = GNUNET_GNS_LO_DEFAULT;
533 }
534 else
535 {
536 //atoi because no valid conversion is default local option
537 enum_test = atoi(temp_val);
538 if (2 < enum_test)
539 handle->options = GNUNET_GNS_LO_DEFAULT;
540 else
541 handle->options = enum_test;
542 }
543 }
544 else
545 handle->options = GNUNET_GNS_LO_DEFAULT;
546
547 //check parameter pkey, shortcut to lookup
523 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_PKEY, 548 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_PKEY,
524 strlen (GNUNET_REST_JSONAPI_GNS_PKEY), 549 strlen (GNUNET_REST_JSONAPI_GNS_PKEY),
525 &key); 550 &key);
526 if ( GNUNET_YES == 551 if ( GNUNET_YES
527 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, 552 == GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
528 &key) ) 553 &key))
529 { 554 {
530 handle->pkey_str = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, 555 handle->pkey_str = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
531 &key); 556 &key);
532 GNUNET_assert (NULL != handle->pkey_str); 557 GNUNET_assert(NULL != handle->pkey_str);
533 if (GNUNET_OK != 558 if (GNUNET_OK
534 GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->pkey_str, 559 != GNUNET_CRYPTO_ecdsa_public_key_from_string (
535 strlen(handle->pkey_str), 560 handle->pkey_str, strlen (handle->pkey_str), &(handle->pkey)))
536 &(handle->pkey)))
537 { 561 {
562 handle->emsg = GNUNET_strdup("Parameter pkey has a wrong format");
538 GNUNET_SCHEDULER_add_now (&do_error, handle); 563 GNUNET_SCHEDULER_add_now (&do_error, handle);
539 return; 564 return;
540 } 565 }
541 lookup_with_public_key (handle); 566 lookup_with_public_key (handle);
542 return; 567 return;
543 } 568 }
569
570 //check parameter ego, lookup public key of ego
544 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_EGO, 571 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_EGO,
545 strlen (GNUNET_REST_JSONAPI_GNS_EGO), 572 strlen (GNUNET_REST_JSONAPI_GNS_EGO),
546 &key); 573 &key);
@@ -556,24 +583,23 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
556 handle); 583 handle);
557 return; 584 return;
558 } 585 }
586
587 //if name ends with .zkey then get public key
559 if ( (NULL != handle->name) && 588 if ( (NULL != handle->name) &&
560 (strlen (handle->name) > 4) && 589 (strlen (handle->name) > 4) &&
561 (0 == strcmp (".zkey", 590 (0 == strcmp (".zkey",
562 &handle->name[strlen (handle->name) - 4])) ) 591 &handle->name[strlen (handle->name) - 4])) )
563 { 592 {
564 GNUNET_CRYPTO_ecdsa_key_get_public 593 GNUNET_CRYPTO_ecdsa_key_get_public( GNUNET_CRYPTO_ecdsa_key_get_anonymous (),
565 (GNUNET_CRYPTO_ecdsa_key_get_anonymous (), 594 &(handle->pkey));
566 &(handle->pkey));
567 lookup_with_public_key (handle); 595 lookup_with_public_key (handle);
568 } 596 }
569 else 597 else //else use gns-master identity
570 { 598 {
571 GNUNET_break (NULL == handle->id_op);
572 handle->id_op = GNUNET_IDENTITY_get (handle->identity, 599 handle->id_op = GNUNET_IDENTITY_get (handle->identity,
573 "gns-master", 600 "gns-master",
574 &identity_master_cb, 601 &identity_master_cb,
575 handle); 602 handle);
576 GNUNET_assert (NULL != handle->id_op);
577 } 603 }
578} 604}
579 605
@@ -631,10 +657,10 @@ rest_gns_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
631 handle->proc = proc; 657 handle->proc = proc;
632 handle->rest_handle = conndata_handle; 658 handle->rest_handle = conndata_handle;
633 659
634 if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle, 660 if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle,
635 handlers, 661 handlers,
636 &err, 662 &err,
637 handle)) 663 handle))
638 { 664 {
639 handle->response_code = err.error_code; 665 handle->response_code = err.error_code;
640 GNUNET_SCHEDULER_add_now (&do_error, handle); 666 GNUNET_SCHEDULER_add_now (&do_error, handle);