summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-06-12 10:22:12 +0200
committerChristian Grothoff <christian@grothoff.org>2020-06-12 10:22:12 +0200
commit175162ba4469d7a6bbee7dd9d5dcd2e2d9195e01 (patch)
treec0da50a9db916aeb3881f50b1ab218e5d6c76e62 /src
parent3fd4ebf798ac13eea1b7c78d90d6c180afff298b (diff)
downloadmerchant-175162ba4469d7a6bbee7dd9d5dcd2e2d9195e01.tar.gz
merchant-175162ba4469d7a6bbee7dd9d5dcd2e2d9195e01.tar.bz2
merchant-175162ba4469d7a6bbee7dd9d5dcd2e2d9195e01.zip
do not forget to kick MHD
Diffstat (limited to 'src')
-rw-r--r--src/backend/taler-merchant-httpd.c1
-rw-r--r--src/backend/taler-merchant-httpd_post-tips-ID-pickup.c8
-rw-r--r--src/backend/taler-merchant-httpd_private-get-orders-ID.c201
-rw-r--r--src/backend/taler-merchant-httpd_private-get-orders.c2
-rw-r--r--src/include/taler_merchant_service.h13
5 files changed, 165 insertions, 60 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index a73feabc..1aad33fd 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -291,6 +291,7 @@ do_resume (void *cls)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Resuming long polled job due to timeout\n");
MHD_resume_connection (sc->con);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
}
resume_timeout_task = GNUNET_SCHEDULER_add_at (sc->long_poll_timeout,
&do_resume,
diff --git a/src/backend/taler-merchant-httpd_post-tips-ID-pickup.c b/src/backend/taler-merchant-httpd_post-tips-ID-pickup.c
index e6437c39..bf1e3297 100644
--- a/src/backend/taler-merchant-httpd_post-tips-ID-pickup.c
+++ b/src/backend/taler-merchant-httpd_post-tips-ID-pickup.c
@@ -297,6 +297,7 @@ withdraw_cb (void *cls,
"exchange_http_status", (json_int_t) hr->http_status,
"exchange_reply", hr->reply);
MHD_resume_connection (pc->connection);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
return;
}
qs = TMH_db->insert_pickup_blind_signature (TMH_db->cls,
@@ -311,12 +312,14 @@ withdraw_cb (void *cls,
TALER_EC_TIP_PICKUP_DB_STORE_HARD_ERROR,
"Could not store blind signature in DB");
MHD_resume_connection (pc->connection);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
return;
}
if (NULL == pc->po_head)
{
stop_operations (pc); /* stops timeout job */
MHD_resume_connection (pc->connection);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
}
}
@@ -360,6 +363,7 @@ do_withdraw (void *cls,
"exchange_http_status", (json_int_t) hr->http_status,
"exchange_reply", hr->reply);
MHD_resume_connection (pc->connection);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
return;
}
po->w2h = TALER_EXCHANGE_withdraw2 (eh,
@@ -423,6 +427,7 @@ do_timeout (void *cls)
TALER_EC_TIP_PICKUP_EXCHANGE_TIMEOUT,
"Timeout trying to withdraw from exchange (try again later)");
MHD_resume_connection (pc->connection);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
}
@@ -464,6 +469,7 @@ compute_total_requested (void *cls,
"exchange_http_status", (json_int_t) hr->http_status,
"exchange_reply", hr->reply);
MHD_resume_connection (pc->connection);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
return;
}
TALER_amount_get_zero (TMH_currency,
@@ -486,6 +492,7 @@ compute_total_requested (void *cls,
"exchange_http_status", (json_int_t) hr->http_status,
"exchange_reply", hr->reply);
MHD_resume_connection (pc->connection);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
return;
}
@@ -502,6 +509,7 @@ compute_total_requested (void *cls,
TALER_MHD_make_error (TALER_EC_TIP_PICKUP_SUMMATION_FAILED,
"Could not add up values to compute pickup total");
MHD_resume_connection (pc->connection);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
return;
}
}
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 5635d634..336d83fa 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
@@ -164,12 +164,18 @@ struct GetOrderRequestContext
json_t *contract_terms;
/**
- * Wire details for the payment, to be returned to the query. NULL
+ * Wire details for the payment, to be returned in the reply. NULL
* if not available.
*/
json_t *wire_details;
/**
+ * Problems we encountered when looking up Wire details
+ * for the payment, to be returned. NULL if not available.
+ */
+ json_t *wire_reports;
+
+ /**
* Details about refunds, NULL if there are no refunds.
*/
json_t *refund_details;
@@ -231,6 +237,11 @@ struct GetOrderRequestContext
enum TALER_ErrorCode wire_ec;
/**
+ * HTTP status to return with @e wire_ec, 0 if @e wire_ec is #TALER_EC_NONE.
+ */
+ unsigned int wire_hc;
+
+ /**
* Set to true if this payment has been refunded and
* @e refund_amount is initialized.
*/
@@ -257,15 +268,17 @@ static struct GetOrderRequestContext *gorc_tail;
/**
+ * Resume processing the request, cancelling all pending asynchronous
+ * operations.
*
* @param gorc request to resume
+ * @param http_status HTTP status to return, 0 to continue with success
* @param ec error code for the request, #TALER_EC_NONE on success
- * @param exchange_hr details from exchange, NULL if exchange is blameless
*/
static void
gorc_resume (struct GetOrderRequestContext *gorc,
- enum TALER_ErrorCode ec,
- const struct TALER_EXCHANGE_HttpResponse *exchange_hr)
+ unsigned int http_status,
+ enum TALER_ErrorCode ec)
{
struct TransferQuery *tq;
@@ -287,16 +300,58 @@ gorc_resume (struct GetOrderRequestContext *gorc,
tq->dgh = NULL;
}
}
+ gorc->wire_hc = http_status;
gorc->wire_ec = ec;
- if (NULL != exchange_hr)
- {
- gorc->exchange_hc = exchange_hr->http_status;
- gorc->exchange_ec = exchange_hr->ec;
- }
GNUNET_CONTAINER_DLL_remove (gorc_head,
gorc_tail,
gorc);
MHD_resume_connection (gorc->sc.con);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
+}
+
+
+/**
+ * Add a report about trouble obtaining wire transfer data to the reply.
+ *
+ * @param gorc request to add wire report to
+ * @param ec error code to add
+ * @param hint human-readable hint
+ * @param coin_pub public key of the affected coin
+ * @param exchange_hr details from exchange, NULL if exchange is blameless
+ */
+static void
+gorc_report (struct GetOrderRequestContext *gorc,
+ enum TALER_ErrorCode ec,
+ const char *hint,
+ struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_EXCHANGE_HttpResponse *exchange_hr)
+{
+ if (NULL != exchange_hr)
+ GNUNET_assert (0 ==
+ json_array_append_new (
+ gorc->wire_reports,
+ json_pack ("{s:I, s:s, s:o, s:I, s:I}",
+ "code",
+ (json_int_t) ec,
+ "hint",
+ hint,
+ "coin_pub",
+ GNUNET_JSON_from_data_auto (coin_pub),
+ "exchange_ec",
+ (json_int_t) exchange_hr->ec,
+ "exchange_hc",
+ (json_int_t) exchange_hr->http_status)));
+ else
+ GNUNET_assert (0 ==
+ json_array_append_new (
+ gorc->wire_reports,
+ json_pack ("{s:I, s:s, s:o}",
+ "code",
+ (json_int_t) ec,
+ "hint",
+ hint,
+ "coin_pub",
+ GNUNET_JSON_from_data_auto (coin_pub))));
}
@@ -313,8 +368,8 @@ exchange_timeout_cb (void *cls)
gorc->tt = NULL;
gorc_resume (gorc,
- TALER_EC_GET_ORDERS_EXCHANGE_TIMEOUT,
- NULL);
+ MHD_HTTP_REQUEST_TIMEOUT,
+ TALER_EC_GET_ORDERS_EXCHANGE_TIMEOUT);
}
@@ -338,10 +393,16 @@ deposit_get_cb (void *cls,
tq);
if (NULL == dd)
{
- gorc_resume (gorc,
+ gorc_report (gorc,
TALER_EC_GET_ORDERS_EXCHANGE_TRACKING_FAILURE,
+ "Exchange failed to return tracking data",
+ &tq->coin_pub,
hr);
GNUNET_free (tq);
+ if (NULL == gorc->tq_head)
+ gorc_resume (gorc,
+ 0,
+ TALER_EC_NONE);
return;
}
else if (MHD_HTTP_OK == hr->http_status)
@@ -353,10 +414,16 @@ deposit_get_cb (void *cls,
dd);
if (qs < 0)
{
- gorc_resume (gorc,
+ gorc_report (gorc,
TALER_EC_GET_ORDERS_DB_STORE_TRACKING_FAILURE,
+ "Merchant backend failed to store transfer details in DB",
+ &tq->coin_pub,
NULL);
GNUNET_free (tq);
+ if (NULL == gorc->tq_head)
+ gorc_resume (gorc,
+ 0,
+ TALER_EC_NONE);
return;
}
/* Compute total amount *wired* */
@@ -365,10 +432,16 @@ deposit_get_cb (void *cls,
&gorc->deposits_total,
&dd->coin_contribution))
{
- gorc_resume (gorc,
+ gorc_report (gorc,
TALER_EC_GET_ORDERS_AMOUNT_ARITHMETIC_FAILURE,
+ "Merchant backend could not sum up deposit total",
+ &tq->coin_pub,
NULL);
GNUNET_free (tq);
+ if (NULL == gorc->tq_head)
+ gorc_resume (gorc,
+ 0,
+ TALER_EC_NONE);
return;
}
if (0 >
@@ -376,24 +449,35 @@ deposit_get_cb (void *cls,
&gorc->deposit_fees_total,
&tq->deposit_fee))
{
- gorc_resume (gorc,
+ gorc_report (gorc,
TALER_EC_GET_ORDERS_AMOUNT_ARITHMETIC_FAILURE,
+ "Merchant backend could not sum up deposit fees",
+ &tq->coin_pub,
NULL);
GNUNET_free (tq);
+ if (NULL == gorc->tq_head)
+ gorc_resume (gorc,
+ 0,
+ TALER_EC_NONE);
return;
}
}
else
{
/* got a 'preliminary' reply from the exchange, simply skip */
+ gorc_report (gorc,
+ TALER_EC_NONE,
+ "Exchange returned preliminary response",
+ &tq->coin_pub,
+ hr);
}
GNUNET_free (tq);
if (NULL != gorc->tq_head)
return;
/* *all* are done, resume! */
gorc_resume (gorc,
- TALER_EC_NONE,
- NULL);
+ 0,
+ TALER_EC_NONE);
}
@@ -427,9 +511,11 @@ exchange_found_cb (void *cls,
gorc->tq_tail,
tq);
GNUNET_free (tq);
+ gorc->exchange_hc = hr->http_status;
+ gorc->exchange_ec = hr->ec;
gorc_resume (gorc,
- TALER_EC_GET_ORDERS_EXCHANGE_LOOKUP_FAILURE,
- hr);
+ MHD_HTTP_FAILED_DEPENDENCY,
+ TALER_EC_GET_ORDERS_EXCHANGE_LOOKUP_FAILURE);
return;
}
tq->dgh = TALER_EXCHANGE_deposits_get (eh,
@@ -446,8 +532,8 @@ exchange_found_cb (void *cls,
tq);
GNUNET_free (tq);
gorc_resume (gorc,
- TALER_EC_GET_ORDERS_EXCHANGE_REQUEST_FAILURE,
- NULL);
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GET_ORDERS_EXCHANGE_REQUEST_FAILURE);
}
}
@@ -498,8 +584,8 @@ deposit_cb (void *cls,
if (NULL == tq->fo)
{
gorc_resume (gorc,
- TALER_EC_GET_ORDERS_EXCHANGE_LOOKUP_FAILURE,
- NULL);
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GET_ORDERS_EXCHANGE_LOOKUP_START_FAILURE);
}
}
@@ -520,6 +606,8 @@ gorc_cleanup (void *cls)
json_decref (gorc->wire_details);
if (NULL != gorc->refund_details)
json_decref (gorc->refund_details);
+ if (NULL != gorc->wire_reports)
+ json_decref (gorc->wire_reports);
GNUNET_assert (NULL == gorc->tt);
GNUNET_free (gorc);
}
@@ -551,11 +639,6 @@ process_refunds_cb (void *cls,
{
struct GetOrderRequestContext *gorc = cls;
- if (NULL == gorc->refund_details)
- {
- gorc->refund_details = json_array ();
- GNUNET_assert (NULL != gorc->refund_details);
- }
GNUNET_assert (0 ==
json_array_append_new (
gorc->refund_details,
@@ -566,15 +649,6 @@ process_refunds_cb (void *cls,
GNUNET_JSON_from_time_abs (timestamp),
"reason",
reason)));
- if (gorc->refunded)
- {
- GNUNET_assert (0 <=
- TALER_amount_add (&gorc->refund_amount,
- &gorc->refund_amount,
- refund_amount));
- return;
- }
-
/* For refunded coins, we are not charged deposit fees, so subtract those
again */
for (struct TransferQuery *tq = gorc->tq_head;
@@ -591,7 +665,10 @@ process_refunds_cb (void *cls,
&tq->deposit_fee));
}
}
- gorc->refund_amount = *refund_amount;
+ GNUNET_assert (0 <=
+ TALER_amount_add (&gorc->refund_amount,
+ &gorc->refund_amount,
+ refund_amount));
gorc->refunded = true;
}
@@ -669,12 +746,18 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
if (NULL == gorc)
{
/* First time here, parse request and check order is known */
+ GNUNET_assert (NULL != hc->infix);
gorc = GNUNET_new (struct GetOrderRequestContext);
hc->cc = &gorc_cleanup;
hc->ctx = gorc;
gorc->sc.con = connection;
gorc->hc = hc;
- GNUNET_assert (NULL != hc->infix);
+ gorc->wire_details = json_array ();
+ GNUNET_assert (NULL != gorc->wire_details);
+ gorc->refund_details = json_array ();
+ GNUNET_assert (NULL != gorc->refund_details);
+ gorc->wire_reports = json_array ();
+ GNUNET_assert (NULL != gorc->wire_reports);
gorc->session_id = MHD_lookup_connection_value (connection,
MHD_GET_ARGUMENT_KIND,
"session_id");
@@ -792,15 +875,19 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
&gorc->h_contract_terms))
{
GNUNET_break (0);
- return (MHD_YES ==
- TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GET_ORDERS_FAILED_COMPUTE_PROPOSAL_HASH,
- "Failed to hash contract terms"))
- ? GNUNET_NO
- : GNUNET_SYSERR;
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GET_ORDERS_FAILED_COMPUTE_PROPOSAL_HASH,
+ "Failed to hash contract terms");
}
}
+ if (TALER_EC_NONE != gorc->wire_ec)
+ {
+ return TALER_MHD_reply_with_error (connection,
+ gorc->wire_hc,
+ gorc->wire_ec,
+ "Failed to obtain wire details");
+ }
GNUNET_assert (NULL != gorc->contract_terms);
@@ -926,6 +1013,9 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
/* Accumulate refunds, if any. */
{
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_get_zero (TMH_currency,
+ &gorc->refund_amount));
qs = TMH_db->lookup_refunds_detailed (TMH_db->cls,
hc->instance->settings.id,
&gorc->h_contract_terms,
@@ -945,8 +1035,6 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
{
MHD_RESULT ret;
- gorc->wire_details = json_array ();
- GNUNET_assert (NULL != gorc->wire_details);
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (TMH_currency,
&gorc->deposits_total));
@@ -1008,10 +1096,10 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
ret = TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK,
- "{s:I, s:I, s:I, s:o, s:O,"
- " s:b, s:b, s:o?, s:o?, s:o?}",
- "wire_ec",
- (json_int_t) gorc->wire_ec,
+ "{s:o, s:I, s:I, s:o, s:O,"
+ " s:b, s:b, s:b, s:o, s:o, s:o}",
+ "wire_reports",
+ gorc->wire_reports,
"exchange_ec",
(json_int_t) gorc->exchange_ec,
"exchange_hc",
@@ -1025,16 +1113,17 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh,
true,
"refunded",
gorc->refunded,
+ "wired",
+ wired,
"refund_amount",
- (gorc->refunded)
- ? TALER_JSON_from_amount (
- &gorc->refund_amount)
- : NULL,
+ TALER_JSON_from_amount (
+ &gorc->refund_amount),
"wire_details",
gorc->wire_details,
"refund_details",
gorc->refund_details);
gorc->wire_details = NULL;
+ gorc->wire_reports = NULL;
gorc->refund_details = NULL;
return ret;
}
diff --git a/src/backend/taler-merchant-httpd_private-get-orders.c b/src/backend/taler-merchant-httpd_private-get-orders.c
index e8351511..669a2e3b 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders.c
@@ -162,6 +162,7 @@ order_timeout (void *cls)
po);
json_decref (po->pa);
MHD_resume_connection (po->con);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
GNUNET_free (po->instance_id);
GNUNET_free (po);
}
@@ -285,6 +286,7 @@ TMH_notify_order_change (const char *instance_id,
GNUNET_assert (po ==
GNUNET_CONTAINER_heap_remove_node (po->hn));
MHD_resume_connection (po->con);
+ TMH_trigger_daemon (); /* we resumed, kick MHD */
json_decref (po->pa);
GNUNET_free (po->instance_id);
GNUNET_free (po);
diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h
index 9e7504aa..4ae3112a 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -1509,16 +1509,21 @@ struct TALER_MERCHANT_WireConflict
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
+ * HTTP response data from the exchange (NULL if not available).
+ */
+ const struct TALER_EXCHANGE_HttpResponse *hr;
+
+ /**
* A claim by the exchange about the transactions associated
- * with a given wire transfer.
+ * with a given wire transfer, NULL if not available.
*/
- struct TALER_EXCHANGE_TransferData wtid_claim;
+ const struct TALER_EXCHANGE_TransferData *wtid_claim;
/**
* A claim by the exchange that the given transaction is included
- * in the above WTID.
+ * in the above WTID, NULL if not available.
*/
- struct TALER_EXCHANGE_DepositData deposit_claim;
+ const struct TALER_EXCHANGE_DepositData *deposit_claim;
};