668dc5d38ae3b160ac9c55572ec14de326be10bc
[oweals/gnunet.git] / src / rest-plugins / 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 /**
19  * @author Martin Schanzenbach
20  * @file gns/plugin_rest_copying.c
21  * @brief REST plugin that serves licensing information.
22  *
23  */
24
25 #include "platform.h"
26 #include "gnunet_rest_plugin.h"
27 #include <gnunet_rest_lib.h>
28
29 #define GNUNET_REST_API_NS_COPYING "/copying"
30
31 #define GNUNET_REST_COPYING_TEXT "GNU Affero General Public License version 3 or later. See also: <http://www.gnu.org/licenses/>"
32
33 /**
34  * @brief struct returned by the initialization function of the plugin
35  */
36 struct Plugin
37 {
38   const struct GNUNET_CONFIGURATION_Handle *cfg;
39 };
40
41 const struct GNUNET_CONFIGURATION_Handle *cfg;
42
43 struct RequestHandle
44 {
45   /**
46    * Handle to rest request
47    */
48   struct GNUNET_REST_RequestHandle *rest_handle;
49
50   /**
51    * The plugin result processor
52    */
53   GNUNET_REST_ResultProcessor proc;
54
55   /**
56    * The closure of the result processor
57    */
58   void *proc_cls;
59
60   /**
61    * HTTP response code
62    */
63   int response_code;
64
65 };
66
67
68 /**
69  * Cleanup request handle.
70  *
71  * @param handle Handle to clean up
72  */
73 static void
74 cleanup_handle (struct RequestHandle *handle)
75 {
76   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
77               "Cleaning up\n");
78   GNUNET_free (handle);
79 }
80
81
82 /**
83  * Task run on shutdown.  Cleans up everything.
84  *
85  * @param cls unused
86  * @param tc scheduler context
87  */
88 static void
89 do_error (void *cls)
90 {
91   struct RequestHandle *handle = cls;
92   struct MHD_Response *resp;
93
94   resp = GNUNET_REST_create_response (NULL);
95   handle->proc (handle->proc_cls, resp, handle->response_code);
96   cleanup_handle (handle);
97 }
98
99
100 /**
101  * Handle rest request
102  *
103  * @param handle the lookup handle
104  */
105 static void
106 get_cont (struct GNUNET_REST_RequestHandle *con_handle,
107               const char* url,
108               void *cls)
109 {
110   struct MHD_Response *resp;
111   struct RequestHandle *handle = cls;
112
113   resp = GNUNET_REST_create_response (GNUNET_REST_COPYING_TEXT);
114   handle->proc (handle->proc_cls,
115                 resp,
116                 MHD_HTTP_OK);
117   cleanup_handle (handle);
118 }
119
120
121
122 /**
123  * Handle rest request
124  *
125  * @param handle the lookup handle
126  */
127 static void
128 options_cont (struct GNUNET_REST_RequestHandle *con_handle,
129               const char* url,
130               void *cls)
131 {
132   struct MHD_Response *resp;
133   struct RequestHandle *handle = cls;
134
135   resp = GNUNET_REST_create_response (NULL);
136   MHD_add_response_header (resp,
137                            "Access-Control-Allow-Methods",
138                            MHD_HTTP_METHOD_GET);
139   handle->proc (handle->proc_cls,
140                 resp,
141                 MHD_HTTP_OK);
142   cleanup_handle (handle);
143 }
144
145
146 /**
147  * Function processing the REST call
148  *
149  * @param method HTTP method
150  * @param url URL of the HTTP request
151  * @param data body of the HTTP request (optional)
152  * @param data_size length of the body
153  * @param proc callback function for the result
154  * @param proc_cls closure for @a proc
155  * @return #GNUNET_OK if request accepted
156  */
157 static void
158 rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
159                               GNUNET_REST_ResultProcessor proc,
160                               void *proc_cls)
161 {
162   static const struct GNUNET_REST_RequestHandler handlers[] = {
163     {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_COPYING, &get_cont},
164     {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_COPYING, &options_cont},
165     GNUNET_REST_HANDLER_END
166   };
167   struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
168   struct GNUNET_REST_RequestHandlerError err;
169
170   handle->proc_cls = proc_cls;
171   handle->proc = proc;
172   handle->rest_handle = conndata_handle;
173
174   if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle,
175                                                handlers,
176                                                &err,
177                                                handle))
178   {
179     handle->response_code = err.error_code;
180     GNUNET_SCHEDULER_add_now (&do_error, handle);
181   }
182 }
183
184
185 /**
186  * Entry point for the plugin.
187  *
188  * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
189  * @return NULL on error, otherwise the plugin context
190  */
191 void *
192 libgnunet_plugin_rest_copying_init (void *cls)
193 {
194   static struct Plugin plugin;
195   cfg = cls;
196   struct GNUNET_REST_Plugin *api;
197
198   if (NULL != plugin.cfg)
199     return NULL;                /* can only initialize once! */
200   memset (&plugin, 0, sizeof (struct Plugin));
201   plugin.cfg = cfg;
202   api = GNUNET_new (struct GNUNET_REST_Plugin);
203   api->cls = &plugin;
204   api->name = GNUNET_REST_API_NS_COPYING;
205   api->process_request = &rest_copying_process_request;
206   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
207               _("COPYING REST API initialized\n"));
208   return api;
209 }
210
211
212 /**
213  * Exit point from the plugin.
214  *
215  * @param cls the plugin context (as returned by "init")
216  * @return always NULL
217  */
218 void *
219 libgnunet_plugin_rest_copying_done (void *cls)
220 {
221   struct GNUNET_REST_Plugin *api = cls;
222   struct Plugin *plugin = api->cls;
223
224   plugin->cfg = NULL;
225   GNUNET_free (api);
226   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
227               "COPYING REST plugin is finished\n");
228   return NULL;
229 }
230
231 /* end of plugin_rest_copying.c */