diff options
Diffstat (limited to 'src/backend/taler-merchant-httpd.c')
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 22e11d74..a6a45928 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -291,6 +291,40 @@ compute_pay_key (const char *order_id, /** + * Compute @a key to use for @a session_id and @a fulfillment_url in our + * #payment_trigger_map. + * + * @param session_id the session for which @a fulfillment_url matters + * @param fulfillment_url fullfillment URL of an order + * @param key[out] set to the hash map key to use + */ +static void +compute_pay_key2 (const char *session_id, + const char *fulfillment_url, + struct GNUNET_HashCode *key) +{ + size_t slen = strlen (session_id) + 1; + size_t ulen = strlen (fulfillment_url) + 1; + char buf[slen + ulen]; + + memcpy (buf, + session_id, + slen); + memcpy (&buf[slen], + fulfillment_url, + ulen); + GNUNET_CRYPTO_hash (buf, + sizeof (buf), + key); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Pay key for %s/%s is %s\n", + session_id, + fulfillment_url, + GNUNET_h2s (key)); +} + + +/** * Resume processing all suspended connections past timeout. * * @param cls unused @@ -318,6 +352,11 @@ do_resume (void *cls) GNUNET_CONTAINER_multihashmap_remove (payment_trigger_map, &sc->key, sc)); + if (sc->has_key2) + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (payment_trigger_map, + &sc->key2, + sc)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Resuming long polled job due to timeout\n"); MHD_resume_connection (sc->con); @@ -333,6 +372,8 @@ do_resume (void *cls) * Suspend connection from @a sc until payment has been received. * * @param order_id the order that we are waiting on + * @param session_id session ID of the requester + * @param fulfillment_url fulfillment URL of the contract * @param mi the merchant instance we are waiting on * @param sc connection to suspend * @param min_refund refund amount we are waiting on to be exceeded before resuming, @@ -340,6 +381,8 @@ do_resume (void *cls) */ void TMH_long_poll_suspend (const char *order_id, + const char *session_id, + const char *fulfillment_url, const struct TMH_MerchantInstance *mi, struct TMH_SuspendedConnection *sc, const struct TALER_Amount *min_refund) @@ -355,6 +398,22 @@ TMH_long_poll_suspend (const char *order_id, &sc->key, sc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); + if ( (NULL != session_id) && + (NULL != fulfillment_url) ) + { + sc->has_key2 = true; + compute_pay_key (order_id, + &mi->merchant_pub, + &sc->key2); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Suspending operation on key2 %s\n", + GNUNET_h2s (&sc->key2)); + GNUNET_assert (GNUNET_OK == + GNUNET_CONTAINER_multihashmap_put (payment_trigger_map, + &sc->key2, + sc, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); + } if (NULL != min_refund) { sc->awaiting_refund = true; @@ -392,6 +451,9 @@ resume_operation (void *cls, const struct ResumeData *rd = cls; struct TMH_SuspendedConnection *sc = value; + GNUNET_assert (0 == + GNUNET_memcmp (key, + &sc->key)); /* If the conditions are satisfied partially, turn them off for future calls. */ if ( (sc->awaiting_refund_obtained) && @@ -427,6 +489,11 @@ resume_operation (void *cls, GNUNET_CONTAINER_multihashmap_remove (payment_trigger_map, key, sc)); + if (sc->has_key2) + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (payment_trigger_map, + &sc->key2, + sc)); GNUNET_assert (sc == GNUNET_CONTAINER_heap_remove_node (sc->hn)); sc->hn = NULL; @@ -476,6 +543,75 @@ TMH_long_poll_resume (const char *order_id, /** + * Function called to resume suspended connections. + * + * @param cls NULL + * @param key key in the #payment_trigger_map + * @param value a `struct TMH_SuspendedConnection` to resume + * @return #GNUNET_OK (continue to iterate) + */ +static int +resume_operation2 (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct TMH_SuspendedConnection *sc = value; + + GNUNET_assert (sc->has_key2); + GNUNET_assert (0 == GNUNET_memcmp (key, + &sc->key2)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Resuming operation suspended pending payment on key %s\n", + GNUNET_h2s (key)); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (payment_trigger_map, + &sc->key, + sc)); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (payment_trigger_map, + &sc->key2, + sc)); + GNUNET_assert (sc == + GNUNET_CONTAINER_heap_remove_node (sc->hn)); + sc->hn = NULL; + MHD_resume_connection (sc->con); + TMH_trigger_daemon (); + return GNUNET_OK; +} + + +/** + * Find out if we have any clients long-polling for @a order_id to be + * confirmed at merchant @a mpub, and if so, tell them to resume. + * + * @param session_id the session for which @a fulfillment_url became paid + * @param fulfillment_url fullfillment URL of which an order was paid + */ +void +TMH_long_poll_resume2 (const char *session_id, + const char *fulfillment_url) +{ + struct GNUNET_HashCode key; + int ret; + + compute_pay_key2 (session_id, + fulfillment_url, + &key); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Resuming operations suspended pending payment on key %s\n", + GNUNET_h2s (&key)); + ret = GNUNET_CONTAINER_multihashmap_get_multiple (payment_trigger_map, + &key, + &resume_operation2, + NULL); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%u operations remain suspended pending payment (%d)\n", + GNUNET_CONTAINER_multihashmap_size (payment_trigger_map), + ret); +} + + +/** * Shutdown task (magically invoked when the application is being * quit) * |