aboutsummaryrefslogtreecommitdiff
path: root/src/rest
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2015-03-11 17:39:32 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2015-03-11 17:39:32 +0000
commitb5cb8ce9b34d0f8cf2eb19cf82680aca365d157f (patch)
tree7db300f694ca75a5fcd5fc81bc59db30f67fb641 /src/rest
parent86882d3e761fe639e833446ccfef8d31e0e42998 (diff)
downloadgnunet-b5cb8ce9b34d0f8cf2eb19cf82680aca365d157f.tar.gz
gnunet-b5cb8ce9b34d0f8cf2eb19cf82680aca365d157f.zip
- fixes, intendation
Diffstat (limited to 'src/rest')
-rw-r--r--src/rest/gnunet-rest-server.c451
1 files changed, 220 insertions, 231 deletions
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c
index fa1e87a3a..26ca8f5cd 100644
--- a/src/rest/gnunet-rest-server.c
+++ b/src/rest/gnunet-rest-server.c
@@ -1,22 +1,22 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 Christian Grothoff (and other contributing authors) 3 Copyright (C) 2012-2015 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version. 8 option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19 */
20/** 20/**
21 * @author Martin Schanzenbach 21 * @author Martin Schanzenbach
22 * @file src/rest/gnunet-rest-server.c 22 * @file src/rest/gnunet-rest-server.c
@@ -119,15 +119,15 @@ struct GNUNET_CONTAINER_MultiHashMap *plugin_map;
119 */ 119 */
120struct MhdConnectionHandle 120struct MhdConnectionHandle
121{ 121{
122 struct MHD_Connection *con; 122 struct MHD_Connection *con;
123
124 struct MHD_Response *response;
125 123
126 struct GNUNET_REST_Plugin *plugin; 124 struct MHD_Response *response;
127 125
128 int status; 126 struct GNUNET_REST_Plugin *plugin;
129 127
130 int state; 128 int status;
129
130 int state;
131}; 131};
132 132
133/* ************************* Global helpers ********************* */ 133/* ************************* Global helpers ********************* */
@@ -146,8 +146,6 @@ do_httpd (void *cls,
146 146
147/** 147/**
148 * Run MHD now, we have extra data ready for the callback. 148 * Run MHD now, we have extra data ready for the callback.
149 *
150 * @param hd the daemon to run now.
151 */ 149 */
152static void 150static void
153run_mhd_now () 151run_mhd_now ()
@@ -156,7 +154,7 @@ run_mhd_now ()
156 httpd_task) 154 httpd_task)
157 GNUNET_SCHEDULER_cancel (httpd_task); 155 GNUNET_SCHEDULER_cancel (httpd_task);
158 httpd_task = GNUNET_SCHEDULER_add_now (&do_httpd, 156 httpd_task = GNUNET_SCHEDULER_add_now (&do_httpd,
159 NULL); 157 NULL);
160} 158}
161 159
162/** 160/**
@@ -173,14 +171,14 @@ plugin_callback (void *cls,
173 size_t len, 171 size_t len,
174 int status) 172 int status)
175{ 173{
176 struct MhdConnectionHandle *handle = cls; 174 struct MhdConnectionHandle *handle = cls;
177 struct MHD_Response *resp = MHD_create_response_from_buffer (len, 175 struct MHD_Response *resp = MHD_create_response_from_buffer (len,
178 (void*)data, 176 (void*)data,
179 MHD_RESPMEM_MUST_COPY); 177 MHD_RESPMEM_MUST_COPY);
180 (void) MHD_add_response_header (resp,MHD_HTTP_HEADER_CONTENT_TYPE,"application/json"); 178 (void) MHD_add_response_header (resp,MHD_HTTP_HEADER_CONTENT_TYPE,"application/json");
181 handle->status = status; 179 handle->status = status;
182 handle->response = resp; 180 handle->response = resp;
183 run_mhd_now(); 181 run_mhd_now();
184} 182}
185 183
186/* ********************************* MHD response generation ******************* */ 184/* ********************************* MHD response generation ******************* */
@@ -218,90 +216,90 @@ create_response (void *cls,
218 size_t *upload_data_size, 216 size_t *upload_data_size,
219 void **con_cls) 217 void **con_cls)
220{ 218{
221 char *plugin_name; 219 char *plugin_name;
222 struct GNUNET_HashCode key; 220 struct GNUNET_HashCode key;
223 struct MhdConnectionHandle *con_handle; 221 struct MhdConnectionHandle *con_handle;
224 222
225 con_handle = *con_cls; 223 con_handle = *con_cls;
226 224
227 if (NULL == *con_cls) 225 if (NULL == *con_cls)
226 {
227 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
228 "New connection %s\n", url);
229 char tmp_url[strlen(url)+1];
230 strcpy (tmp_url, url);
231 con_handle = GNUNET_new (struct MhdConnectionHandle);
232 con_handle->con = con;
233 con_handle->state = GN_REST_STATE_INIT;
234 *con_cls = con_handle;
235
236 plugin_name = strtok(tmp_url, "/");
237
238 if (NULL != plugin_name)
228 { 239 {
229 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 240 GNUNET_CRYPTO_hash (plugin_name, strlen (plugin_name), &key);
230 "New connection %s\n", url); 241
231 char tmp_url[strlen(url)+1]; 242 con_handle->plugin = GNUNET_CONTAINER_multihashmap_get (plugin_map,
232 strcpy (tmp_url, url); 243 &key);
233 con_handle = GNUNET_new (struct MhdConnectionHandle); 244 }
234 con_handle->con = con; 245 else
235 con_handle->state = GN_REST_STATE_INIT; 246 con_handle->plugin = NULL;
236 *con_cls = con_handle; 247
237 248 if (NULL == con_handle->plugin)
238 plugin_name = strtok(tmp_url, "/"); 249 {
239 250 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
240 if (NULL != plugin_name)
241 {
242 GNUNET_CRYPTO_hash (plugin_name, strlen (plugin_name), &key);
243
244 con_handle->plugin = GNUNET_CONTAINER_multihashmap_get (plugin_map,
245 &key);
246 }
247 else
248 con_handle->plugin = NULL;
249
250 if (NULL == con_handle->plugin)
251 {
252 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
253 "Queueing response with MHD\n"); 251 "Queueing response with MHD\n");
254 GNUNET_free (con_handle); 252 GNUNET_free (con_handle);
255 MHD_queue_response (con, 253 MHD_queue_response (con,
256 MHD_HTTP_INTERNAL_SERVER_ERROR, 254 MHD_HTTP_INTERNAL_SERVER_ERROR,
257 failure_response); 255 failure_response);
258 }
259 return MHD_YES;
260 } 256 }
261 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 257 return MHD_YES;
262 "Size %d\n", *upload_data_size); 258 }
263 if (GN_REST_STATE_INIT == con_handle->state) 259 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
260 "Size %d\n", *upload_data_size);
261 if (GN_REST_STATE_INIT == con_handle->state)
262 {
263 if (0 != *upload_data_size)
264 { 264 {
265 if (0 != *upload_data_size) 265 con_handle->state = GN_REST_STATE_UPLOAD;
266 { 266
267 con_handle->state = GN_REST_STATE_UPLOAD; 267 con_handle->plugin->process_request (meth,
268 268 url,
269 con_handle->plugin->process_request (meth, 269 upload_data,
270 url, 270 *upload_data_size,
271 upload_data, 271 &plugin_callback,
272 *upload_data_size, 272 con_handle);
273 &plugin_callback, 273 *upload_data_size = 0;
274 con_handle); 274
275 *upload_data_size = 0;
276
277 }
278 else
279 {
280 con_handle->state = GN_REST_STATE_RECV;
281 con_handle->plugin->process_request (meth,
282 url,
283 NULL,
284 0,
285 &plugin_callback,
286 con_handle);
287 }
288 } 275 }
289 if (NULL != con_handle->response) 276 else
290 { 277 {
278 con_handle->state = GN_REST_STATE_RECV;
279 con_handle->plugin->process_request (meth,
280 url,
281 NULL,
282 0,
283 &plugin_callback,
284 con_handle);
285 }
286 }
287 if (NULL != con_handle->response)
288 {
291 289
292GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
293 "Queueing response from plugin with MHD\n"); 291 "Queueing response from plugin with MHD\n");
294 if (GNUNET_OK == con_handle->status) { 292 if (GNUNET_OK == con_handle->status) {
295 return MHD_queue_response (con, 293 return MHD_queue_response (con,
296 MHD_HTTP_OK, 294 MHD_HTTP_OK,
297 con_handle->response); 295 con_handle->response);
298 } else { 296 } else {
299 return MHD_queue_response (con, 297 return MHD_queue_response (con,
300 MHD_HTTP_BAD_REQUEST, 298 MHD_HTTP_BAD_REQUEST,
301 con_handle->response); 299 con_handle->response);
302 }
303 } 300 }
304 return MHD_YES; 301 }
302 return MHD_YES;
305} 303}
306 304
307/* ******************** MHD HTTP setup and event loop ******************** */ 305/* ******************** MHD HTTP setup and event loop ******************** */
@@ -405,19 +403,19 @@ schedule_httpd ()
405 if (NULL != httpd_task) 403 if (NULL != httpd_task)
406 GNUNET_SCHEDULER_cancel (httpd_task); 404 GNUNET_SCHEDULER_cancel (httpd_task);
407 if ( (MHD_YES != haveto) && 405 if ( (MHD_YES != haveto) &&
408 (-1 == max)) 406 (-1 == max))
409 { 407 {
410 /* daemon is idle, kill after timeout */ 408 /* daemon is idle, kill after timeout */
411 httpd_task = GNUNET_SCHEDULER_add_delayed (MHD_CACHE_TIMEOUT, 409 httpd_task = GNUNET_SCHEDULER_add_delayed (MHD_CACHE_TIMEOUT,
412 &kill_httpd_task, 410 &kill_httpd_task,
413 NULL); 411 NULL);
414 } 412 }
415 else 413 else
416 { 414 {
417 httpd_task = 415 httpd_task =
418 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 416 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
419 tv, wrs, wws, 417 tv, wrs, wws,
420 &do_httpd, NULL); 418 &do_httpd, NULL);
421 } 419 }
422 if (NULL != wrs) 420 if (NULL != wrs)
423 GNUNET_NETWORK_fdset_destroy (wrs); 421 GNUNET_NETWORK_fdset_destroy (wrs);
@@ -484,10 +482,10 @@ do_accept (void *cls,
484 if (MHD_YES != MHD_add_connection (httpd, fd, addr, len)) 482 if (MHD_YES != MHD_add_connection (httpd, fd, addr, len))
485 { 483 {
486 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 484 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
487 _("Failed to pass client to MHD\n")); 485 _("Failed to pass client to MHD\n"));
488 return; 486 return;
489 } 487 }
490 488
491 schedule_httpd (); 489 schedule_httpd ();
492} 490}
493 491
@@ -588,31 +586,29 @@ load_plugin (void *cls,
588 const char *libname, 586 const char *libname,
589 void *lib_ret) 587 void *lib_ret)
590{ 588{
591 struct GNUNET_REST_Plugin *plugin = lib_ret; 589 struct GNUNET_REST_Plugin *plugin = lib_ret;
592 struct GNUNET_HashCode key; 590 struct GNUNET_HashCode key;
593 if (NULL == lib_ret) 591 if (NULL == lib_ret)
594 { 592 {
595 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 593 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
596 "Could not load plugin `%s'\n", 594 "Could not load plugin `%s'\n",
597 libname);
598 return;
599 }
600
601 GNUNET_CRYPTO_hash (plugin->name, strlen (plugin->name), &key);
602
603 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (plugin_map,
604 &key,
605 plugin,
606 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
607 {
608 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
609 "Could not load add plugin `%s'\n",
610 libname); 595 libname);
611 return; 596 return;
612 } 597 }
613 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 598 GNUNET_CRYPTO_hash (plugin->name, strlen (plugin->name), &key);
614 "Loaded plugin `%s'\n", 599 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (plugin_map,
600 &key,
601 plugin,
602 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
603 {
604 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
605 "Could not load add plugin `%s'\n",
615 libname); 606 libname);
607 return;
608 }
609 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
610 "Loaded plugin `%s'\n",
611 libname);
616} 612}
617 613
618/** 614/**
@@ -627,78 +623,72 @@ static void
627run (void *cls, char *const *args, const char *cfgfile, 623run (void *cls, char *const *args, const char *cfgfile,
628 const struct GNUNET_CONFIGURATION_Handle *c) 624 const struct GNUNET_CONFIGURATION_Handle *c)
629{ 625{
630 cfg = c; 626 cfg = c;
631 627 plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
632 plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); 628
633 629 /* Open listen socket proxy */
634 /* Load plugins */ 630 lsock6 = bind_v6 ();
635 GNUNET_PLUGIN_load_all ("libgnunet_plugin_rest", 631 if (NULL == lsock6)
636 (void *) cfg, 632 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
637 &load_plugin, 633 else
638 NULL); 634 {
639 635 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock6, 5))
640
641 /* Open listen socket proxy */
642 lsock6 = bind_v6 ();
643 if (NULL == lsock6)
644 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
645 else
646 { 636 {
647 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock6, 5)) 637 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
648 { 638 GNUNET_NETWORK_socket_close (lsock6);
649 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen"); 639 lsock6 = NULL;
650 GNUNET_NETWORK_socket_close (lsock6);
651 lsock6 = NULL;
652 }
653 else
654 {
655 ltask6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
656 lsock6, &do_accept, lsock6);
657 }
658 } 640 }
659 lsock4 = bind_v4 ();
660 if (NULL == lsock4)
661 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
662 else 641 else
663 { 642 {
664 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock4, 5)) 643 ltask6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
665 { 644 lsock6, &do_accept, lsock6);
666 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen"); 645 }
667 GNUNET_NETWORK_socket_close (lsock4); 646 }
668 lsock4 = NULL; 647 lsock4 = bind_v4 ();
669 } 648 if (NULL == lsock4)
670 else 649 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
671 { 650 else
672 ltask4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 651 {
673 lsock4, &do_accept, lsock4); 652 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock4, 5))
674 } 653 {
654 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
655 GNUNET_NETWORK_socket_close (lsock4);
656 lsock4 = NULL;
675 } 657 }
676 if ( (NULL == lsock4) && 658 else
677 (NULL == lsock6) )
678 { 659 {
679 GNUNET_SCHEDULER_shutdown (); 660 ltask4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
680 return; 661 lsock4, &do_accept, lsock4);
681 } 662 }
682 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 663 }
664 if ( (NULL == lsock4) &&
665 (NULL == lsock6) )
666 {
667 GNUNET_SCHEDULER_shutdown ();
668 return;
669 }
670 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
683 "Service listens on port %u\n", 671 "Service listens on port %u\n",
684 port); 672 port);
685 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET, 673 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET,
686 0, 674 0,
687 NULL, NULL, 675 NULL, NULL,
688 &create_response, NULL, 676 &create_response, NULL,
689 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, 677 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
690 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL, 678 MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL,
691 MHD_OPTION_END); 679 MHD_OPTION_END);
692 if (NULL == httpd) 680 if (NULL == httpd)
693 { 681 {
694 GNUNET_SCHEDULER_shutdown (); 682 GNUNET_SCHEDULER_shutdown ();
695 return; 683 return;
696 } 684 }
697 685 /* Load plugins */
698 686 GNUNET_PLUGIN_load_all ("libgnunet_plugin_rest",
699 687 (void *) cfg,
700 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 688 &load_plugin,
701 &do_shutdown, NULL); 689 NULL);
690 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
691 &do_shutdown, NULL);
702} 692}
703 693
704/** 694/**
@@ -713,34 +703,33 @@ run (void *cls, char *const *args, const char *cfgfile,
713int 703int
714main (int argc, char *const *argv) 704main (int argc, char *const *argv)
715{ 705{
716 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 706 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
717 {'p', "port", NULL, 707 {'p', "port", NULL,
718 gettext_noop ("listen on specified port (default: 7776)"), 1, 708 gettext_noop ("listen on specified port (default: 7776)"), 1,
719 &GNUNET_GETOPT_set_ulong, &port}, 709 &GNUNET_GETOPT_set_ulong, &port},
720 GNUNET_GETOPT_OPTION_END 710 GNUNET_GETOPT_OPTION_END
721 }; 711 };
722 static const char* err_page = 712 static const char* err_page =
723 "<html><head><title>gnunet-rest-service</title>" 713 "{}";
724 "</head><body>ERROR</body></html>"; 714 int ret;
725 int ret; 715
726 716 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
727 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 717 return 2;
728 return 2; 718 GNUNET_log_setup ("gnunet-rest-service", "WARNING", NULL);
729 GNUNET_log_setup ("gnunet-rest-service", "WARNING", NULL); 719 failure_response = MHD_create_response_from_buffer (strlen(err_page),
730 failure_response = MHD_create_response_from_buffer (strlen(err_page), 720 (void*)err_page,
731 (void*)err_page, 721 MHD_RESPMEM_PERSISTENT);
732 MHD_RESPMEM_PERSISTENT); 722 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
733 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 723 "Start\n");
734 "Start\n"); 724 ret =
735 ret = 725 (GNUNET_OK ==
736 (GNUNET_OK == 726 GNUNET_PROGRAM_run (argc, argv, "gnunet-rest-server",
737 GNUNET_PROGRAM_run (argc, argv, "gnunet-rest-service", 727 _("GNUnet REST server"),
738 _("GNUnet REST service"), 728 options,
739 options, 729 &run, NULL)) ? 0: 1;
740 &run, NULL)) ? 0: 1; 730 MHD_destroy_response (failure_response);
741 MHD_destroy_response (failure_response); 731 GNUNET_free_non_null ((char *) argv);
742 GNUNET_free_non_null ((char *) argv); 732 return ret;
743 return ret;
744} 733}
745 734
746/* end of gnunet-rest-service.c */ 735/* end of gnunet-rest-server.c */