[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant] branch master updated (27f71ff3 -> 12c8aeb6)
From: |
gnunet |
Subject: |
[taler-merchant] branch master updated (27f71ff3 -> 12c8aeb6) |
Date: |
Tue, 01 Oct 2024 14:05:45 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a change to branch master
in repository merchant.
from 27f71ff3 fix #9219
new a5694e74 skip tests if curl/jq are not found
new 1e2a6651 support 451 response in client API
new 12c8aeb6 fix #9197: wait at most 250ms for /keys from exchanges before
giving up
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../taler-merchant-httpd_private-post-orders.c | 71 ++++++++++++++++++++++
src/include/taler_merchant_service.h | 15 +++++
src/lib/merchant_api_post_order_pay.c | 46 ++++++++++++++
src/testing/setup.sh | 6 ++
4 files changed, 138 insertions(+)
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c
b/src/backend/taler-merchant-httpd_private-post-orders.c
index 7053ac70..c1583791 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -68,6 +68,14 @@
*/
#define STANDARD_LABEL_MERCHANT_ADDRESS "_ma"
+/**
+ * How long do we wait at most for /keys from the exchange(s)?
+ * Ensures that we do not block forever just because some exchange
+ * fails to respond *or* because our taler-merchant-keyscheck
+ * refuses a forced download.
+ */
+#define MAX_KEYS_WAIT \
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250)
/**
* Generate the base URL for the given merchant instance.
@@ -449,6 +457,17 @@ struct OrderContext
* order creation requests exceeds legal limits.
*/
struct TALER_Amount total_exchange_limit;
+
+ /**
+ * How long do we wait at most until giving up on getting keys?
+ */
+ struct GNUNET_TIME_Absolute keys_timeout;
+
+ /**
+ * Task to wake us up on @e keys_timeout.
+ */
+ struct GNUNET_SCHEDULER_Task *wakeup_task;
+
} set_exchanges;
/**
@@ -664,6 +683,11 @@ clean_order (void *cls)
GNUNET_free (rx->url);
GNUNET_free (rx);
}
+ if (NULL != oc->set_exchanges.wakeup_task)
+ {
+ GNUNET_SCHEDULER_cancel (oc->set_exchanges.wakeup_task);
+ oc->set_exchanges.wakeup_task = NULL;
+ }
if (NULL != oc->set_exchanges.exchanges)
{
json_decref (oc->set_exchanges.exchanges);
@@ -2104,6 +2128,28 @@ notify_kyc_required (const struct OrderContext *oc)
}
+/**
+ * Task run when we are timing out on /keys and will just
+ * proceed with what we got.
+ *
+ * @param cls our `struct OrderContext *` to resume
+ */
+static void
+wakeup_timeout (void *cls)
+{
+ struct OrderContext *oc = cls;
+
+ oc->set_exchanges.wakeup_task = NULL;
+ GNUNET_assert (GNUNET_YES == oc->suspended);
+ GNUNET_CONTAINER_DLL_remove (oc_head,
+ oc_tail,
+ oc);
+ MHD_resume_connection (oc->connection);
+ oc->suspended = GNUNET_NO;
+ TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */
+}
+
+
/**
* Set list of acceptable exchanges in @a oc. Upon success, continue
* processing with set_max_fee().
@@ -2114,6 +2160,11 @@ notify_kyc_required (const struct OrderContext *oc)
static bool
set_exchanges (struct OrderContext *oc)
{
+ if (NULL != oc->set_exchanges.wakeup_task)
+ {
+ GNUNET_SCHEDULER_cancel (oc->set_exchanges.wakeup_task);
+ oc->set_exchanges.wakeup_task = NULL;
+ }
if (TALER_amount_is_zero (&oc->parse_order.brutto))
{
/* Total amount is zero, so we don't actually need exchanges! */
@@ -2127,6 +2178,8 @@ set_exchanges (struct OrderContext *oc)
matter. */
if (NULL == oc->set_exchanges.exchanges)
{
+ oc->set_exchanges.keys_timeout
+ = GNUNET_TIME_relative_to_absolute (MAX_KEYS_WAIT);
oc->set_exchanges.exchanges = json_array ();
GNUNET_assert (NULL != oc->set_exchanges.exchanges);
GNUNET_assert (
@@ -2147,11 +2200,29 @@ set_exchanges (struct OrderContext *oc)
oc);
}
}
+ if (GNUNET_TIME_absolute_is_past (oc->set_exchanges.keys_timeout))
+ {
+ struct RekeyExchange *rx;
+
+ while (NULL != (rx = oc->set_exchanges.pending_reload_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (oc->set_exchanges.pending_reload_head,
+ oc->set_exchanges.pending_reload_tail,
+ rx);
+ TMH_EXCHANGES_keys4exchange_cancel (rx->fo);
+ GNUNET_free (rx->url);
+ GNUNET_free (rx);
+ }
+ }
if (NULL != oc->set_exchanges.pending_reload_head)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Still trying to (re)load %skeys\n",
oc->set_exchanges.pending_reload_head->url);
+ oc->set_exchanges.wakeup_task
+ = GNUNET_SCHEDULER_add_at (oc->set_exchanges.keys_timeout,
+ &wakeup_timeout,
+ oc);
MHD_suspend_connection (oc->connection);
oc->suspended = GNUNET_YES;
GNUNET_CONTAINER_DLL_insert (oc_head,
diff --git a/src/include/taler_merchant_service.h
b/src/include/taler_merchant_service.h
index 05ea273b..0ad7dc75 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -3239,6 +3239,21 @@ struct TALER_MERCHANT_PayResponse
// TODO: might want to return further details on errors,
// especially refund signatures on double-pay conflict.
+ struct
+ {
+
+ /**
+ * Array of exchange URLs which had legal problems.
+ */
+ const char **exchanges;
+
+ /**
+ * Length of the @e exchanges array.
+ */
+ unsigned int num_exchanges;
+
+ } unavailable_for_legal_reasons;
+
} details;
};
diff --git a/src/lib/merchant_api_post_order_pay.c
b/src/lib/merchant_api_post_order_pay.c
index 14eebd28..d10fc6d7 100644
--- a/src/lib/merchant_api_post_order_pay.c
+++ b/src/lib/merchant_api_post_order_pay.c
@@ -322,6 +322,52 @@ handle_pay_finished (void *cls,
of some disagreement on the PKI). We should pass the JSON reply to the
application */
break;
+ case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
+ {
+ json_t *ebus = json_object_get (json,
+ "exchange_base_urls");
+ if (NULL == ebus)
+ {
+ GNUNET_break_op (0);
+ pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ pr.hr.http_status = 0;
+ pr.hr.hint = "failed to parse exchange_base_urls field in response";
+ break;
+ }
+ {
+ size_t alen = json_array_size (ebus);
+ const char *ebua[GNUNET_NZL (alen)];
+ size_t idx;
+ json_t *jebu;
+ bool ok = true;
+
+ GNUNET_assert (alen <= UINT_MAX);
+ json_array_foreach (ebus, idx, jebu)
+ {
+ ebua[idx] = json_string_value (jebu);
+ if (NULL == ebua[idx])
+ {
+ GNUNET_break_op (0);
+ pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ pr.hr.http_status = 0;
+ pr.hr.hint = "non-string value in exchange_base_urls in response";
+ ok = false;
+ break;
+ }
+ }
+ if (! ok)
+ break;
+ pr.details.unavailable_for_legal_reasons.num_exchanges
+ = (unsigned int) alen;
+ pr.details.unavailable_for_legal_reasons.exchanges
+ = ebua;
+ oph->pay_cb (oph->pay_cb_cls,
+ &pr);
+ TALER_MERCHANT_order_pay_cancel (oph);
+ return;
+ }
+ }
+ break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
TALER_MERCHANT_parse_error_details_ (json,
response_code,
diff --git a/src/testing/setup.sh b/src/testing/setup.sh
index 80933149..6aff2599 100755
--- a/src/testing/setup.sh
+++ b/src/testing/setup.sh
@@ -65,3 +65,9 @@ function get_payto_uri() {
libeufin-bank create-account -u "$1" -p "$2" --name "$1" 2> /dev/null
}
+echo -n "Checking for curl ..."
+curl --version 2> /dev/null > /dev/null || exit_skip " no curl"
+echo " OK"
+echo -n "Checking for jq ..."
+jq --version 2> /dev/null > /dev/null || exit_skip " no jq"
+echo " OK"
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-merchant] branch master updated (27f71ff3 -> 12c8aeb6),
gnunet <=