summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/taler_merchant_service.h50
-rw-r--r--src/lib/merchant_api_tip_pickup.c36
-rw-r--r--src/lib/merchant_api_tip_pickup2.c72
3 files changed, 93 insertions, 65 deletions
diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h
index f936d54e..dcd936e7 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -4654,23 +4654,55 @@ TALER_MERCHANT_tip_pickup_cancel (struct TALER_MERCHANT_TipPickupHandle *tph);
struct TALER_MERCHANT_TipPickup2Handle;
-// FIXME: change signature!
+/**
+ * Response for a POST /tips/$TIP_ID/pickup request.
+ */
+struct TALER_MERCHANT_TipPickup2Response
+{
+ /**
+ * HTTP response details
+ */
+ struct TALER_MERCHANT_HttpResponse hr;
+
+ /**
+ * Details depending on status.
+ */
+ union
+ {
+
+ /**
+ * Details if status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+
+ /**
+ * length of the @a blind_sigs array
+ */
+ unsigned int num_blind_sigs;
+
+ /**
+ * array of blind signatures over the planchets
+ */
+ const struct TALER_BlindedDenominationSignature *blind_sigs;
+
+ } ok;
+
+ } details;
+};
+
+
/**
* Callback for a POST /tips/$TIP_ID/pickup request. Returns the result of
- * the operation. Note that the client MUST still do the unblinding of the @a
- * blind_sigs.
+ * the operation. Note that the client MUST still do the unblinding.
*
* @param cls closure
- * @param hr HTTP response details
- * @param num_blind_sigs length of the @a blind_sigs array, 0 on error
- * @param blind_sigs array of blind signatures over the planchets, NULL on error
+ * @param tpr response details
*/
typedef void
(*TALER_MERCHANT_TipPickup2Callback) (
void *cls,
- const struct TALER_MERCHANT_HttpResponse *hr,
- unsigned int num_blind_sigs,
- const struct TALER_BlindedDenominationSignature blind_sigs[]);
+ const struct TALER_MERCHANT_TipPickup2Response *tpr);
/**
diff --git a/src/lib/merchant_api_tip_pickup.c b/src/lib/merchant_api_tip_pickup.c
index 75ec2d6c..cd1f2035 100644
--- a/src/lib/merchant_api_tip_pickup.c
+++ b/src/lib/merchant_api_tip_pickup.c
@@ -159,23 +159,19 @@ fail_pickup (struct TALER_MERCHANT_TipPickupHandle *tp,
* Note that the client MUST still do the unblinding of the @a blind_sigs.
*
* @param cls closure, a `struct TALER_MERCHANT_TipPickupHandle *`
- * @param hr HTTP response details
- * @param num_blind_sigs length of the @a reserve_sigs array, 0 on error
- * @param blind_sigs array of blind signatures over the planchets, NULL on error
+ * @param tpr response details
*/
static void
pickup_done_cb (void *cls,
- const struct TALER_MERCHANT_HttpResponse *hr,
- unsigned int num_blind_sigs,
- const struct TALER_BlindedDenominationSignature *blind_sigs)
+ const struct TALER_MERCHANT_TipPickup2Response *tpr)
{
struct TALER_MERCHANT_TipPickupHandle *tp = cls;
struct TALER_MERCHANT_PickupDetails pd = {
- .hr = *hr
+ .hr = tpr->hr
};
tp->tpo2 = NULL;
- if (NULL == blind_sigs)
+ if (MHD_HTTP_OK != tpr->hr.http_status)
{
tp->cb (tp->cb_cls,
&pd);
@@ -185,14 +181,17 @@ pickup_done_cb (void *cls,
{
enum GNUNET_GenericReturnValue ok = GNUNET_OK;
- for (unsigned int i = 0; i<num_blind_sigs; i++)
+ for (unsigned int i = 0; i<tpr->details.ok.num_blind_sigs; i++)
{
- struct TALER_EXCHANGE_PrivateCoinDetails *pcd = &tp->pcds[i];
+ const struct TALER_BlindedDenominationSignature *blind_sig
+ = &tpr->details.ok.blind_sigs[i];
+ struct TALER_EXCHANGE_PrivateCoinDetails *pcd
+ = &tp->pcds[i];
struct TALER_FreshCoin fc;
if (GNUNET_OK !=
TALER_planchet_to_coin (&tp->planchets[i].pk.key,
- &blind_sigs[i],
+ blind_sig,
&pcd->bks,
&pcd->coin_priv,
NULL,
@@ -207,22 +206,15 @@ pickup_done_cb (void *cls,
}
if (GNUNET_OK != ok)
{
- struct TALER_MERCHANT_HttpResponse hrx = {
- .reply = hr->reply,
- .ec = TALER_EC_MERCHANT_TIP_PICKUP_UNBLIND_FAILURE
- };
-
- pd.hr = hrx;
- tp->cb (tp->cb_cls,
- &pd);
+ pd.hr.ec = TALER_EC_MERCHANT_TIP_PICKUP_UNBLIND_FAILURE;
}
else
{
- pd.details.ok.num_sigs = num_blind_sigs;
+ pd.details.ok.num_sigs = tpr->details.ok.num_blind_sigs;
pd.details.ok.pcds = tp->pcds;
- tp->cb (tp->cb_cls,
- &pd);
}
+ tp->cb (tp->cb_cls,
+ &pd);
}
TALER_MERCHANT_tip_pickup_cancel (tp);
}
diff --git a/src/lib/merchant_api_tip_pickup2.c b/src/lib/merchant_api_tip_pickup2.c
index 33457024..9cb5a496 100644
--- a/src/lib/merchant_api_tip_pickup2.c
+++ b/src/lib/merchant_api_tip_pickup2.c
@@ -83,23 +83,22 @@ struct TALER_MERCHANT_TipPickup2Handle
* call the callback (and set it to NULL afterwards).
*
* @param tpo handle of the original authorization operation
+ * @param[in] tpr response to complete
* @param json cryptographic proof returned by the exchange/merchant
* @return #GNUNET_OK if response is valid
*/
-static int
+static enum GNUNET_GenericReturnValue
check_ok (struct TALER_MERCHANT_TipPickup2Handle *tpo,
+ struct TALER_MERCHANT_TipPickup2Response *tpr,
const json_t *json)
{
- json_t *ja;
+ const json_t *ja;
unsigned int ja_len;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_json ("blind_sigs", &ja),
+ GNUNET_JSON_spec_array_const ("blind_sigs",
+ &ja),
GNUNET_JSON_spec_end ()
};
- struct TALER_MERCHANT_HttpResponse hr = {
- .http_status = MHD_HTTP_OK,
- .reply = json
- };
if (GNUNET_OK !=
GNUNET_JSON_parse (json,
@@ -117,11 +116,12 @@ check_ok (struct TALER_MERCHANT_TipPickup2Handle *tpo,
return GNUNET_SYSERR;
}
{
- struct TALER_BlindedDenominationSignature mblind_sigs[ja_len];
+ struct TALER_BlindedDenominationSignature mblind_sigs[GNUNET_NZL (ja_len)];
for (unsigned int i = 0; i<ja_len; i++)
{
- json_t *pj = json_array_get (ja, i);
+ json_t *pj = json_array_get (ja,
+ i);
struct GNUNET_JSON_Specification ispec[] = {
TALER_JSON_spec_blinded_denom_sig ("blind_sig",
&mblind_sigs[i]),
@@ -135,16 +135,18 @@ check_ok (struct TALER_MERCHANT_TipPickup2Handle *tpo,
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
+ for (unsigned int j = 0; j<i; j++)
+ TALER_blinded_denom_sig_free (&mblind_sigs[j]);
return GNUNET_SYSERR;
}
}
+ tpr->details.ok.num_blind_sigs = ja_len;
+ tpr->details.ok.blind_sigs = mblind_sigs;
tpo->cb (tpo->cb_cls,
- &hr,
- ja_len,
- mblind_sigs);
+ tpr);
+ tpo->cb = NULL; /* do not call twice */
for (unsigned int i = 0; i<ja_len; i++)
TALER_blinded_denom_sig_free (&mblind_sigs[i]);
- tpo->cb = NULL; /* do not call twice */
}
GNUNET_JSON_parse_free (spec);
return GNUNET_OK;
@@ -166,64 +168,65 @@ handle_tip_pickup_finished (void *cls,
{
struct TALER_MERCHANT_TipPickup2Handle *tpo = cls;
const json_t *json = response;
- struct TALER_MERCHANT_HttpResponse hr = {
- .http_status = (unsigned int) response_code,
- .reply = json
+ struct TALER_MERCHANT_TipPickup2Response tpr = {
+ .hr.http_status = (unsigned int) response_code,
+ .hr.reply = json
};
tpo->job = NULL;
switch (response_code)
{
case MHD_HTTP_OK:
- if (GNUNET_OK != check_ok (tpo,
- json))
+ if (GNUNET_OK !=
+ check_ok (tpo,
+ &tpr,
+ json))
{
GNUNET_break_op (0);
- hr.http_status = 0;
- hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ tpr.hr.http_status = 0;
+ tpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ break;
}
break;
case MHD_HTTP_BAD_REQUEST:
/* Can happen if we pickup an amount that exceeds the tip... */
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ tpr.hr.ec = TALER_JSON_get_error_code (json);
+ tpr.hr.hint = TALER_JSON_get_error_hint (json);
GNUNET_break (TALER_EC_MERCHANT_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING ==
- hr.ec);
+ tpr.hr.ec);
break;
case MHD_HTTP_CONFLICT:
/* legal, can happen if we pickup a tip twice... */
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ tpr.hr.ec = TALER_JSON_get_error_code (json);
+ tpr.hr.hint = TALER_JSON_get_error_hint (json);
break;
case MHD_HTTP_NOT_FOUND:
/* legal, can happen if tip ID is unknown */
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ tpr.hr.ec = TALER_JSON_get_error_code (json);
+ tpr.hr.hint = TALER_JSON_get_error_hint (json);
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
/* Server had an internal issue; we should retry, but this API
leaves this to the application */
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ tpr.hr.ec = TALER_JSON_get_error_code (json);
+ tpr.hr.hint = TALER_JSON_get_error_hint (json);
break;
default:
/* unexpected response code */
GNUNET_break_op (0);
TALER_MERCHANT_parse_error_details_ (json,
response_code,
- &hr);
+ &tpr.hr);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d\n",
(unsigned int) response_code,
- (int) hr.ec);
+ (int) tpr.hr.ec);
break;
}
if (NULL != tpo->cb)
{
tpo->cb (tpo->cb_cls,
- &hr,
- 0,
- NULL);
+ &tpr);
tpo->cb = NULL;
}
TALER_MERCHANT_tip_pickup2_cancel (tpo);
@@ -250,6 +253,7 @@ TALER_MERCHANT_tip_pickup2 (struct GNUNET_CURL_Context *ctx,
return NULL;
}
pa = json_array ();
+ GNUNET_assert (NULL != pa);
for (unsigned int i = 0; i<num_planchets; i++)
{
const struct TALER_PlanchetDetail *planchet = &planchets[i];