diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_wire.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_wire.c | 135 |
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 | */ |
34 | static pthread_key_t wire_state; | 34 | static 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 | */ | ||
97 | int | 98 | int |
98 | TEH_WIRE_init () | 99 | TEH_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 | */ | ||
111 | void | 109 | void |
112 | TEH_WIRE_done () | 110 | TEH_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 | */ | ||
125 | static json_t * | ||
126 | make_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 | */ | ||
358 | MHD_RESULT | 371 | MHD_RESULT |
359 | TEH_handler_wire (const struct TEH_RequestHandler *rh, | 372 | TEH_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 | |||
379 | MHD_RESULT | ||
380 | TEH_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 | ||