diff options
Diffstat (limited to 'src/lib/merchant_api_proposal.c')
-rw-r--r-- | src/lib/merchant_api_proposal.c | 312 |
1 files changed, 36 insertions, 276 deletions
diff --git a/src/lib/merchant_api_proposal.c b/src/lib/merchant_api_proposal.c index d532231d..e5e155fe 100644 --- a/src/lib/merchant_api_proposal.c +++ b/src/lib/merchant_api_proposal.c @@ -16,10 +16,9 @@ License along with TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> */ - /** * @file lib/merchant_api_proposal.c - * @brief Implementation of the /proposal POST and GET + * @brief Implementation of the /proposal POST * @author Christian Grothoff * @author Marcello Stanisci */ @@ -72,48 +71,6 @@ struct TALER_MERCHANT_ProposalOperation struct TALER_CURL_PostContext post_ctx; }; -/** - * Structure representing a GET /proposal operation. - */ -struct TALER_MERCHANT_ProposalLookupOperation -{ - /** - * Full URL, includes "/proposal". - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_ProposalLookupOperationCallback cb; - - /** - * Closure for @a cb. - */ - void *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Should we send the lookup operation with a nonce? - */ - int has_nonce; - - /** - * Nonce, only initialized if has_nonce is GNUNET_YES. - */ - struct GNUNET_CRYPTO_EddsaPublicKey nonce; - -}; - /** * Function called when we're done processing the @@ -129,9 +86,12 @@ handle_proposal_finished (void *cls, const void *response) { struct TALER_MERCHANT_ProposalOperation *po = cls; - const char *order_id; + const char *order_id = NULL; const json_t *json = response; - enum TALER_ErrorCode ec; + struct TALER_MERCHANT_HttpResponse hr = { + .http_status = (unsigned int) response_code, + .reply = json + }; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("order_id", &order_id), @@ -142,73 +102,66 @@ handle_proposal_finished (void *cls, switch (response_code) { case 0: - po->cb (po->cb_cls, - response_code, - TALER_EC_INVALID_RESPONSE, - json, - order_id); - TALER_MERCHANT_proposal_cancel (po); - return; + hr.ec = TALER_EC_INVALID_RESPONSE; + break; case MHD_HTTP_OK: + if (GNUNET_OK != + GNUNET_JSON_parse (json, + spec, + NULL, NULL)) { - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - response_code = 0; - ec = TALER_JSON_get_error_code (json); - break; - } - else - { - ec = TALER_EC_NONE; - } + GNUNET_break_op (0); + hr.http_status = 0; + hr.ec = TALER_EC_PROPOSAL_REPLY_MALFORMED; } break; case MHD_HTTP_BAD_REQUEST: - ec = TALER_JSON_get_error_code (json); + hr.ec = TALER_JSON_get_error_code (json); + 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_CONFLICT: - ec = TALER_JSON_get_error_code (json); + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: /* 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 reply to the application */ - ec = TALER_JSON_get_error_code (json); + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: /* Nothing really to verify, this should never happen, we should pass the JSON reply to the application */ - ec = TALER_JSON_get_error_code (json); + hr.ec = TALER_JSON_get_error_code (json); + 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 */ - ec = TALER_JSON_get_error_code (json); + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u\n", - (unsigned int) response_code); - GNUNET_break (0); - response_code = 0; - ec = TALER_JSON_get_error_code (json); + "Unexpected response code %u/%d\n", + (unsigned int) response_code, + (int) hr.ec); + GNUNET_break_op (0); break; } po->cb (po->cb_cls, - response_code, - ec, - json, + &hr, order_id); - GNUNET_JSON_parse_free (spec); + if (MHD_HTTP_OK == response_code) + GNUNET_JSON_parse_free (spec); TALER_MERCHANT_proposal_cancel (po); } @@ -269,187 +222,13 @@ TALER_MERCHANT_order_put (struct GNUNET_CURL_Context *ctx, /** - * Function called when we're done processing the GET /proposal request. - * - * @param cls the `struct TALER_MERCHANT_ProposalLookupOperation` - * @param response_code HTTP response code, 0 on error - * @param json response body, should be NULL - */ -static void -handle_proposal_lookup_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_ProposalLookupOperation *plo = cls; - json_t *contract_terms; - struct TALER_MerchantSignatureP sig; - struct GNUNET_HashCode hash; - const json_t *json = response; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("contract_terms", - &contract_terms), - GNUNET_JSON_spec_fixed_auto ("sig", - &sig), - GNUNET_JSON_spec_end () - }; - - plo->job = NULL; - if (MHD_HTTP_OK != response_code) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Proposal lookup failed with HTTP status code %u\n", - (unsigned int) response_code); - GNUNET_break (0); - plo->cb (plo->cb_cls, - response_code, - json, - NULL, - NULL, - NULL); - TALER_MERCHANT_proposal_lookup_cancel (plo); - return; - } - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "proposal lookup failed to parse JSON\n"); - GNUNET_break_op (0); - plo->cb (plo->cb_cls, - 0, - json, - NULL, - NULL, - NULL); - TALER_MERCHANT_proposal_lookup_cancel (plo); - return; - } - - if (GNUNET_OK != - TALER_JSON_hash (contract_terms, - &hash)) - { - GNUNET_break (0); - GNUNET_JSON_parse_free (spec); - plo->cb (plo->cb_cls, - 0, - json, - NULL, - NULL, - NULL); - TALER_MERCHANT_proposal_lookup_cancel (plo); - return; - } - - plo->job = NULL; - /** - * As no data is supposed to be extracted from this - * call, we just invoke the provided callback. - */ - plo->cb (plo->cb_cls, - response_code, - json, - contract_terms, - &sig, - &hash); - GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_proposal_lookup_cancel (plo); -} - - -/** - * Calls the GET /proposal API at the backend. That is, - * retrieve a proposal data by providing its transaction id. - * - * @param ctx execution context - * @param backend_url base URL of the merchant backend - * @param order_id order id used to perform the lookup - * @param nonce nonce used to perform the lookup - * @param plo_cb callback which will work the response gotten from the backend - * @param plo_cb_cls closure to pass to @a history_cb - * @return handle for this operation, NULL upon errors - */ -struct TALER_MERCHANT_ProposalLookupOperation * -TALER_MERCHANT_proposal_lookup (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const struct - GNUNET_CRYPTO_EddsaPublicKey *nonce, - TALER_MERCHANT_ProposalLookupOperationCallback - plo_cb, - void *plo_cb_cls) -{ - struct TALER_MERCHANT_ProposalLookupOperation *plo; - CURL *eh; - char *nonce_str = NULL; - - plo = GNUNET_new (struct TALER_MERCHANT_ProposalLookupOperation); - plo->ctx = ctx; - plo->cb = plo_cb; - plo->cb_cls = plo_cb_cls; - if (NULL != nonce) - { - plo->has_nonce = GNUNET_YES; - plo->nonce = *nonce; - nonce_str = GNUNET_STRINGS_data_to_string_alloc (nonce, sizeof (struct - GNUNET_CRYPTO_EddsaPublicKey)); - } - plo->url = TALER_url_join (backend_url, "proposal", - "order_id", - order_id, - "nonce", - nonce_str, - NULL); - GNUNET_free_non_null (nonce_str); - if (NULL == plo->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (plo); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "looking up proposal from %s\n", - plo->url); - eh = curl_easy_init (); - if (CURLE_OK != curl_easy_setopt (eh, - CURLOPT_URL, - plo->url)) - { - GNUNET_break (0); - curl_easy_cleanup (eh); - GNUNET_free (plo->url); - GNUNET_free (plo); - return NULL; - } - - if (NULL == (plo->job = GNUNET_CURL_job_add (ctx, - eh, - GNUNET_YES, - &handle_proposal_lookup_finished, - plo))) - { - GNUNET_break (0); - GNUNET_free (plo->url); - GNUNET_free (plo); - return NULL; - } - return plo; -} - - -/** * Cancel a POST /proposal request. This function cannot be used * on a request handle if a response is already served for it. * * @param po the proposal operation request handle */ void -TALER_MERCHANT_proposal_cancel - (struct TALER_MERCHANT_ProposalOperation *po) +TALER_MERCHANT_proposal_cancel (struct TALER_MERCHANT_ProposalOperation *po) { if (NULL != po->job) { @@ -462,23 +241,4 @@ TALER_MERCHANT_proposal_cancel } -/** - * Cancel a GET /proposal request. - * - * @param plo handle to the request to be canceled - */ -void -TALER_MERCHANT_proposal_lookup_cancel - (struct TALER_MERCHANT_ProposalLookupOperation *plo) -{ - if (NULL != plo->job) - { - GNUNET_CURL_job_cancel (plo->job); - plo->job = NULL; - } - GNUNET_free (plo->url); - GNUNET_free (plo); -} - - -/* end of merchant_api_contract.c */ +/* end of merchant_api_proposal.c */ |