aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/plugin_rest_namestore.c
diff options
context:
space:
mode:
authorPhil <phil.buschmann@tum.de>2018-08-08 03:59:08 +0200
committerPhil <phil.buschmann@tum.de>2018-08-08 03:59:08 +0200
commit9eb2df3407246f984f0d85af338bff872d5e6fba (patch)
tree9284695f8d44784308cdca7ffb1eb0d7a3e9201f /src/namestore/plugin_rest_namestore.c
parent65f9785e7752b6d73e2ad8c6ff2735336ad5baa6 (diff)
downloadgnunet-9eb2df3407246f984f0d85af338bff872d5e6fba.tar.gz
gnunet-9eb2df3407246f984f0d85af338bff872d5e6fba.zip
-wip namestore
Diffstat (limited to 'src/namestore/plugin_rest_namestore.c')
-rw-r--r--src/namestore/plugin_rest_namestore.c322
1 files changed, 282 insertions, 40 deletions
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c
index 90928165e..3801431b2 100644
--- a/src/namestore/plugin_rest_namestore.c
+++ b/src/namestore/plugin_rest_namestore.c
@@ -34,14 +34,31 @@
34 34
35 35
36#define GNUNET_REST_API_NS_NAMESTORE "/namestore" 36#define GNUNET_REST_API_NS_NAMESTORE "/namestore"
37
38#define GNUNET_REST_SUBSYSTEM_NAMESTORE "namestore" 37#define GNUNET_REST_SUBSYSTEM_NAMESTORE "namestore"
39 38
39/**
40 * Parameter names
41 */
42#define GNUNET_REST_API_PARAM_PUBKEY "pubkey"
43#define GNUNET_REST_API_PARAM_NAME "name"
44
45/**
46 * Error messages
47 */
40#define GNUNET_REST_NAMESTORE_ERROR_UNKNOWN "Unknown Error" 48#define GNUNET_REST_NAMESTORE_ERROR_UNKNOWN "Unknown Error"
41 49
42#define GNUNET_REST_NAMESTORE_RD_COUNT 1 50#define GNUNET_REST_NAMESTORE_RD_COUNT 1
43 51
44/** 52/**
53 * State while collecting all egos
54 */
55#define ID_REST_STATE_INIT 0
56
57/**
58 * Done collecting egos
59 */
60#define ID_REST_STATE_POST_INIT 1
61/**
45 * The configuration handle 62 * The configuration handle
46 */ 63 */
47const struct GNUNET_CONFIGURATION_Handle *cfg; 64const struct GNUNET_CONFIGURATION_Handle *cfg;
@@ -65,9 +82,19 @@ struct Plugin
65struct EgoEntry 82struct EgoEntry
66{ 83{
67 /** 84 /**
85 * DLL
86 */
87 struct EgoEntry *next;
88
89 /**
90 * DLL
91 */
92 struct EgoEntry *prev;
93
94 /**
68 * Ego Identifier 95 * Ego Identifier
69 */ 96 */
70 const char *identifier; 97 char *identifier;
71 98
72 /** 99 /**
73 * Public key string 100 * Public key string
@@ -104,6 +131,11 @@ struct RequestHandle
104 json_t *resp_object; 131 json_t *resp_object;
105 132
106 /** 133 /**
134 * The processing state
135 */
136 int state;
137
138 /**
107 * Handle to NAMESTORE 139 * Handle to NAMESTORE
108 */ 140 */
109 struct GNUNET_NAMESTORE_Handle *ns_handle; 141 struct GNUNET_NAMESTORE_Handle *ns_handle;
@@ -116,7 +148,7 @@ struct RequestHandle
116 /** 148 /**
117 * Private key for the zone 149 * Private key for the zone
118 */ 150 */
119 struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey; 151 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_pkey;
120 152
121 /** 153 /**
122 * IDENTITY Operation 154 * IDENTITY Operation
@@ -124,6 +156,16 @@ struct RequestHandle
124 struct EgoEntry *ego_entry; 156 struct EgoEntry *ego_entry;
125 157
126 /** 158 /**
159 * Ego list
160 */
161 struct EgoEntry *ego_head;
162
163 /**
164 * Ego list
165 */
166 struct EgoEntry *ego_tail;
167
168 /**
127 * IDENTITY Operation 169 * IDENTITY Operation
128 */ 170 */
129 struct GNUNET_IDENTITY_Operation *op; 171 struct GNUNET_IDENTITY_Operation *op;
@@ -183,6 +225,8 @@ static void
183cleanup_handle (void *cls) 225cleanup_handle (void *cls)
184{ 226{
185 struct RequestHandle *handle = cls; 227 struct RequestHandle *handle = cls;
228 struct EgoEntry *ego_entry;
229 struct EgoEntry *ego_tmp;
186 230
187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
188 "Cleaning up\n"); 232 "Cleaning up\n");
@@ -216,12 +260,14 @@ cleanup_handle (void *cls)
216 GNUNET_NAMESTORE_disconnect(handle->ns_handle); 260 GNUNET_NAMESTORE_disconnect(handle->ns_handle);
217 } 261 }
218 262
219 if (NULL != handle->ego_entry) 263 for (ego_entry = handle->ego_head;
264 NULL != ego_entry;)
220 { 265 {
221 if (NULL != handle->ego_entry->keystring) 266 ego_tmp = ego_entry;
222 GNUNET_free(handle->ego_entry->keystring); 267 ego_entry = ego_entry->next;
223 268 GNUNET_free(ego_tmp->identifier);
224 GNUNET_free(handle->ego_entry); 269 GNUNET_free(ego_tmp->keystring);
270 GNUNET_free(ego_tmp);
225 } 271 }
226 272
227 if(NULL != handle->resp_object) 273 if(NULL != handle->resp_object)
@@ -261,6 +307,46 @@ do_error (void *cls)
261 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 307 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
262} 308}
263 309
310
311/**
312 * Get EgoEntry from list with either a public key or a name
313 * If public key and name are not NULL, it returns the public key result first
314 *
315 * @param handle the RequestHandle
316 * @param pubkey the public key of an identity (only one can be NULL)
317 * @param name the name of an identity (only one can be NULL)
318 * @return EgoEntry or NULL if not found
319 */
320struct EgoEntry*
321get_egoentry(struct RequestHandle *handle, char* pubkey, char *name)
322{
323 struct EgoEntry *ego_entry;
324 if (NULL != pubkey)
325 {
326 for (ego_entry = handle->ego_head;
327 NULL != ego_entry;
328 ego_entry = ego_entry->next)
329 {
330 if (0 != strcasecmp (pubkey, ego_entry->keystring))
331 continue;
332 return ego_entry;
333 }
334 }
335 if (NULL != name)
336 {
337 for (ego_entry = handle->ego_head;
338 NULL != ego_entry;
339 ego_entry = ego_entry->next)
340 {
341 if (0 != strcasecmp (name, ego_entry->identifier))
342 continue;
343 return ego_entry;
344 }
345 }
346 return NULL;
347}
348
349
264/** 350/**
265 * Does internal server error when iteration failed. 351 * Does internal server error when iteration failed.
266 */ 352 */
@@ -273,6 +359,7 @@ namestore_iteration_error (void *cls)
273 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 359 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
274} 360}
275 361
362
276static void 363static void
277create_finished (void *cls, int32_t success, const char *emsg) 364create_finished (void *cls, int32_t success, const char *emsg)
278{ 365{
@@ -291,6 +378,7 @@ create_finished (void *cls, int32_t success, const char *emsg)
291 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 378 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
292} 379}
293 380
381
294static void 382static void
295del_finished (void *cls, int32_t success, const char *emsg) 383del_finished (void *cls, int32_t success, const char *emsg)
296{ 384{
@@ -314,6 +402,8 @@ del_finished (void *cls, int32_t success, const char *emsg)
314 MHD_HTTP_NO_CONTENT); 402 MHD_HTTP_NO_CONTENT);
315 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 403 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
316} 404}
405
406
317/** 407/**
318 * Iteration over all results finished, build final 408 * Iteration over all results finished, build final
319 * response. 409 * response.
@@ -344,7 +434,6 @@ namestore_list_finished (void *cls)
344} 434}
345 435
346 436
347
348/** 437/**
349 * Create a response with requested records 438 * Create a response with requested records
350 * 439 *
@@ -406,14 +495,50 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
406 void *cls) 495 void *cls)
407{ 496{
408 struct RequestHandle *handle = cls; 497 struct RequestHandle *handle = cls;
409 if (strlen (GNUNET_REST_API_NS_NAMESTORE) != strlen (handle->url)) 498 struct EgoEntry *ego_entry = NULL;
499 struct GNUNET_HashCode key;
500 char *pubkey = NULL;
501 char *name = NULL;
502
503 //change zone if pubkey or name specified
504 GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_PUBKEY,
505 strlen (GNUNET_REST_API_PARAM_PUBKEY),
506 &key);
507 if ( GNUNET_YES
508 == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
509 &key))
410 { 510 {
411 handle->emsg = GNUNET_strdup("Wrong URL"); 511 pubkey = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
412 GNUNET_SCHEDULER_add_now (&do_error, handle); 512 &key);
413 return; 513 }
514 GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_NAME,
515 strlen (GNUNET_REST_API_PARAM_NAME),
516 &key);
517 if ( GNUNET_YES
518 == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
519 &key))
520 {
521 name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
522 &key);
523 }
524
525 ego_entry = get_egoentry(handle,pubkey,name);
526 if (NULL == ego_entry)
527 {
528 if (NULL != pubkey || NULL != name)
529 {
530 handle->emsg = GNUNET_strdup("Invalid identity");
531 handle->response_code = MHD_HTTP_NOT_FOUND;
532 GNUNET_SCHEDULER_add_now (&do_error, handle);
533 return;
534 }
535 }
536 if ( NULL != ego_entry )
537 {
538 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
414 } 539 }
415 handle->list_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, 540 handle->list_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
416 &handle->zone_pkey, 541 handle->zone_pkey,
417 &namestore_iteration_error, 542 &namestore_iteration_error,
418 handle, 543 handle,
419 &namestore_list_iteration, 544 &namestore_list_iteration,
@@ -459,7 +584,7 @@ create_new_record_cont (void *cls,
459 return; 584 return;
460 } 585 }
461 handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, 586 handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
462 &handle->zone_pkey, 587 handle->zone_pkey,
463 handle->label_name, 588 handle->label_name,
464 GNUNET_REST_NAMESTORE_RD_COUNT, 589 GNUNET_REST_NAMESTORE_RD_COUNT,
465 handle->rd, 590 handle->rd,
@@ -484,6 +609,12 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
484 json_t *data_js; 609 json_t *data_js;
485 json_t *name_json; 610 json_t *name_json;
486 json_error_t err; 611 json_error_t err;
612
613 struct EgoEntry *ego_entry = NULL;
614 struct GNUNET_HashCode key;
615 char *pubkey = NULL;
616 char *name = NULL;
617
487 char term_data[handle->rest_handle->data_size + 1]; 618 char term_data[handle->rest_handle->data_size + 1];
488 struct GNUNET_JSON_Specification gnsspec[] = { 619 struct GNUNET_JSON_Specification gnsspec[] = {
489 GNUNET_JSON_spec_gnsrecord_data(&gns_record), 620 GNUNET_JSON_spec_gnsrecord_data(&gns_record),
@@ -506,12 +637,21 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
506 GNUNET_memcpy(term_data, handle->rest_handle->data, 637 GNUNET_memcpy(term_data, handle->rest_handle->data,
507 handle->rest_handle->data_size); 638 handle->rest_handle->data_size);
508 data_js = json_loads (term_data, JSON_DECODE_ANY, &err); 639 data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
509 GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL)); 640 if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL))
641 {
642 handle->emsg = GNUNET_strdup("Invalid data");
643 GNUNET_SCHEDULER_add_now (&do_error, handle);
644 GNUNET_free_non_null(gns_record);
645 json_decref (data_js);
646 return;
647 }
510 name_json = json_object_get(data_js, "label"); 648 name_json = json_object_get(data_js, "label");
511 if (!json_is_string(name_json)) 649 if (!json_is_string(name_json))
512 { 650 {
513 handle->emsg = GNUNET_strdup("Missing name"); 651 handle->emsg = GNUNET_strdup("Missing name");
514 GNUNET_SCHEDULER_add_now (&do_error, handle); 652 GNUNET_SCHEDULER_add_now (&do_error, handle);
653 GNUNET_free_non_null(gns_record);
654 json_decref (data_js);
515 return; 655 return;
516 } 656 }
517 handle->label_name = GNUNET_strdup(json_string_value(name_json)); 657 handle->label_name = GNUNET_strdup(json_string_value(name_json));
@@ -519,12 +659,60 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
519 { 659 {
520 handle->emsg = GNUNET_strdup("Missing name"); 660 handle->emsg = GNUNET_strdup("Missing name");
521 GNUNET_SCHEDULER_add_now (&do_error, handle); 661 GNUNET_SCHEDULER_add_now (&do_error, handle);
662 GNUNET_free_non_null(gns_record);
663 json_decref (data_js);
664 return;
665 }
666 if (0 >= strlen(handle->label_name))
667 {
668 handle->emsg = GNUNET_strdup("Missing name");
669 GNUNET_SCHEDULER_add_now (&do_error, handle);
670 GNUNET_free_non_null(gns_record);
671 json_decref (data_js);
522 return; 672 return;
523 } 673 }
524 json_decref (data_js); 674 json_decref (data_js);
525 handle->rd = gns_record; 675 handle->rd = gns_record;
676
677 //change zone if pubkey or name specified
678 GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_PUBKEY,
679 strlen (GNUNET_REST_API_PARAM_PUBKEY),
680 &key);
681 if ( GNUNET_YES
682 == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
683 &key))
684 {
685 pubkey = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
686 &key);
687 }
688 GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_NAME,
689 strlen (GNUNET_REST_API_PARAM_NAME),
690 &key);
691 if ( GNUNET_YES
692 == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
693 &key))
694 {
695 name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
696 &key);
697 }
698
699 ego_entry = get_egoentry(handle,pubkey,name);
700 if (NULL == ego_entry)
701 {
702 if (NULL != pubkey || NULL != name)
703 {
704 handle->emsg = GNUNET_strdup("Invalid identity");
705 handle->response_code = MHD_HTTP_NOT_FOUND;
706 GNUNET_SCHEDULER_add_now (&do_error, handle);
707 return;
708 }
709 }
710 if ( NULL != ego_entry )
711 {
712 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
713 }
526 handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, 714 handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
527 &handle->zone_pkey, 715 handle->zone_pkey,
528 handle->label_name, 716 handle->label_name,
529 &do_error, 717 &do_error,
530 handle, 718 handle,
@@ -551,7 +739,7 @@ del_cont (void *cls,
551 } 739 }
552 740
553 handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, 741 handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
554 &handle->zone_pkey, 742 handle->zone_pkey,
555 handle->label_name, 743 handle->label_name,
556 0, NULL, 744 0, NULL,
557 &del_finished, 745 &del_finished,
@@ -572,6 +760,47 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle,
572{ 760{
573 struct RequestHandle *handle = cls; 761 struct RequestHandle *handle = cls;
574 struct GNUNET_HashCode key; 762 struct GNUNET_HashCode key;
763 struct EgoEntry *ego_entry = NULL;
764 char *pubkey = NULL;
765 char *name = NULL;
766
767 //change zone if pubkey or name specified
768 GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_PUBKEY,
769 strlen (GNUNET_REST_API_PARAM_PUBKEY),
770 &key);
771 if ( GNUNET_YES
772 == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
773 &key))
774 {
775 pubkey = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
776 &key);
777 }
778 GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_NAME,
779 strlen (GNUNET_REST_API_PARAM_NAME),
780 &key);
781 if ( GNUNET_YES
782 == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map,
783 &key))
784 {
785 name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
786 &key);
787 }
788
789 ego_entry = get_egoentry(handle,pubkey,name);
790 if (NULL == ego_entry)
791 {
792 if (NULL != pubkey || NULL != name)
793 {
794 handle->emsg = GNUNET_strdup("Invalid identity");
795 handle->response_code = MHD_HTTP_NOT_FOUND;
796 GNUNET_SCHEDULER_add_now (&do_error, handle);
797 return;
798 }
799 }
800 if ( NULL != ego_entry )
801 {
802 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
803 }
575 804
576 GNUNET_CRYPTO_hash ("label", strlen ("label"), &key); 805 GNUNET_CRYPTO_hash ("label", strlen ("label"), &key);
577 if ( GNUNET_NO 806 if ( GNUNET_NO
@@ -582,11 +811,10 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle,
582 GNUNET_SCHEDULER_add_now (&do_error, handle); 811 GNUNET_SCHEDULER_add_now (&do_error, handle);
583 return; 812 return;
584 } 813 }
585 handle->label_name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, 814 handle->label_name = GNUNET_strdup(
586 &key); 815 GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key));
587
588 handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, 816 handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
589 &handle->zone_pkey, 817 handle->zone_pkey,
590 handle->label_name, 818 handle->label_name,
591 &do_error, 819 &do_error,
592 handle, 820 handle,
@@ -651,34 +879,27 @@ init_cont (struct RequestHandle *handle)
651} 879}
652 880
653/** 881/**
654 * 882 * @param cls closure
883 * @param ego ego handle
884 * @param ctx context for application to store data for this ego
885 * (during the lifetime of this process, initially NULL)
886 * @param identifier identifier assigned by the user for this ego,
887 * NULL if the user just deleted the ego and it
888 * must thus no longer be used
655 */ 889 */
656static void 890static void
657default_ego_cb (void *cls, 891default_ego_cb (void *cls,
658 struct GNUNET_IDENTITY_Ego *ego, 892 struct GNUNET_IDENTITY_Ego *ego,
659 void **ctx, 893 void **ctx,
660 const char *name) 894 const char *identifier)
661{ 895{
662 struct RequestHandle *handle = cls; 896 struct RequestHandle *handle = cls;
663 struct EgoEntry *ego_entry;
664 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
665
666 handle->op = NULL; 897 handle->op = NULL;
667 898
668 if (NULL == ego) 899 if (ego != NULL)
669 { 900 {
670 handle->emsg = GNUNET_strdup ("No default ego configured in identity service"); 901 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
671 GNUNET_SCHEDULER_add_now (&do_error, handle);
672 return;
673 } 902 }
674 ego_entry = GNUNET_new(struct EgoEntry);
675 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
676 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
677 ego_entry->identifier = name;
678 ego_entry->ego = ego;
679 handle->ego_entry = ego_entry;
680 handle->zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
681 init_cont (handle);
682} 903}
683 904
684 905
@@ -692,13 +913,33 @@ id_connect_cb (void *cls,
692 const char *name) 913 const char *name)
693{ 914{
694 struct RequestHandle *handle = cls; 915 struct RequestHandle *handle = cls;
695 if (NULL == ego) 916 struct EgoEntry *ego_entry;
917 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
918
919 if ((NULL == ego) && (NULL == handle->zone_pkey))
696 { 920 {
697 handle->op = GNUNET_IDENTITY_get (handle->identity_handle, 921 handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
698 GNUNET_REST_SUBSYSTEM_NAMESTORE, 922 GNUNET_REST_SUBSYSTEM_NAMESTORE,
699 &default_ego_cb, 923 &default_ego_cb,
700 handle); 924 handle);
701 } 925 }
926 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
927 {
928 handle->state = ID_REST_STATE_POST_INIT;
929 init_cont (handle);
930 return;
931 }
932 if (ID_REST_STATE_INIT == handle->state)
933 {
934 ego_entry = GNUNET_new(struct EgoEntry);
935 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
936 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
937 ego_entry->ego = ego;
938 GNUNET_asprintf (&ego_entry->identifier, "%s", name);
939 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head, handle->ego_tail,
940 ego_entry);
941 }
942
702} 943}
703 944
704 945
@@ -725,6 +966,7 @@ rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
725 handle->proc_cls = proc_cls; 966 handle->proc_cls = proc_cls;
726 handle->proc = proc; 967 handle->proc = proc;
727 handle->rest_handle = rest_handle; 968 handle->rest_handle = rest_handle;
969 handle->zone_pkey = NULL;
728 970
729 handle->url = GNUNET_strdup (rest_handle->url); 971 handle->url = GNUNET_strdup (rest_handle->url);
730 if (handle->url[strlen (handle->url)-1] == '/') 972 if (handle->url[strlen (handle->url)-1] == '/')