From 801a505c178d456b29f5f4553dd30e9c1a038bb5 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 10 Sep 2020 17:00:26 +0200 Subject: fix long polling: need to re-fetch contract terms --- .../taler-merchant-httpd_private-get-orders-ID.c | 165 +++++++++++---------- .../taler-merchant-httpd_private-get-orders.c | 5 + 2 files changed, 90 insertions(+), 80 deletions(-) (limited to 'src') 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 392954ce..1f47a475 100644 --- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c +++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c @@ -818,93 +818,98 @@ TMH_private_get_orders_ID (const struct TMH_RequestHandler *rh, hc->infix, GNUNET_STRINGS_absolute_time_to_string ( gorc->sc.long_poll_timeout)); - if (NULL == gorc->contract_terms) + if (NULL != gorc->contract_terms) + { + /* Clear old contract terms, might be from an earlier unclaimed contract + and thus could have changed during claiming. */ + json_decref (gorc->contract_terms); + gorc->contract_terms = NULL; + gorc->fulfillment_url = NULL; + } + TMH_db->preflight (TMH_db->cls); + qs = TMH_db->lookup_contract_terms (TMH_db->cls, + hc->instance->settings.id, + hc->infix, + &gorc->contract_terms, + &gorc->order_serial); + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + struct GNUNET_HashCode unused; + + /* We don't have contract terms, but the order may still exist. */ + qs = TMH_db->lookup_order (TMH_db->cls, + hc->instance->settings.id, + hc->infix, + &claim_token, + &unused, + &gorc->contract_terms); + order_only = true; + } + if (0 > qs) { - TMH_db->preflight (TMH_db->cls); - qs = TMH_db->lookup_contract_terms (TMH_db->cls, - hc->instance->settings.id, - hc->infix, - &gorc->contract_terms, - &gorc->order_serial); - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + /* single, read-only SQL statements should never cause + serialization problems */ + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); + /* Always report on hard error as well to enable diagnostics */ + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR, + NULL); + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_GET_ORDERS_ORDER_NOT_FOUND, + hc->infix); + } + /* extract the fulfillment URL and total amount from the contract terms! */ + { + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount ("amount", + &gorc->contract_amount), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (gorc->contract_terms, + spec, + NULL, NULL)) { - struct GNUNET_HashCode unused; - - /* We don't have contract terms, but the order may still exist. */ - qs = TMH_db->lookup_order (TMH_db->cls, - hc->instance->settings.id, - hc->infix, - &claim_token, - &unused, - &gorc->contract_terms); - order_only = true; + GNUNET_break (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR, + hc->infix); } - if (0 > qs) + if (0 != + strcasecmp (TMH_currency, + gorc->contract_amount.currency)) { - /* single, read-only SQL statements should never cause - serialization problems */ - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); - /* Always report on hard error as well to enable diagnostics */ - GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR, - NULL); + GNUNET_break (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR, + gorc->contract_amount.currency); } - if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + } + gorc->fulfillment_url + = json_string_value (json_object_get (gorc->contract_terms, + "fulfillment_url")); + if (! order_only) + { + if (GNUNET_OK != + TALER_JSON_contract_hash (gorc->contract_terms, + &gorc->h_contract_terms)) { + GNUNET_break (0); return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_GET_ORDERS_ORDER_NOT_FOUND, - hc->infix); - } - /* extract the fulfillment URL and total amount from the contract terms! */ - { - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount ("amount", - &gorc->contract_amount), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (gorc->contract_terms, - spec, - NULL, NULL)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR, - hc->infix); - } - if (0 != - strcasecmp (TMH_currency, - gorc->contract_amount.currency)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GET_ORDERS_DB_FETCH_CONTRACT_TERMS_ERROR, - gorc->contract_amount.currency); - } - } - gorc->fulfillment_url - = json_string_value (json_object_get (gorc->contract_terms, - "fulfillment_url")); - if (! order_only) - { - if (GNUNET_OK != - TALER_JSON_contract_hash (gorc->contract_terms, - &gorc->h_contract_terms)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GET_ORDERS_FAILED_COMPUTE_PROPOSAL_HASH, - NULL); - } + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GET_ORDERS_FAILED_COMPUTE_PROPOSAL_HASH, + NULL); } } if (TALER_EC_NONE != gorc->wire_ec) diff --git a/src/backend/taler-merchant-httpd_private-get-orders.c b/src/backend/taler-merchant-httpd_private-get-orders.c index 3d4c1c5b..3c77e9c4 100644 --- a/src/backend/taler-merchant-httpd_private-get-orders.c +++ b/src/backend/taler-merchant-httpd_private-get-orders.c @@ -272,6 +272,7 @@ add_order (void *cls, paid = false; if (qs < 0) { + GNUNET_break (0); aos->result = TALER_EC_MERCHANT_PRIVATE_GET_ORDERS_STATUS_DB_LOOKUP_ERROR; return; } @@ -282,6 +283,7 @@ add_order (void *cls, /* if the order was paid, it must have been claimed, so use lookup_contract_terms to avoid the order being deleted in the db. */ uint64_t os; + qs = TMH_db->lookup_contract_terms (TMH_db->cls, aos->instance_id, order_id, @@ -302,6 +304,7 @@ add_order (void *cls, if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) { + GNUNET_break (0); aos->result = TALER_EC_MERCHANT_PRIVATE_GET_ORDERS_CONTRACT_DB_LOOKUP_ERROR; json_decref (contract_terms); return; @@ -326,6 +329,7 @@ add_order (void *cls, spec, NULL, NULL)) { + GNUNET_break (0); aos->result = TALER_EC_MERCHANT_PRIVATE_GET_ORDERS_PARSE_CONTRACT_ERROR; json_decref (contract_terms); return; @@ -346,6 +350,7 @@ add_order (void *cls, &refund_amount); if (0 > qs) { + GNUNET_break (0); aos->result = TALER_EC_MERCHANT_PRIVATE_GET_ORDERS_REFUND_DB_LOOKUP_ERROR; json_decref (contract_terms); -- cgit v1.2.3