diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-04-03 21:25:56 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-04-03 21:25:56 +0200 |
commit | cf0d8b8511f727c4650f86241c0254f30f40362e (patch) | |
tree | a4669a22e57482100d3d40342a73e7f9a5406769 | |
parent | ca4d806d18f1d6e135e3463cf4cad8271dff3219 (diff) | |
download | merchant-cf0d8b8511f727c4650f86241c0254f30f40362e.tar.gz merchant-cf0d8b8511f727c4650f86241c0254f30f40362e.tar.bz2 merchant-cf0d8b8511f727c4650f86241c0254f30f40362e.zip |
work on tipping logic to report exchange errors back to fontend
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-authorize.c | 6 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-query.c | 71 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-reserve-helper.c | 258 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_tip-reserve-helper.h | 10 | ||||
-rw-r--r-- | src/lib/merchant_api_tip_authorize.c | 24 | ||||
-rw-r--r-- | src/lib/test_merchant_api.c | 6 |
6 files changed, 227 insertions, 148 deletions
diff --git a/src/backend/taler-merchant-httpd_tip-authorize.c b/src/backend/taler-merchant-httpd_tip-authorize.c index a879b4df..52a7fe5e 100644 --- a/src/backend/taler-merchant-httpd_tip-authorize.c +++ b/src/backend/taler-merchant-httpd_tip-authorize.c @@ -55,7 +55,7 @@ struct TipAuthContext /** * Context for checking the tipping reserve's status. */ - struct CheckTipReserve ctr; + struct TMH_CheckTipReserve ctr; /** * Tip amount requested. @@ -180,7 +180,7 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh, "Instance `%s' not configured for tipping\n", mi->id); return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, + MHD_HTTP_PRECONDITION_FAILED, TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP, "exchange for tipping not configured for the instance"); } @@ -233,7 +233,7 @@ MH_handler_tip_authorize (struct TMH_RequestHandler *rh, break; case TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN: msg = "Failed to approve tip: merchant's tipping reserve does not exist"; - rc = MHD_HTTP_NOT_FOUND; + rc = MHD_HTTP_SERVICE_UNAVAILABLE; break; default: rc = MHD_HTTP_INTERNAL_SERVER_ERROR; diff --git a/src/backend/taler-merchant-httpd_tip-query.c b/src/backend/taler-merchant-httpd_tip-query.c index a93b32fb..12198470 100644 --- a/src/backend/taler-merchant-httpd_tip-query.c +++ b/src/backend/taler-merchant-httpd_tip-query.c @@ -36,6 +36,9 @@ #define MAX_RETRIES 5 +/** + * Internal per-request state for processing tip queries. + */ struct TipQueryContext { /** @@ -50,15 +53,15 @@ struct TipQueryContext const char *instance; /** - * GNUNET_YES if the tip query has already been processed - * and we can queue the response. + * Context for checking the tipping reserve's status. */ - int processed; + struct TMH_CheckTipReserve ctr; /** - * Context for checking the tipping reserve's status. + * #GNUNET_YES if the tip query has already been processed + * and we can queue the response. */ - struct CheckTipReserve ctr; + int processed; }; @@ -109,29 +112,26 @@ generate_final_response (struct TipQueryContext *tqc) a2); GNUNET_free (a2); GNUNET_free (a1); - return TALER_MHD_reply_with_error (tqc->ctr.connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_INCONSISTENT, - "Exchange returned invalid reserve history (amount overflow)"); + return TALER_MHD_reply_with_error ( + tqc->ctr.connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_INCONSISTENT, + "Exchange returned invalid reserve history (amount overflow)"); } - return TALER_MHD_reply_json_pack (tqc->ctr.connection, - MHD_HTTP_OK, - "{s:o, s:o, s:o, s:o, s:o}", - "reserve_pub", - GNUNET_JSON_from_data_auto ( - &reserve_pub), - "reserve_expiration", - GNUNET_JSON_from_time_abs ( - tqc->ctr.reserve_expiration), - "amount_authorized", - TALER_JSON_from_amount ( - &tqc->ctr.amount_authorized), - "amount_picked_up", - TALER_JSON_from_amount ( - &tqc->ctr.amount_withdrawn), - "amount_available", - TALER_JSON_from_amount ( - &amount_available)); + return TALER_MHD_reply_json_pack ( + tqc->ctr.connection, + MHD_HTTP_OK, + "{s:o, s:o, s:o, s:o, s:o}", + "reserve_pub", + GNUNET_JSON_from_data_auto (&reserve_pub), + "reserve_expiration", + GNUNET_JSON_from_time_abs (tqc->ctr.reserve_expiration), + "amount_authorized", + TALER_JSON_from_amount (&tqc->ctr.amount_authorized), + "amount_picked_up", + TALER_JSON_from_amount (&tqc->ctr.amount_withdrawn), + "amount_available", + TALER_JSON_from_amount (&amount_available)); } @@ -199,18 +199,20 @@ MH_handler_tip_query (struct TMH_RequestHandler *rh, if (NULL == mi->tip_exchange) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Instance `%s' not configured for tipping\n", mi->id); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP, - "exchange for tipping not configured for the instance"); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_PRECONDITION_FAILED, + TALER_EC_TIP_QUERY_INSTANCE_DOES_NOT_TIP, + "exchange for tipping not configured for the instance"); } tqc->ctr.reserve_priv = mi->tip_reserve; { - int qs; + enum GNUNET_DB_QueryStatus qs; + for (unsigned int i = 0; i<MAX_RETRIES; i++) { db->preflight (db->cls); @@ -222,8 +224,7 @@ MH_handler_tip_query (struct TMH_RequestHandler *rh, } if (0 > qs) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Database hard error on get_authorized_tip_amount\n"); + GNUNET_break (0); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_TIP_QUERY_DB_ERROR, diff --git a/src/backend/taler-merchant-httpd_tip-reserve-helper.c b/src/backend/taler-merchant-httpd_tip-reserve-helper.c index 0ded8ace..28c491b0 100644 --- a/src/backend/taler-merchant-httpd_tip-reserve-helper.c +++ b/src/backend/taler-merchant-httpd_tip-reserve-helper.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2018--2019 Taler Systems SA + (C) 2018--2020 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -25,12 +25,12 @@ /** * Head of active ctr context DLL. */ -static struct CheckTipReserve *ctr_head; +static struct TMH_CheckTipReserve *ctr_head; /** * Tail of active ctr context DLL. */ -static struct CheckTipReserve *ctr_tail; +static struct TMH_CheckTipReserve *ctr_tail; /** @@ -39,7 +39,7 @@ static struct CheckTipReserve *ctr_tail; * @param ctr what to resume */ static void -resume_ctr (struct CheckTipReserve *ctr) +resume_ctr (struct TMH_CheckTipReserve *ctr) { GNUNET_assert (GNUNET_YES == ctr->suspended); GNUNET_CONTAINER_DLL_remove (ctr_head, @@ -60,7 +60,7 @@ resume_ctr (struct CheckTipReserve *ctr) * @param response response data to send back */ static void -resume_with_response (struct CheckTipReserve *ctr, +resume_with_response (struct TMH_CheckTipReserve *ctr, unsigned int response_code, struct MHD_Response *response) { @@ -76,7 +76,7 @@ resume_with_response (struct CheckTipReserve *ctr, * for the tipping reserve. Update our database balance with the * result. * - * @param cls closure with a `struct CheckTipReserve *' + * @param cls closure with a `struct TMH_CheckTipReserve *' * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request * 0 if the exchange's reply is bogus (fails to follow the protocol) * @param ec taler-specific error code, #TALER_EC_NONE on success @@ -94,25 +94,37 @@ handle_status (void *cls, unsigned int history_length, const struct TALER_EXCHANGE_ReserveHistory *history) { - struct CheckTipReserve *ctr = cls; + struct TMH_CheckTipReserve *ctr = cls; ctr->rsh = NULL; ctr->reserve_expiration = GNUNET_TIME_UNIT_ZERO_ABS; if (MHD_HTTP_NOT_FOUND == http_status) { - resume_with_response (ctr, - MHD_HTTP_NOT_FOUND, - TALER_MHD_make_error (ec, - "Reserve unknown at exchange")); + resume_with_response ( + ctr, + MHD_HTTP_SERVICE_UNAVAILABLE, + TALER_MHD_make_json_pack ( + "{s:I, s:I, s:s, s:I, s:O}", + "code", (json_int_t) TALER_EC_TIP_QUERY_RESERVE_UNKNOWN_TO_EXCHANGE, + "exchange-http-status", http_status, + "hint", "tipping reserve unknown at exchange", + "exchange-code", TALER_JSON_get_error_code (json), + "exchange-reply", json)); return; } if (MHD_HTTP_OK != http_status) { GNUNET_break_op (0); - resume_with_response (ctr, - MHD_HTTP_SERVICE_UNAVAILABLE, - TALER_MHD_make_error (ec, - "Exchange returned error code for reserve status")); + resume_with_response ( + ctr, + MHD_HTTP_FAILED_DEPENDENCY, + TALER_MHD_make_json_pack ( + "{s:I, s:I, s:s, s:I, s:O}", + "code", (json_int_t) TALER_EC_TIP_QUERY_RESERVE_HISTORY_FAILED, + "exchange-http-status", http_status, + "hint", "exchange failed to provide reserve history", + "exchange-code", TALER_JSON_get_error_code (json), + "exchange-reply", json)); return; } @@ -120,57 +132,56 @@ handle_status (void *cls, { GNUNET_break_op (0); resume_with_response (ctr, - MHD_HTTP_SERVICE_UNAVAILABLE, + MHD_HTTP_FAILED_DEPENDENCY, TALER_MHD_make_error ( TALER_EC_TIP_QUERY_RESERVE_HISTORY_FAILED_EMPTY, "Exchange returned empty reserve history")); return; } - if (TALER_EXCHANGE_RTT_CREDIT != history[0].type) { - GNUNET_break_op (0); - resume_with_response (ctr, - MHD_HTTP_SERVICE_UNAVAILABLE, - TALER_MHD_make_error ( - TALER_EC_TIP_QUERY_RESERVE_HISTORY_INVALID_NO_DEPOSIT, - "Exchange returned invalid reserve history")); - return; - } + unsigned int found = UINT_MAX; - if (GNUNET_OK != - TALER_amount_get_zero (history[0].amount.currency, - &ctr->amount_withdrawn)) - { - GNUNET_break_op (0); - resume_with_response (ctr, - MHD_HTTP_SERVICE_UNAVAILABLE, - TALER_MHD_make_error ( - TALER_EC_TIP_QUERY_RESERVE_HISTORY_INVALID_CURRENCY, - "Exchange returned invalid reserve history")); - return; - } + for (unsigned int i = 0; i<history_length; i++) + if (TALER_EXCHANGE_RTT_CREDIT == history[i].type) + found = i; + if (UINT_MAX == found) + { + GNUNET_break_op (0); + resume_with_response (ctr, + MHD_HTTP_FAILED_DEPENDENCY, + TALER_MHD_make_error ( + TALER_EC_TIP_QUERY_RESERVE_HISTORY_INVALID_NO_DEPOSIT, + "Exchange returned invalid reserve history")); + return; + } - if (0 != strcasecmp (TMH_currency, - history[0].amount.currency)) - { - GNUNET_break_op (0); - resume_with_response (ctr, - MHD_HTTP_SERVICE_UNAVAILABLE, - TALER_MHD_make_error ( - TALER_EC_TIP_QUERY_RESERVE_CURRENCY_MISMATCH, - "Exchange currency unexpected")); - return; + if (0 != strcasecmp (TMH_currency, + history[found].amount.currency)) + { + GNUNET_break_op (0); + resume_with_response (ctr, + MHD_HTTP_SERVICE_UNAVAILABLE, + TALER_MHD_make_error ( + TALER_EC_TIP_QUERY_RESERVE_CURRENCY_MISMATCH, + "Exchange currency unexpected")); + return; + } + GNUNET_assert (GNUNET_OK == + TALER_amount_get_zero (history[found].amount.currency, + &ctr->amount_withdrawn)); } if (GNUNET_YES == ctr->none_authorized) - ctr->amount_authorized = ctr->amount_withdrawn; - ctr->amount_deposited = ctr->amount_withdrawn; + ctr->amount_authorized = ctr->amount_withdrawn; /* aka zero */ + ctr->amount_deposited = ctr->amount_withdrawn; /* aka zero */ /* Update DB based on status! */ for (unsigned int i = 0; i<history_length; i++) { - switch (history[i].type) + const struct TALER_EXCHANGE_ReserveHistory *hi = &history[i]; + + switch (hi->type) { case TALER_EXCHANGE_RTT_CREDIT: { @@ -178,43 +189,43 @@ handle_status (void *cls, struct GNUNET_HashCode uuid; struct GNUNET_TIME_Absolute deposit_expiration; + if (GNUNET_OK != + TALER_amount_add (&ctr->amount_deposited, + &ctr->amount_deposited, + &hi->amount)) + { + GNUNET_break_op (0); + resume_with_response ( + ctr, + MHD_HTTP_FAILED_DEPENDENCY, + TALER_MHD_make_error ( + TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_DEPOSIT, + "Exchange returned invalid reserve history (amount overflow)")); + return; + } deposit_expiration = GNUNET_TIME_absolute_add ( - history[i].details.in_details.timestamp, - ctr-> - idle_reserve_expiration_time); + hi->details.in_details.timestamp, + ctr->idle_reserve_expiration_time); /* We're interested in the latest DEPOSIT timestamp, since this determines the * reserve's expiration date. Note that the history isn't chronologically ordered. */ ctr->reserve_expiration = GNUNET_TIME_absolute_max ( ctr->reserve_expiration, deposit_expiration); - GNUNET_CRYPTO_hash (history[i].details.in_details.wire_reference, - history[i].details.in_details.wire_reference_size, + GNUNET_CRYPTO_hash (hi->details.in_details.wire_reference, + hi->details.in_details.wire_reference_size, &uuid); db->preflight (db->cls); qs = db->enable_tip_reserve_TR (db->cls, &ctr->reserve_priv, &uuid, - &history[i].amount, + &hi->amount, deposit_expiration); - if (GNUNET_OK != - TALER_amount_add (&ctr->amount_deposited, - &ctr->amount_deposited, - &history[i].amount)) - { - GNUNET_break_op (0); - resume_with_response (ctr, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_MHD_make_error ( - TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_DEPOSIT, - "Exchange returned invalid reserve history (amount overflow)")); - return; - } if (0 > qs) { + /* This is not inherently fatal for the client's request, so we merely log it */ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ ( - "Database error updating tipping reserve status: %d\n"), + "Database error updating tipping reserve status: %d\n", qs); } } @@ -223,36 +234,89 @@ handle_status (void *cls, if (GNUNET_OK != TALER_amount_add (&ctr->amount_withdrawn, &ctr->amount_withdrawn, - &history[i].amount)) + &hi->amount)) { GNUNET_break_op (0); - resume_with_response (ctr, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_MHD_make_error ( - TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_WITHDRAW, - "Exchange returned invalid reserve history (amount overflow)")); + resume_with_response ( + ctr, + MHD_HTTP_FAILED_DEPENDENCY, + TALER_MHD_make_error ( + TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_WITHDRAW, + "Exchange returned invalid reserve history (amount overflow)")); return; } break; case TALER_EXCHANGE_RTT_RECOUP: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ ( - "Encountered unsupported /recoup operation on tipping reserve\n")); - /* FIXME: probably should count these like deposits!? */ + { + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_HashContext *hc; + struct GNUNET_HashCode uuid; + struct GNUNET_TIME_Absolute deposit_expiration; + struct GNUNET_TIME_AbsoluteNBO de; + + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Encountered unexpected recoup operation on tipping reserve\n"); + /* While unexpected, we can simply count these like deposits. */ + if (GNUNET_OK != + TALER_amount_add (&ctr->amount_deposited, + &ctr->amount_deposited, + &hi->amount)) + { + GNUNET_break_op (0); + resume_with_response ( + ctr, + MHD_HTTP_FAILED_DEPENDENCY, + TALER_MHD_make_error ( + TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_RECOUP, + "Exchange returned invalid reserve history (amount overflow)")); + return; + } + deposit_expiration = GNUNET_TIME_absolute_add ( + hi->details.recoup_details.timestamp, + ctr->idle_reserve_expiration_time); + ctr->reserve_expiration = GNUNET_TIME_absolute_max ( + ctr->reserve_expiration, + deposit_expiration); + de = GNUNET_TIME_absolute_hton (deposit_expiration); + hc = GNUNET_CRYPTO_hash_context_start (); + GNUNET_CRYPTO_hash_context_read ( + hc, + &hi->details.recoup_details.coin_pub, + sizeof (struct TALER_CoinSpendPublicKeyP)); + GNUNET_CRYPTO_hash_context_read (hc, + &de, + sizeof (de)); + GNUNET_CRYPTO_hash_context_finish (hc, + &uuid); + db->preflight (db->cls); + qs = db->enable_tip_reserve_TR (db->cls, + &ctr->reserve_priv, + &uuid, + &hi->amount, + deposit_expiration); + if (0 > qs) + { + /* This is not inherently fatal for the client's request, so we merely log it */ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Database error updating tipping reserve status: %d\n", + qs); + } + } break; case TALER_EXCHANGE_RTT_CLOSE: /* We count 'closing' amounts just like withdrawals */ if (GNUNET_OK != TALER_amount_add (&ctr->amount_withdrawn, &ctr->amount_withdrawn, - &history[i].amount)) + &hi->amount)) { GNUNET_break_op (0); - resume_with_response (ctr, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_MHD_make_error ( - TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_CLOSED, - "Exchange returned invalid reserve history (amount overflow)")); + resume_with_response ( + ctr, + MHD_HTTP_FAILED_DEPENDENCY, + TALER_MHD_make_error ( + TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_CLOSED, + "Exchange returned invalid reserve history (amount overflow)")); return; } break; @@ -271,7 +335,7 @@ handle_status (void *cls, * operation. Given the exchange handle, we will then interrogate * the exchange about the status of the tipping reserve. * - * @param cls closure with a `struct CheckTipReserve *` + * @param cls closure with a `struct TMH_CheckTipReserve *` * @param eh handle to the exchange context * @param wire_fee current applicable wire fee for dealing with @a eh, NULL if not available * @param exchange_trusted #GNUNET_YES if this exchange is trusted by config @@ -282,7 +346,7 @@ exchange_cont (void *cls, const struct TALER_Amount *wire_fee, int exchange_trusted) { - struct CheckTipReserve *ctr = cls; + struct TMH_CheckTipReserve *ctr = cls; struct TALER_ReservePublicKeyP reserve_pub; const struct TALER_EXCHANGE_Keys *keys; @@ -290,9 +354,9 @@ exchange_cont (void *cls, if (NULL == eh) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ ("Failed to contact exchange configured for tipping!\n")); + "Failed to contact exchange configured for tipping!\n"); resume_with_response (ctr, - MHD_HTTP_SERVICE_UNAVAILABLE, + MHD_HTTP_FAILED_DEPENDENCY, TALER_MHD_make_error ( TALER_EC_TIP_QUERY_RESERVE_STATUS_FAILED_EXCHANGE_DOWN, "Unable to obtain /keys from exchange")); @@ -321,15 +385,15 @@ exchange_cont (void *cls, * @param tip_exchange the URL of the exchange to query */ void -TMH_check_tip_reserve (struct CheckTipReserve *ctr, +TMH_check_tip_reserve (struct TMH_CheckTipReserve *ctr, const char *tip_exchange) { MHD_suspend_connection (ctr->connection); - db->preflight (db->cls); + ctr->suspended = GNUNET_YES; GNUNET_CONTAINER_DLL_insert (ctr_head, ctr_tail, ctr); - ctr->suspended = GNUNET_YES; + db->preflight (db->cls); ctr->fo = TMH_EXCHANGES_find_exchange (tip_exchange, NULL, &exchange_cont, @@ -352,7 +416,7 @@ TMH_check_tip_reserve (struct CheckTipReserve *ctr, * @param[in] context to clean up */ void -TMH_check_tip_reserve_cleanup (struct CheckTipReserve *ctr) +TMH_check_tip_reserve_cleanup (struct TMH_CheckTipReserve *ctr) { if (NULL != ctr->rsh) { @@ -384,9 +448,9 @@ TMH_check_tip_reserve_cleanup (struct CheckTipReserve *ctr) void MH_force_trh_resume () { - struct CheckTipReserve *n; + struct TMH_CheckTipReserve *n; - for (struct CheckTipReserve *ctr = ctr_head; + for (struct TMH_CheckTipReserve *ctr = ctr_head; NULL != ctr; ctr = n) { diff --git a/src/backend/taler-merchant-httpd_tip-reserve-helper.h b/src/backend/taler-merchant-httpd_tip-reserve-helper.h index 615b9d5b..f180546d 100644 --- a/src/backend/taler-merchant-httpd_tip-reserve-helper.h +++ b/src/backend/taler-merchant-httpd_tip-reserve-helper.h @@ -33,7 +33,7 @@ * Context with input, output and internal state for * #TMH_check_tip_reserve() and #TMH_check_tip_reserve_cleanup(). */ -struct CheckTipReserve +struct TMH_CheckTipReserve { /** * Input: MHD connection we should resume when finished @@ -63,12 +63,12 @@ struct CheckTipReserve /** * Internal: DLL for resumption on shutdown. */ - struct CheckTipReserve *next; + struct TMH_CheckTipReserve *next; /** * Internal: DLL for resumption on shutdown. */ - struct CheckTipReserve *prev; + struct TMH_CheckTipReserve *prev; /** * Output: response object to return (on error only) @@ -130,7 +130,7 @@ struct CheckTipReserve * @param tip_exchange the URL of the exchange to query */ void -TMH_check_tip_reserve (struct CheckTipReserve *ctr, +TMH_check_tip_reserve (struct TMH_CheckTipReserve *ctr, const char *tip_exchange); @@ -140,7 +140,7 @@ TMH_check_tip_reserve (struct CheckTipReserve *ctr, * @param[in] context to clean up */ void -TMH_check_tip_reserve_cleanup (struct CheckTipReserve *ctr); +TMH_check_tip_reserve_cleanup (struct TMH_CheckTipReserve *ctr); /** * Force all tip reserve helper contexts to be resumed as we are about to shut diff --git a/src/lib/merchant_api_tip_authorize.c b/src/lib/merchant_api_tip_authorize.c index b9218310..632ee24d 100644 --- a/src/lib/merchant_api_tip_authorize.c +++ b/src/lib/merchant_api_tip_authorize.c @@ -130,27 +130,40 @@ handle_tip_authorize_finished (void *cls, { struct TALER_MERCHANT_TipAuthorizeOperation *tao = cls; const json_t *json = response; + enum TALER_ErrorCode ec; tao->job = NULL; switch (response_code) { case MHD_HTTP_OK: - if (GNUNET_OK != check_ok (tao, - json)) + if (GNUNET_OK == + check_ok (tao, + json)) { - GNUNET_break_op (0); - response_code = 0; + TALER_MERCHANT_tip_authorize_cancel (tao); + return; } + GNUNET_break_op (0); + response_code = 0; + ec = TALER_EC_INVALID_RESPONSE; break; case MHD_HTTP_NOT_FOUND: /* Well-defined status code, pass on to application! */ + ec = TALER_JSON_get_error_code (json); break; case MHD_HTTP_PRECONDITION_FAILED: /* Well-defined status code, pass on to application! */ + ec = TALER_JSON_get_error_code (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: /* Server had an internal issue; we should retry, but this API leaves this to the application */ + ec = TALER_JSON_get_error_code (json); + break; + case MHD_HTTP_SERVICE_UNAVAILABLE: + /* Server had an unclear (internal or external) issue; we should retry, + but this API leaves this to the application */ + ec = TALER_JSON_get_error_code (json); break; default: /* unexpected response code */ @@ -158,13 +171,14 @@ handle_tip_authorize_finished (void *cls, "Unexpected response code %u\n", (unsigned int) response_code); GNUNET_break (0); + ec = TALER_JSON_get_error_code (json); response_code = 0; break; } if (NULL != tao->cb) tao->cb (tao->cb_cls, response_code, - TALER_JSON_get_error_code (json), + ec, NULL, NULL); TALER_MERCHANT_tip_authorize_cancel (tao); } diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c index 39248178..6791fac0 100644 --- a/src/lib/test_merchant_api.c +++ b/src/lib/test_merchant_api.c @@ -596,10 +596,10 @@ run (void *cls, TALER_TESTING_cmd_tip_authorize_with_ec ("authorize-tip-null", merchant_url_internal ("nulltip"), EXCHANGE_URL, - MHD_HTTP_NOT_FOUND, + MHD_HTTP_SERVICE_UNAVAILABLE, "tip 2", "EUR:5.01", - TALER_EC_RESERVE_STATUS_UNKNOWN), + TALER_EC_TIP_QUERY_RESERVE_UNKNOWN_TO_EXCHANGE), TALER_TESTING_cmd_tip_query ("query-tip-1", merchant_url_internal ("tip"), MHD_HTTP_OK), @@ -663,7 +663,7 @@ run (void *cls, TALER_TESTING_cmd_tip_authorize_with_ec ("authorize-tip-5-notip-instance", merchant_url, EXCHANGE_URL, - MHD_HTTP_NOT_FOUND, + MHD_HTTP_PRECONDITION_FAILED, "tip 5", "EUR:5.01", TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP), |