aboutsummaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd_wire.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-httpd_wire.c')
-rw-r--r--src/exchange/taler-exchange-httpd_wire.c135
1 files changed, 68 insertions, 67 deletions
diff --git a/src/exchange/taler-exchange-httpd_wire.c b/src/exchange/taler-exchange-httpd_wire.c
index 7e4418bdb..2617b574f 100644
--- a/src/exchange/taler-exchange-httpd_wire.c
+++ b/src/exchange/taler-exchange-httpd_wire.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of TALER 2 This file is part of TALER
3 Copyright (C) 2015-2020 Taler Systems SA 3 Copyright (C) 2015-2021 Taler Systems SA
4 4
5 TALER is free software; you can redistribute it and/or modify it under the 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 6 terms of the GNU Affero General Public License as published by the Free Software
@@ -33,6 +33,7 @@
33 */ 33 */
34static pthread_key_t wire_state; 34static pthread_key_t wire_state;
35 35
36
36/** 37/**
37 * Counter incremented whenever we have a reason to re-build the #wire_state 38 * Counter incremented whenever we have a reason to re-build the #wire_state
38 * because something external changed (in another thread). The counter is 39 * because something external changed (in another thread). The counter is
@@ -59,6 +60,11 @@ struct WireStateHandle
59 */ 60 */
60 uint64_t wire_generation; 61 uint64_t wire_generation;
61 62
63 /**
64 * HTTP status to return with this response.
65 */
66 unsigned int http_status;
67
62}; 68};
63 69
64 70
@@ -89,11 +95,6 @@ destroy_wire_state_cb (void *cls)
89} 95}
90 96
91 97
92/**
93 * Initialize WIRE submodule.
94 *
95 * @return #GNUNET_OK on success
96 */
97int 98int
98TEH_WIRE_init () 99TEH_WIRE_init ()
99{ 100{
@@ -105,9 +106,6 @@ TEH_WIRE_init ()
105} 106}
106 107
107 108
108/**
109 * Fully clean up our state.
110 */
111void 109void
112TEH_WIRE_done () 110TEH_WIRE_done ()
113{ 111{
@@ -117,6 +115,27 @@ TEH_WIRE_done ()
117 115
118 116
119/** 117/**
118 * Create standard JSON response format using
119 * @param ec and @a detail
120 *
121 * @param ec error code to return
122 * @param detail optional detail text to return, can be NULL
123 * @return JSON response
124 */
125static json_t *
126make_ec_reply (enum TALER_ErrorCode ec,
127 const char *detail)
128{
129 return GNUNET_JSON_PACK (
130 GNUNET_JSON_pack_uint64 ("code", ec),
131 GNUNET_JSON_pack_string ("hint",
132 TALER_ErrorCode_get_hint (ec)),
133 GNUNET_JSON_pack_allow_null (
134 GNUNET_JSON_pack_string ("detail", detail)));
135}
136
137
138/**
120 * Add information about a wire account to @a cls. 139 * Add information about a wire account to @a cls.
121 * 140 *
122 * @param cls a `json_t *` object to expand with wire account details 141 * @param cls a `json_t *` object to expand with wire account details
@@ -200,7 +219,10 @@ build_wire_state (void)
200 json_t *wire_fee_object; 219 json_t *wire_fee_object;
201 uint64_t wg = wire_generation; /* must be obtained FIRST */ 220 uint64_t wg = wire_generation; /* must be obtained FIRST */
202 enum GNUNET_DB_QueryStatus qs; 221 enum GNUNET_DB_QueryStatus qs;
222 struct WireStateHandle *wsh;
203 223
224 wsh = GNUNET_new (struct WireStateHandle);
225 wsh->wire_generation = wg;
204 wire_accounts_array = json_array (); 226 wire_accounts_array = json_array ();
205 GNUNET_assert (NULL != wire_accounts_array); 227 GNUNET_assert (NULL != wire_accounts_array);
206 qs = TEH_plugin->get_wire_accounts (TEH_plugin->cls, 228 qs = TEH_plugin->get_wire_accounts (TEH_plugin->cls,
@@ -210,14 +232,20 @@ build_wire_state (void)
210 { 232 {
211 GNUNET_break (0); 233 GNUNET_break (0);
212 json_decref (wire_accounts_array); 234 json_decref (wire_accounts_array);
213 return NULL; 235 wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
236 wsh->wire_reply
237 = make_ec_reply (TALER_EC_GENERIC_DB_FETCH_FAILED,
238 "get_wire_accounts");
239 return wsh;
214 } 240 }
215 if (0 == json_array_size (wire_accounts_array)) 241 if (0 == json_array_size (wire_accounts_array))
216 { 242 {
217 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
218 "No bank accounts for the exchange configured. Administrator must `enable-account` with taler-exchange-offline!\n");
219 json_decref (wire_accounts_array); 243 json_decref (wire_accounts_array);
220 return NULL; 244 wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
245 wsh->wire_reply
246 = make_ec_reply (TALER_EC_EXCHANGE_WIRE_NO_ACCOUNTS_CONFIGURED,
247 NULL);
248 return wsh;
221 } 249 }
222 wire_fee_object = json_object (); 250 wire_fee_object = json_object ();
223 GNUNET_assert (NULL != wire_fee_object); 251 GNUNET_assert (NULL != wire_fee_object);
@@ -234,12 +262,13 @@ build_wire_state (void)
234 wire_method = TALER_payto_get_method (payto_uri); 262 wire_method = TALER_payto_get_method (payto_uri);
235 if (NULL == wire_method) 263 if (NULL == wire_method)
236 { 264 {
237 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 265 wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
238 "payto:// URI `%s' stored in our database is malformed\n", 266 wsh->wire_reply
239 payto_uri); 267 = make_ec_reply (TALER_EC_EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED,
268 payto_uri);
240 json_decref (wire_accounts_array); 269 json_decref (wire_accounts_array);
241 json_decref (wire_fee_object); 270 json_decref (wire_fee_object);
242 return NULL; 271 return wsh;
243 } 272 }
244 if (NULL == json_object_get (wire_fee_object, 273 if (NULL == json_object_get (wire_fee_object,
245 wire_method)) 274 wire_method))
@@ -258,18 +287,23 @@ build_wire_state (void)
258 json_decref (wire_fee_object); 287 json_decref (wire_fee_object);
259 json_decref (wire_accounts_array); 288 json_decref (wire_accounts_array);
260 GNUNET_free (wire_method); 289 GNUNET_free (wire_method);
261 return NULL; 290 wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
291 wsh->wire_reply
292 = make_ec_reply (TALER_EC_GENERIC_DB_FETCH_FAILED,
293 "get_wire_fees");
294 return wsh;
262 } 295 }
263 if (0 == json_array_size (a)) 296 if (0 == json_array_size (a))
264 { 297 {
265 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
266 "No wire fees for `%s' configured. Administrator must set `wire-fee` with taler-exchange-offline!\n",
267 wire_method);
268 json_decref (a); 298 json_decref (a);
269 json_decref (wire_accounts_array); 299 json_decref (wire_accounts_array);
270 json_decref (wire_fee_object); 300 json_decref (wire_fee_object);
301 wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
302 wsh->wire_reply
303 = make_ec_reply (TALER_EC_EXCHANGE_WIRE_FEES_NOT_CONFIGURED,
304 wire_method);
271 GNUNET_free (wire_method); 305 GNUNET_free (wire_method);
272 return NULL; 306 return wsh;
273 } 307 }
274 GNUNET_assert (0 == 308 GNUNET_assert (0 ==
275 json_object_set_new (wire_fee_object, 309 json_object_set_new (wire_fee_object,
@@ -279,27 +313,15 @@ build_wire_state (void)
279 GNUNET_free (wire_method); 313 GNUNET_free (wire_method);
280 } 314 }
281 } 315 }
282 { 316 wsh->wire_reply = GNUNET_JSON_PACK (
283 json_t *wire_reply; 317 GNUNET_JSON_pack_array_steal ("accounts",
284 struct WireStateHandle *wsh; 318 wire_accounts_array),
285 319 GNUNET_JSON_pack_object_steal ("fees",
286 wire_reply = GNUNET_JSON_PACK ( 320 wire_fee_object),
287 GNUNET_JSON_pack_array_steal ("accounts", 321 GNUNET_JSON_pack_data_auto ("master_public_key",
288 wire_accounts_array), 322 &TEH_master_public_key));
289 GNUNET_JSON_pack_object_steal ("fees", 323 wsh->http_status = MHD_HTTP_OK;
290 wire_fee_object), 324 return wsh;
291 GNUNET_JSON_pack_data_auto ("master_public_key",
292 &TEH_master_public_key));
293 if (NULL == wire_reply)
294 {
295 GNUNET_break (0);
296 return NULL;
297 }
298 wsh = GNUNET_new (struct WireStateHandle);
299 wsh->wire_reply = wire_reply;
300 wsh->wire_generation = wg;
301 return wsh;
302 }
303} 325}
304 326
305 327
@@ -330,13 +352,12 @@ get_wire_state (void)
330 struct WireStateHandle *wsh; 352 struct WireStateHandle *wsh;
331 353
332 wsh = build_wire_state (); 354 wsh = build_wire_state ();
333 if (NULL == wsh)
334 return NULL;
335 if (0 != pthread_setspecific (wire_state, 355 if (0 != pthread_setspecific (wire_state,
336 wsh)) 356 wsh))
337 { 357 {
338 GNUNET_break (0); 358 GNUNET_break (0);
339 destroy_wire_state (wsh); 359 if (NULL != wsh)
360 destroy_wire_state (wsh);
340 return NULL; 361 return NULL;
341 } 362 }
342 if (NULL != old_wsh) 363 if (NULL != old_wsh)
@@ -347,14 +368,6 @@ get_wire_state (void)
347} 368}
348 369
349 370
350/**
351 * Handle a "/wire" request.
352 *
353 * @param rh context of the handler
354 * @param connection the MHD connection to handle
355 * @param args array of additional options (must be empty for this function)
356 * @return MHD result code
357 */
358MHD_RESULT 371MHD_RESULT
359TEH_handler_wire (const struct TEH_RequestHandler *rh, 372TEH_handler_wire (const struct TEH_RequestHandler *rh,
360 struct MHD_Connection *connection, 373 struct MHD_Connection *connection,
@@ -372,19 +385,7 @@ TEH_handler_wire (const struct TEH_RequestHandler *rh,
372 NULL); 385 NULL);
373 return TALER_MHD_reply_json (connection, 386 return TALER_MHD_reply_json (connection,
374 wsh->wire_reply, 387 wsh->wire_reply,
375 MHD_HTTP_OK); 388 wsh->http_status);
376}
377
378
379MHD_RESULT
380TEH_wire_management_get_wire_handler (const struct TEH_RequestHandler *rh,
381 struct MHD_Connection *connection)
382{
383 return TALER_MHD_REPLY_JSON_PACK (
384 connection,
385 MHD_HTTP_OK,
386 GNUNET_JSON_pack_string ("foo",
387 "bar"));
388} 389}
389 390
390 391