aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/plugin_rest_namestore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/namestore/plugin_rest_namestore.c')
-rw-r--r--src/namestore/plugin_rest_namestore.c214
1 files changed, 161 insertions, 53 deletions
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c
index d93b2e185..7a5a70fca 100644
--- a/src/namestore/plugin_rest_namestore.c
+++ b/src/namestore/plugin_rest_namestore.c
@@ -35,11 +35,16 @@
35#include <jansson.h> 35#include <jansson.h>
36 36
37/** 37/**
38 * Namestore Namespace 38 * Namestore namespace
39 */ 39 */
40#define GNUNET_REST_API_NS_NAMESTORE "/namestore" 40#define GNUNET_REST_API_NS_NAMESTORE "/namestore"
41 41
42/** 42/**
43 * Namestore import API namespace
44 */
45#define GNUNET_REST_API_NS_NAMESTORE_IMPORT "/namestore/import"
46
47/**
43 * Error message Unknown Error 48 * Error message Unknown Error
44 */ 49 */
45#define GNUNET_REST_NAMESTORE_ERROR_UNKNOWN "Unknown Error" 50#define GNUNET_REST_NAMESTORE_ERROR_UNKNOWN "Unknown Error"
@@ -196,11 +201,31 @@ struct RequestHandle
196 unsigned int rd_count; 201 unsigned int rd_count;
197 202
198 /** 203 /**
204 * RecordInfo array
205 */
206 struct GNUNET_NAMESTORE_RecordInfo *ri;
207
208 /**
209 * Size of record info
210 */
211 unsigned int rd_set_count;
212
213 /**
214 * Position of record info
215 */
216 unsigned int rd_set_pos;
217
218 /**
199 * NAMESTORE Operation 219 * NAMESTORE Operation
200 */ 220 */
201 struct GNUNET_NAMESTORE_QueueEntry *ns_qe; 221 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
202 222
203 /** 223 /**
224 * For bulk import, we need a dedicated Namestore handle
225 */
226 struct GNUNET_NAMESTORE_Handle *nc;
227
228 /**
204 * Response object 229 * Response object
205 */ 230 */
206 json_t *resp_object; 231 json_t *resp_object;
@@ -314,7 +339,8 @@ cleanup_handle (void *cls)
314 GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it); 339 GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it);
315 if (NULL != handle->ns_qe) 340 if (NULL != handle->ns_qe)
316 GNUNET_NAMESTORE_cancel (handle->ns_qe); 341 GNUNET_NAMESTORE_cancel (handle->ns_qe);
317 342 if (NULL != handle->nc)
343 GNUNET_NAMESTORE_disconnect (handle->nc);
318 if (NULL != handle->resp_object) 344 if (NULL != handle->resp_object)
319 { 345 {
320 json_decref (handle->resp_object); 346 json_decref (handle->resp_object);
@@ -721,20 +747,16 @@ ns_lookup_cb (void *cls,
721 } 747 }
722} 748}
723 749
724/** 750
725 * Import callback
726 *
727 * @param cls the `struct RequestHandle`
728 * @param success the success indicating integer, GNUNET_OK on success
729 * @param emsg the error message (can be NULL)
730 */
731static void 751static void
732import_finished_cb (void *cls, int32_t success, const char *emsg) 752bulk_tx_commit_cb (void *cls, int32_t success, const char *emsg)
733{ 753{
734 struct RequestHandle *handle = cls; 754 struct RequestHandle *handle = cls;
735 struct MHD_Response *resp; 755 struct MHD_Response *resp;
736 756
737 handle->ns_qe = NULL; 757 handle->ns_qe = NULL;
758 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
759 "Commit finished, %d\n", success);
738 if (GNUNET_YES != success) 760 if (GNUNET_YES != success)
739 { 761 {
740 if (NULL != emsg) 762 if (NULL != emsg)
@@ -743,7 +765,7 @@ import_finished_cb (void *cls, int32_t success, const char *emsg)
743 GNUNET_SCHEDULER_add_now (&do_error, handle); 765 GNUNET_SCHEDULER_add_now (&do_error, handle);
744 return; 766 return;
745 } 767 }
746 handle->emsg = GNUNET_strdup ("Error importing records"); 768 handle->emsg = GNUNET_strdup ("Error importing records on commit");
747 GNUNET_SCHEDULER_add_now (&do_error, handle); 769 GNUNET_SCHEDULER_add_now (&do_error, handle);
748 return; 770 return;
749 } 771 }
@@ -754,45 +776,69 @@ import_finished_cb (void *cls, int32_t success, const char *emsg)
754 776
755 777
756/** 778/**
757 * Handle namestore POST import 779 * Import callback
758 * 780 *
759 * @param con_handle the connection handle 781 * @param cls the `struct RequestHandle`
760 * @param url the url 782 * @param success the success indicating integer, GNUNET_OK on success
761 * @param cls the RequestHandle 783 * @param emsg the error message (can be NULL)
762 */ 784 */
763void 785static void
764namestore_import (struct GNUNET_REST_RequestHandle *con_handle, 786import_next_cb (void *cls, int32_t success, const char *emsg)
765 const char *url,
766 void *cls)
767{ 787{
768 struct RequestHandle *handle = cls; 788 struct RequestHandle *handle = cls;
769 struct EgoEntry *ego_entry;
770 char *egoname;
771 json_t *data_js;
772 json_error_t err;
773 789
774 char term_data[handle->rest_handle->data_size + 1]; 790 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
775 // set zone to name if given 791 "Import finished, %d\n", success);
776 if (strlen (GNUNET_REST_API_NS_NAMESTORE) + 1 >= strlen (handle->url)) 792 handle->ns_qe = NULL;
793 if (GNUNET_YES != success)
777 { 794 {
778 handle->response_code = MHD_HTTP_NOT_FOUND; 795 if (NULL != emsg)
779 handle->emsg = GNUNET_strdup (GNUNET_REST_IDENTITY_NOT_FOUND); 796 {
797 handle->emsg = GNUNET_strdup (emsg);
798 GNUNET_SCHEDULER_add_now (&do_error, handle);
799 return;
800 }
801 handle->emsg = GNUNET_strdup ("Error importing records");
780 GNUNET_SCHEDULER_add_now (&do_error, handle); 802 GNUNET_SCHEDULER_add_now (&do_error, handle);
781 return; 803 return;
782 } 804 }
783 ego_entry = NULL; 805 unsigned int remaining = handle->rd_set_count - handle->rd_set_pos;
784 806 if (0 == remaining)
785 egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
786 ego_entry = get_egoentry_namestore (handle, egoname);
787
788 if (NULL == ego_entry)
789 { 807 {
790 handle->response_code = MHD_HTTP_NOT_FOUND; 808 handle->ns_qe = GNUNET_NAMESTORE_transaction_commit (handle->nc,
791 handle->emsg = GNUNET_strdup (GNUNET_REST_IDENTITY_NOT_FOUND); 809 &bulk_tx_commit_cb,
810 handle);
811 return;
812 }
813 unsigned int sent_rds = 0;
814 // Find the smallest set of records we can send with our message size
815 // restriction of 16 bit
816 handle->ns_qe = GNUNET_NAMESTORE_records_store2 (handle->nc,
817 handle->zone_pkey,
818 remaining,
819 &handle->ri[handle->
820 rd_set_pos],
821 &sent_rds,
822 &import_next_cb,
823 handle);
824 if ((NULL == handle->ns_qe) && (0 == sent_rds))
825 {
826 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
792 GNUNET_SCHEDULER_add_now (&do_error, handle); 827 GNUNET_SCHEDULER_add_now (&do_error, handle);
793 return; 828 return;
794 } 829 }
830 handle->rd_set_pos += sent_rds;
831}
832
833static void
834bulk_tx_start (void *cls, int32_t success, const char *emsg)
835{
836 struct RequestHandle *handle = cls;
837 json_t *data_js;
838 json_error_t err;
795 839
840 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
841 "Transaction started...\n");
796 if (0 >= handle->rest_handle->data_size) 842 if (0 >= handle->rest_handle->data_size)
797 { 843 {
798 handle->response_code = MHD_HTTP_BAD_REQUEST; 844 handle->response_code = MHD_HTTP_BAD_REQUEST;
@@ -800,6 +846,7 @@ namestore_import (struct GNUNET_REST_RequestHandle *con_handle,
800 GNUNET_SCHEDULER_add_now (&do_error, handle); 846 GNUNET_SCHEDULER_add_now (&do_error, handle);
801 return; 847 return;
802 } 848 }
849 char term_data[handle->rest_handle->data_size + 1];
803 term_data[handle->rest_handle->data_size] = '\0'; 850 term_data[handle->rest_handle->data_size] = '\0';
804 GNUNET_memcpy (term_data, 851 GNUNET_memcpy (term_data,
805 handle->rest_handle->data, 852 handle->rest_handle->data,
@@ -818,11 +865,11 @@ namestore_import (struct GNUNET_REST_RequestHandle *con_handle,
818 json_decref (data_js); 865 json_decref (data_js);
819 return; 866 return;
820 } 867 }
821 size_t rd_set_count = json_array_size (data_js); 868 handle->rd_set_count = json_array_size (data_js);
822 struct GNUNET_NAMESTORE_RecordInfo ri[rd_set_count]; 869 handle->ri = GNUNET_malloc (handle->rd_set_count
870 * sizeof (struct GNUNET_NAMESTORE_RecordInfo));
823 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 871 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
824 "Got record set of size %d\n", rd_set_count); 872 "Got record set of size %d\n", handle->rd_set_count);
825 const struct GNUNET_GNSRECORD_Data *a_rd[rd_set_count];
826 char *albl; 873 char *albl;
827 size_t index; 874 size_t index;
828 json_t *value; 875 json_t *value;
@@ -830,7 +877,8 @@ namestore_import (struct GNUNET_REST_RequestHandle *con_handle,
830 { 877 {
831 struct GNUNET_GNSRECORD_Data *rd; 878 struct GNUNET_GNSRECORD_Data *rd;
832 struct GNUNET_JSON_Specification gnsspec[] = 879 struct GNUNET_JSON_Specification gnsspec[] =
833 { GNUNET_GNSRECORD_JSON_spec_gnsrecord (&rd, &ri[index].a_rd_count, 880 { GNUNET_GNSRECORD_JSON_spec_gnsrecord (&rd,
881 &handle->ri[index].a_rd_count,
834 &albl), 882 &albl),
835 GNUNET_JSON_spec_end () }; 883 GNUNET_JSON_spec_end () };
836 if (GNUNET_OK != GNUNET_JSON_parse (value, gnsspec, NULL, NULL)) 884 if (GNUNET_OK != GNUNET_JSON_parse (value, gnsspec, NULL, NULL))
@@ -840,27 +888,86 @@ namestore_import (struct GNUNET_REST_RequestHandle *con_handle,
840 json_decref (data_js); 888 json_decref (data_js);
841 return; 889 return;
842 } 890 }
843 ri[index].a_rd = rd; 891 handle->ri[index].a_rd = rd;
844 ri[index].a_label = albl; 892 handle->ri[index].a_label = albl;
845 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
846 "Parsed record set for name %s\n", ri[index].a_label); 894 "Parsed record set for name %s\n",
895 handle->ri[index].a_label);
847 } 896 }
848 } 897 }
849 //json_decref (data_js); 898 // json_decref (data_js);
850 899
851 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 900 unsigned int sent_rds = 0;
852 handle->ns_qe = GNUNET_NAMESTORE_records_store2 (ns_handle, 901 // Find the smallest set of records we can send with our message size
902 // restriction of 16 bit
903 handle->ns_qe = GNUNET_NAMESTORE_records_store2 (handle->nc,
853 handle->zone_pkey, 904 handle->zone_pkey,
854 rd_set_count, 905 handle->rd_set_count,
855 ri, 906 handle->ri,
856 &import_finished_cb, 907 &sent_rds,
908 &import_next_cb,
857 handle); 909 handle);
858 if (NULL == handle->ns_qe) 910 if ((NULL == handle->ns_qe) && (0 == sent_rds))
859 { 911 {
860 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED); 912 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
861 GNUNET_SCHEDULER_add_now (&do_error, handle); 913 GNUNET_SCHEDULER_add_now (&do_error, handle);
862 return; 914 return;
863 } 915 }
916 handle->rd_set_pos += sent_rds;
917}
918
919
920/**
921 * Handle namestore POST import
922 *
923 * @param con_handle the connection handle
924 * @param url the url
925 * @param cls the RequestHandle
926 */
927void
928namestore_import (struct GNUNET_REST_RequestHandle *con_handle,
929 const char *url,
930 void *cls)
931{
932 struct RequestHandle *handle = cls;
933 struct EgoEntry *ego_entry;
934 char *egoname;
935
936 // set zone to name if given
937 if (strlen (GNUNET_REST_API_NS_NAMESTORE_IMPORT) + 1 >= strlen (
938 handle->url))
939 {
940 handle->response_code = MHD_HTTP_NOT_FOUND;
941 handle->emsg = GNUNET_strdup (GNUNET_REST_IDENTITY_NOT_FOUND);
942 GNUNET_SCHEDULER_add_now (&do_error, handle);
943 return;
944 }
945 ego_entry = NULL;
946
947 egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE_IMPORT) + 1];
948 ego_entry = get_egoentry_namestore (handle, egoname);
949
950 if (NULL == ego_entry)
951 {
952 handle->response_code = MHD_HTTP_NOT_FOUND;
953 handle->emsg = GNUNET_strdup (GNUNET_REST_IDENTITY_NOT_FOUND);
954 GNUNET_SCHEDULER_add_now (&do_error, handle);
955 return;
956 }
957 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
958
959 // We need a per-client connection for a transactional bulk import
960 handle->nc = GNUNET_NAMESTORE_connect (cfg);
961 if (NULL == handle->nc)
962 {
963 handle->response_code = MHD_HTTP_BAD_REQUEST;
964 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_NO_DATA);
965 GNUNET_SCHEDULER_add_now (&do_error, handle);
966 return;
967 }
968 handle->ns_qe = GNUNET_NAMESTORE_transaction_begin (handle->nc,
969 &bulk_tx_start,
970 handle);
864} 971}
865 972
866/** 973/**
@@ -1183,8 +1290,9 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1183 struct GNUNET_REST_RequestHandlerError err; 1290 struct GNUNET_REST_RequestHandlerError err;
1184 static const struct GNUNET_REST_RequestHandler handlers[] = 1291 static const struct GNUNET_REST_RequestHandler handlers[] =
1185 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get }, 1292 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get },
1186 //{ MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add }, 1293 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE_IMPORT,
1187 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_import }, 1294 &namestore_import },
1295 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add },
1188 { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update }, 1296 { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update },
1189 { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, 1297 { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE,
1190 &namestore_delete }, 1298 &namestore_delete },