/* This file is part of TALER Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, If not, see */ /** * @file mint-lib/mint_api.c * @brief Implementation of the client interface to mint's HTTP API * @author Sree Harsha Totakura */ #include "platform.h" #include #include #include #include "taler_mint_service.h" #include "taler_signatures.h" // leftovers follow... /** * Log error related to CURL operations. * * @param type log level * @param function which function failed to run * @param code what was the curl error code */ #define CURL_STRERROR(type, function, code) \ GNUNET_log (type, "Curl function `%s' has failed at `%s:%d' with error: %s", \ function, __FILE__, __LINE__, curl_easy_strerror (code)); /** * Print JSON parsing related error information */ #define JSON_WARN(error) \ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \ "JSON parsing failed at %s:%u: %s (%s)", \ __FILE__, __LINE__, error.text, error.source) /** * Failsafe flag. Raised if our constructor fails to initialize * the Curl library. */ static int TALER_MINT_curl_fail; /** * A handle to submit a deposit permission and get its status */ struct TALER_MINT_DepositHandle { /** *The connection to mint this request handle will use */ struct TALER_MINT_Handle *mint; /** * The url for this handle */ char *url; TALER_MINT_DepositResultCallback cb; void *cb_cls; char *json_enc; struct curl_slist *headers; }; #define EXITIF(cond) \ do { \ if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ } while (0) static int parse_deposit_response (void *buf, size_t size, int *r_status, json_t **r_obj) { json_t *obj; const char *status_str; json_error_t error; status_str = NULL; obj = NULL; obj = json_loadb (buf, size, JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK, &error); if (NULL == obj) { JSON_WARN (error); return GNUNET_SYSERR; } EXITIF (-1 == json_unpack (obj, "{s:s}", "status", &status_str)); TALER_LOG_DEBUG ("Received deposit response: %s from mint\n", status_str); if (0 == strcmp ("DEPOSIT_OK", status_str)) *r_status = 1; else if (0 == strcmp ("DEPOSIT_QUEUED", status_str)) *r_status = 2; else *r_status = 0; *r_obj = obj; return GNUNET_OK; EXITIF_exit: json_decref (obj); return GNUNET_SYSERR; } #undef EXITIF /** * Submit a deposit permission to the mint and get the mint's response * * @param mint the mint handle * @param cb the callback to call when a reply for this request is available * @param cb_cls closure for the above callback * @param deposit_obj the deposit permission received from the customer along * with the wireformat JSON object * @return a handle for this request; NULL if the JSON object could not be * parsed or is of incorrect format or any other error. In this case, * the callback is not called. */ struct TALER_MINT_DepositHandle * TALER_MINT_deposit_submit_json (struct TALER_MINT_Handle *mint, TALER_MINT_DepositResultCallback cb, void *cb_cls, json_t *deposit_obj) { struct TALER_MINT_DepositHandle *dh; GNUNET_assert (REQUEST_TYPE_NONE == mint->req_type); dh = GNUNET_new (struct TALER_MINT_DepositHandle); dh->mint = mint; mint->req_type = REQUEST_TYPE_DEPOSIT; mint->req.deposit = dh; dh->cb = cb; dh->cb_cls = cb_cls; GNUNET_asprintf (&dh->url, "http://%s:%hu/deposit", mint->hostname, mint->port); GNUNET_assert (NULL != (dh->json_enc = json_dumps (deposit_obj, JSON_COMPACT))); GNUNET_assert (CURLE_OK == curl_easy_setopt (mint->curl, CURLOPT_URL, dh->url)); GNUNET_assert (CURLE_OK == curl_easy_setopt (mint->curl, CURLOPT_POSTFIELDS, dh->json_enc)); GNUNET_assert (CURLE_OK == curl_easy_setopt (mint->curl, CURLOPT_POSTFIELDSIZE, strlen (dh->json_enc))); GNUNET_assert (NULL != (dh->headers = curl_slist_append (dh->headers, "Content-Type: application/json"))); GNUNET_assert (CURLE_OK == curl_easy_setopt (mint->curl, CURLOPT_HTTPHEADER, dh->headers)); if (GNUNET_NO == mint->connected) mint_connect (mint); perform_now (mint->ctx); return dh; } /* end of mint_api.c */