diff options
| -rw-r--r-- | src/bank-lib/Makefile.am | 3 | ||||
| -rw-r--r-- | src/bank-lib/bank_api_admin.c | 91 | ||||
| -rw-r--r-- | src/bank-lib/bank_api_context.c | 570 | ||||
| -rw-r--r-- | src/bank-lib/bank_api_context.h | 182 | ||||
| -rw-r--r-- | src/bank-lib/test_bank_api.c | 24 | ||||
| -rw-r--r-- | src/exchange-lib/exchange_api_refresh.c | 8 | ||||
| -rw-r--r-- | src/include/taler_bank_service.h | 86 | ||||
| -rw-r--r-- | src/include/taler_exchange_service.h | 75 | 
8 files changed, 74 insertions, 965 deletions
| diff --git a/src/bank-lib/Makefile.am b/src/bank-lib/Makefile.am index 58b1c67d..dc52f8e0 100644 --- a/src/bank-lib/Makefile.am +++ b/src/bank-lib/Makefile.am @@ -14,11 +14,11 @@ libtalerbank_la_LDFLAGS = \    -no-undefined  libtalerbank_la_SOURCES = \ -  bank_api_context.c bank_api_context.h \    bank_api_admin.c  libtalerbank_la_LIBADD = \    $(top_builddir)/src/json/libtalerjson.la \ +  -lgnunetcurl \    -lgnunetjson \    -lgnunetutil \    -ljansson \ @@ -43,5 +43,6 @@ test_bank_api_SOURCES = \  test_bank_api_LDADD = \    libtalerbank.la \    $(top_builddir)/src/util/libtalerutil.la \ +  -lgnunetcurl \    -lgnunetutil \    -ljansson diff --git a/src/bank-lib/bank_api_admin.c b/src/bank-lib/bank_api_admin.c index 907e15ea..a334d462 100644 --- a/src/bank-lib/bank_api_admin.c +++ b/src/bank-lib/bank_api_admin.c @@ -25,9 +25,9 @@  #include <microhttpd.h> /* just for HTTP status codes */  #include <gnunet/gnunet_util_lib.h>  #include <gnunet/gnunet_json_lib.h> +#include <gnunet/gnunet_curl_lib.h>  #include "taler_bank_service.h"  #include "taler_json_lib.h" -#include "bank_api_context.h"  #include "taler_signatures.h" @@ -38,14 +38,9 @@ struct TALER_BANK_AdminAddIncomingHandle  {    /** -   * The connection to bank this request handle will use -   */ -  struct TALER_BANK_Context *bank; - -  /**     * The url for this request.     */ -  char *url; +  char *request_url;    /**     * JSON encoding of the request to POST. @@ -55,7 +50,7 @@ struct TALER_BANK_AdminAddIncomingHandle    /**     * Handle for the request.     */ -  struct BAC_Job *job; +  struct GNUNET_CURL_Job *job;    /**     * HTTP headers for the request. @@ -72,33 +67,53 @@ struct TALER_BANK_AdminAddIncomingHandle     */    void *cb_cls; -  /** -   * Download buffer -   */ -  struct BAC_DownloadBuffer db; -  }; + +/** + * Obtain the URL to use for an API request. + * + * @param u base URL of the bank + * @param path Taler API path (i.e. "/reserve/withdraw") + * @return the full URI to use with cURL + */ +static char * +path_to_url (const char *u, +             const char *path) +{ +  char *url; + +  if ( ('/' == path[0]) && +       (0 < strlen (u)) && +       ('/' == u[strlen (u) - 1]) ) +    path++; /* avoid generating URL with "//" from concat */ +  GNUNET_asprintf (&url, +                   "%s%s", +                   u, +                   path); +  return url; +} + + + +  /**   * Function called when we're done processing the   * HTTP /admin/add/incoming request.   *   * @param cls the `struct TALER_BANK_AdminAddIncomingHandle` - * @param eh the curl request handle + * @param response_code HTTP response code, 0 on error + * @param json parsed JSON result, NULL on error   */  static void  handle_admin_add_incoming_finished (void *cls, -                                    CURL *eh) +                                    long response_code, +                                    const json_t *json)  {    struct TALER_BANK_AdminAddIncomingHandle *aai = cls; -  long response_code; -  json_t *json;    aai->job = NULL; -  json = BAC_download_get_result (&aai->db, -                                  eh, -                                  &response_code);    switch (response_code)    {    case 0: @@ -137,7 +152,6 @@ handle_admin_add_incoming_finished (void *cls,    aai->cb (aai->cb_cls,             response_code,             json); -  json_decref (json);    TALER_BANK_admin_add_incoming_cancel (aai);  } @@ -148,7 +162,8 @@ handle_admin_add_incoming_finished (void *cls,   * API and thus not accessible to typical bank clients, but only   * to the operators of the bank.   * - * @param bank the bank handle; the bank must be ready to operate + * @param ctx curl context for the event loop + * @param bank_base_url URL of the bank   * @param reserve_pub public key of the reserve   * @param amount amount that was deposited   * @param execution_date when did we receive the amount @@ -161,7 +176,8 @@ handle_admin_add_incoming_finished (void *cls,   *         In this case, the callback is not called.   */  struct TALER_BANK_AdminAddIncomingHandle * -TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank, +TALER_BANK_admin_add_incoming (struct GNUNET_CURL_Context *ctx, +                               const char *bank_base_url,                                 const struct TALER_WireTransferIdentifierRawP *wtid,                                 const struct TALER_Amount *amount,                                 uint64_t debit_account_no, @@ -181,10 +197,10 @@ TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank,                           "debit_account", (json_int_t) debit_account_no,                           "credit_account", (json_int_t) credit_account_no);    aai = GNUNET_new (struct TALER_BANK_AdminAddIncomingHandle); -  aai->bank = bank;    aai->cb = res_cb;    aai->cb_cls = res_cb_cls; -  aai->url = BAC_path_to_url (bank, "/admin/add/incoming"); +  aai->request_url = path_to_url (bank_base_url, +                                  "/admin/add/incoming");    eh = curl_easy_init ();    GNUNET_assert (NULL != (aai->json_enc = @@ -194,7 +210,7 @@ TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank,    GNUNET_assert (CURLE_OK ==                   curl_easy_setopt (eh,                                     CURLOPT_URL, -                                   aai->url)); +                                   aai->request_url));    GNUNET_assert (CURLE_OK ==                   curl_easy_setopt (eh,                                     CURLOPT_POSTFIELDS, @@ -203,19 +219,11 @@ TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank,                   curl_easy_setopt (eh,                                     CURLOPT_POSTFIELDSIZE,                                     strlen (aai->json_enc))); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_WRITEFUNCTION, -                                   &BAC_download_cb)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_WRITEDATA, -                                   &aai->db)); -  aai->job = BAC_job_add (bank, -                          eh, -                          GNUNET_YES, -                          &handle_admin_add_incoming_finished, -                          aai); +  aai->job = GNUNET_CURL_job_add (ctx, +                                  eh, +                                  GNUNET_YES, +                                  &handle_admin_add_incoming_finished, +                                  aai);    return aai;  } @@ -231,12 +239,11 @@ TALER_BANK_admin_add_incoming_cancel (struct TALER_BANK_AdminAddIncomingHandle *  {    if (NULL != aai->job)    { -    BAC_job_cancel (aai->job); +    GNUNET_CURL_job_cancel (aai->job);      aai->job = NULL;    }    curl_slist_free_all (aai->headers); -  GNUNET_free_non_null (aai->db.buf); -  GNUNET_free (aai->url); +  GNUNET_free (aai->request_url);    GNUNET_free (aai->json_enc);    GNUNET_free (aai);  } diff --git a/src/bank-lib/bank_api_context.c b/src/bank-lib/bank_api_context.c deleted file mode 100644 index 2e4083ca..00000000 --- a/src/bank-lib/bank_api_context.c +++ /dev/null @@ -1,570 +0,0 @@ -/* -  This file is part of TALER -  Copyright (C) 2014, 2015 GNUnet e.V. - -  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 -  <http://www.gnu.org/licenses/> -*/ -/** - * @file bank-lib/bank_api_context.c - * @brief Implementation of the context part of the bank's HTTP API - * @author Sree Harsha Totakura <sreeharsha@totakura.in> - * @author Christian Grothoff - */ -#include "platform.h" -#include <curl/curl.h> -#include "taler_bank_service.h" -#include "bank_api_context.h" - - -/** - * 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\n", \ -             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)\n",              \ -                __FILE__, __LINE__, error.text, error.source) - - -/** - * Failsafe flag. Raised if our constructor fails to initialize - * the Curl library. - */ -static int TALER_BANK_curl_fail; - - -/** - * Jobs are CURL requests running within a `struct TALER_BANK_Context`. - */ -struct BAC_Job -{ - -  /** -   * We keep jobs in a DLL. -   */ -  struct BAC_Job *next; - -  /** -   * We keep jobs in a DLL. -   */ -  struct BAC_Job *prev; - -  /** -   * Easy handle of the job. -   */ -  CURL *easy_handle; - -  /** -   * Context this job runs in. -   */ -  struct TALER_BANK_Context *ctx; - -  /** -   * Function to call upon completion. -   */ -  BAC_JobCompletionCallback jcc; - -  /** -   * Closure for @e jcc. -   */ -  void *jcc_cls; - -}; - - -/** - * Context - */ -struct TALER_BANK_Context -{ -  /** -   * Curl multi handle -   */ -  CURLM *multi; - -  /** -   * Curl share handle -   */ -  CURLSH *share; - -  /** -   * We keep jobs in a DLL. -   */ -  struct BAC_Job *jobs_head; - -  /** -   * We keep jobs in a DLL. -   */ -  struct BAC_Job *jobs_tail; - -  /** -   * HTTP header "application/json", created once and used -   * for all requests that need it. -   */ -  struct curl_slist *json_header; - -  /** -   * Base URL of the bank. -   */ -  char *url; - -}; - - -/** - * Initialise this library.  This function should be called before using any of - * the following functions. - * - * @param url HTTP base URL for the bank - * @return library context - */ -struct TALER_BANK_Context * -TALER_BANK_init (const char *url) -{ -  struct TALER_BANK_Context *ctx; -  CURLM *multi; -  CURLSH *share; - -  if (TALER_BANK_curl_fail) -  { -    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -                "Curl was not initialised properly\n"); -    return NULL; -  } -  if (NULL == (multi = curl_multi_init ())) -  { -    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -                "Failed to create a Curl multi handle\n"); -    return NULL; -  } -  if (NULL == (share = curl_share_init ())) -  { -    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -                "Failed to create a Curl share handle\n"); -    return NULL; -  } -  ctx = GNUNET_new (struct TALER_BANK_Context); -  ctx->multi = multi; -  ctx->share = share; -  ctx->url = GNUNET_strdup (url); -  GNUNET_assert (NULL != (ctx->json_header = -                          curl_slist_append (NULL, -                                             "Content-Type: application/json"))); -  return ctx; -} - - -/** - * Schedule a CURL request to be executed and call the given @a jcc - * upon its completion.  Note that the context will make use of the - * CURLOPT_PRIVATE facility of the CURL @a eh.  Applications can - * instead use #BAC_easy_to_closure to extract the @a jcc_cls argument - * from a valid @a eh afterwards. - * - * This function modifies the CURL handle to add the - * "Content-Type: application/json" header if @a add_json is set. - * - * @param ctx context to execute the job in - * @param eh curl easy handle for the request, will - *           be executed AND cleaned up - * @param add_json add "application/json" content type header - * @param jcc callback to invoke upon completion - * @param jcc_cls closure for @a jcc - */ -struct BAC_Job * -BAC_job_add (struct TALER_BANK_Context *ctx, -             CURL *eh, -             int add_json, -             BAC_JobCompletionCallback jcc, -             void *jcc_cls) -{ -  struct BAC_Job *job; - -  if (GNUNET_YES == add_json) -    GNUNET_assert (CURLE_OK == -                   curl_easy_setopt (eh, -                                     CURLOPT_HTTPHEADER, -                                     ctx->json_header)); - -  job = GNUNET_new (struct BAC_Job); -  job->easy_handle = eh; -  job->ctx = ctx; -  job->jcc = jcc; -  job->jcc_cls = jcc_cls; -  GNUNET_CONTAINER_DLL_insert (ctx->jobs_head, -                               ctx->jobs_tail, -                               job); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_PRIVATE, -                                   job)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_SHARE, -                                   ctx->share)); -  GNUNET_assert (CURLM_OK == -                 curl_multi_add_handle (ctx->multi, -                                        eh)); -  return job; -} - - -/** - * Obtain the `jcc_cls` argument from an `eh` that was - * given to #BAC_job_add(). - * - * @param eh easy handle that was used - * @return the `jcc_cls` that was given to #BAC_job_add(). - */ -void * -BAC_easy_to_closure (CURL *eh) -{ -  struct BAC_Job *job; - -  GNUNET_assert (CURLE_OK == -                 curl_easy_getinfo (eh, -                                    CURLINFO_PRIVATE, -                                    (char **) &job)); -  return job->jcc_cls; -} - - -/** - * Cancel a job.  Must only be called before the job completion - * callback is called for the respective job. - * - * @param job job to cancel - */ -void -BAC_job_cancel (struct BAC_Job *job) -{ -  struct TALER_BANK_Context *ctx = job->ctx; - -  GNUNET_CONTAINER_DLL_remove (ctx->jobs_head, -                               ctx->jobs_tail, -                               job); -  GNUNET_assert (CURLM_OK == -                 curl_multi_remove_handle (ctx->multi, -                                           job->easy_handle)); -  curl_easy_cleanup (job->easy_handle); -  GNUNET_free (job); -} - - -/** - * Run the main event loop for the Taler interaction. - * - * @param ctx the library context - */ -void -TALER_BANK_perform (struct TALER_BANK_Context *ctx) -{ -  CURLMsg *cmsg; -  struct BAC_Job *job; -  int n_running; -  int n_completed; - -  (void) curl_multi_perform (ctx->multi, -                             &n_running); -  while (NULL != (cmsg = curl_multi_info_read (ctx->multi, -                                               &n_completed))) -  { -    /* Only documented return value is CURLMSG_DONE */ -    GNUNET_break (CURLMSG_DONE == cmsg->msg); -    GNUNET_assert (CURLE_OK == -                   curl_easy_getinfo (cmsg->easy_handle, -                                      CURLINFO_PRIVATE, -                                      (char **) &job)); -    GNUNET_assert (job->ctx == ctx); -    job->jcc (job->jcc_cls, -              cmsg->easy_handle); -    BAC_job_cancel (job); -  } -} - - -/** - * Obtain the information for a select() call to wait until - * #TALER_BANK_perform() is ready again.  Note that calling - * any other TALER_BANK-API may also imply that the library - * is again ready for #TALER_BANK_perform(). - * - * Basically, a client should use this API to prepare for select(), - * then block on select(), then call #TALER_BANK_perform() and then - * start again until the work with the context is done. - * - * This function will NOT zero out the sets and assumes that @a max_fd - * and @a timeout are already set to minimal applicable values.  It is - * safe to give this API FD-sets and @a max_fd and @a timeout that are - * already initialized to some other descriptors that need to go into - * the select() call. - * - * @param ctx context to get the event loop information for - * @param read_fd_set will be set for any pending read operations - * @param write_fd_set will be set for any pending write operations - * @param except_fd_set is here because curl_multi_fdset() has this argument - * @param max_fd set to the highest FD included in any set; - *        if the existing sets have no FDs in it, the initial - *        value should be "-1". (Note that `max_fd + 1` will need - *        to be passed to select().) - * @param timeout set to the timeout in milliseconds (!); -1 means - *        no timeout (NULL, blocking forever is OK), 0 means to - *        proceed immediately with #TALER_BANK_perform(). - */ -void -TALER_BANK_get_select_info (struct TALER_BANK_Context *ctx, -                            fd_set *read_fd_set, -                            fd_set *write_fd_set, -                            fd_set *except_fd_set, -                            int *max_fd, -                            long *timeout) -{ -  long to; -  int m; - -  m = -1; -  GNUNET_assert (CURLM_OK == -                 curl_multi_fdset (ctx->multi, -                                   read_fd_set, -                                   write_fd_set, -                                   except_fd_set, -                                   &m)); -  to = *timeout; -  *max_fd = GNUNET_MAX (m, *max_fd); -  GNUNET_assert (CURLM_OK == -                 curl_multi_timeout (ctx->multi, -                                     &to)); - -  /* Only if what we got back from curl is smaller than what we -     already had (-1 == infinity!), then update timeout */ -  if ( (to < *timeout) && -       (-1 != to) ) -    *timeout = to; -  if ( (-1 == (*timeout)) && -       (NULL != ctx->jobs_head) ) -    *timeout = to; -} - - -/** - * Cleanup library initialisation resources.  This function should be called - * after using this library to cleanup the resources occupied during library's - * initialisation. - * - * @param ctx the library context - */ -void -TALER_BANK_fini (struct TALER_BANK_Context *ctx) -{ -  /* all jobs must have been cancelled at this time, assert this */ -  GNUNET_assert (NULL == ctx->jobs_head); -  curl_share_cleanup (ctx->share); -  curl_multi_cleanup (ctx->multi); -  curl_slist_free_all (ctx->json_header); -  GNUNET_free (ctx->url); -  GNUNET_free (ctx); -} - - -/** - * Obtain the URL to use for an API request. - * - * @param h the exchange handle to query - * @param path Taler API path (i.e. "/reserve/withdraw") - * @return the full URI to use with cURL - */ -char * -BAC_path_to_url (struct TALER_BANK_Context *h, -                 const char *path) -{ -  char *url; - -  if ( ('/' == path[0]) && -       (0 < strlen (h->url)) && -       ('/' == h->url[strlen (h->url) - 1]) ) -    path++; /* avoid generating URL with "//" from concat */ -  GNUNET_asprintf (&url, -                   "%s%s", -                   h->url, -                   path); -  return url; -} - - -/** - * Callback used when downloading the reply to an HTTP request. - * Just appends all of the data to the `buf` in the - * `struct BAC_DownloadBuffer` for further processing. The size of - * the download is limited to #GNUNET_MAX_MALLOC_CHECKED, if - * the download exceeds this size, we abort with an error. - * - * @param bufptr data downloaded via HTTP - * @param size size of an item in @a bufptr - * @param nitems number of items in @a bufptr - * @param cls the `struct KeysRequest` - * @return number of bytes processed from @a bufptr - */ -size_t -BAC_download_cb (char *bufptr, -                 size_t size, -                 size_t nitems, -                 void *cls) -{ -  struct BAC_DownloadBuffer *db = cls; -  size_t msize; -  void *buf; - -  if (0 == size * nitems) -  { -    /* Nothing (left) to do */ -    return 0; -  } -  msize = size * nitems; -  if ( (msize + db->buf_size) >= GNUNET_MAX_MALLOC_CHECKED) -  { -    db->eno = ENOMEM; -    return 0; /* signals an error to curl */ -  } -  db->buf = GNUNET_realloc (db->buf, -                            db->buf_size + msize); -  buf = db->buf + db->buf_size; -  memcpy (buf, bufptr, msize); -  db->buf_size += msize; -  return msize; -} - - -/** - * Obtain information about the final result about the - * HTTP download. If the download was successful, parses - * the JSON in the @a db and returns it. Also returns - * the HTTP @a response_code.  If the download failed, - * the return value is NULL.  The response code is set - * in any case, on download errors to zero. - * - * Calling this function also cleans up @a db. - * - * @param db download buffer - * @param eh CURL handle (to get the response code) - * @param[out] response_code set to the HTTP response code - *             (or zero if we aborted the download, i.e. - *              because the response was too big, or if - *              the JSON we received was malformed). - * @return NULL if downloading a JSON reply failed - */ -json_t * -BAC_download_get_result (struct BAC_DownloadBuffer *db, -                         CURL *eh, -                         long *response_code) -{ -  json_t *json; -  json_error_t error; -  char *ct; - -  if ( (CURLE_OK != -        curl_easy_getinfo (eh, -                           CURLINFO_CONTENT_TYPE, -                           &ct)) || -       (NULL == ct) || -       (0 != strcasecmp (ct, -                         "application/json")) ) -  { -    /* No content type or explicitly not JSON, refuse to parse -       (but keep response code) */ -    if (CURLE_OK != -        curl_easy_getinfo (eh, -                           CURLINFO_RESPONSE_CODE, -                           response_code)) -    { -      /* unexpected error... */ -      GNUNET_break (0); -      *response_code = 0; -    } -    return NULL; -  } - -  json = NULL; -  if (0 == db->eno) -  { -    json = json_loadb (db->buf, -                       db->buf_size, -                       JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK, -                       &error); -    if (NULL == json) -    { -      JSON_WARN (error); -      *response_code = 0; -    } -  } -  GNUNET_free_non_null (db->buf); -  db->buf = NULL; -  db->buf_size = 0; -  if (NULL != json) -  { -    if (CURLE_OK != -        curl_easy_getinfo (eh, -                           CURLINFO_RESPONSE_CODE, -                           response_code)) -    { -      /* unexpected error... */ -      GNUNET_break (0); -      *response_code = 0; -    } -  } -  return json; -} - - -/** - * Initial global setup logic, specifically runs the Curl setup. - */ -__attribute__ ((constructor)) -void -TALER_BANK_constructor__ (void) -{ -  CURLcode ret; - -  if (CURLE_OK != (ret = curl_global_init (CURL_GLOBAL_DEFAULT))) -  { -    CURL_STRERROR (GNUNET_ERROR_TYPE_ERROR, -                   "curl_global_init", -                   ret); -    TALER_BANK_curl_fail = 1; -  } -} - - -/** - * Cleans up after us, specifically runs the Curl cleanup. - */ -__attribute__ ((destructor)) -void -TALER_BANK_destructor__ (void) -{ -  if (TALER_BANK_curl_fail) -    return; -  curl_global_cleanup (); -} - -/* end of bank_api_context.c */ diff --git a/src/bank-lib/bank_api_context.h b/src/bank-lib/bank_api_context.h deleted file mode 100644 index 1f21cb8d..00000000 --- a/src/bank-lib/bank_api_context.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -  This file is part of TALER -  Copyright (C) 2014, 2015 GNUnet e.V. - -  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 -  <http://www.gnu.org/licenses/> -*/ -/** - * @file bank-lib/bank_api_context.h - * @brief Internal interface to the context part of the bank's HTTP API - * @author Sree Harsha Totakura <sreeharsha@totakura.in> - * @author Christian Grothoff - */ -#include "platform.h" -#include <jansson.h> -#include <curl/curl.h> -#include <gnunet/gnunet_util_lib.h> -#include "taler_bank_service.h" -#include "taler_signatures.h" - - -/** - * Entry in the context's job queue. - */ -struct BAC_Job; - -/** - * Function to call upon completion of a job. - * - * @param cls closure - * @param eh original easy handle (for inspection) - */ -typedef void -(*BAC_JobCompletionCallback)(void *cls, -                             CURL *eh); - - -/** - * Schedule a CURL request to be executed and call the given @a jcc - * upon its completion. Note that the context will make use of the - * CURLOPT_PRIVATE facility of the CURL @a eh.  Applications can - * instead use #BAC_easy_to_closure to extract the @a jcc_cls argument - * from a valid @a eh afterwards. - * - * This function modifies the CURL handle to add the - * "Content-Type: application/json" header if @a add_json is set. - * - * @param ctx context to execute the job in - * @param eh curl easy handle for the request, will - *           be executed AND cleaned up - * @param add_json add "application/json" content type header - * @param jcc callback to invoke upon completion - * @param jcc_cls closure for @a jcc - */ -struct BAC_Job * -BAC_job_add (struct TALER_BANK_Context *ctx, -             CURL *eh, -             int add_json, -             BAC_JobCompletionCallback jcc, -             void *jcc_cls); - - -/** - * Obtain the `jcc_cls` argument from an `eh` that was - * given to #BAC_job_add(). - * - * @param eh easy handle that was used - * @return the `jcc_cls` that was given to #BAC_job_add(). - */ -void * -BAC_easy_to_closure (CURL *eh); - - -/** - * Cancel a job.  Must only be called before the job completion - * callback is called for the respective job. - * - * @param job job to cancel - */ -void -BAC_job_cancel (struct BAC_Job *job); - - -/** - * @brief Buffer data structure we use to buffer the HTTP download - * before giving it to the JSON parser. - */ -struct BAC_DownloadBuffer -{ - -  /** -   * Download buffer -   */ -  void *buf; - -  /** -   * The size of the download buffer -   */ -  size_t buf_size; - -  /** -   * Error code (based on libc errno) if we failed to download -   * (i.e. response too large). -   */ -  int eno; - -}; - - -/** - * Callback used when downloading the reply to an HTTP request. - * Just appends all of the data to the `buf` in the - * `struct BAC_DownloadBuffer` for further processing. The size of - * the download is limited to #GNUNET_MAX_MALLOC_CHECKED, if - * the download exceeds this size, we abort with an error. - * - * Should be used by the various routines as the - * CURLOPT_WRITEFUNCTION.  A `struct BAC_DownloadBuffer` needs to be - * passed to the CURLOPT_WRITEDATA. - * - * Afterwards, `eno` needs to be checked to ensure that the download - * completed correctly. - * - * @param bufptr data downloaded via HTTP - * @param size size of an item in @a bufptr - * @param nitems number of items in @a bufptr - * @param cls the `struct KeysRequest` - * @return number of bytes processed from @a bufptr - */ -size_t -BAC_download_cb (char *bufptr, -                 size_t size, -                 size_t nitems, -                 void *cls); - - -/** - * Obtain information about the final result about the - * HTTP download. If the download was successful, parses - * the JSON in the @a db and returns it. Also returns - * the HTTP @a response_code.  If the download failed, - * the return value is NULL.  The response code is set - * in any case, on download errors to zero. - * - * Calling this function also cleans up @a db. - * - * @param db download buffer - * @param eh CURL handle (to get the response code) - * @param[out] response_code set to the HTTP response code - *             (or zero if we aborted the download, i.e. - *              because the response was too big, or if - *              the JSON we received was malformed). - * @return NULL if downloading a JSON reply failed - */ -json_t * -BAC_download_get_result (struct BAC_DownloadBuffer *db, -                         CURL *eh, -                         long *response_code); - - -/** - * Obtain the URL to use for an API request. - * - * @param h the bank handle to query - * @param path Taler API path (i.e. "/reserve/withdraw") - * @return the full URI to use with cURL - */ -char * -BAC_path_to_url (struct TALER_BANK_Context *h, -                 const char *path); - - -/* end of bank_api_context.h */ diff --git a/src/bank-lib/test_bank_api.c b/src/bank-lib/test_bank_api.c index 4d6b9700..1b695f45 100644 --- a/src/bank-lib/test_bank_api.c +++ b/src/bank-lib/test_bank_api.c @@ -23,13 +23,14 @@  #include "taler_signatures.h"  #include "taler_bank_service.h"  #include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_curl_lib.h>  #include <microhttpd.h>  /**   * Main execution context for the main loop.   */ -static struct TALER_BANK_Context *ctx; +static struct GNUNET_CURL_Context *ctx;  /**   * Task run on shutdown. @@ -247,7 +248,7 @@ interpreter_run (void *cls);  static void  add_incoming_cb (void *cls,                   unsigned int http_status, -                 json_t *json) +                 const json_t *json)  {    struct InterpreterState *is = cls;    struct Command *cmd = &is->commands[is->ip]; @@ -319,6 +320,7 @@ interpreter_run (void *cls)                                  sizeof (cmd->details.admin_add_incoming.wtid));      cmd->details.admin_add_incoming.aih        = TALER_BANK_admin_add_incoming (ctx, +                                       "http://localhost:8081",                                         &cmd->details.admin_add_incoming.wtid,                                         &amount,                                         cmd->details.admin_add_incoming.debit_account_no, @@ -399,7 +401,7 @@ do_shutdown (void *cls)    }    if (NULL != ctx)    { -    TALER_BANK_fini (ctx); +    GNUNET_CURL_fini (ctx);      ctx = NULL;    }  } @@ -423,18 +425,18 @@ context_task (void *cls)    struct GNUNET_TIME_Relative delay;    ctx_task = NULL; -  TALER_BANK_perform (ctx); +  GNUNET_CURL_perform (ctx);    max_fd = -1;    timeout = -1;    FD_ZERO (&read_fd_set);    FD_ZERO (&write_fd_set);    FD_ZERO (&except_fd_set); -  TALER_BANK_get_select_info (ctx, -                              &read_fd_set, -                              &write_fd_set, -                              &except_fd_set, -                              &max_fd, -                              &timeout); +  GNUNET_CURL_get_select_info (ctx, +                               &read_fd_set, +                               &write_fd_set, +                               &except_fd_set, +                               &max_fd, +                               &timeout);    if (timeout >= 0)      delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,                                             timeout); @@ -484,7 +486,7 @@ run (void *cls)    is = GNUNET_new (struct InterpreterState);    is->commands = commands; -  ctx = TALER_BANK_init ("http://localhost:8081"); +  ctx = GNUNET_CURL_init ();    GNUNET_assert (NULL != ctx);    ctx_task = GNUNET_SCHEDULER_add_now (&context_task,                                         ctx); diff --git a/src/exchange-lib/exchange_api_refresh.c b/src/exchange-lib/exchange_api_refresh.c index 8435a469..5fe17567 100644 --- a/src/exchange-lib/exchange_api_refresh.c +++ b/src/exchange-lib/exchange_api_refresh.c @@ -1403,10 +1403,10 @@ melted_coin_to_json (const struct GNUNET_HashCode *melt_session_hash,   */  struct TALER_EXCHANGE_RefreshMeltHandle *  TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange, -                         size_t refresh_data_length, -                         const char *refresh_data, -                         TALER_EXCHANGE_RefreshMeltCallback melt_cb, -                         void *melt_cb_cls) +                             size_t refresh_data_length, +                             const char *refresh_data, +                             TALER_EXCHANGE_RefreshMeltCallback melt_cb, +                             void *melt_cb_cls)  {    json_t *melt_obj;    json_t *new_denoms; diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h index 920ae47f..a353b8ee 100644 --- a/src/include/taler_bank_service.h +++ b/src/include/taler_bank_service.h @@ -23,85 +23,9 @@  #define _TALER_BANK_SERVICE_H  #include <jansson.h> +#include <gnunet/gnunet_curl_lib.h>  #include "taler_util.h" -/* ********************* event loop *********************** */ - -/** - * @brief Handle to this library context.  This is where the - * main event loop logic lives. - */ -struct TALER_BANK_Context; - - -/** - * Initialise a context.  A context should be used for each thread and should - * not be shared among multiple threads. - * - * @param url HTTP base URL for the bank - * @return the context, NULL on error (failure to initialize) - */ -struct TALER_BANK_Context * -TALER_BANK_init (const char *url); - - -/** - * Obtain the information for a select() call to wait until - * #TALER_BANK_perform() is ready again.  Note that calling - * any other TALER_BANK-API may also imply that the library - * is again ready for #TALER_BANK_perform(). - * - * Basically, a client should use this API to prepare for select(), - * then block on select(), then call #TALER_BANK_perform() and then - * start again until the work with the context is done. - * - * This function will NOT zero out the sets and assumes that @a max_fd - * and @a timeout are already set to minimal applicable values.  It is - * safe to give this API FD-sets and @a max_fd and @a timeout that are - * already initialized to some other descriptors that need to go into - * the select() call. - * - * @param ctx context to get the event loop information for - * @param read_fd_set will be set for any pending read operations - * @param write_fd_set will be set for any pending write operations - * @param except_fd_set is here because curl_multi_fdset() has this argument - * @param max_fd set to the highest FD included in any set; - *        if the existing sets have no FDs in it, the initial - *        value should be "-1". (Note that `max_fd + 1` will need - *        to be passed to select().) - * @param timeout set to the timeout in milliseconds (!); -1 means - *        no timeout (NULL, blocking forever is OK), 0 means to - *        proceed immediately with #TALER_BANK_perform(). - */ -void -TALER_BANK_get_select_info (struct TALER_BANK_Context *ctx, -                            fd_set *read_fd_set, -                            fd_set *write_fd_set, -                            fd_set *except_fd_set, -                            int *max_fd, -                            long *timeout); - - -/** - * Run the main event loop for the Taler interaction. - * - * @param ctx the library context - */ -void -TALER_BANK_perform (struct TALER_BANK_Context *ctx); - - -/** - * Cleanup library initialisation resources.  This function should be called - * after using this library to cleanup the resources occupied during library's - * initialisation. - * - * @param ctx the library context - */ -void -TALER_BANK_fini (struct TALER_BANK_Context *ctx); - -  /* ********************* /admin/add/incoming *********************** */ @@ -123,7 +47,7 @@ struct TALER_BANK_AdminAddIncomingHandle;  typedef void  (*TALER_BANK_AdminAddIncomingResultCallback) (void *cls,                                                unsigned int http_status, -                                              json_t *json); +                                              const json_t *json);  /** @@ -132,7 +56,8 @@ typedef void   * API and thus not accessible to typical bank clients, but only   * to the operators of the bank.   * - * @param bank the bank handle; the bank must be ready to operate + * @param ctx curl context for the event loop + * @param bank_base_url URL of the bank   * @param reserve_pub public key of the reserve   * @param amount amount that was deposited   * @param execution_date when did we receive the amount @@ -145,7 +70,8 @@ typedef void   *         In this case, the callback is not called.   */  struct TALER_BANK_AdminAddIncomingHandle * -TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank, +TALER_BANK_admin_add_incoming (struct GNUNET_CURL_Context *ctx, +                               const char *bank_base_url,                                 const struct TALER_WireTransferIdentifierRawP *wtid,                                 const struct TALER_Amount *amount,                                 uint64_t debit_account_no, diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index fa240ee9..e52e94d9 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -26,81 +26,6 @@  #include "taler_util.h"  #include <gnunet/gnunet_curl_lib.h> -/* ********************* event loop *********************** */ - -/** - * @brief Handle to this library context.  This is where the - * main event loop logic lives. - */ -struct TALER_EXCHANGE_Context; - - -/** - * Initialise a context.  A context should be used for each thread and should - * not be shared among multiple threads. - * - * @return the context, NULL on error (failure to initialize) - */ -struct TALER_EXCHANGE_Context * -TALER_EXCHANGE_init (void); - - -/** - * Obtain the information for a select() call to wait until - * #TALER_EXCHANGE_perform() is ready again.  Note that calling - * any other TALER_EXCHANGE-API may also imply that the library - * is again ready for #TALER_EXCHANGE_perform(). - * - * Basically, a client should use this API to prepare for select(), - * then block on select(), then call #TALER_EXCHANGE_perform() and then - * start again until the work with the context is done. - * - * This function will NOT zero out the sets and assumes that @a max_fd - * and @a timeout are already set to minimal applicable values.  It is - * safe to give this API FD-sets and @a max_fd and @a timeout that are - * already initialized to some other descriptors that need to go into - * the select() call. - * - * @param ctx context to get the event loop information for - * @param read_fd_set will be set for any pending read operations - * @param write_fd_set will be set for any pending write operations - * @param except_fd_set is here because curl_multi_fdset() has this argument - * @param max_fd set to the highest FD included in any set; - *        if the existing sets have no FDs in it, the initial - *        value should be "-1". (Note that `max_fd + 1` will need - *        to be passed to select().) - * @param timeout set to the timeout in milliseconds (!); -1 means - *        no timeout (NULL, blocking forever is OK), 0 means to - *        proceed immediately with #TALER_EXCHANGE_perform(). - */ -void -TALER_EXCHANGE_get_select_info (struct TALER_EXCHANGE_Context *ctx, -                                fd_set *read_fd_set, -                                fd_set *write_fd_set, -                                fd_set *except_fd_set, -                                int *max_fd, -                                long *timeout); - - -/** - * Run the main event loop for the Taler interaction. - * - * @param ctx the library context - */ -void -TALER_EXCHANGE_perform (struct TALER_EXCHANGE_Context *ctx); - - -/** - * Cleanup library initialisation resources.  This function should be called - * after using this library to cleanup the resources occupied during library's - * initialisation. - * - * @param ctx the library context - */ -void -TALER_EXCHANGE_fini (struct TALER_EXCHANGE_Context *ctx); -  /* *********************  /keys *********************** */ | 
