summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/taler-merchant-httpd.c')
-rw-r--r--src/backend/taler-merchant-httpd.c136
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)
*