summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_get-orders-ID.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/taler-merchant-httpd_get-orders-ID.c')
-rw-r--r--src/backend/taler-merchant-httpd_get-orders-ID.c154
1 files changed, 117 insertions, 37 deletions
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c b/src/backend/taler-merchant-httpd_get-orders-ID.c
index 72b96eb8..0025a6ce 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -78,7 +78,12 @@ struct GetOrderData
/**
* Database event we are waiting on to be resuming.
*/
- struct GNUNET_DB_EventHandler *eh;
+ struct GNUNET_DB_EventHandler *pay_eh;
+
+ /**
+ * Database event we are waiting on to be resuming.
+ */
+ struct GNUNET_DB_EventHandler *refund_eh;
/**
* Which merchant instance is this for?
@@ -200,17 +205,75 @@ resume_by_event (void *cls,
size_t extra_size)
{
struct GetOrderData *god = cls;
+ struct GNUNET_AsyncScopeSave old;
- (void) extra;
- (void) extra_size;
+ GNUNET_async_scope_enter (&god->hc->async_scope_id,
+ &old);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received event for %s with argument `%.*s`\n",
+ god->order_id,
+ (int) extra_size,
+ (const char *) extra);
if (! god->suspended)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Not suspended, ignoring event\n");
+ GNUNET_async_scope_restore (&old);
return; /* duplicate event is possible */
+ }
+ if (GNUNET_TIME_absolute_is_future (god->sc.long_poll_timeout) &&
+ god->sc.awaiting_refund)
+ {
+ char *as;
+ struct TALER_Amount a;
+
+ if (0 == extra_size)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "No amount given, but need refund above threshold\n");
+ GNUNET_async_scope_restore (&old);
+ return; /* not relevant */
+ }
+ as = GNUNET_strndup (extra,
+ extra_size);
+ if (GNUNET_OK !=
+ TALER_string_to_amount (as,
+ &a))
+ {
+ GNUNET_break (0);
+ GNUNET_async_scope_restore (&old);
+ return;
+ }
+ if (GNUNET_OK !=
+ TALER_amount_cmp_currency (&god->sc.refund_expected,
+ &a))
+ {
+ GNUNET_break (0);
+ GNUNET_async_scope_restore (&old);
+ return; /* bad currency!? */
+ }
+ if (1 == TALER_amount_cmp (&god->sc.refund_expected,
+ &a))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Amount too small to trigger resuming\n");
+ GNUNET_async_scope_restore (&old);
+ return; /* refund too small */
+ }
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Resuming (%d/%d) by event with argument `%.*s`\n",
+ (int) GNUNET_TIME_absolute_is_future (god->sc.long_poll_timeout),
+ god->sc.awaiting_refund,
+ (int) extra_size,
+ (const char *) extra);
god->suspended = false;
- GNUNET_CONTAINER_DLL_insert (god_head,
+ GNUNET_CONTAINER_DLL_remove (god_head,
god_tail,
god);
MHD_resume_connection (god->sc.con);
TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */
+ GNUNET_async_scope_restore (&old);
}
@@ -222,7 +285,7 @@ resume_by_event (void *cls,
static void
suspend_god (struct GetOrderData *god)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Suspending GET /orders/%s\n",
god->order_id);
if (NULL != god->contract_terms)
@@ -236,14 +299,7 @@ suspend_god (struct GetOrderData *god)
GNUNET_CONTAINER_DLL_insert (god_head,
god_tail,
god);
- TMH_long_poll_suspend (god->order_id,
- god->session_id,
- god->fulfillment_url,
- god->hc->instance,
- &god->sc,
- god->sc.awaiting_refund
- ? &god->sc.refund_expected
- : NULL);
+ MHD_suspend_connection (god->sc.con);
}
@@ -536,7 +592,7 @@ send_pay_request (struct GetOrderData *god,
(NULL == already_paid_order_id) )
{
/* long polling: do not queue a response, suspend connection instead */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Suspending request: long polling for payment\n");
suspend_god (god);
return MHD_YES;
@@ -726,10 +782,15 @@ god_cleanup (void *cls)
json_decref (god->contract_terms);
god->contract_terms = NULL;
}
- if (NULL != god->eh)
+ if (NULL != god->refund_eh)
+ {
+ TMH_db->event_listen_cancel (god->refund_eh);
+ god->refund_eh = NULL;
+ }
+ if (NULL != god->pay_eh)
{
- TMH_db->event_listen_cancel (god->eh);
- god->eh = NULL;
+ TMH_db->event_listen_cancel (god->pay_eh);
+ god->pay_eh = NULL;
}
GNUNET_free (god);
}
@@ -824,6 +885,9 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
? 0 == strcasecmp (await_refund_obtained_s,
"yes")
: false;
+ if (god->sc.awaiting_refund_obtained)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Awaiting refund obtained\n");
}
{
@@ -847,6 +911,9 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
"refund");
}
god->sc.awaiting_refund = true;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Awaiting minimum refund of %s\n",
+ min_refund);
}
}
@@ -886,37 +953,50 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
= GNUNET_TIME_relative_to_absolute (timeout);
if (! GNUNET_TIME_relative_is_zero (timeout))
{
- if (god->sc.awaiting_refund)
+ if (god->sc.awaiting_refund ||
+ god->sc.awaiting_refund_obtained)
{
- struct TMH_OrderPayEvent refund_eh = {
+#ifndef TALER_API_VERSION
+#define TALER_DBEVENT_MERCHANT_REFUND_OBTAINED 1104
+#endif
+ struct TMH_OrderPayEventP refund_eh = {
.header.size = htons (sizeof (refund_eh)),
- .header.type = htons (TALER_DBEVENT_MERCHANT_ORDER_REFUND)
+ .header.type = htons (god->sc.awaiting_refund_obtained
+ ? TALER_DBEVENT_MERCHANT_REFUND_OBTAINED
+ : TALER_DBEVENT_MERCHANT_ORDER_REFUND),
+ .merchant_pub = hc->instance->merchant_pub
};
GNUNET_CRYPTO_hash (god->order_id,
strlen (god->order_id),
&refund_eh.h_order_id);
- god->eh = TMH_db->event_listen (TMH_db->cls,
- &refund_eh.header,
- timeout,
- &resume_by_event,
- god);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Subscribing to refunds on %s\n",
+ god->order_id);
+ god->refund_eh = TMH_db->event_listen (TMH_db->cls,
+ &refund_eh.header,
+ timeout,
+ &resume_by_event,
+ god);
}
- else /* ! waiting for refund */
{
- struct TMH_OrderPayEvent pay_eh = {
+ struct TMH_OrderPayEventP pay_eh = {
.header.size = htons (sizeof (pay_eh)),
- .header.type = htons (TALER_DBEVENT_MERCHANT_ORDER_PAID)
+ .header.type = htons (TALER_DBEVENT_MERCHANT_ORDER_PAID),
+ .merchant_pub = hc->instance->merchant_pub
};
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Subscribing to payments on %s\n",
+ god->order_id);
GNUNET_CRYPTO_hash (god->order_id,
strlen (god->order_id),
&pay_eh.h_order_id);
- god->eh = TMH_db->event_listen (TMH_db->cls,
- &pay_eh.header,
- timeout,
- &resume_by_event,
- god);
+ god->pay_eh = TMH_db->event_listen (TMH_db->cls,
+ &pay_eh.header,
+ timeout,
+ &resume_by_event,
+ god);
}
} /* end of timeout non-zero */
} /* end of HTML generation NOT requested */
@@ -1156,7 +1236,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
public_reorder_url));
}
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Claim token or contract matched\n");
if ( (NULL != god->session_id) &&
@@ -1276,8 +1356,8 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
( (! god->refunded) ||
(1 != TALER_amount_cmp (&god->refund_amount,
&god->sc.refund_expected)) )) ||
- ((god->sc.awaiting_refund_obtained) &&
- (god->refund_available)) )
+ ( (god->sc.awaiting_refund_obtained) &&
+ (god->refund_available) ) )
{
/* Client is waiting for a refund larger than what we have, suspend
until timeout */
@@ -1292,7 +1372,7 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
"Awaiting refund exceeding %s\n",
TALER_amount2s (&god->sc.refund_expected));
if (god->sc.awaiting_refund_obtained)
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Awaiting pending refunds\n");
suspend_god (god);
return MHD_YES;