diff options
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-post-reserves.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-reserves.c | 403 |
1 files changed, 0 insertions, 403 deletions
diff --git a/src/backend/taler-merchant-httpd_private-post-reserves.c b/src/backend/taler-merchant-httpd_private-post-reserves.c deleted file mode 100644 index 82fc865f..00000000 --- a/src/backend/taler-merchant-httpd_private-post-reserves.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - This file is part of TALER - (C) 2021, 2022 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation; either version 3, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with TALER; see the file COPYING. If not, - see <http://www.gnu.org/licenses/> -*/ - -/** - * @file taler-merchant-httpd_private-post-reserves.c - * @brief implementing POST /reserves request handling - * @author Christian Grothoff - */ -#include "platform.h" -#include "taler-merchant-httpd_exchanges.h" -#include "taler-merchant-httpd_private-post-reserves.h" -#include "taler-merchant-httpd_reserves.h" -#include <taler/taler_json_lib.h> - - -/** - * How long to wait before giving up processing with the exchange? - */ -#define EXCHANGE_GENERIC_TIMEOUT (GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_SECONDS, \ - 15)) - - -/** - * Information we keep for an individual call to the POST /reserves handler. - */ -struct PostReserveContext -{ - - /** - * Stored in a DLL. - */ - struct PostReserveContext *next; - - /** - * Stored in a DLL. - */ - struct PostReserveContext *prev; - - /** - * Array with @e coins_cnt coins we are despositing. - */ - struct DepositConfirmation *dc; - - /** - * MHD connection to return to - */ - struct MHD_Connection *connection; - - /** - * Details about the client's request. - */ - struct TMH_HandlerContext *hc; - - /** - * URL of the exchange. - */ - const char *exchange_url; - - /** - * URI of the exchange where the payment needs to be made to. - */ - char *payto_uri; - - /** - * Handle for contacting the exchange. - */ - struct TMH_EXCHANGES_FindOperation *fo; - - /** - * Task run on timeout. - */ - struct GNUNET_SCHEDULER_Task *timeout_task; - - /** - * Initial balance of the reserve. - */ - struct TALER_Amount initial_balance; - - /** - * When will the reserve expire. - */ - struct GNUNET_TIME_Timestamp reserve_expiration; - - /** - * Which HTTP status should we return? - */ - unsigned int http_status; - - /** - * Which error code should we return? - */ - enum TALER_ErrorCode ec; - - /** - * Did we suspend @a connection and are thus in - * the #rc_head DLL (#GNUNET_YES). Set to - * #GNUNET_NO if we are not suspended, and to - * #GNUNET_SYSERR if we should close the connection - * without a response due to shutdown. - */ - enum GNUNET_GenericReturnValue suspended; -}; - - -/** - * Stored in a DLL. - */ -static struct PostReserveContext *rc_head; - -/** - * Stored in a DLL. - */ -static struct PostReserveContext *rc_tail; - - -/** - * Force all post reserve contexts to be resumed as we are about - * to shut down MHD. - */ -void -TMH_force_rc_resume () -{ - struct PostReserveContext *rcn; - - for (struct PostReserveContext *rc = rc_head; - NULL != rc; - rc = rcn) - { - rcn = rc->next; - if (NULL != rc->timeout_task) - { - GNUNET_SCHEDULER_cancel (rc->timeout_task); - rc->timeout_task = NULL; - } - if (GNUNET_YES == rc->suspended) - { - rc->suspended = GNUNET_SYSERR; - MHD_resume_connection (rc->connection); - GNUNET_CONTAINER_DLL_remove (rc_head, - rc_tail, - rc); - } - if (NULL != rc->fo) - { - TMH_EXCHANGES_find_exchange_cancel (rc->fo); - rc->fo = NULL; - } - } -} - - -/** - * Custom cleanup routine for a `struct PostReserveContext`. - * - * @param cls the `struct PostReserveContext` to clean up. - */ -static void -reserve_context_cleanup (void *cls) -{ - struct PostReserveContext *rc = cls; - - if (NULL != rc->fo) - { - TMH_EXCHANGES_find_exchange_cancel (rc->fo); - rc->fo = NULL; - } - if (NULL != rc->timeout_task) - { - GNUNET_SCHEDULER_cancel (rc->timeout_task); - rc->timeout_task = NULL; - } - GNUNET_assert (GNUNET_YES != rc->suspended); - GNUNET_free (rc->payto_uri); - GNUNET_free (rc); -} - - -/** - * Function called with the result of a #TMH_EXCHANGES_find_exchange() - * operation. - * - * @param cls closure with our `struct PostReserveContext *` - * @param hr HTTP response details - * @param payto_uri URI of the exchange for the wire transfer, NULL on errors - * @param eh handle to the exchange context - * @param wire_fee current applicable wire fee for dealing with @a eh, NULL if not available - * @param exchange_trusted true if this exchange is trusted by config - */ -static void -handle_exchange (void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - struct TALER_EXCHANGE_Handle *eh, - const char *payto_uri, - const struct TALER_Amount *wire_fee, - bool exchange_trusted) -{ - struct PostReserveContext *rc = cls; - const struct TALER_EXCHANGE_Keys *keys; - - rc->fo = NULL; - if (NULL != rc->timeout_task) - { - GNUNET_SCHEDULER_cancel (rc->timeout_task); - rc->timeout_task = NULL; - } - rc->suspended = GNUNET_NO; - MHD_resume_connection (rc->connection); - GNUNET_CONTAINER_DLL_remove (rc_head, - rc_tail, - rc); - if (NULL == hr) - { - rc->ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_TIMEOUT; - rc->http_status = MHD_HTTP_GATEWAY_TIMEOUT; - TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ - return; - } - if (NULL == eh) - { - rc->ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_CONNECT_FAILURE; - rc->http_status = MHD_HTTP_BAD_GATEWAY; - TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ - return; - } - keys = TALER_EXCHANGE_get_keys (eh); - if (NULL == keys) - { - rc->ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_KEYS_FAILURE; - rc->http_status = MHD_HTTP_BAD_GATEWAY; - TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ - return; - } - if (MHD_HTTP_OK != hr->http_status) - { - rc->ec = hr->ec; - rc->http_status = hr->http_status; - TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ - return; - } - if (NULL == payto_uri) - { - rc->ec = TALER_EC_MERCHANT_PRIVATE_POST_RESERVES_UNSUPPORTED_WIRE_METHOD; - rc->http_status = MHD_HTTP_CONFLICT; - TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ - return; - } - rc->reserve_expiration - = GNUNET_TIME_relative_to_timestamp (keys->reserve_closing_delay); - rc->payto_uri = GNUNET_strdup (payto_uri); - TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ -} - - -/** - * Handle a timeout for the processing of the wire request. - * - * @param cls closure - */ -static void -handle_exchange_timeout (void *cls) -{ - struct PostReserveContext *rc = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Resuming POST /private/reserves with error after timeout\n"); - rc->timeout_task = NULL; - if (NULL != rc->fo) - { - TMH_EXCHANGES_find_exchange_cancel (rc->fo); - rc->fo = NULL; - } - rc->suspended = GNUNET_NO; - MHD_resume_connection (rc->connection); - GNUNET_CONTAINER_DLL_remove (rc_head, - rc_tail, - rc); - rc->ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_TIMEOUT; - rc->http_status = MHD_HTTP_GATEWAY_TIMEOUT; - TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */ -} - - -MHD_RESULT -TMH_private_post_reserves (const struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - struct TMH_HandlerContext *hc) -{ - struct PostReserveContext *rc = hc->ctx; - struct TMH_MerchantInstance *mi = hc->instance; - - GNUNET_assert (NULL != mi); - if (NULL == rc) - { - const char *wire_method; - - rc = GNUNET_new (struct PostReserveContext); - rc->connection = connection; - rc->hc = hc; - hc->ctx = rc; - hc->cc = &reserve_context_cleanup; - - { - enum GNUNET_GenericReturnValue res; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("exchange_url", - &rc->exchange_url), - GNUNET_JSON_spec_string ("wire_method", - &wire_method), - TALER_JSON_spec_amount ("initial_balance", - TMH_currency, - &rc->initial_balance), - GNUNET_JSON_spec_end () - }; - res = TALER_MHD_parse_json_data (connection, - hc->request_body, - spec); - if (GNUNET_OK != res) - return (GNUNET_NO == res) - ? MHD_YES - : MHD_NO; - } - rc->fo = TMH_EXCHANGES_find_exchange (rc->exchange_url, - wire_method, - GNUNET_NO, - &handle_exchange, - rc); - rc->timeout_task - = GNUNET_SCHEDULER_add_delayed (EXCHANGE_GENERIC_TIMEOUT, - &handle_exchange_timeout, - rc); - rc->suspended = GNUNET_YES; - GNUNET_CONTAINER_DLL_insert (rc_head, - rc_tail, - rc); - MHD_suspend_connection (connection); - return MHD_YES; - } - if (GNUNET_SYSERR == rc->suspended) - return MHD_NO; /* we are in shutdown */ - - GNUNET_assert (GNUNET_NO == rc->suspended); - if (NULL == rc->payto_uri) - { - return TALER_MHD_reply_with_error (connection, - rc->http_status, - rc->ec, - NULL); - } - { - struct TALER_ReservePublicKeyP reserve_pub; - struct TALER_ReservePrivateKeyP reserve_priv; - enum GNUNET_DB_QueryStatus qs; - - GNUNET_CRYPTO_eddsa_key_create (&reserve_priv.eddsa_priv); - GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv.eddsa_priv, - &reserve_pub.eddsa_pub); - qs = TMH_db->insert_reserve (TMH_db->cls, - mi->settings.id, - &reserve_priv, - &reserve_pub, - rc->exchange_url, - rc->payto_uri, - &rc->initial_balance, - rc->reserve_expiration); - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); - TMH_RESERVES_check (mi->settings.id, - rc->exchange_url, - &reserve_pub, - &rc->initial_balance); - if (qs < 0) - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_STORE_FAILED, - "reserve"); - return TALER_MHD_REPLY_JSON_PACK ( - connection, - MHD_HTTP_OK, - GNUNET_JSON_pack_data_auto ("reserve_pub", - &reserve_pub), - GNUNET_JSON_pack_string ("payto_uri", - rc->payto_uri)); - } -} - - -/* end of taler-merchant-httpd_private-post-reserves.c */ |