From 117b8006d628b03d6e5945338c2362720a7f0e94 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 12 Jan 2023 23:09:24 +0100 Subject: fix #7570 and #7571 --- src/backend/taler-merchant-httpd_exchanges.c | 16 ++++++ .../taler-merchant-httpd_private-post-reserves.c | 7 +++ src/merchant-tools/taler-merchant-setup-reserve.c | 66 +++++++++++++++++++++- 3 files changed, 88 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/backend/taler-merchant-httpd_exchanges.c b/src/backend/taler-merchant-httpd_exchanges.c index 7f6336c1..12c75ca4 100644 --- a/src/backend/taler-merchant-httpd_exchanges.c +++ b/src/backend/taler-merchant-httpd_exchanges.c @@ -238,6 +238,12 @@ struct Exchange */ bool trusted; + /** + * true if this exchange did return to use the + * response from /wire. + */ + bool have_wire; + }; @@ -627,6 +633,13 @@ process_find_operations (struct Exchange *exchange) .http_status = MHD_HTTP_OK, }; + if ( (NULL != fo->wire_method) && + (! exchange->have_wire) ) + { + /* We needed /wire, but didn't get it. That's not "200 OK". */ + hr.http_status = MHD_HTTP_BAD_GATEWAY; + hr.ec = TALER_EC_MERCHANT_GENERIC_EXCHANGE_WIRE_REQUEST_FAILED; + } fo->fc (fo->fc_cls, &hr, exchange->conn, @@ -676,6 +689,7 @@ handle_wire_data (void *cls, { struct TMH_EXCHANGES_FindOperation *fo; + exchange->have_wire = false; GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to obtain /wire details from `%s': %u/%d\n", exchange->url, @@ -710,6 +724,7 @@ handle_wire_data (void *cls, }; GNUNET_break_op (0); + exchange->have_wire = false; while (NULL != (fo = exchange->fo_head)) { fo->fc (fo->fc_cls, @@ -722,6 +737,7 @@ handle_wire_data (void *cls, } return; } + exchange->have_wire = true; if ( (process_find_operations (exchange)) && (NULL == exchange->wire_task) && (NULL == exchange->wire_request) ) diff --git a/src/backend/taler-merchant-httpd_private-post-reserves.c b/src/backend/taler-merchant-httpd_private-post-reserves.c index 0351ab10..82fc865f 100644 --- a/src/backend/taler-merchant-httpd_private-post-reserves.c +++ b/src/backend/taler-merchant-httpd_private-post-reserves.c @@ -247,6 +247,13 @@ handle_exchange (void *cls, 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; diff --git a/src/merchant-tools/taler-merchant-setup-reserve.c b/src/merchant-tools/taler-merchant-setup-reserve.c index cb43eaf5..1ed50530 100644 --- a/src/merchant-tools/taler-merchant-setup-reserve.c +++ b/src/merchant-tools/taler-merchant-setup-reserve.c @@ -24,6 +24,10 @@ #include #include "taler_merchant_service.h" +/** + * How often do we try before giving up? + */ +#define MAX_TRIES 30 /** * Return value from main(). @@ -96,6 +100,17 @@ static char *apikey; */ static char *keypass; +/** + * How often have we tried? + */ +static unsigned int tries; + +/** + * Task to do the main work. + */ +static struct GNUNET_SCHEDULER_Task *task; + + /** * Shutdown task (invoked when the process is being terminated) * @@ -104,6 +119,11 @@ static char *keypass; static void do_shutdown (void *cls) { + if (NULL != task) + { + GNUNET_SCHEDULER_cancel (task); + task = NULL; + } if (NULL != ctx) { GNUNET_CURL_fini (ctx); @@ -122,6 +142,15 @@ do_shutdown (void *cls) } +/** + * Function that makes the call to setup the reserve. + * + * @param cls NULL + */ +static void +do_request (void *cls); + + /** * Callbacks of this type are used to work the result of submitting a * POST /reserves request to a merchant @@ -161,6 +190,32 @@ result_cb (void *cls, res_str); } break; + case MHD_HTTP_CONFLICT: + fprintf (stderr, + "Conflict trying to setup reserve: %u/%d\nHint: %s\n", + hr->http_status, + (int) hr->ec, + hr->hint); + global_ret = 1; + break; + case MHD_HTTP_INTERNAL_SERVER_ERROR: + case MHD_HTTP_BAD_GATEWAY: + tries++; + if (tries < MAX_TRIES) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Merchant failed, will try again.\n"); + task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, + &do_request, + NULL); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Merchant failed too often (%u/%d), giving up\n", + hr->http_status, + hr->ec); + global_ret = 1; + break; default: fprintf (stderr, "Unexpected backend failure: %u/%d\nHint: %s\n", @@ -219,10 +274,19 @@ run (void *cls, } GNUNET_free (auth_header); } - /* setup termination logic */ GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); + task = GNUNET_SCHEDULER_add_now (&do_request, + NULL); +} + + +static void +do_request (void *cls) +{ + (void) cls; + task = NULL; /* run actual (async) operation */ prh = TALER_MERCHANT_reserves_post (ctx, merchant_base_url, -- cgit v1.2.3