summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_private-post-orders.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-post-orders.c')
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders.c94
1 files changed, 80 insertions, 14 deletions
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c
index 61051b9a..09c709e9 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -39,6 +39,11 @@
#define MAX_RETRIES 3
/**
+ * How long do we wait for /keys from the exchange?
+ */
+#define KEYS_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2)
+
+/**
* What is the label under which we find/place the merchant's
* jurisdiction in the locations list by default?
*/
@@ -124,6 +129,11 @@ struct RekeyExchange
*/
struct TMH_EXCHANGES_KeysOperation *fo;
+ /**
+ * Timeout task handle.
+ */
+ struct GNUNET_SCHEDULER_Task *tx;
+
};
@@ -419,6 +429,7 @@ clean_order (void *cls)
oc->pending_reload_tail,
rx);
TMH_EXCHANGES_keys4exchange_cancel (rx->fo);
+ GNUNET_SCHEDULER_cancel (rx->tx);
GNUNET_free (rx->url);
GNUNET_free (rx);
}
@@ -964,6 +975,28 @@ get_acceptable (void *cls,
/**
+ * Exchange `/keys` processing is done, resume handling
+ * the order.
+ *
+ * @param[in,out] oc context to resume
+ */
+static void
+resume_with_keys (struct OrderContext *oc)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Resuming order processing after /keys downloads (now have %u accounts)\n",
+ (unsigned int) json_array_size (oc->exchanges));
+ GNUNET_assert (GNUNET_YES == oc->suspended);
+ GNUNET_CONTAINER_DLL_remove (oc_head,
+ oc_tail,
+ oc);
+ oc->suspended = GNUNET_NO;
+ MHD_resume_connection (oc->connection);
+ TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */
+}
+
+
+/**
* Function called with the result of a #TMH_EXCHANGES_keys4exchange()
* operation.
*
@@ -983,13 +1016,15 @@ keys_cb (
&oc->hc->instance->settings;
rx->fo = NULL;
+ GNUNET_SCHEDULER_cancel (rx->tx);
+ rx->tx = NULL;
GNUNET_CONTAINER_DLL_remove (oc->pending_reload_head,
oc->pending_reload_tail,
rx);
if (NULL == keys)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failed to download %s/keys\n",
+ "Failed to download %skeys\n",
rx->url);
}
else
@@ -999,24 +1034,41 @@ keys_cb (
TALER_amount_is_valid (&oc->max_fee)) )
update_stefan (oc,
keys);
+ get_acceptable (oc,
+ rx->url,
+ exchange);
}
- get_acceptable (oc,
- rx->url,
- exchange);
GNUNET_free (rx->url);
GNUNET_free (rx);
if (NULL != oc->pending_reload_head)
return;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Resuming order processing after /keys downloads (now have %u accounts)\n",
- (unsigned int) json_array_size (oc->exchanges));
- GNUNET_assert (GNUNET_YES == oc->suspended);
- GNUNET_CONTAINER_DLL_remove (oc_head,
- oc_tail,
- oc);
- oc->suspended = GNUNET_NO;
- MHD_resume_connection (oc->connection);
- TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */
+ resume_with_keys (oc);
+}
+
+
+/**
+ * A `/keys` request to an exchange is taking too
+ * long, ignore the exchange for now.
+ *
+ * @param cls a `struct RekeyExchange *`
+ */
+static void
+keys_timeout (void *cls)
+{
+ struct RekeyExchange *rx = cls;
+ struct OrderContext *oc = rx->oc;
+
+ rx->tx = NULL;
+ TMH_EXCHANGES_keys4exchange_cancel (rx->fo);
+ rx->fo = NULL;
+ GNUNET_CONTAINER_DLL_remove (oc->pending_reload_head,
+ oc->pending_reload_tail,
+ rx);
+ GNUNET_free (rx->url);
+ GNUNET_free (rx);
+ if (NULL != oc->pending_reload_head)
+ return;
+ resume_with_keys (oc);
}
@@ -1050,6 +1102,10 @@ get_exchange_keys (void *cls,
oc->forced_reload,
&keys_cb,
rx);
+ rx->tx
+ = GNUNET_SCHEDULER_add_delayed (KEYS_TIMEOUT,
+ &keys_timeout,
+ rx);
}
@@ -1247,6 +1303,16 @@ patch_order (struct OrderContext *oc)
ret);
return;
}
+ if (! TMH_test_exchange_configured_for_currency (oc->brutto.currency))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ reply_with_error (oc,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_CURRENCY_MISMATCH,
+ NULL);
+ return;
+ }
/* Add order_id if it doesn't exist. */
if (NULL == order_id)