diff options
author | t3sserakt <t3ss@posteo.de> | 2020-08-06 16:25:51 +0200 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2020-08-06 16:25:51 +0200 |
commit | 38193fe48a572e475b4f84717ff5b3edbcaf2d2a (patch) | |
tree | d6deeb56d81f75ab411d88a03b865f7da7eaaed4 /src/rest/gnunet-rest-server.c | |
parent | 33954ae13d4d26cefa45ac86f5e2184b6abd724f (diff) | |
parent | 6ab14a20690a499ad32e3f2ad448d64d4e6b65fc (diff) | |
download | gnunet-38193fe48a572e475b4f84717ff5b3edbcaf2d2a.tar.gz gnunet-38193fe48a572e475b4f84717ff5b3edbcaf2d2a.zip |
Merge branch 'master' of ssh://gnunet.org/gnunet
Diffstat (limited to 'src/rest/gnunet-rest-server.c')
-rw-r--r-- | src/rest/gnunet-rest-server.c | 379 |
1 files changed, 291 insertions, 88 deletions
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c index 875509536..436b5b205 100644 --- a/src/rest/gnunet-rest-server.c +++ b/src/rest/gnunet-rest-server.c | |||
@@ -115,11 +115,6 @@ static struct MHD_Response *failure_response; | |||
115 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 115 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
116 | 116 | ||
117 | /** | 117 | /** |
118 | * Map of loaded plugins. | ||
119 | */ | ||
120 | static struct GNUNET_CONTAINER_MultiHashMap *plugin_map; | ||
121 | |||
122 | /** | ||
123 | * Echo request Origin in CORS | 118 | * Echo request Origin in CORS |
124 | */ | 119 | */ |
125 | static int echo_origin; | 120 | static int echo_origin; |
@@ -140,6 +135,38 @@ static char *allow_headers; | |||
140 | static char *allow_credentials; | 135 | static char *allow_credentials; |
141 | 136 | ||
142 | /** | 137 | /** |
138 | * Plugin list head | ||
139 | */ | ||
140 | static struct PluginListEntry *plugins_head; | ||
141 | |||
142 | /** | ||
143 | * Plugin list tail | ||
144 | */ | ||
145 | static struct PluginListEntry *plugins_tail; | ||
146 | |||
147 | /** | ||
148 | * A plugin list entry | ||
149 | */ | ||
150 | struct PluginListEntry | ||
151 | { | ||
152 | /* DLL */ | ||
153 | struct PluginListEntry *next; | ||
154 | |||
155 | /* DLL */ | ||
156 | struct PluginListEntry *prev; | ||
157 | |||
158 | /** | ||
159 | * libname (to cleanup) | ||
160 | */ | ||
161 | char *libname; | ||
162 | |||
163 | /** | ||
164 | * The plugin | ||
165 | */ | ||
166 | struct GNUNET_REST_Plugin *plugin; | ||
167 | }; | ||
168 | |||
169 | /** | ||
143 | * MHD Connection handle | 170 | * MHD Connection handle |
144 | */ | 171 | */ |
145 | struct MhdConnectionHandle | 172 | struct MhdConnectionHandle |
@@ -148,8 +175,6 @@ struct MhdConnectionHandle | |||
148 | 175 | ||
149 | struct MHD_Response *response; | 176 | struct MHD_Response *response; |
150 | 177 | ||
151 | struct GNUNET_REST_Plugin *plugin; | ||
152 | |||
153 | struct GNUNET_REST_RequestHandle *data_handle; | 178 | struct GNUNET_REST_RequestHandle *data_handle; |
154 | 179 | ||
155 | struct MHD_PostProcessor *pp; | 180 | struct MHD_PostProcessor *pp; |
@@ -159,6 +184,42 @@ struct MhdConnectionHandle | |||
159 | int state; | 184 | int state; |
160 | }; | 185 | }; |
161 | 186 | ||
187 | /** | ||
188 | * Accepted requests | ||
189 | */ | ||
190 | struct AcceptedRequest | ||
191 | { | ||
192 | /** | ||
193 | * DLL | ||
194 | */ | ||
195 | struct AcceptedRequest *next; | ||
196 | |||
197 | /** | ||
198 | * DLL | ||
199 | */ | ||
200 | struct AcceptedRequest *prev; | ||
201 | |||
202 | /** | ||
203 | * Socket | ||
204 | */ | ||
205 | struct GNUNET_NETWORK_Handle *sock; | ||
206 | |||
207 | /** | ||
208 | * Connection | ||
209 | */ | ||
210 | struct MhdConnectionHandle *con_handle; | ||
211 | }; | ||
212 | |||
213 | /** | ||
214 | * AcceptedRequest list head | ||
215 | */ | ||
216 | static struct AcceptedRequest *req_list_head; | ||
217 | |||
218 | /** | ||
219 | * AcceptedRequest list tail | ||
220 | */ | ||
221 | static struct AcceptedRequest *req_list_tail; | ||
222 | |||
162 | /* ************************* Global helpers ********************* */ | 223 | /* ************************* Global helpers ********************* */ |
163 | 224 | ||
164 | 225 | ||
@@ -213,7 +274,6 @@ cleanup_url_map (void *cls, const struct GNUNET_HashCode *key, void *value) | |||
213 | return GNUNET_YES; | 274 | return GNUNET_YES; |
214 | } | 275 | } |
215 | 276 | ||
216 | |||
217 | static void | 277 | static void |
218 | cleanup_handle (struct MhdConnectionHandle *handle) | 278 | cleanup_handle (struct MhdConnectionHandle *handle) |
219 | { | 279 | { |
@@ -243,6 +303,19 @@ cleanup_handle (struct MhdConnectionHandle *handle) | |||
243 | GNUNET_free (handle); | 303 | GNUNET_free (handle); |
244 | } | 304 | } |
245 | 305 | ||
306 | static void | ||
307 | cleanup_ar (struct AcceptedRequest *ar) | ||
308 | { | ||
309 | if (NULL != ar->con_handle) | ||
310 | { | ||
311 | cleanup_handle (ar->con_handle); | ||
312 | } | ||
313 | GNUNET_NETWORK_socket_free_memory_only_ (ar->sock); | ||
314 | GNUNET_CONTAINER_DLL_remove (req_list_head, | ||
315 | req_list_tail, | ||
316 | ar); | ||
317 | GNUNET_free (ar); | ||
318 | } | ||
246 | 319 | ||
247 | static int | 320 | static int |
248 | header_iterator (void *cls, | 321 | header_iterator (void *cls, |
@@ -321,19 +394,24 @@ post_data_iter (void *cls, | |||
321 | return MHD_YES; | 394 | return MHD_YES; |
322 | 395 | ||
323 | GNUNET_CRYPTO_hash (key, strlen (key), &hkey); | 396 | GNUNET_CRYPTO_hash (key, strlen (key), &hkey); |
324 | GNUNET_asprintf (&val, "%s", data); | 397 | val = GNUNET_CONTAINER_multihashmap_get (handle->url_param_map, |
325 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( | 398 | &hkey); |
326 | handle->url_param_map, | 399 | if (NULL == val) |
327 | &hkey, | ||
328 | val, | ||
329 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
330 | { | 400 | { |
331 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 401 | val = GNUNET_malloc (65536); |
332 | "Could not load add url param '%s'=%s\n", | 402 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( |
333 | key, | 403 | handle->url_param_map, |
334 | data); | 404 | &hkey, |
335 | GNUNET_free (val); | 405 | val, |
406 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
407 | { | ||
408 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
409 | "Could not add url param '%s'\n", | ||
410 | key); | ||
411 | GNUNET_free (val); | ||
412 | } | ||
336 | } | 413 | } |
414 | memcpy (val + off, data, size); | ||
337 | return MHD_YES; | 415 | return MHD_YES; |
338 | } | 416 | } |
339 | 417 | ||
@@ -373,41 +451,30 @@ create_response (void *cls, | |||
373 | size_t *upload_data_size, | 451 | size_t *upload_data_size, |
374 | void **con_cls) | 452 | void **con_cls) |
375 | { | 453 | { |
376 | char *plugin_name; | ||
377 | char *origin; | 454 | char *origin; |
455 | struct AcceptedRequest *ar; | ||
378 | struct GNUNET_HashCode key; | 456 | struct GNUNET_HashCode key; |
379 | struct MhdConnectionHandle *con_handle; | 457 | struct MhdConnectionHandle *con_handle; |
380 | struct GNUNET_REST_RequestHandle *rest_conndata_handle; | 458 | struct GNUNET_REST_RequestHandle *rest_conndata_handle; |
459 | struct PluginListEntry *ple; | ||
381 | 460 | ||
382 | con_handle = *con_cls; | 461 | ar = *con_cls; |
462 | if (NULL == ar) | ||
463 | { | ||
464 | GNUNET_break (0); | ||
465 | return MHD_NO; | ||
466 | } | ||
383 | 467 | ||
384 | if (NULL == *con_cls) | 468 | if (NULL == ar->con_handle) |
385 | { | 469 | { |
386 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url); | 470 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url); |
387 | char tmp_url[strlen (url) + 1]; | ||
388 | strcpy (tmp_url, url); | ||
389 | con_handle = GNUNET_new (struct MhdConnectionHandle); | 471 | con_handle = GNUNET_new (struct MhdConnectionHandle); |
390 | con_handle->con = con; | 472 | con_handle->con = con; |
391 | con_handle->state = GN_REST_STATE_INIT; | 473 | con_handle->state = GN_REST_STATE_INIT; |
392 | *con_cls = con_handle; | 474 | ar->con_handle = con_handle; |
393 | |||
394 | plugin_name = strtok (tmp_url, "/"); | ||
395 | |||
396 | if (NULL != plugin_name) | ||
397 | { | ||
398 | GNUNET_CRYPTO_hash (plugin_name, strlen (plugin_name), &key); | ||
399 | |||
400 | con_handle->plugin = GNUNET_CONTAINER_multihashmap_get (plugin_map, &key); | ||
401 | } | ||
402 | if (NULL == con_handle->plugin) | ||
403 | { | ||
404 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing response with MHD\n"); | ||
405 | GNUNET_free (con_handle); | ||
406 | return MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response); | ||
407 | } | ||
408 | |||
409 | return MHD_YES; | 475 | return MHD_YES; |
410 | } | 476 | } |
477 | con_handle = ar->con_handle; | ||
411 | if (GN_REST_STATE_INIT == con_handle->state) | 478 | if (GN_REST_STATE_INIT == con_handle->state) |
412 | { | 479 | { |
413 | rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle); | 480 | rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle); |
@@ -428,6 +495,7 @@ create_response (void *cls, | |||
428 | MHD_HEADER_KIND, | 495 | MHD_HEADER_KIND, |
429 | (MHD_KeyValueIterator) & header_iterator, | 496 | (MHD_KeyValueIterator) & header_iterator, |
430 | rest_conndata_handle); | 497 | rest_conndata_handle); |
498 | |||
431 | con_handle->pp = MHD_create_post_processor (con, | 499 | con_handle->pp = MHD_create_post_processor (con, |
432 | 65536, | 500 | 65536, |
433 | &post_data_iter, | 501 | &post_data_iter, |
@@ -439,9 +507,18 @@ create_response (void *cls, | |||
439 | MHD_destroy_post_processor (con_handle->pp); | 507 | MHD_destroy_post_processor (con_handle->pp); |
440 | 508 | ||
441 | con_handle->state = GN_REST_STATE_PROCESSING; | 509 | con_handle->state = GN_REST_STATE_PROCESSING; |
442 | con_handle->plugin->process_request (rest_conndata_handle, | 510 | for (ple = plugins_head; NULL != ple; ple = ple->next) |
443 | &plugin_callback, | 511 | { |
444 | con_handle); | 512 | if (GNUNET_YES == ple->plugin->process_request (rest_conndata_handle, |
513 | &plugin_callback, | ||
514 | con_handle)) | ||
515 | break; /* Request handled */ | ||
516 | } | ||
517 | if (NULL == ple) | ||
518 | { | ||
519 | /** Request not handled **/ | ||
520 | MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response); | ||
521 | } | ||
445 | *upload_data_size = 0; | 522 | *upload_data_size = 0; |
446 | run_mhd_now (); | 523 | run_mhd_now (); |
447 | return MHD_YES; | 524 | return MHD_YES; |
@@ -513,7 +590,7 @@ create_response (void *cls, | |||
513 | MHD_RESULT ret = MHD_queue_response (con, | 590 | MHD_RESULT ret = MHD_queue_response (con, |
514 | con_handle->status, | 591 | con_handle->status, |
515 | con_handle->response); | 592 | con_handle->response); |
516 | cleanup_handle (con_handle); | 593 | //cleanup_handle (con_handle); |
517 | return ret; | 594 | return ret; |
518 | } | 595 | } |
519 | } | 596 | } |
@@ -521,27 +598,6 @@ create_response (void *cls, | |||
521 | 598 | ||
522 | /* ******************** MHD HTTP setup and event loop ******************** */ | 599 | /* ******************** MHD HTTP setup and event loop ******************** */ |
523 | 600 | ||
524 | /** | ||
525 | * Function called when MHD decides that we are done with a connection. | ||
526 | * | ||
527 | * @param cls NULL | ||
528 | * @param connection connection handle | ||
529 | * @param con_cls value as set by the last call to | ||
530 | * the MHD_AccessHandlerCallback, should be our handle | ||
531 | * @param toe reason for request termination (ignored) | ||
532 | */ | ||
533 | static void | ||
534 | mhd_completed_cb (void *cls, | ||
535 | struct MHD_Connection *connection, | ||
536 | void **con_cls, | ||
537 | enum MHD_RequestTerminationCode toe) | ||
538 | { | ||
539 | if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) | ||
540 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
541 | "MHD encountered error handling request: %d\n", | ||
542 | toe); | ||
543 | } | ||
544 | |||
545 | 601 | ||
546 | /** | 602 | /** |
547 | * Kill the MHD daemon. | 603 | * Kill the MHD daemon. |
@@ -649,6 +705,135 @@ schedule_httpd () | |||
649 | GNUNET_NETWORK_fdset_destroy (wws); | 705 | GNUNET_NETWORK_fdset_destroy (wws); |
650 | } | 706 | } |
651 | 707 | ||
708 | /** | ||
709 | * Function called when MHD first processes an incoming connection. | ||
710 | * Gives us the respective URI information. | ||
711 | * | ||
712 | * We use this to associate the `struct MHD_Connection` with our | ||
713 | * internal `struct AcceptedRequest` data structure (by checking | ||
714 | * for matching sockets). | ||
715 | * | ||
716 | * @param cls the HTTP server handle (a `struct MhdHttpList`) | ||
717 | * @param url the URL that is being requested | ||
718 | * @param connection MHD connection object for the request | ||
719 | * @return the `struct Socks5Request` that this @a connection is for | ||
720 | */ | ||
721 | static void * | ||
722 | mhd_log_callback (void *cls, | ||
723 | const char *url, | ||
724 | struct MHD_Connection *connection) | ||
725 | { | ||
726 | struct AcceptedRequest *ar; | ||
727 | const union MHD_ConnectionInfo *ci; | ||
728 | |||
729 | ci = MHD_get_connection_info (connection, | ||
730 | MHD_CONNECTION_INFO_SOCKET_CONTEXT); | ||
731 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url); | ||
732 | if (NULL == ci) | ||
733 | { | ||
734 | GNUNET_break (0); | ||
735 | return NULL; | ||
736 | } | ||
737 | ar = ci->socket_context; | ||
738 | return ar; | ||
739 | } | ||
740 | |||
741 | |||
742 | |||
743 | /** | ||
744 | * Function called when MHD decides that we are done with a connection. | ||
745 | * | ||
746 | * @param cls NULL | ||
747 | * @param connection connection handle | ||
748 | * @param con_cls value as set by the last call to | ||
749 | * the MHD_AccessHandlerCallback, should be our handle | ||
750 | * @param toe reason for request termination (ignored) | ||
751 | */ | ||
752 | static void | ||
753 | mhd_completed_cb (void *cls, | ||
754 | struct MHD_Connection *connection, | ||
755 | void **con_cls, | ||
756 | enum MHD_RequestTerminationCode toe) | ||
757 | { | ||
758 | struct AcceptedRequest *ar = *con_cls; | ||
759 | if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) | ||
760 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
761 | "MHD encountered error handling request: %d\n", | ||
762 | toe); | ||
763 | if (NULL == ar) | ||
764 | return; | ||
765 | if (NULL != ar->con_handle) | ||
766 | { | ||
767 | cleanup_handle (ar->con_handle); | ||
768 | ar->con_handle = NULL; | ||
769 | } | ||
770 | schedule_httpd (); | ||
771 | *con_cls = NULL; | ||
772 | } | ||
773 | |||
774 | /** | ||
775 | * Function called when MHD connection is opened or closed. | ||
776 | * | ||
777 | * @param cls NULL | ||
778 | * @param connection connection handle | ||
779 | * @param con_cls value as set by the last call to | ||
780 | * the MHD_AccessHandlerCallback, should be our `struct Socks5Request *` | ||
781 | * @param toe connection notification type | ||
782 | */ | ||
783 | static void | ||
784 | mhd_connection_cb (void *cls, | ||
785 | struct MHD_Connection *connection, | ||
786 | void **con_cls, | ||
787 | enum MHD_ConnectionNotificationCode cnc) | ||
788 | { | ||
789 | struct AcceptedRequest *ar; | ||
790 | const union MHD_ConnectionInfo *ci; | ||
791 | int sock; | ||
792 | |||
793 | switch (cnc) | ||
794 | { | ||
795 | case MHD_CONNECTION_NOTIFY_STARTED: | ||
796 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n"); | ||
797 | ci = MHD_get_connection_info (connection, | ||
798 | MHD_CONNECTION_INFO_CONNECTION_FD); | ||
799 | if (NULL == ci) | ||
800 | { | ||
801 | GNUNET_break (0); | ||
802 | return; | ||
803 | } | ||
804 | sock = ci->connect_fd; | ||
805 | for (ar = req_list_head; NULL != ar; ar = ar->next) | ||
806 | { | ||
807 | if (GNUNET_NETWORK_get_fd (ar->sock) == sock) | ||
808 | { | ||
809 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
810 | "Context set...\n"); | ||
811 | *con_cls = ar; | ||
812 | break; | ||
813 | } | ||
814 | } | ||
815 | break; | ||
816 | |||
817 | case MHD_CONNECTION_NOTIFY_CLOSED: | ||
818 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
819 | "Connection closed... cleaning up\n"); | ||
820 | ar = *con_cls; | ||
821 | if (NULL == ar) | ||
822 | { | ||
823 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
824 | "Connection stale!\n"); | ||
825 | return; | ||
826 | } | ||
827 | cleanup_ar (ar); | ||
828 | *con_cls = NULL; | ||
829 | break; | ||
830 | |||
831 | default: | ||
832 | GNUNET_break (0); | ||
833 | } | ||
834 | } | ||
835 | |||
836 | |||
652 | 837 | ||
653 | /** | 838 | /** |
654 | * Task run whenever HTTP server operations are pending. | 839 | * Task run whenever HTTP server operations are pending. |
@@ -674,7 +859,7 @@ static void | |||
674 | do_accept (void *cls) | 859 | do_accept (void *cls) |
675 | { | 860 | { |
676 | struct GNUNET_NETWORK_Handle *lsock = cls; | 861 | struct GNUNET_NETWORK_Handle *lsock = cls; |
677 | struct GNUNET_NETWORK_Handle *s; | 862 | struct AcceptedRequest *ar; |
678 | int fd; | 863 | int fd; |
679 | const struct sockaddr *addr; | 864 | const struct sockaddr *addr; |
680 | socklen_t len; | 865 | socklen_t len; |
@@ -696,24 +881,30 @@ do_accept (void *cls) | |||
696 | } | 881 | } |
697 | else | 882 | else |
698 | GNUNET_assert (0); | 883 | GNUNET_assert (0); |
699 | s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); | 884 | ar = GNUNET_new (struct AcceptedRequest); |
700 | if (NULL == s) | 885 | ar->sock = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); |
886 | if (NULL == ar->sock) | ||
701 | { | 887 | { |
888 | GNUNET_free (ar); | ||
702 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept"); | 889 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept"); |
703 | return; | 890 | return; |
704 | } | 891 | } |
705 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 892 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
706 | "Got an inbound connection, waiting for data\n"); | 893 | "Got an inbound connection, waiting for data\n"); |
707 | fd = GNUNET_NETWORK_get_fd (s); | 894 | fd = GNUNET_NETWORK_get_fd (ar->sock); |
708 | addr = GNUNET_NETWORK_get_addr (s); | 895 | addr = GNUNET_NETWORK_get_addr (ar->sock); |
709 | len = GNUNET_NETWORK_get_addrlen (s); | 896 | len = GNUNET_NETWORK_get_addrlen (ar->sock); |
897 | GNUNET_CONTAINER_DLL_insert (req_list_head, | ||
898 | req_list_tail, | ||
899 | ar); | ||
710 | if (MHD_YES != MHD_add_connection (httpd, fd, addr, len)) | 900 | if (MHD_YES != MHD_add_connection (httpd, fd, addr, len)) |
711 | { | 901 | { |
902 | GNUNET_NETWORK_socket_close (ar->sock); | ||
903 | GNUNET_free (ar); | ||
712 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 904 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
713 | _ ("Failed to pass client to MHD\n")); | 905 | _ ("Failed to pass client to MHD\n")); |
714 | return; | 906 | return; |
715 | } | 907 | } |
716 | GNUNET_free (s); | ||
717 | schedule_httpd (); | 908 | schedule_httpd (); |
718 | } | 909 | } |
719 | 910 | ||
@@ -726,6 +917,18 @@ do_accept (void *cls) | |||
726 | static void | 917 | static void |
727 | do_shutdown (void *cls) | 918 | do_shutdown (void *cls) |
728 | { | 919 | { |
920 | struct PluginListEntry *ple; | ||
921 | |||
922 | while (NULL != plugins_head) | ||
923 | { | ||
924 | ple = plugins_head; | ||
925 | GNUNET_CONTAINER_DLL_remove (plugins_head, | ||
926 | plugins_tail, | ||
927 | ple); | ||
928 | GNUNET_PLUGIN_unload (ple->libname, NULL); | ||
929 | GNUNET_free (ple->libname); | ||
930 | GNUNET_free (ple); | ||
931 | } | ||
729 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n"); | 932 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n"); |
730 | kill_httpd (); | 933 | kill_httpd (); |
731 | GNUNET_free (allow_credentials); | 934 | GNUNET_free (allow_credentials); |
@@ -814,7 +1017,7 @@ static void | |||
814 | load_plugin (void *cls, const char *libname, void *lib_ret) | 1017 | load_plugin (void *cls, const char *libname, void *lib_ret) |
815 | { | 1018 | { |
816 | struct GNUNET_REST_Plugin *plugin = lib_ret; | 1019 | struct GNUNET_REST_Plugin *plugin = lib_ret; |
817 | struct GNUNET_HashCode key; | 1020 | struct PluginListEntry *ple; |
818 | 1021 | ||
819 | if (NULL == lib_ret) | 1022 | if (NULL == lib_ret) |
820 | { | 1023 | { |
@@ -825,18 +1028,12 @@ load_plugin (void *cls, const char *libname, void *lib_ret) | |||
825 | } | 1028 | } |
826 | GNUNET_assert (1 < strlen (plugin->name)); | 1029 | GNUNET_assert (1 < strlen (plugin->name)); |
827 | GNUNET_assert ('/' == *plugin->name); | 1030 | GNUNET_assert ('/' == *plugin->name); |
828 | GNUNET_CRYPTO_hash (plugin->name + 1, strlen (plugin->name + 1), &key); | 1031 | ple = GNUNET_new (struct PluginListEntry); |
829 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( | 1032 | ple->libname = GNUNET_strdup (libname); |
830 | plugin_map, | 1033 | ple->plugin = plugin; |
831 | &key, | 1034 | GNUNET_CONTAINER_DLL_insert (plugins_head, |
832 | plugin, | 1035 | plugins_tail, |
833 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | 1036 | ple); |
834 | { | ||
835 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
836 | "Could not load add plugin `%s'\n", | ||
837 | libname); | ||
838 | return; | ||
839 | } | ||
840 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname); | 1037 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname); |
841 | } | 1038 | } |
842 | 1039 | ||
@@ -858,8 +1055,8 @@ run (void *cls, | |||
858 | char *addr_str; | 1055 | char *addr_str; |
859 | 1056 | ||
860 | cfg = c; | 1057 | cfg = c; |
861 | plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | 1058 | plugins_head = NULL; |
862 | 1059 | plugins_tail = NULL; | |
863 | /* Get port to bind to */ | 1060 | /* Get port to bind to */ |
864 | if (GNUNET_OK != | 1061 | if (GNUNET_OK != |
865 | GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port)) | 1062 | GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port)) |
@@ -1004,6 +1201,12 @@ run (void *cls, | |||
1004 | NULL, | 1201 | NULL, |
1005 | MHD_OPTION_CONNECTION_TIMEOUT, | 1202 | MHD_OPTION_CONNECTION_TIMEOUT, |
1006 | (unsigned int) 16, | 1203 | (unsigned int) 16, |
1204 | MHD_OPTION_NOTIFY_CONNECTION, | ||
1205 | &mhd_connection_cb, | ||
1206 | NULL, | ||
1207 | MHD_OPTION_URI_LOG_CALLBACK, | ||
1208 | mhd_log_callback, | ||
1209 | NULL, | ||
1007 | MHD_OPTION_NOTIFY_COMPLETED, | 1210 | MHD_OPTION_NOTIFY_COMPLETED, |
1008 | &mhd_completed_cb, | 1211 | &mhd_completed_cb, |
1009 | NULL, | 1212 | NULL, |