summaryrefslogtreecommitdiff
path: root/src/lib/merchant_api_post_order_abort.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/merchant_api_post_order_abort.c')
-rw-r--r--src/lib/merchant_api_post_order_abort.c120
1 files changed, 59 insertions, 61 deletions
diff --git a/src/lib/merchant_api_post_order_abort.c b/src/lib/merchant_api_post_order_abort.c
index b5a7a00b..270ceb7e 100644
--- a/src/lib/merchant_api_post_order_abort.c
+++ b/src/lib/merchant_api_post_order_abort.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2021 Taler Systems SA
+ Copyright (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
@@ -39,6 +39,12 @@
/**
+ * Maximum number of refunds we return.
+ */
+#define MAX_REFUNDS 1024
+
+
+/**
* @brief An abort Handle
*/
struct TALER_MERCHANT_OrderAbortHandle
@@ -102,17 +108,20 @@ struct TALER_MERCHANT_OrderAbortHandle
* OK. Otherwise returns #GNUNET_SYSERR.
*
* @param oah handle to operation that created the reply
+ * @param[in] ar abort response, partially initialized
* @param json the reply to parse
* @return #GNUNET_OK on success
*/
-static int
+static enum GNUNET_GenericReturnValue
check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah,
+ struct TALER_MERCHANT_AbortResponse *ar,
const json_t *json)
{
- json_t *refunds;
+ const json_t *refunds;
unsigned int num_refunds;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_json ("refunds", &refunds),
+ GNUNET_JSON_spec_array_const ("refunds",
+ &refunds),
GNUNET_JSON_spec_end ()
};
@@ -124,13 +133,14 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah,
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- if (! json_is_array (refunds))
+ num_refunds = (unsigned int) json_array_size (refunds);
+ if ( (json_array_size (refunds) != (size_t) num_refunds) ||
+ (num_refunds > MAX_REFUNDS) )
{
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
+ GNUNET_break (0);
return GNUNET_SYSERR;
}
- num_refunds = json_array_size (refunds);
+
{
struct TALER_MERCHANT_AbortedCoin res[GNUNET_NZL (num_refunds)];
@@ -150,7 +160,6 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah,
NULL, NULL))
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
if (MHD_HTTP_OK == exchange_status)
@@ -169,7 +178,6 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah,
NULL, NULL))
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
@@ -184,26 +192,17 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah,
&res[i].exchange_sig))
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
}
}
- {
- struct TALER_MERCHANT_HttpResponse hr = {
- .reply = json,
- .http_status = MHD_HTTP_OK
- };
-
- oah->abort_cb (oah->abort_cb_cls,
- &hr,
- &oah->merchant_pub,
- num_refunds,
- res);
- }
+ ar->details.ok.merchant_pub = &oah->merchant_pub;
+ ar->details.ok.num_aborts = num_refunds;
+ ar->details.ok.aborts = res;
+ oah->abort_cb (oah->abort_cb_cls,
+ ar);
oah->abort_cb = NULL;
}
- GNUNET_JSON_parse_free (spec);
return GNUNET_OK;
}
@@ -223,9 +222,9 @@ handle_abort_finished (void *cls,
{
struct TALER_MERCHANT_OrderAbortHandle *oah = cls;
const json_t *json = response;
- struct TALER_MERCHANT_HttpResponse hr = {
- .http_status = (unsigned int) response_code,
- .reply = json
+ struct TALER_MERCHANT_AbortResponse ar = {
+ .hr.http_status = (unsigned int) response_code,
+ .hr.reply = json
};
oah->job = NULL;
@@ -235,40 +234,41 @@ handle_abort_finished (void *cls,
switch (response_code)
{
case 0:
- hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ ar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
case MHD_HTTP_OK:
if (GNUNET_OK ==
check_abort_refund (oah,
+ &ar,
json))
{
TALER_MERCHANT_order_abort_cancel (oah);
return;
}
- hr.http_status = 0;
- hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ ar.hr.http_status = 0;
+ ar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
case MHD_HTTP_BAD_REQUEST:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ ar.hr.ec = TALER_JSON_get_error_code (json);
+ ar.hr.hint = TALER_JSON_get_error_hint (json);
/* This should never happen, either us or the
merchant is buggy (or API version conflict); just
pass JSON reply to the application */
break;
case MHD_HTTP_FORBIDDEN:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ ar.hr.ec = TALER_JSON_get_error_code (json);
+ ar.hr.hint = TALER_JSON_get_error_hint (json);
break;
case MHD_HTTP_NOT_FOUND:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ ar.hr.ec = TALER_JSON_get_error_code (json);
+ ar.hr.hint = TALER_JSON_get_error_hint (json);
/* Nothing really to verify, this should never
happen, we should pass the JSON reply to the
application */
break;
case MHD_HTTP_REQUEST_TIMEOUT:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ ar.hr.ec = TALER_JSON_get_error_code (json);
+ ar.hr.hint = TALER_JSON_get_error_hint (json);
/* Nothing really to verify, merchant says one of
the signatures is invalid; as we checked them,
this should never happen, we should pass the JSON
@@ -276,19 +276,19 @@ handle_abort_finished (void *cls,
break;
case MHD_HTTP_PRECONDITION_FAILED:
/* Our *payment* already succeeded fully. */
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ ar.hr.ec = TALER_JSON_get_error_code (json);
+ ar.hr.hint = TALER_JSON_get_error_hint (json);
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ ar.hr.ec = TALER_JSON_get_error_code (json);
+ ar.hr.hint = TALER_JSON_get_error_hint (json);
/* Server had an internal issue; we should retry,
but this API leaves this to the application */
break;
case MHD_HTTP_BAD_GATEWAY:
TALER_MERCHANT_parse_error_details_ (json,
response_code,
- &hr);
+ &ar.hr);
/* Nothing really to verify, the merchant is blaming the exchange.
We should pass the JSON reply to the application */
break;
@@ -296,33 +296,31 @@ handle_abort_finished (void *cls,
/* unexpected response code */
TALER_MERCHANT_parse_error_details_ (json,
response_code,
- &hr);
+ &ar.hr);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d\n",
(unsigned int) response_code,
- (int) hr.ec);
+ (int) ar.hr.ec);
GNUNET_break_op (0);
break;
}
oah->abort_cb (oah->abort_cb_cls,
- &hr,
- NULL,
- 0,
- NULL);
+ &ar);
TALER_MERCHANT_order_abort_cancel (oah);
}
struct TALER_MERCHANT_OrderAbortHandle *
-TALER_MERCHANT_order_abort (struct GNUNET_CURL_Context *ctx,
- const char *merchant_url,
- const char *order_id,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct TALER_PrivateContractHashP *h_contract,
- unsigned int num_coins,
- const struct TALER_MERCHANT_AbortCoin coins[],
- TALER_MERCHANT_AbortCallback cb,
- void *cb_cls)
+TALER_MERCHANT_order_abort (
+ struct GNUNET_CURL_Context *ctx,
+ const char *merchant_url,
+ const char *order_id,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_PrivateContractHashP *h_contract,
+ unsigned int num_coins,
+ const struct TALER_MERCHANT_AbortCoin coins[static num_coins],
+ TALER_MERCHANT_AbortCallback cb,
+ void *cb_cls)
{
struct TALER_MERCHANT_OrderAbortHandle *oah;
json_t *abort_obj;
@@ -389,9 +387,9 @@ TALER_MERCHANT_order_abort (struct GNUNET_CURL_Context *ctx,
oah->num_coins = num_coins;
oah->coins = GNUNET_new_array (num_coins,
struct TALER_MERCHANT_AbortCoin);
- memcpy (oah->coins,
- coins,
- num_coins * sizeof (struct TALER_MERCHANT_AbortCoin));
+ GNUNET_memcpy (oah->coins,
+ coins,
+ num_coins * sizeof (struct TALER_MERCHANT_AbortCoin));
{
CURL *eh;