summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mint-lib/mint_api_admin.c112
-rw-r--r--src/mint-lib/mint_api_context.c133
-rw-r--r--src/mint-lib/mint_api_context.h82
-rw-r--r--src/mint-lib/mint_api_deposit.c115
-rw-r--r--src/mint-lib/mint_api_handle.c160
-rw-r--r--src/mint-lib/mint_api_withdraw.c208
-rw-r--r--src/mint/taler-mint-httpd_admin.c1
-rw-r--r--src/mint/taler-mint-httpd_parsing.c31
8 files changed, 303 insertions, 539 deletions
diff --git a/src/mint-lib/mint_api_admin.c b/src/mint-lib/mint_api_admin.c
index 47158665a..472b02e7d 100644
--- a/src/mint-lib/mint_api_admin.c
+++ b/src/mint-lib/mint_api_admin.c
@@ -32,15 +32,6 @@
/**
- * 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)
-
-
-/**
* @brief An admin/add/incoming Handle
*/
struct TALER_MINT_AdminAddIncomingHandle
@@ -84,18 +75,7 @@ struct TALER_MINT_AdminAddIncomingHandle
/**
* 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;
+ struct MAC_DownloadBuffer db;
};
@@ -113,35 +93,12 @@ handle_admin_add_incoming_finished (void *cls,
{
struct TALER_MINT_AdminAddIncomingHandle *aai = cls;
long response_code;
- json_error_t error;
json_t *json;
aai->job = NULL;
- json = NULL;
- if (0 == aai->eno)
- {
- json = json_loadb (aai->buf,
- aai->buf_size,
- JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
- &error);
- if (NULL == json)
- {
- JSON_WARN (error);
- response_code = 0;
- }
- }
- if (NULL != json)
- {
- if (CURLE_OK !=
- curl_easy_getinfo (eh,
- CURLINFO_RESPONSE_CODE,
- &response_code))
- {
- /* unexpected error... */
- GNUNET_break (0);
- response_code = 0;
- }
- }
+ json = MAC_download_get_result (&aai->db,
+ eh,
+ &response_code);
switch (response_code)
{
case 0:
@@ -170,6 +127,9 @@ handle_admin_add_incoming_finished (void *cls,
break;
default:
/* unexpected response code */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u\n",
+ response_code);
GNUNET_break (0);
response_code = 0;
break;
@@ -183,49 +143,6 @@ handle_admin_add_incoming_finished (void *cls,
/**
- * Callback used when downloading the reply to a /admin/add/incoming
- * request. Just appends all of the data to the `buf` in the `struct
- * TALER_MINT_AdminAddIncomingHandle` 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 TALER_MINT_DepositHandle`
- * @return number of bytes processed from @a bufptr
- */
-static int
-admin_add_incoming_download_cb (char *bufptr,
- size_t size,
- size_t nitems,
- void *cls)
-{
- struct TALER_MINT_AdminAddIncomingHandle *aai = cls;
- size_t msize;
- void *buf;
-
- if (0 == size * nitems)
- {
- /* Nothing (left) to do */
- return 0;
- }
- msize = size * nitems;
- if ( (msize + aai->buf_size) >= GNUNET_MAX_MALLOC_CHECKED)
- {
- aai->eno = ENOMEM;
- return 0; /* signals an error to curl */
- }
- aai->buf = GNUNET_realloc (aai->buf,
- aai->buf_size + msize);
- buf = aai->buf + aai->buf_size;
- memcpy (buf, bufptr, msize);
- aai->buf_size += msize;
- return msize;
-}
-
-
-/**
* Notify the mint that we have received an incoming transaction
* which fills a reserve. Note that this API is an administrative
* API and thus not accessible to typical mint clients, but only
@@ -265,7 +182,7 @@ TALER_MINT_admin_add_incoming (struct TALER_MINT_Handle *mint,
return NULL;
}
admin_obj = json_pack ("{s:o, s:o," /* reserve_pub/amount */
- " s:o, s:o}", /* execution_Date/wire */
+ " s:o, s:O}", /* execution_Date/wire */
"reserve_pub", TALER_json_from_data (reserve_pub,
sizeof (*reserve_pub)),
"amount", TALER_json_from_amount (amount),
@@ -297,21 +214,15 @@ TALER_MINT_admin_add_incoming (struct TALER_MINT_Handle *mint,
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_WRITEFUNCTION,
- &admin_add_incoming_download_cb));
+ &MAC_download_cb));
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_WRITEDATA,
- aai));
- GNUNET_assert (NULL != (aai->headers =
- curl_slist_append (aai->headers,
- "Content-Type: application/json")));
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_HTTPHEADER,
- aai->headers));
+ &aai->db));
ctx = MAH_handle_to_context (mint);
aai->job = MAC_job_add (ctx,
eh,
+ GNUNET_YES,
&handle_admin_add_incoming_finished,
aai);
return aai;
@@ -333,6 +244,7 @@ TALER_MINT_admin_add_incoming_cancel (struct TALER_MINT_AdminAddIncomingHandle *
aai->job = NULL;
}
curl_slist_free_all (aai->headers);
+ GNUNET_free_non_null (aai->db.buf);
GNUNET_free (aai->url);
GNUNET_free (aai->json_enc);
GNUNET_free (aai);
diff --git a/src/mint-lib/mint_api_context.c b/src/mint-lib/mint_api_context.c
index 2daba89e7..9beeef149 100644
--- a/src/mint-lib/mint_api_context.c
+++ b/src/mint-lib/mint_api_context.c
@@ -34,9 +34,18 @@
* @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", \
+ 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
@@ -109,6 +118,12 @@ struct TALER_MINT_Context
*/
struct MAC_Job *jobs_tail;
+ /**
+ * HTTP header "application/json", created once and used
+ * for all requests that need it.
+ */
+ struct curl_slist *json_header;
+
};
@@ -146,6 +161,9 @@ TALER_MINT_init ()
ctx = GNUNET_new (struct TALER_MINT_Context);
ctx->multi = multi;
ctx->share = share;
+ GNUNET_assert (NULL != (ctx->json_header =
+ curl_slist_append (NULL,
+ "Content-Type: application/json")));
return ctx;
}
@@ -157,20 +175,31 @@ TALER_MINT_init ()
* instead use #MAC_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 MAC_Job *
MAC_job_add (struct TALER_MINT_Context *ctx,
CURL *eh,
+ int add_json,
MAC_JobCompletionCallback jcc,
void *jcc_cls)
{
struct MAC_Job *job;
+ if (GNUNET_YES == add_json)
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_HTTPHEADER,
+ ctx->json_header));
+
job = GNUNET_new (struct MAC_Job);
job->easy_handle = eh;
job->ctx = ctx;
@@ -333,11 +362,113 @@ TALER_MINT_fini (struct TALER_MINT_Context *ctx)
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);
}
/**
+ * Callback used when downloading the reply to an HTTP request.
+ * Just appends all of the data to the `buf` in the
+ * `struct MAC_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
+MAC_download_cb (char *bufptr,
+ size_t size,
+ size_t nitems,
+ void *cls)
+{
+ struct MAC_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 *
+MAC_download_get_result (struct MAC_DownloadBuffer *db,
+ CURL *eh,
+ long *response_code)
+{
+ json_t *json;
+ json_error_t error;
+
+ 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))
diff --git a/src/mint-lib/mint_api_context.h b/src/mint-lib/mint_api_context.h
index 235c32bd1..c545a3fe7 100644
--- a/src/mint-lib/mint_api_context.h
+++ b/src/mint-lib/mint_api_context.h
@@ -50,15 +50,20 @@ typedef void
* instead use #MAC_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 MAC_Job *
MAC_job_add (struct TALER_MINT_Context *ctx,
CURL *eh,
+ int add_json,
MAC_JobCompletionCallback jcc,
void *jcc_cls);
@@ -84,4 +89,81 @@ void
MAC_job_cancel (struct MAC_Job *job);
+/**
+ * Buffer data structure we use to buffer the HTTP download
+ * before giving it to the JSON parser.
+ */
+struct MAC_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 MAC_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 MAC_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
+MAC_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 *
+MAC_download_get_result (struct MAC_DownloadBuffer *db,
+ CURL *eh,
+ long *response_code);
+
+
/* end of mint_api_context.h */
diff --git a/src/mint-lib/mint_api_deposit.c b/src/mint-lib/mint_api_deposit.c
index 34915eaf1..7be88a887 100644
--- a/src/mint-lib/mint_api_deposit.c
+++ b/src/mint-lib/mint_api_deposit.c
@@ -33,15 +33,6 @@
/**
- * 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)
-
-
-/**
* @brief A Deposit Handle
*/
struct TALER_MINT_DepositHandle
@@ -68,11 +59,6 @@ struct TALER_MINT_DepositHandle
struct MAC_Job *job;
/**
- * HTTP headers for the request.
- */
- struct curl_slist *headers;
-
- /**
* Function to call with the result.
*/
TALER_MINT_DepositResultCallback cb;
@@ -85,7 +71,7 @@ struct TALER_MINT_DepositHandle
/**
* Download buffer
*/
- void *buf;
+ struct MAC_DownloadBuffer db;
/**
* Information the mint should sign in response.
@@ -102,17 +88,6 @@ struct TALER_MINT_DepositHandle
*/
struct TALER_Amount coin_value;
- /**
- * 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;
-
};
@@ -321,35 +296,12 @@ handle_deposit_finished (void *cls,
{
struct TALER_MINT_DepositHandle *dh = cls;
long response_code;
- json_error_t error;
json_t *json;
dh->job = NULL;
- json = NULL;
- if (0 == dh->eno)
- {
- json = json_loadb (dh->buf,
- dh->buf_size,
- JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
- &error);
- if (NULL == json)
- {
- JSON_WARN (error);
- response_code = 0;
- }
- }
- if (NULL != json)
- {
- if (CURLE_OK !=
- curl_easy_getinfo (eh,
- CURLINFO_RESPONSE_CODE,
- &response_code))
- {
- /* unexpected error... */
- GNUNET_break (0);
- response_code = 0;
- }
- }
+ json = MAC_download_get_result (&dh->db,
+ eh,
+ &response_code);
switch (response_code)
{
case 0:
@@ -485,49 +437,6 @@ verify_signatures (const struct TALER_MINT_DenomPublicKey *dki,
/**
- * Callback used when downloading the reply to a /deposit request.
- * Just appends all of the data to the `buf` in the
- * `struct TALER_MINT_DepositHandle` 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 TALER_MINT_DepositHandle`
- * @return number of bytes processed from @a bufptr
- */
-static int
-deposit_download_cb (char *bufptr,
- size_t size,
- size_t nitems,
- void *cls)
-{
- struct TALER_MINT_DepositHandle *dh = cls;
- size_t msize;
- void *buf;
-
- if (0 == size * nitems)
- {
- /* Nothing (left) to do */
- return 0;
- }
- msize = size * nitems;
- if ( (msize + dh->buf_size) >= GNUNET_MAX_MALLOC_CHECKED)
- {
- dh->eno = ENOMEM;
- return 0; /* signals an error to curl */
- }
- dh->buf = GNUNET_realloc (dh->buf,
- dh->buf_size + msize);
- buf = dh->buf + dh->buf_size;
- memcpy (buf, bufptr, msize);
- dh->buf_size += msize;
- return msize;
-}
-
-
-/**
* Submit a deposit permission to the mint and get the mint's response.
* Note that while we return the response verbatim to the caller for
* further processing, we do already verify that the response is
@@ -624,7 +533,7 @@ TALER_MINT_deposit (struct TALER_MINT_Handle *mint,
return NULL;
}
- deposit_obj = json_pack ("{s:o, s:o," /* f/wire */
+ deposit_obj = json_pack ("{s:o, s:O," /* f/wire */
" s:o, s:o," /* H_wire, H_contract */
" s:o, s:o," /* coin_pub, denom_pub */
" s:o, s:o," /* ub_sig, timestamp */
@@ -691,21 +600,15 @@ TALER_MINT_deposit (struct TALER_MINT_Handle *mint,
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_WRITEFUNCTION,
- &deposit_download_cb));
+ &MAC_download_cb));
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_WRITEDATA,
- dh));
- GNUNET_assert (NULL != (dh->headers =
- curl_slist_append (dh->headers,
- "Content-Type: application/json")));
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_HTTPHEADER,
- dh->headers));
+ &dh->db));
ctx = MAH_handle_to_context (mint);
dh->job = MAC_job_add (ctx,
eh,
+ GNUNET_YES,
&handle_deposit_finished,
dh);
return dh;
@@ -726,7 +629,7 @@ TALER_MINT_deposit_cancel (struct TALER_MINT_DepositHandle *deposit)
MAC_job_cancel (deposit->job);
deposit->job = NULL;
}
- curl_slist_free_all (deposit->headers);
+ GNUNET_free_non_null (deposit->db.buf);
GNUNET_free (deposit->url);
GNUNET_free (deposit->json_enc);
GNUNET_free (deposit);
diff --git a/src/mint-lib/mint_api_handle.c b/src/mint-lib/mint_api_handle.c
index 88a4f9331..f5e26ff15 100644
--- a/src/mint-lib/mint_api_handle.c
+++ b/src/mint-lib/mint_api_handle.c
@@ -45,14 +45,6 @@
/**
- * 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)
-
-/**
* Stages of initialization for the `struct TALER_MINT_Handle`
*/
enum MintHandleState
@@ -149,73 +141,14 @@ struct KeysRequest
struct MAC_Job *job;
/**
- * Error buffer for Curl. Do we need this?
- */
- char emsg[CURL_ERROR_SIZE];
-
- /**
- * 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).
+ * Data structure for the download.
*/
- int eno;
+ struct MAC_DownloadBuffer db;
};
/**
- * Callback used when downloading the reply to a /keys request.
- * Just appends all of the data to the `buf` in the
- * `struct KeysRequest` 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
- */
-static size_t
-keys_download_cb (char *bufptr,
- size_t size,
- size_t nitems,
- void *cls)
-{
- struct KeysRequest *kr = cls;
- size_t msize;
- void *buf;
-
- if (0 == size * nitems)
- {
- /* Nothing (left) to do */
- return 0;
- }
- msize = size * nitems;
- if ( (msize + kr->buf_size) >= GNUNET_MAX_MALLOC_CHECKED)
- {
- kr->eno = ENOMEM;
- return 0; /* signals an error to curl */
- }
- kr->buf = GNUNET_realloc (kr->buf,
- kr->buf_size + msize);
- buf = kr->buf + kr->buf_size;
- memcpy (buf, bufptr, msize);
- kr->buf_size += msize;
- return msize;
-}
-
-
-/**
* Release memory occupied by a keys request.
* Note that this does not cancel the request
* itself.
@@ -225,7 +158,7 @@ keys_download_cb (char *bufptr,
static void
free_keys_request (struct KeysRequest *kr)
{
- GNUNET_free_non_null (kr->buf);
+ GNUNET_free_non_null (kr->db.buf);
GNUNET_free (kr->url);
GNUNET_free (kr);
}
@@ -493,7 +426,6 @@ decode_keys_json (json_t *resp_obj,
hash_context));
}
}
- return GNUNET_OK;
/* FIXME: parse the auditor keys (#3847) */
@@ -522,48 +454,6 @@ decode_keys_json (json_t *resp_obj,
/**
- * We have successfully received the reply to the /keys
- * request from the mint. We now need to parse the reply
- * and, if successful, store the resulting information
- * in the `key_data` structure.
- *
- * @param kr key request with all of the data to parse
- * and references to the `struct TALER_MINT_Handle`
- * where we need to store the result
- * @return #GNUNET_OK on success,
- * #GNUNET_SYSERR on failure
- */
-static int
-parse_response_keys_get (struct KeysRequest *kr)
-{
- json_t *resp_obj;
- json_error_t error;
- int ret;
-
- resp_obj = json_loadb (kr->buf,
- kr->buf_size,
- JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
- &error);
- if (NULL == resp_obj)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unable to parse received /keys data as JSON object\n");
- GNUNET_free_non_null (kr->buf);
- kr->buf = NULL;
- kr->buf_size = 0;
- return GNUNET_SYSERR;
- }
- GNUNET_free_non_null (kr->buf);
- kr->buf = NULL;
- kr->buf_size = 0;
- ret = decode_keys_json (resp_obj,
- &kr->mint->key_data);
- json_decref (resp_obj);
- return ret;
-}
-
-
-/**
* Callback used when downloading the reply to a /keys request
* is complete.
*
@@ -576,35 +466,32 @@ keys_completed_cb (void *cls,
{
struct KeysRequest *kr = cls;
struct TALER_MINT_Handle *mint = kr->mint;
+ json_t *resp_obj;
long response_code;
- /* FIXME: might want to check response code? */
- if (CURLE_OK !=
- curl_easy_getinfo (eh,
- CURLINFO_RESPONSE_CODE,
- &response_code))
- {
- /* unexpected error... */
- GNUNET_break (0);
- response_code = 0;
- }
+ resp_obj = MAC_download_get_result (&kr->db,
+ eh,
+ &response_code);
switch (response_code) {
case 0:
- kr->eno = 1;
break;
case MHD_HTTP_OK:
+ if ( (NULL == resp_obj) ||
+ (GNUNET_OK !=
+ decode_keys_json (resp_obj,
+ &kr->mint->key_data)) )
+ response_code = 0;
break;
default:
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Mint returned status code %u for /keys\n",
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u\n",
response_code);
- kr->eno = 1;
break;
}
+ if (NULL != resp_obj)
+ json_decref (resp_obj);
- if ( (0 != kr->eno) ||
- (GNUNET_OK !=
- parse_response_keys_get (kr)) )
+ if (MHD_HTTP_OK != response_code)
{
mint->kr = NULL;
free_keys_request (kr);
@@ -724,18 +611,15 @@ TALER_MINT_connect (struct TALER_MINT_Context *ctx,
kr->url));
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (c,
- CURLOPT_ERRORBUFFER,
- kr->emsg));
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (c,
CURLOPT_WRITEFUNCTION,
- &keys_download_cb));
+ &MAC_download_cb));
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (c,
CURLOPT_WRITEDATA,
- kr));
+ &kr->db));
kr->job = MAC_job_add (mint->ctx,
c,
+ GNUNET_NO,
&keys_completed_cb,
kr);
mint->kr = kr;
@@ -751,6 +635,8 @@ TALER_MINT_connect (struct TALER_MINT_Context *ctx,
void
TALER_MINT_disconnect (struct TALER_MINT_Handle *mint)
{
+ unsigned int i;
+
if (NULL != mint->kr)
{
MAC_job_cancel (mint->kr->job);
@@ -760,6 +646,8 @@ TALER_MINT_disconnect (struct TALER_MINT_Handle *mint)
GNUNET_array_grow (mint->key_data.sign_keys,
mint->key_data.num_sign_keys,
0);
+ for (i=0;i<mint->key_data.num_denom_keys;i++)
+ GNUNET_CRYPTO_rsa_public_key_free (mint->key_data.denom_keys[i].key.rsa_public_key);
GNUNET_array_grow (mint->key_data.denom_keys,
mint->key_data.num_denom_keys,
0);
diff --git a/src/mint-lib/mint_api_withdraw.c b/src/mint-lib/mint_api_withdraw.c
index 157d2db72..e7a1a61d4 100644
--- a/src/mint-lib/mint_api_withdraw.c
+++ b/src/mint-lib/mint_api_withdraw.c
@@ -31,15 +31,6 @@
#include "taler_signatures.h"
-/**
- * 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)
-
-
/* ********************** /withdraw/status ********************** */
/**
@@ -81,18 +72,7 @@ struct TALER_MINT_WithdrawStatusHandle
/**
* 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;
+ struct MAC_DownloadBuffer db;
};
@@ -295,35 +275,12 @@ handle_withdraw_status_finished (void *cls,
{
struct TALER_MINT_WithdrawStatusHandle *wsh = cls;
long response_code;
- json_error_t error;
json_t *json;
wsh->job = NULL;
- json = NULL;
- if (0 == wsh->eno)
- {
- json = json_loadb (wsh->buf,
- wsh->buf_size,
- JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
- &error);
- if (NULL == json)
- {
- JSON_WARN (error);
- response_code = 0;
- }
- }
- if (NULL != json)
- {
- if (CURLE_OK !=
- curl_easy_getinfo (eh,
- CURLINFO_RESPONSE_CODE,
- &response_code))
- {
- /* unexpected error... */
- GNUNET_break (0);
- response_code = 0;
- }
- }
+ json = MAC_download_get_result (&wsh->db,
+ eh,
+ &response_code);
switch (response_code)
{
case 0:
@@ -404,6 +361,9 @@ handle_withdraw_status_finished (void *cls,
break;
default:
/* unexpected response code */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u\n",
+ response_code);
GNUNET_break (0);
response_code = 0;
break;
@@ -420,49 +380,6 @@ handle_withdraw_status_finished (void *cls,
/**
- * Callback used when downloading the reply to a /withdraw/status request.
- * Just appends all of the data to the `buf` in the
- * `struct TALER_MINT_WithdrawStatusHandle` 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 TALER_MINT_DepositHandle`
- * @return number of bytes processed from @a bufptr
- */
-static int
-withdraw_status_download_cb (char *bufptr,
- size_t size,
- size_t nitems,
- void *cls)
-{
- struct TALER_MINT_WithdrawStatusHandle *wsh = cls;
- size_t msize;
- void *buf;
-
- if (0 == size * nitems)
- {
- /* Nothing (left) to do */
- return 0;
- }
- msize = size * nitems;
- if ( (msize + wsh->buf_size) >= GNUNET_MAX_MALLOC_CHECKED)
- {
- wsh->eno = ENOMEM;
- return 0; /* signals an error to curl */
- }
- wsh->buf = GNUNET_realloc (wsh->buf,
- wsh->buf_size + msize);
- buf = wsh->buf + wsh->buf_size;
- memcpy (buf, bufptr, msize);
- wsh->buf_size += msize;
- return msize;
-}
-
-
-/**
* Submit a request to obtain the transaction history of a reserve
* from the mint. Note that while we return the full response to the
* caller for further processing, we do already verify that the
@@ -519,14 +436,15 @@ TALER_MINT_withdraw_status (struct TALER_MINT_Handle *mint,
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_WRITEFUNCTION,
- &withdraw_status_download_cb));
+ &MAC_download_cb));
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_WRITEDATA,
- wsh));
+ &wsh->db));
ctx = MAH_handle_to_context (mint);
wsh->job = MAC_job_add (ctx,
eh,
+ GNUNET_NO,
&handle_withdraw_status_finished,
wsh);
return wsh;
@@ -547,6 +465,7 @@ TALER_MINT_withdraw_status_cancel (struct TALER_MINT_WithdrawStatusHandle *wsh)
MAC_job_cancel (wsh->job);
wsh->job = NULL;
}
+ GNUNET_free_non_null (wsh->db.buf);
GNUNET_free (wsh->url);
GNUNET_free (wsh);
}
@@ -581,11 +500,6 @@ struct TALER_MINT_WithdrawSignHandle
struct MAC_Job *job;
/**
- * HTTP headers for the request.
- */
- struct curl_slist *headers;
-
- /**
* Function to call with the result.
*/
TALER_MINT_WithdrawSignResultCallback cb;
@@ -608,7 +522,7 @@ struct TALER_MINT_WithdrawSignHandle
/**
* Download buffer
*/
- void *buf;
+ struct MAC_DownloadBuffer db;
/**
* Hash of the public key of the coin we are signing.
@@ -620,17 +534,6 @@ struct TALER_MINT_WithdrawSignHandle
*/
struct TALER_ReservePublicKeyP reserve_pub;
- /**
- * 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;
-
};
@@ -797,33 +700,12 @@ handle_withdraw_sign_finished (void *cls,
{
struct TALER_MINT_WithdrawSignHandle *wsh = cls;
long response_code;
- json_error_t error;
json_t *json;
wsh->job = NULL;
- json = NULL;
- if (CURLE_OK !=
- curl_easy_getinfo (eh,
- CURLINFO_RESPONSE_CODE,
- &response_code))
- {
- /* unexpected error... */
- GNUNET_break (0);
- response_code = 0;
- }
- if ( (0 == wsh->eno) &&
- (0 != response_code) )
- {
- json = json_loadb (wsh->buf,
- wsh->buf_size,
- JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK,
- &error);
- if (NULL == json)
- {
- JSON_WARN (error);
- response_code = 0;
- }
- }
+ json = MAC_download_get_result (&wsh->db,
+ eh,
+ &response_code);
switch (response_code)
{
case 0:
@@ -870,6 +752,9 @@ handle_withdraw_sign_finished (void *cls,
break;
default:
/* unexpected response code */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u\n",
+ response_code);
GNUNET_break (0);
response_code = 0;
break;
@@ -885,49 +770,6 @@ handle_withdraw_sign_finished (void *cls,
/**
- * Callback used when downloading the reply to a /withdraw/sign request.
- * Just appends all of the data to the `buf` in the
- * `struct TALER_MINT_WithdrawSignHandle` 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 TALER_MINT_DepositHandle`
- * @return number of bytes processed from @a bufptr
- */
-static int
-withdraw_sign_download_cb (char *bufptr,
- size_t size,
- size_t nitems,
- void *cls)
-{
- struct TALER_MINT_WithdrawSignHandle *wsh = cls;
- size_t msize;
- void *buf;
-
- if (0 == size * nitems)
- {
- /* Nothing (left) to do */
- return 0;
- }
- msize = size * nitems;
- if ( (msize + wsh->buf_size) >= GNUNET_MAX_MALLOC_CHECKED)
- {
- wsh->eno = ENOMEM;
- return 0; /* signals an error to curl */
- }
- wsh->buf = GNUNET_realloc (wsh->buf,
- wsh->buf_size + msize);
- buf = wsh->buf + wsh->buf_size;
- memcpy (buf, bufptr, msize);
- wsh->buf_size += msize;
- return msize;
-}
-
-
-/**
* Withdraw a coin from the mint using a /withdraw/sign request. Note
* that to ensure that no money is lost in case of hardware failures,
* the caller must have committed (most of) the arguments to disk
@@ -1045,21 +887,15 @@ TALER_MINT_withdraw_sign (struct TALER_MINT_Handle *mint,
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_WRITEFUNCTION,
- &withdraw_sign_download_cb));
+ &MAC_download_cb));
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_WRITEDATA,
- wsh));
- GNUNET_assert (NULL != (wsh->headers =
- curl_slist_append (wsh->headers,
- "Content-Type: application/json")));
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_HTTPHEADER,
- wsh->headers));
+ &wsh->db));
ctx = MAH_handle_to_context (mint);
wsh->job = MAC_job_add (ctx,
eh,
+ GNUNET_YES,
&handle_withdraw_sign_finished,
wsh);
return wsh;
@@ -1080,7 +916,7 @@ TALER_MINT_withdraw_sign_cancel (struct TALER_MINT_WithdrawSignHandle *sign)
MAC_job_cancel (sign->job);
sign->job = NULL;
}
- curl_slist_free_all (sign->headers);
+ GNUNET_free_non_null (sign->db.buf);
GNUNET_free (sign->url);
GNUNET_free (sign->json_enc);
GNUNET_free (sign);
diff --git a/src/mint/taler-mint-httpd_admin.c b/src/mint/taler-mint-httpd_admin.c
index c757fd183..5fdfa58ee 100644
--- a/src/mint/taler-mint-httpd_admin.c
+++ b/src/mint/taler-mint-httpd_admin.c
@@ -146,6 +146,7 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
wire))
{
TMH_PARSE_release_data (spec);
+ json_decref (root);
return TMH_RESPONSE_reply_arg_unknown (connection,
"wire");
}
diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c
index 8d7903eb5..78380f861 100644
--- a/src/mint/taler-mint-httpd_parsing.c
+++ b/src/mint/taler-mint-httpd_parsing.c
@@ -152,7 +152,6 @@ release_data (struct TMH_PARSE_FieldSpecification *spec,
unsigned int spec_len)
{
unsigned int i;
- void *ptr;
for (i=0; i < spec_len; i++)
{
@@ -175,11 +174,15 @@ release_data (struct TMH_PARSE_FieldSpecification *spec,
}
break;
case TMH_PARSE_JNC_RET_TYPED_JSON:
- ptr = *(void **) spec[i].destination;
- if (NULL != ptr)
{
- json_decref (ptr);
- *(void**) spec[i].destination = NULL;
+ json_t *json;
+
+ json = *(json_t **) spec[i].destination;
+ if (NULL != json)
+ {
+ json_decref (json);
+ *(json_t**) spec[i].destination = NULL;
+ }
}
break;
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
@@ -606,7 +609,9 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
int typ = va_arg (argp, int);
const json_t **r_json = va_arg (argp, const json_t **);
- if ( (-1 != typ) && (json_typeof (root) != typ))
+ if ( (NULL == root) ||
+ ( (-1 != typ) &&
+ (json_typeof (root) != typ)) )
{
*r_json = NULL;
ret = (MHD_YES ==
@@ -899,7 +904,7 @@ TMH_PARSE_json_data (struct MHD_Connection *connection,
spec[i].field_name,
TMH_PARSE_JNC_RET_TYPED_JSON,
spec[i].type,
- &spec[i].destination);
+ spec[i].destination);
break;
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
ret = TMH_PARSE_navigate_json (connection,
@@ -994,7 +999,7 @@ TMH_PARSE_member_uint64 (const char *field,
* Generate line in parser specification for JSON object value.
*
* @param field name of the field
- * @param jsonp address of pointer to JSON to initialize
+ * @param[out] jsonp address of pointer to JSON to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
@@ -1002,7 +1007,8 @@ TMH_PARSE_member_object (const char *field,
json_t **jsonp)
{
struct TMH_PARSE_FieldSpecification ret =
- { field, (void **) jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_OBJECT };
+ { field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_OBJECT };
+ *jsonp = NULL;
return ret;
}
@@ -1011,7 +1017,7 @@ TMH_PARSE_member_object (const char *field,
* Generate line in parser specification for JSON array value.
*
* @param field name of the field
- * @param jsonp address of JSON pointer to initialize
+ * @param[out] jsonp address of JSON pointer to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
@@ -1020,6 +1026,7 @@ TMH_PARSE_member_array (const char *field,
{
struct TMH_PARSE_FieldSpecification ret =
{ field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_ARRAY };
+ *jsonp = NULL;
return ret;
}
@@ -1053,6 +1060,7 @@ TMH_PARSE_member_denomination_public_key (const char *field,
{
struct TMH_PARSE_FieldSpecification ret =
{ field, pk, 0, NULL, TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, 0 };
+ pk->rsa_public_key = NULL;
return ret;
}
@@ -1070,6 +1078,7 @@ TMH_PARSE_member_denomination_signature (const char *field,
{
struct TMH_PARSE_FieldSpecification ret =
{ field, sig, 0, NULL, TMH_PARSE_JNC_RET_RSA_SIGNATURE, 0 };
+ sig->rsa_signature = NULL;
return ret;
}
@@ -1087,6 +1096,7 @@ TMH_PARSE_member_amount (const char *field,
{
struct TMH_PARSE_FieldSpecification ret =
{ field, amount, sizeof(struct TALER_Amount), NULL, TMH_PARSE_JNC_RET_AMOUNT, 0 };
+ memset (amount, 0, sizeof (struct TALER_Amount));
return ret;
}
@@ -1106,6 +1116,7 @@ TMH_PARSE_member_variable (const char *field,
{
struct TMH_PARSE_FieldSpecification ret =
{ field, ptr, 0, ptr_size, TMH_PARSE_JNC_RET_DATA_VAR, 0 };
+ *ptr = NULL;
return ret;
}