diff options
Diffstat (limited to 'src/lib/merchant_api_post_order_abort.c')
-rw-r--r-- | src/lib/merchant_api_post_order_abort.c | 120 |
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; |