diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-10-30 17:13:09 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-10-30 17:13:09 +0100 |
commit | 09c40af96fa338f6ba57a24df7d43b65384420f9 (patch) | |
tree | 59cd6a3b6efec590cb0f3872b08792a7f7387f7f /src/lib | |
parent | df8395e9c528a3eed89ce0814bc8b5c37daae267 (diff) | |
download | merchant-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.c | 136 |
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) { |