diff options
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-post-orders.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-orders.c | 94 |
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) |