error handling
[oweals/gnunet.git] / src / rest / plugin_rest_copying.c
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 \
34   "GNU Affero General Public License version 3 or later. See also: <http://www.gnu.org/licenses/>"
35
36 /**
37  * @brief struct returned by the initialization function of the plugin
38  */
39 struct Plugin
40 {
41   const struct GNUNET_CONFIGURATION_Handle *cfg;
42 };
43
44 const struct GNUNET_CONFIGURATION_Handle *cfg;
45
46 struct RequestHandle
47 {
48   /**
49    * Handle to rest request
50    */
51   struct GNUNET_REST_RequestHandle *rest_handle;
52
53   /**
54    * The plugin result processor
55    */
56   GNUNET_REST_ResultProcessor proc;
57
58   /**
59    * The closure of the result processor
60    */
61   void *proc_cls;
62
63   /**
64    * HTTP response code
65    */
66   int response_code;
67 };
68
69
70 /**
71  * Cleanup request handle.
72  *
73  * @param handle Handle to clean up
74  */
75 static void
76 cleanup_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  */
90 static void
91 do_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  */
107 static void
108 get_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  * Handle rest request
125  *
126  * @param handle the lookup handle
127  */
128 static void
129 options_cont (struct GNUNET_REST_RequestHandle *con_handle,
130               const char*url,
131               void *cls)
132 {
133   struct MHD_Response *resp;
134   struct RequestHandle *handle = cls;
135
136   resp = GNUNET_REST_create_response (NULL);
137   MHD_add_response_header (resp,
138                            "Access-Control-Allow-Methods",
139                            MHD_HTTP_METHOD_GET);
140   handle->proc (handle->proc_cls,
141                 resp,
142                 MHD_HTTP_OK);
143   cleanup_handle (handle);
144 }
145
146
147 /**
148  * Function processing the REST call
149  *
150  * @param method HTTP method
151  * @param url URL of the HTTP request
152  * @param data body of the HTTP request (optional)
153  * @param data_size length of the body
154  * @param proc callback function for the result
155  * @param proc_cls closure for @a proc
156  * @return #GNUNET_OK if request accepted
157  */
158 static void
159 rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
160                               GNUNET_REST_ResultProcessor proc,
161                               void *proc_cls)
162 {
163   static const struct GNUNET_REST_RequestHandler handlers[] = {
164     { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_COPYING, &get_cont },
165     { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_COPYING, &options_cont },
166     GNUNET_REST_HANDLER_END
167   };
168   struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
169   struct GNUNET_REST_RequestHandlerError err;
170
171   handle->proc_cls = proc_cls;
172   handle->proc = proc;
173   handle->rest_handle = conndata_handle;
174
175   if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle,
176                                                handlers,
177                                                &err,
178                                                handle))
179   {
180     handle->response_code = err.error_code;
181     GNUNET_SCHEDULER_add_now (&do_error, handle);
182   }
183 }
184
185
186 /**
187  * Entry point for the plugin.
188  *
189  * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
190  * @return NULL on error, otherwise the plugin context
191  */
192 void *
193 libgnunet_plugin_rest_copying_init (void *cls)
194 {
195   static struct Plugin plugin;
196
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  */
220 void *
221 libgnunet_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
234 /* end of plugin_rest_copying.c */