aboutsummaryrefslogtreecommitdiff
path: root/src/mint/taler-mint-httpd_mhd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mint/taler-mint-httpd_mhd.c')
-rw-r--r--src/mint/taler-mint-httpd_mhd.c300
1 files changed, 300 insertions, 0 deletions
diff --git a/src/mint/taler-mint-httpd_mhd.c b/src/mint/taler-mint-httpd_mhd.c
new file mode 100644
index 000000000..09f3025b8
--- /dev/null
+++ b/src/mint/taler-mint-httpd_mhd.c
@@ -0,0 +1,300 @@
1/*
2 This file is part of TALER
3 (C) 2014 GNUnet e.V.
4
5 TALER is free software; you can redistribute it and/or modify it under the
6 terms of the GNU Affero General Public License as published by the Free Software
7 Foundation; either version 3, or (at your option) any later version.
8
9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
12
13 You should have received a copy of the GNU Affero General Public License along with
14 TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
15*/
16
17/**
18 * @file taler-mint-httpd_mhd.c
19 * @brief helpers for MHD interaction
20 * @author Florian Dold
21 * @author Benedikt Mueller
22 * @author Christian Grothoff
23 */
24#include "platform.h"
25#include <gnunet/gnunet_util_lib.h>
26#include <jansson.h>
27#include <microhttpd.h>
28#include <libpq-fe.h>
29#include <pthread.h>
30#include "taler_microhttpd_lib.h"
31#include "taler-mint-httpd.h"
32#include "taler-mint-httpd_mhd.h"
33
34
35/**
36 * Function to call to handle the request by sending
37 * back static data from the @a rh.
38 *
39 * @param rh context of the handler
40 * @param connection the MHD connection to handle
41 * @param[IN|OUT] connection_cls the connection's closure (can be updated)
42 * @param upload_data upload data
43 * @param[IN|OUT] upload_data_size number of bytes (left) in @a upload_data
44 * @return MHD result code
45 */
46int
47TALER_MINT_handler_static_response (struct RequestHandler *rh,
48 struct MHD_Connection *connection,
49 void **connection_cls,
50 const char *upload_data,
51 size_t *upload_data_size)
52{
53 struct MHD_Response *response;
54 int ret;
55
56 if (0 == rh->data_size)
57 rh->data_size = strlen ((const char *) rh->data);
58 response = MHD_create_response_from_buffer (rh->data_size,
59 (void *) rh->data,
60 MHD_RESPMEM_PERSISTENT);
61 if (NULL == response)
62 {
63 GNUNET_break (0);
64 return MHD_NO;
65 }
66 if (NULL != rh->mime_type)
67 (void) MHD_add_response_header (response,
68 MHD_HTTP_HEADER_CONTENT_TYPE,
69 rh->mime_type);
70 ret = MHD_queue_response (connection,
71 rh->response_code,
72 response);
73 MHD_destroy_response (response);
74 return ret;
75}
76
77
78/**
79 * Function to call to handle the request by sending
80 * back a redirect to the AGPL source code.
81 *
82 * @param rh context of the handler
83 * @param connection the MHD connection to handle
84 * @param[IN|OUT] connection_cls the connection's closure (can be updated)
85 * @param upload_data upload data
86 * @param[IN|OUT] upload_data_size number of bytes (left) in @a upload_data
87 * @return MHD result code
88 */
89int
90TALER_MINT_handler_agpl_redirect (struct RequestHandler *rh,
91 struct MHD_Connection *connection,
92 void **connection_cls,
93 const char *upload_data,
94 size_t *upload_data_size)
95{
96 const char *agpl =
97 "This server is licensed under the Affero GPL. You will now be redirected to the source code.";
98 struct MHD_Response *response;
99 int ret;
100
101 response = MHD_create_response_from_buffer (strlen (agpl),
102 (void *) agpl,
103 MHD_RESPMEM_PERSISTENT);
104 if (NULL == response)
105 {
106 GNUNET_break (0);
107 return MHD_NO;
108 }
109 if (NULL != rh->mime_type)
110 (void) MHD_add_response_header (response,
111 MHD_HTTP_HEADER_CONTENT_TYPE,
112 rh->mime_type);
113 MHD_add_response_header (response,
114 MHD_HTTP_HEADER_LOCATION,
115 "http://www.git.taler.net/?p=mint.git");
116 ret = MHD_queue_response (connection,
117 rh->response_code,
118 response);
119 MHD_destroy_response (response);
120 return ret;
121}
122
123
124/**
125 * Function to call to handle the request by building a JSON
126 * reply from varargs.
127 *
128 * @param rh context of the handler
129 * @param connection the MHD connection to handle
130 * @param[IN|OUT] connection_cls the connection's closure (can be updated)
131 * @param response_code HTTP response code to use
132 * @param do_cache can the response be cached? (0: no, 1: yes)
133 * @param fmt format string for pack
134 * @param ... varargs
135 * @return MHD result code
136 */
137int
138TALER_MINT_helper_send_json_pack (struct RequestHandler *rh,
139 struct MHD_Connection *connection,
140 void *connection_cls,
141 int response_code,
142 int do_cache,
143 const char *fmt,
144 ...)
145{
146 int ret;
147 json_t *json;
148 va_list argp;
149 char *json_str;
150 struct MHD_Response *response;
151
152 va_start (argp, fmt);
153 json = json_vpack_ex (NULL, 0, fmt, argp);
154 va_end (argp);
155 if (NULL == json)
156 return MHD_NO;
157 json_str = json_dumps (json, JSON_INDENT(2));
158 json_decref (json);
159 if (NULL == json_str)
160 return MHD_NO;
161 response = MHD_create_response_from_buffer (strlen (json_str),
162 json_str,
163 MHD_RESPMEM_MUST_FREE);
164 if (NULL == response)
165 {
166 free (json_str);
167 return MHD_NO;
168 }
169 if (NULL != rh->mime_type)
170 (void) MHD_add_response_header (response,
171 MHD_HTTP_HEADER_CONTENT_TYPE,
172 rh->mime_type);
173 ret = MHD_queue_response (connection,
174 response_code,
175 response);
176 MHD_destroy_response (response);
177 return ret;
178}
179
180
181/**
182 * Function to call to handle the request by building a JSON
183 * reply with an error message from @a rh.
184 *
185 * @param rh context of the handler
186 * @param connection the MHD connection to handle
187 * @param[IN|OUT] connection_cls the connection's closure (can be updated)
188 * @param upload_data upload data
189 * @param[IN|OUT] upload_data_size number of bytes (left) in @a upload_data
190 * @return MHD result code
191 */
192int
193TALER_MINT_handler_send_json_pack_error (struct RequestHandler *rh,
194 struct MHD_Connection *connection,
195 void **connection_cls,
196 const char *upload_data,
197 size_t *upload_data_size)
198{
199 return TALER_MINT_helper_send_json_pack (rh,
200 connection,
201 connection_cls,
202 1, /* caching enabled */
203 rh->response_code,
204 "{s:s}",
205 "error",
206 rh->data);
207}
208
209
210/**
211 * Send a response for an invalid argument.
212 *
213 * @param connection the MHD connection to use
214 * @param param_name the parameter that is missing
215 * @return a GNUnet result code
216 */
217static int
218request_arg_invalid (struct MHD_Connection *connection,
219 const char *param_name)
220{
221 json_t *json;
222 json = json_pack ("{ s:s, s:s }",
223 "error", "invalid parameter",
224 "parameter", param_name);
225 if (MHD_YES != send_response_json (connection, json, MHD_HTTP_BAD_REQUEST))
226 {
227 GNUNET_break (0);
228 return GNUNET_SYSERR;
229 }
230 return GNUNET_NO;
231}
232
233
234/**
235 * Get a GET paramater that is a string,
236 * or send an error response if the parameter is missing.
237 *
238 * @param connection the connection to get the parameter from /
239 * send the error response to
240 * @param param_name the parameter name
241 * @param str pointer to store the parameter string,
242 * must be freed by the caller
243 * @return GNUNET_YES if the parameter is present and valid,
244 * GNUNET_NO if the parameter is missing
245 * GNUNET_SYSERR on internal error
246 */
247static int
248request_arg_require_string (struct MHD_Connection *connection,
249 const char *param_name,
250 const char **str)
251{
252 *str = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, param_name);
253 if (NULL == *str)
254 {
255 if (MHD_NO ==
256 request_send_json_pack (connection, MHD_HTTP_BAD_REQUEST,
257 "{ s:s, s:s }",
258 "error", "missing parameter",
259 "parameter", param_name))
260 return GNUNET_SYSERR;
261 return GNUNET_NO;
262 }
263 return GNUNET_OK;
264}
265
266
267/**
268 * Extraxt base32crockford encoded data from request.
269 *
270 * Queues an error response to the connection if the parameter is missing or
271 * invalid.
272 *
273 * @param connection the MHD connection
274 * @param param_name the name of the parameter with the key
275 * @param[out] out_data pointer to store the result
276 * @param out_size expected size of data
277 * @return
278 * GNUNET_YES if the the argument is present
279 * GNUNET_NO if the argument is absent or malformed
280 * GNUNET_SYSERR on internal error (error response could not be sent)
281 */
282int
283TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection,
284 const char *param_name,
285 void *out_data,
286 size_t out_size)
287{
288 const char *str;
289 int ret;
290
291 if (GNUNET_OK != (ret = request_arg_require_string (connection, param_name, &str)))
292 return ret;
293 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (str, strlen (str), out_data, out_size))
294 return request_arg_invalid (connection, param_name);
295 return GNUNET_OK;
296}
297
298
299
300/* end of taler-mint-httpd_mhd.c */