aboutsummaryrefslogtreecommitdiff
path: root/src/rest
diff options
context:
space:
mode:
Diffstat (limited to 'src/rest')
-rw-r--r--src/rest/Makefile.am15
-rw-r--r--src/rest/gnunet-rest-server.c63
-rw-r--r--src/rest/plugin_rest_copying.c233
-rw-r--r--src/rest/rest.conf2
4 files changed, 310 insertions, 3 deletions
diff --git a/src/rest/Makefile.am b/src/rest/Makefile.am
index 6c23ad2a6..acb95140b 100644
--- a/src/rest/Makefile.am
+++ b/src/rest/Makefile.am
@@ -20,14 +20,27 @@ if USE_COVERAGE
20endif 20endif
21 21
22lib_LTLIBRARIES = \ 22lib_LTLIBRARIES = \
23 libgnunetrest.la 23 libgnunetrest.la
24 24
25libexec_PROGRAMS = \ 25libexec_PROGRAMS = \
26 gnunet-rest-server 26 gnunet-rest-server
27 27
28plugin_LTLIBRARIES = libgnunet_plugin_rest_copying.la
29
28EXTRA_DIST = \ 30EXTRA_DIST = \
29 rest.conf 31 rest.conf
30 32
33libgnunet_plugin_rest_copying_la_SOURCES = \
34 plugin_rest_copying.c
35libgnunet_plugin_rest_copying_la_LIBADD = \
36 libgnunetrest.la \
37 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
38 $(LTLIBINTL) -lmicrohttpd
39libgnunet_plugin_rest_copying_la_LDFLAGS = \
40 $(GN_PLUGIN_LDFLAGS)
41
42
43
31gnunet_rest_server_SOURCES = \ 44gnunet_rest_server_SOURCES = \
32 gnunet-rest-server.c 45 gnunet-rest-server.c
33 46
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c
index 77f3d898d..3cbb750ba 100644
--- a/src/rest/gnunet-rest-server.c
+++ b/src/rest/gnunet-rest-server.c
@@ -64,6 +64,16 @@
64static struct GNUNET_SCHEDULER_Task *httpd_task; 64static struct GNUNET_SCHEDULER_Task *httpd_task;
65 65
66/** 66/**
67 * The address to bind to
68 */
69static in_addr_t address;
70
71/**
72 * The IPv6 address to bind to
73 */
74static struct in6_addr address6;
75
76/**
67 * The port the service is running on (default 7776) 77 * The port the service is running on (default 7776)
68 */ 78 */
69static unsigned long long port = GNUNET_REST_SERVICE_PORT; 79static unsigned long long port = GNUNET_REST_SERVICE_PORT;
@@ -406,11 +416,11 @@ create_response (void *cls,
406 con_handle->data_handle = rest_conndata_handle; 416 con_handle->data_handle = rest_conndata_handle;
407 MHD_get_connection_values (con, 417 MHD_get_connection_values (con,
408 MHD_GET_ARGUMENT_KIND, 418 MHD_GET_ARGUMENT_KIND,
409 &url_iterator, 419 (MHD_KeyValueIterator) &url_iterator,
410 rest_conndata_handle); 420 rest_conndata_handle);
411 MHD_get_connection_values (con, 421 MHD_get_connection_values (con,
412 MHD_HEADER_KIND, 422 MHD_HEADER_KIND,
413 &header_iterator, 423 (MHD_KeyValueIterator) &header_iterator,
414 rest_conndata_handle); 424 rest_conndata_handle);
415 con_handle->pp = MHD_create_post_processor(con, 425 con_handle->pp = MHD_create_post_processor(con,
416 65536, 426 65536,
@@ -695,6 +705,7 @@ bind_v4 ()
695 memset (&sa4, 0, sizeof (sa4)); 705 memset (&sa4, 0, sizeof (sa4));
696 sa4.sin_family = AF_INET; 706 sa4.sin_family = AF_INET;
697 sa4.sin_port = htons (port); 707 sa4.sin_port = htons (port);
708 sa4.sin_addr.s_addr = address;
698#if HAVE_SOCKADDR_IN_SIN_LEN 709#if HAVE_SOCKADDR_IN_SIN_LEN
699 sa4.sin_len = sizeof (sa4); 710 sa4.sin_len = sizeof (sa4);
700#endif 711#endif
@@ -731,6 +742,7 @@ bind_v6 ()
731 memset (&sa6, 0, sizeof (sa6)); 742 memset (&sa6, 0, sizeof (sa6));
732 sa6.sin6_family = AF_INET6; 743 sa6.sin6_family = AF_INET6;
733 sa6.sin6_port = htons (port); 744 sa6.sin6_port = htons (port);
745 sa6.sin6_addr = address6;
734#if HAVE_SOCKADDR_IN_SIN_LEN 746#if HAVE_SOCKADDR_IN_SIN_LEN
735 sa6.sin6_len = sizeof (sa6); 747 sa6.sin6_len = sizeof (sa6);
736#endif 748#endif
@@ -806,9 +818,56 @@ run (void *cls,
806 const char *cfgfile, 818 const char *cfgfile,
807 const struct GNUNET_CONFIGURATION_Handle *c) 819 const struct GNUNET_CONFIGURATION_Handle *c)
808{ 820{
821 char* addr_str;
809 cfg = c; 822 cfg = c;
810 plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); 823 plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
811 824
825 /* Get address to bind to */
826 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "rest",
827 "BIND_TO",
828 &addr_str))
829 {
830 //No address specified
831 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
832 "Don't know what to bind to...\n");
833 GNUNET_free (addr_str);
834 GNUNET_SCHEDULER_shutdown ();
835 return;
836 }
837 if (1 != inet_pton (AF_INET, addr_str, &address))
838 {
839 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
840 "Unable to parse address %s\n",
841 addr_str);
842 GNUNET_free (addr_str);
843 GNUNET_SCHEDULER_shutdown ();
844 return;
845 }
846 GNUNET_free (addr_str);
847 /* Get address to bind to */
848 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "rest",
849 "BIND_TO6",
850 &addr_str))
851 {
852 //No address specified
853 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
854 "Don't know what to bind6 to...\n");
855 GNUNET_free (addr_str);
856 GNUNET_SCHEDULER_shutdown ();
857 return;
858 }
859 if (1 != inet_pton (AF_INET6, addr_str, &address6))
860 {
861 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
862 "Unable to parse IPv6 address %s\n",
863 addr_str);
864 GNUNET_free (addr_str);
865 GNUNET_SCHEDULER_shutdown ();
866 return;
867 }
868 GNUNET_free (addr_str);
869
870
812 /* Get CORS data from cfg */ 871 /* Get CORS data from cfg */
813 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "rest", 872 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "rest",
814 "REST_ALLOW_ORIGIN", 873 "REST_ALLOW_ORIGIN",
diff --git a/src/rest/plugin_rest_copying.c b/src/rest/plugin_rest_copying.c
new file mode 100644
index 000000000..92c2c6601
--- /dev/null
+++ b/src/rest/plugin_rest_copying.c
@@ -0,0 +1,233 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @author Martin Schanzenbach
22 * @file gns/plugin_rest_copying.c
23 * @brief REST plugin that serves licensing information.
24 *
25 */
26
27#include "platform.h"
28#include "gnunet_rest_plugin.h"
29#include <gnunet_rest_lib.h>
30
31#define GNUNET_REST_API_NS_COPYING "/copying"
32
33#define GNUNET_REST_COPYING_TEXT "GNU Affero General Public License version 3 or later. See also: <http://www.gnu.org/licenses/>"
34
35/**
36 * @brief struct returned by the initialization function of the plugin
37 */
38struct Plugin
39{
40 const struct GNUNET_CONFIGURATION_Handle *cfg;
41};
42
43const struct GNUNET_CONFIGURATION_Handle *cfg;
44
45struct RequestHandle
46{
47 /**
48 * Handle to rest request
49 */
50 struct GNUNET_REST_RequestHandle *rest_handle;
51
52 /**
53 * The plugin result processor
54 */
55 GNUNET_REST_ResultProcessor proc;
56
57 /**
58 * The closure of the result processor
59 */
60 void *proc_cls;
61
62 /**
63 * HTTP response code
64 */
65 int response_code;
66
67};
68
69
70/**
71 * Cleanup request handle.
72 *
73 * @param handle Handle to clean up
74 */
75static void
76cleanup_handle (struct RequestHandle *handle)
77{
78 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
79 "Cleaning up\n");
80 GNUNET_free (handle);
81}
82
83
84/**
85 * Task run on shutdown. Cleans up everything.
86 *
87 * @param cls unused
88 * @param tc scheduler context
89 */
90static void
91do_error (void *cls)
92{
93 struct RequestHandle *handle = cls;
94 struct MHD_Response *resp;
95
96 resp = GNUNET_REST_create_response (NULL);
97 handle->proc (handle->proc_cls, resp, handle->response_code);
98 cleanup_handle (handle);
99}
100
101
102/**
103 * Handle rest request
104 *
105 * @param handle the lookup handle
106 */
107static void
108get_cont (struct GNUNET_REST_RequestHandle *con_handle,
109 const char* url,
110 void *cls)
111{
112 struct MHD_Response *resp;
113 struct RequestHandle *handle = cls;
114
115 resp = GNUNET_REST_create_response (GNUNET_REST_COPYING_TEXT);
116 handle->proc (handle->proc_cls,
117 resp,
118 MHD_HTTP_OK);
119 cleanup_handle (handle);
120}
121
122
123
124/**
125 * Handle rest request
126 *
127 * @param handle the lookup handle
128 */
129static void
130options_cont (struct GNUNET_REST_RequestHandle *con_handle,
131 const char* url,
132 void *cls)
133{
134 struct MHD_Response *resp;
135 struct RequestHandle *handle = cls;
136
137 resp = GNUNET_REST_create_response (NULL);
138 MHD_add_response_header (resp,
139 "Access-Control-Allow-Methods",
140 MHD_HTTP_METHOD_GET);
141 handle->proc (handle->proc_cls,
142 resp,
143 MHD_HTTP_OK);
144 cleanup_handle (handle);
145}
146
147
148/**
149 * Function processing the REST call
150 *
151 * @param method HTTP method
152 * @param url URL of the HTTP request
153 * @param data body of the HTTP request (optional)
154 * @param data_size length of the body
155 * @param proc callback function for the result
156 * @param proc_cls closure for @a proc
157 * @return #GNUNET_OK if request accepted
158 */
159static void
160rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
161 GNUNET_REST_ResultProcessor proc,
162 void *proc_cls)
163{
164 static const struct GNUNET_REST_RequestHandler handlers[] = {
165 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_COPYING, &get_cont},
166 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_COPYING, &options_cont},
167 GNUNET_REST_HANDLER_END
168 };
169 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
170 struct GNUNET_REST_RequestHandlerError err;
171
172 handle->proc_cls = proc_cls;
173 handle->proc = proc;
174 handle->rest_handle = conndata_handle;
175
176 if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle,
177 handlers,
178 &err,
179 handle))
180 {
181 handle->response_code = err.error_code;
182 GNUNET_SCHEDULER_add_now (&do_error, handle);
183 }
184}
185
186
187/**
188 * Entry point for the plugin.
189 *
190 * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
191 * @return NULL on error, otherwise the plugin context
192 */
193void *
194libgnunet_plugin_rest_copying_init (void *cls)
195{
196 static struct Plugin plugin;
197 cfg = cls;
198 struct GNUNET_REST_Plugin *api;
199
200 if (NULL != plugin.cfg)
201 return NULL; /* can only initialize once! */
202 memset (&plugin, 0, sizeof (struct Plugin));
203 plugin.cfg = cfg;
204 api = GNUNET_new (struct GNUNET_REST_Plugin);
205 api->cls = &plugin;
206 api->name = GNUNET_REST_API_NS_COPYING;
207 api->process_request = &rest_copying_process_request;
208 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
209 _("COPYING REST API initialized\n"));
210 return api;
211}
212
213
214/**
215 * Exit point from the plugin.
216 *
217 * @param cls the plugin context (as returned by "init")
218 * @return always NULL
219 */
220void *
221libgnunet_plugin_rest_copying_done (void *cls)
222{
223 struct GNUNET_REST_Plugin *api = cls;
224 struct Plugin *plugin = api->cls;
225
226 plugin->cfg = NULL;
227 GNUNET_free (api);
228 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
229 "COPYING REST plugin is finished\n");
230 return NULL;
231}
232
233/* end of plugin_rest_copying.c */
diff --git a/src/rest/rest.conf b/src/rest/rest.conf
index 138751696..bef8cf473 100644
--- a/src/rest/rest.conf
+++ b/src/rest/rest.conf
@@ -1,6 +1,8 @@
1[rest] 1[rest]
2UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-rest.sock 2UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-rest.sock
3BINARY=gnunet-rest-server 3BINARY=gnunet-rest-server
4BIND_TO=127.0.0.1
5BIND_TO6=::1
4REST_PORT=7776 6REST_PORT=7776
5REST_ALLOW_HEADERS=Authorization,Accept,Content-Type 7REST_ALLOW_HEADERS=Authorization,Accept,Content-Type
6REST_ALLOW_ORIGIN=* 8REST_ALLOW_ORIGIN=*