diff options
Diffstat (limited to 'src/gns/plugin_rest_gns.c')
-rw-r--r-- | src/gns/plugin_rest_gns.c | 188 |
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 | */ |
445 | static int | ||
446 | parse_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 | |||
468 | static void | 455 | static void |
469 | get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle, | 456 | get_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); |