[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant] branch master updated: likely fix for #6581, still need
From: |
gnunet |
Subject: |
[taler-merchant] branch master updated: likely fix for #6581, still needs testcase |
Date: |
Wed, 09 Sep 2020 23:11:53 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository merchant.
The following commit(s) were added to refs/heads/master by this push:
new e12f64d likely fix for #6581, still needs testcase
e12f64d is described below
commit e12f64d45b2f58b716497aab6fd6273b8f92b740
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed Sep 9 23:11:51 2020 +0200
likely fix for #6581, still needs testcase
---
src/backend/taler-merchant-httpd.c | 136 +++++++++++++++++++++
src/backend/taler-merchant-httpd.h | 29 ++++-
src/backend/taler-merchant-httpd_get-orders-ID.c | 2 +
.../taler-merchant-httpd_post-orders-ID-paid.c | 13 +-
.../taler-merchant-httpd_post-orders-ID-pay.c | 22 +++-
.../taler-merchant-httpd_private-get-orders-ID.c | 2 +
6 files changed, 196 insertions(+), 8 deletions(-)
diff --git a/src/backend/taler-merchant-httpd.c
b/src/backend/taler-merchant-httpd.c
index 22e11d7..a6a4592 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -290,6 +290,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.
*
@@ -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;
@@ -475,6 +542,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)
diff --git a/src/backend/taler-merchant-httpd.h
b/src/backend/taler-merchant-httpd.h
index 0d78312..c631729 100644
--- a/src/backend/taler-merchant-httpd.h
+++ b/src/backend/taler-merchant-httpd.h
@@ -343,6 +343,13 @@ struct TMH_SuspendedConnection
*/
struct GNUNET_HashCode key;
+ /**
+ * Optional session/fulfillment URI-based key
+ * of this entry in the #payment_trigger_map. Used internally by
+ * TMH_long_poll_resume2().
+ */
+ struct GNUNET_HashCode key2;
+
/**
* At what time does this request expire? If set in the future, we
* may wait this long for a payment to arrive before responding.
@@ -355,7 +362,7 @@ struct TMH_SuspendedConnection
struct TALER_Amount refund_expected;
/**
- * #GNUNET_YES if we are waiting for a refund.
+ * true if we are waiting for a refund.
*/
bool awaiting_refund;
@@ -364,6 +371,10 @@ struct TMH_SuspendedConnection
*/
bool awaiting_refund_obtained;
+ /**
+ * True if @a key2 is set.
+ */
+ bool has_key2;
};
@@ -411,6 +422,8 @@ TMH_trigger_daemon (void);
* 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,
@@ -418,6 +431,8 @@ TMH_trigger_daemon (void);
*/
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);
@@ -439,6 +454,18 @@ TMH_long_poll_resume (const char *order_id,
bool obtained);
+/**
+ * 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);
+
+
/**
* Decrement reference counter of @a mi, and free if it hits zero.
*
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c
b/src/backend/taler-merchant-httpd_get-orders-ID.c
index 82d74f4..e875a3b 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -192,6 +192,8 @@ suspend_god (struct GetOrderData *god)
"Suspending GET /orders/%s\n",
god->order_id);
TMH_long_poll_suspend (god->order_id,
+ god->session_id,
+ god->fulfillment_url,
god->hc->instance,
&god->sc,
god->sc.awaiting_refund
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
b/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
index bcb9aa0..bd2c555 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-paid.c
@@ -180,11 +180,16 @@ TMH_post_orders_ID_paid (const struct TMH_RequestHandler
*rh,
NULL);
}
}
+ if (NULL != session_id)
{
- // FIXME-#6581: extract fulfillment_url from contract_terms.
- // IF present, *ALSO* resume long-polling clients for the
- // same fulfillment URL + session_id!
- // NOTE: also should do the same in the pay handler!
+ const char *fulfillment_url;
+
+ fulfillment_url
+ = json_string_value (json_object_get (contract_terms,
+ "fulfillment_url"));
+ if (NULL != fulfillment_url)
+ TMH_long_poll_resume2 (session_id,
+ fulfillment_url);
}
json_decref (contract_terms);
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index 9c75e48..fd6cc7a 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -198,6 +198,11 @@ struct PayContext
*/
char *order_id;
+ /**
+ * Fulfillment URL from the contract, or NULL if we don't have one.
+ */
+ char *fulfillment_url;
+
/**
* Serial number of this order in the database (set once we did the lookup).
*/
@@ -521,6 +526,7 @@ pay_context_cleanup (void *cls)
pc->response = NULL;
}
GNUNET_free (pc->order_id);
+ GNUNET_free (pc->fulfillment_url);
GNUNET_free (pc->session_id);
GNUNET_CONTAINER_DLL_remove (pc_head,
pc_tail,
@@ -1443,6 +1449,10 @@ begin_transaction (struct PayContext *pc)
}
/* Notify clients that have been waiting for the payment to succeed */
+ if ( (NULL != pc->session_id) &&
+ (NULL != pc->fulfillment_url) )
+ TMH_long_poll_resume2 (pc->session_id,
+ pc->fulfillment_url);
TMH_long_poll_resume (pc->order_id,
hc->instance,
NULL,
@@ -1729,10 +1739,16 @@ parse_pay (struct MHD_Connection *connection,
GNUNET_JSON_spec_end ()
};
enum GNUNET_GenericReturnValue res;
+ const char *fulfillment_url;
res = TALER_MHD_parse_internal_json_data (connection,
contract_terms,
espec);
+ fulfillment_url
+ = json_string_value (json_object_get (contract_terms,
+ "fulfillment_url"));
+ if (NULL != fulfillment_url)
+ pc->fulfillment_url = GNUNET_strdup (fulfillment_url);
json_decref (contract_terms);
if (GNUNET_YES != res)
{
@@ -1884,9 +1900,9 @@ TMH_post_orders_ID_pay (const struct TMH_RequestHandler
*rh,
"Suspending pay handling while working with the exchange\n");
GNUNET_assert (NULL == pc->timeout_task);
pc->timeout_task =
- GNUNET_SCHEDULER_add_delayed (get_pay_timeout (pc->coins_cnt),
- &handle_pay_timeout,
- pc);
+ GNUNET_SCHEDULER_add_delayed (get_pay_timeout (pc->coins_cnt),
+ &handle_pay_timeout,
+ pc);
begin_transaction (pc);
return MHD_YES;
}
diff --git a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
index 5c43416..d341361 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
@@ -1035,6 +1035,8 @@ TMH_private_get_orders_ID (const struct
TMH_RequestHandler *rh,
"Suspending GET /private/orders/%s\n",
hc->infix);
TMH_long_poll_suspend (hc->infix,
+ gorc->session_id,
+ gorc->fulfillment_url,
hc->instance,
&gorc->sc,
NULL);
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-merchant] branch master updated: likely fix for #6581, still needs testcase,
gnunet <=