summaryrefslogtreecommitdiff
path: root/src/lib/merchant_api_proposal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/merchant_api_proposal.c')
-rw-r--r--src/lib/merchant_api_proposal.c312
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 */