summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-10-30 17:13:09 +0100
committerChristian Grothoff <christian@grothoff.org>2020-10-30 17:13:09 +0100
commit09c40af96fa338f6ba57a24df7d43b65384420f9 (patch)
tree59cd6a3b6efec590cb0f3872b08792a7f7387f7f /src/lib
parentdf8395e9c528a3eed89ce0814bc8b5c37daae267 (diff)
downloadmerchant-09c40af96fa338f6ba57a24df7d43b65384420f9.tar.gz
merchant-09c40af96fa338f6ba57a24df7d43b65384420f9.tar.bz2
merchant-09c40af96fa338f6ba57a24df7d43b65384420f9.zip
properly parse and return out-of-stock reply, fix 2 FIXMEs
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/merchant_api_post_orders.c136
1 files changed, 81 insertions, 55 deletions
diff --git a/src/lib/merchant_api_post_orders.c b/src/lib/merchant_api_post_orders.c
index a6f1ec71..9c45ad2c 100644
--- a/src/lib/merchant_api_post_orders.c
+++ b/src/lib/merchant_api_post_orders.c
@@ -37,7 +37,7 @@
/**
* @brief A POST /orders Handle
*/
-struct TALER_MERCHANT_PostOrdersOperation
+struct TALER_MERCHANT_PostOrdersHandle
{
/**
@@ -76,7 +76,7 @@ struct TALER_MERCHANT_PostOrdersOperation
* Function called when we're done processing the
* HTTP POST /orders request.
*
- * @param cls the `struct TALER_MERCHANT_PostOrdersOperation`
+ * @param cls the `struct TALER_MERCHANT_PostOrdersHandle`
* @param response_code HTTP response code, 0 on error
* @param response response body, NULL if not JSON
*/
@@ -85,48 +85,50 @@ handle_post_order_finished (void *cls,
long response_code,
const void *response)
{
- struct TALER_MERCHANT_PostOrdersOperation *po = cls;
- const char *order_id = NULL;
- struct TALER_ClaimTokenP token = {0};
+ struct TALER_MERCHANT_PostOrdersHandle *po = cls;
const json_t *json = response;
- struct TALER_MERCHANT_HttpResponse hr = {
- .http_status = (unsigned int) response_code,
- .reply = json
- };
- bool has_token = ((NULL != json_object_get (json,
- "token")) &&
- (false == json_is_null (json_object_get (json,
- "token"))));
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_string ("order_id",
- &order_id),
- (! has_token) ?
- GNUNET_JSON_spec_end () :
- GNUNET_JSON_spec_fixed_auto ("token",
- &token),
- GNUNET_JSON_spec_end ()
+ struct TALER_MERCHANT_PostOrdersReply por = {
+ .hr.http_status = (unsigned int) response_code,
+ .hr.reply = json
};
-
+ struct TALER_ClaimTokenP token = {0};
+
po->job = NULL;
switch (response_code)
{
case 0:
- hr.ec = TALER_EC_INVALID_RESPONSE;
+ por.hr.ec = TALER_EC_INVALID_RESPONSE;
break;
case MHD_HTTP_OK:
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec,
- NULL, NULL))
{
- GNUNET_break_op (0);
- hr.http_status = 0;
- hr.ec = TALER_EC_PROPOSAL_REPLY_MALFORMED;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("order_id",
+ &por.details.ok.order_id),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_fixed_auto ("token",
+ &token)),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (json,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ por.hr.http_status = 0;
+ por.hr.ec = TALER_EC_PROPOSAL_REPLY_MALFORMED;
+ }
+ else
+ {
+ if (! GNUNET_is_zero (&token))
+ por.details.ok.token = &token;
+ }
}
break;
case MHD_HTTP_BAD_REQUEST:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ por.hr.ec = TALER_JSON_get_error_code (json);
+ por.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 */
@@ -136,51 +138,75 @@ handle_post_order_finished (void *cls,
of the signatures is invalid; as we checked them,
this should never happen, we should pass the JSON
reply to the application */
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ por.hr.ec = TALER_JSON_get_error_code (json);
+ por.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 */
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ por.hr.ec = TALER_JSON_get_error_code (json);
+ por.hr.hint = TALER_JSON_get_error_hint (json);
break;
case MHD_HTTP_CONFLICT:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ por.hr.ec = TALER_JSON_get_error_code (json);
+ por.hr.hint = TALER_JSON_get_error_hint (json);
break;
case MHD_HTTP_GONE:
/* The quantity of some product requested was not available. */
- // FIXME: parse the OutOfStockResponse.
- break;
+ {
+
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string (
+ "product_id",
+ &por.details.gone.product_id),
+ GNUNET_JSON_spec_uint64 (
+ "requested_quantity",
+ &por.details.gone.requested_quantity),
+ GNUNET_JSON_spec_uint64 (
+ "available_quantity",
+ &por.details.gone.available_quantity),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_absolute_time (
+ "restock_expected",
+ &por.details.gone.restock_expected)),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (json,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ por.hr.http_status = 0;
+ por.hr.ec = TALER_EC_PROPOSAL_REPLY_MALFORMED;
+ }
+ break;
+ }
case MHD_HTTP_INTERNAL_SERVER_ERROR:
/* Server had an internal issue; we should retry,
but this API leaves this to the application */
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ por.hr.ec = TALER_JSON_get_error_code (json);
+ por.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);
+ por.hr.ec = TALER_JSON_get_error_code (json);
+ por.hr.hint = TALER_JSON_get_error_hint (json);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d\n",
(unsigned int) response_code,
- (int) hr.ec);
+ (int) por.hr.ec);
GNUNET_break_op (0);
break;
}
po->cb (po->cb_cls,
- &hr,
- order_id,
- has_token ? &token : NULL);
- if (MHD_HTTP_OK == response_code)
- GNUNET_JSON_parse_free (spec);
+ &por);
TALER_MERCHANT_orders_post_cancel (po);
}
-struct TALER_MERCHANT_PostOrdersOperation *
+struct TALER_MERCHANT_PostOrdersHandle *
TALER_MERCHANT_orders_post (struct GNUNET_CURL_Context *ctx,
const char *backend_url,
const json_t *order,
@@ -203,7 +229,7 @@ TALER_MERCHANT_orders_post (struct GNUNET_CURL_Context *ctx,
}
-struct TALER_MERCHANT_PostOrdersOperation *
+struct TALER_MERCHANT_PostOrdersHandle *
TALER_MERCHANT_orders_post2 (
struct GNUNET_CURL_Context *ctx,
const char *backend_url,
@@ -218,11 +244,11 @@ TALER_MERCHANT_orders_post2 (
TALER_MERCHANT_PostOrdersCallback cb,
void *cb_cls)
{
- struct TALER_MERCHANT_PostOrdersOperation *po;
+ struct TALER_MERCHANT_PostOrdersHandle *po;
json_t *req;
CURL *eh;
- po = GNUNET_new (struct TALER_MERCHANT_PostOrdersOperation);
+ po = GNUNET_new (struct TALER_MERCHANT_PostOrdersHandle);
po->ctx = ctx;
po->cb = cb;
po->cb_cls = cb_cls;
@@ -327,7 +353,7 @@ TALER_MERCHANT_orders_post2 (
void
TALER_MERCHANT_orders_post_cancel (
- struct TALER_MERCHANT_PostOrdersOperation *po)
+ struct TALER_MERCHANT_PostOrdersHandle *po)
{
if (NULL != po->job)
{