summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-11-29 10:52:45 +0100
committerChristian Grothoff <christian@grothoff.org>2019-11-29 10:52:45 +0100
commit636488c2797b498c8861bc6864539a63323b3608 (patch)
tree11b0f04aa31c40a0736babf5ee0a4d0d29682a32
parent970e3fd4cb4a3f76d1bcf56e4cec668bcb828078 (diff)
parent785f5fb7dd5f8e4aa0258e3e72f519c77942cb7d (diff)
downloadexchange-636488c2797b498c8861bc6864539a63323b3608.tar.gz
exchange-636488c2797b498c8861bc6864539a63323b3608.tar.bz2
exchange-636488c2797b498c8861bc6864539a63323b3608.zip
merge error codes
-rw-r--r--.gitignore1
-rw-r--r--configure.ac1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/auditor/Makefile.am5
-rw-r--r--src/auditor/taler-auditor-httpd.c302
-rw-r--r--src/auditor/taler-auditor-httpd_db.c27
-rw-r--r--src/auditor/taler-auditor-httpd_deposit-confirmation.c53
-rw-r--r--src/auditor/taler-auditor-httpd_exchanges.c19
-rw-r--r--src/auditor/taler-auditor-httpd_mhd.c57
-rw-r--r--src/auditor/taler-auditor-httpd_parsing.c284
-rw-r--r--src/auditor/taler-auditor-httpd_parsing.h139
-rw-r--r--src/auditor/taler-auditor-httpd_responses.c480
-rw-r--r--src/auditor/taler-auditor-httpd_responses.h245
-rw-r--r--src/exchange-tools/Makefile.am8
-rw-r--r--src/exchange-tools/taler-exchange-tvg.c259
-rw-r--r--src/exchange/Makefile.am2
-rw-r--r--src/exchange/taler-exchange-aggregator.c4
-rw-r--r--src/exchange/taler-exchange-httpd.c277
-rw-r--r--src/exchange/taler-exchange-httpd_db.c31
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c140
-rw-r--r--src/exchange/taler-exchange-httpd_keystate.c30
-rw-r--r--src/exchange/taler-exchange-httpd_keystate.h1
-rw-r--r--src/exchange/taler-exchange-httpd_mhd.c48
-rw-r--r--src/exchange/taler-exchange-httpd_parsing.h139
-rw-r--r--src/exchange/taler-exchange-httpd_payback.c183
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_link.c32
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_melt.c154
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_reveal.c195
-rw-r--r--src/exchange/taler-exchange-httpd_refund.c127
-rw-r--r--src/exchange/taler-exchange-httpd_reserve_status.c46
-rw-r--r--src/exchange/taler-exchange-httpd_reserve_withdraw.c128
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c488
-rw-r--r--src/exchange/taler-exchange-httpd_responses.h227
-rw-r--r--src/exchange/taler-exchange-httpd_test.c257
-rw-r--r--src/exchange/taler-exchange-httpd_track_transaction.c91
-rw-r--r--src/exchange/taler-exchange-httpd_track_transfer.c87
-rw-r--r--src/exchange/taler-exchange-httpd_wire.c7
-rw-r--r--src/exchange/taler-exchange-wirewatch.c4
-rw-r--r--src/include/Makefile.am1
-rw-r--r--src/include/gauger.h2
-rw-r--r--src/include/taler_error_codes.h14
-rw-r--r--src/include/taler_json_lib.h13
-rw-r--r--src/include/taler_mhd_lib.h393
-rw-r--r--src/json/json.c29
-rw-r--r--src/lib/auditor_api_deposit_confirmation.c2
-rw-r--r--src/lib/exchange_api_curl_defaults.c1
-rw-r--r--src/lib/exchange_api_deposit.c4
-rw-r--r--src/lib/exchange_api_payback.c4
-rw-r--r--src/lib/exchange_api_refresh.c16
-rw-r--r--src/lib/exchange_api_refund.c2
-rw-r--r--src/lib/exchange_api_reserve.c6
-rw-r--r--src/lib/exchange_api_track_transaction.c2
-rw-r--r--src/lib/exchange_api_track_transfer.c2
-rw-r--r--src/lib/test_auditor_api.conf2
-rw-r--r--src/lib/test_exchange_api.c16
-rw-r--r--src/lib/test_exchange_api_twisted.c9
-rw-r--r--src/mhd/Makefile.am26
-rw-r--r--src/mhd/mhd_config.c396
-rw-r--r--src/mhd/mhd_parsing.c (renamed from src/exchange/taler-exchange-httpd_parsing.c)124
-rw-r--r--src/mhd/mhd_responses.c501
-rw-r--r--src/util/crypto.c28
61 files changed, 2705 insertions, 3468 deletions
diff --git a/.gitignore b/.gitignore
index 5bb943a9..5bb95cb4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,7 @@ src/exchange/test_taler_exchange_httpd_home/.local/share/taler/exchange/live-key
src/exchange/test_taler_exchange_httpd_home/.local/share/taler/exchange/wirefees/
src/exchange-tools/taler-auditor-sign
src/exchange-tools/taler-exchange-dbinit
+src/exchange-tools/taler-exchange-tvg
src/exchange-tools/taler-exchange-keycheck
src/exchange-tools/taler-exchange-keyup
src/exchange-tools/taler-exchange-wire
diff --git a/configure.ac b/configure.ac
index 44703bf1..07fc2860 100644
--- a/configure.ac
+++ b/configure.ac
@@ -550,6 +550,7 @@ AC_CONFIG_FILES([Makefile
src/benchmark/Makefile
src/include/Makefile
src/json/Makefile
+ src/mhd/Makefile
src/pq/Makefile
src/util/Makefile
src/util/taler-config
diff --git a/src/Makefile.am b/src/Makefile.am
index 38bf715f..761b9c33 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,7 +22,7 @@ pkgcfg_DATA = \
EXTRA_DIST = \
taler.conf
-SUBDIRS = include util wire json curl $(PQ_DIR) $(BANK_LIB) wire-plugins exchangedb exchange exchange-tools auditordb auditor
+SUBDIRS = include util wire json curl $(PQ_DIR) mhd $(BANK_LIB) wire-plugins exchangedb exchange exchange-tools auditordb auditor
if HAVE_LIBCURL
SUBDIRS += lib benchmark
else
diff --git a/src/auditor/Makefile.am b/src/auditor/Makefile.am
index e3600e20..a1bb4d24 100644
--- a/src/auditor/Makefile.am
+++ b/src/auditor/Makefile.am
@@ -52,11 +52,10 @@ taler_auditor_httpd_SOURCES = \
taler-auditor-httpd_db.c taler-auditor-httpd_db.h \
taler-auditor-httpd_deposit-confirmation.c taler-auditor-httpd_deposit-confirmation.h \
taler-auditor-httpd_exchanges.c taler-auditor-httpd_exchanges.h \
- taler-auditor-httpd_mhd.c taler-auditor-httpd_mhd.h \
- taler-auditor-httpd_parsing.c taler-auditor-httpd_parsing.h \
- taler-auditor-httpd_responses.c taler-auditor-httpd_responses.h
+ taler-auditor-httpd_mhd.c taler-auditor-httpd_mhd.h
taler_auditor_httpd_LDADD = \
$(LIBGCRYPT_LIBS) \
+ $(top_builddir)/src/mhd/libtalermhd.la \
$(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/wire/libtalerwire.la \
diff --git a/src/auditor/taler-auditor-httpd.c b/src/auditor/taler-auditor-httpd.c
index e37b4a0e..55a34377 100644
--- a/src/auditor/taler-auditor-httpd.c
+++ b/src/auditor/taler-auditor-httpd.c
@@ -27,11 +27,10 @@
#include <microhttpd.h>
#include <pthread.h>
#include <sys/resource.h>
+#include "taler_mhd_lib.h"
#include "taler_auditordb_lib.h"
#include "taler-auditor-httpd_deposit-confirmation.h"
#include "taler-auditor-httpd_exchanges.h"
-#include "taler-auditor-httpd_parsing.h"
-#include "taler-auditor-httpd_responses.h"
#include "taler-auditor-httpd_mhd.h"
#include "taler-auditor-httpd.h"
@@ -291,7 +290,7 @@ handle_mhd_completion_callback (void *cls,
{
if (NULL == *con_cls)
return;
- TAH_PARSE_post_cleanup_callback (*con_cls);
+ TALER_MHD_parse_post_cleanup_callback (*con_cls);
*con_cls = NULL;
}
@@ -332,9 +331,9 @@ handle_version (struct TAH_RequestHandler *rh,
GNUNET_break (0);
return MHD_NO;
}
- return TAH_RESPONSE_reply_json (connection,
- ver,
- MHD_HTTP_OK);
+ return TALER_MHD_reply_json (connection,
+ ver,
+ MHD_HTTP_OK);
}
@@ -384,7 +383,7 @@ handle_mhd_request (void *cls,
&TAH_MHD_handler_static_response, MHD_HTTP_OK },
/* AGPL licensing page, redirect to source. As per the AGPL-license,
every deployment is required to offer the user a download of the
- source. We make this easy by including a redirect to the source
+ source. We make this easy by including a redirect t the source
here. */
{ "/agpl", MHD_HTTP_METHOD_GET, "text/plain",
NULL, 0,
@@ -392,11 +391,6 @@ handle_mhd_request (void *cls,
{ NULL, NULL, NULL, NULL, 0, 0 }
};
- static struct TAH_RequestHandler h404 = {
- "", NULL, "text/html",
- "<html><title>404: not found</title></html>", 0,
- &TAH_MHD_handler_static_response, MHD_HTTP_NOT_FOUND
- };
struct TAH_RequestHandler *rh;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -419,127 +413,13 @@ handle_mhd_request (void *cls,
upload_data,
upload_data_size);
}
- return TAH_MHD_handler_static_response (&h404,
- connection,
- con_cls,
- upload_data,
- upload_data_size);
-}
-
-
-/**
- * Parse the configuration to determine on which port
- * or UNIX domain path we should run an HTTP service.
- *
- * @param section section of the configuration to parse ("auditor" or "auditor-admin")
- * @param[out] rport set to the port number, or 0 for none
- * @param[out] unix_path set to the UNIX path, or NULL for none
- * @param[out] unix_mode set to the mode to be used for @a unix_path
- * @return #GNUNET_OK on success
- */
-static int
-parse_port_config (const char *section,
- uint16_t *rport,
- char **unix_path,
- mode_t *unix_mode)
-{
- const char *choices[] = {"tcp", "unix"};
- const char *serve_type;
- unsigned long long port;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_choice (cfg,
- section,
- "serve",
- choices,
- &serve_type))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section,
- "serve",
- "serve type required");
- return GNUNET_SYSERR;
- }
-
- if (0 == strcmp (serve_type, "tcp"))
- {
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg,
- section,
- "port",
- &port))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section,
- "port",
- "port number required");
- return GNUNET_SYSERR;
- }
-
- if ( (0 == port) ||
- (port > UINT16_MAX) )
- {
- fprintf (stderr,
- "Invalid configuration (value out of range): %llu is not a valid port\n",
- port);
- return GNUNET_SYSERR;
- }
- *rport = (uint16_t) port;
- *unix_path = NULL;
- return GNUNET_OK;
- }
- if (0 == strcmp (serve_type, "unix"))
- {
- struct sockaddr_un s_un;
- char *modestring;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (cfg,
- section,
- "unixpath",
- unix_path))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section,
- "unixpath",
- "unixpath required");
- return GNUNET_SYSERR;
- }
- if (strlen (*unix_path) >= sizeof (s_un.sun_path))
- {
- fprintf (stderr,
- "Invalid configuration: unix path too long\n");
- return GNUNET_SYSERR;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- section,
- "UNIXPATH_MODE",
- &modestring))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- section,
- "UNIXPATH_MODE");
- return GNUNET_SYSERR;
- }
- errno = 0;
- *unix_mode = (mode_t) strtoul (modestring, NULL, 8);
- if (0 != errno)
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section,
- "UNIXPATH_MODE",
- "must be octal number");
- GNUNET_free (modestring);
- return GNUNET_SYSERR;
- }
- GNUNET_free (modestring);
- return GNUNET_OK;
- }
- /* not reached */
- GNUNET_assert (0);
- return GNUNET_SYSERR;
+#define NOT_FOUND "<html><title>404: not found</title></html>"
+ return TALER_MHD_reply_static (connection,
+ MHD_HTTP_NOT_FOUND,
+ "text/html",
+ NOT_FOUND,
+ strlen (NOT_FOUND));
+#undef NOT_FOUND
}
@@ -562,10 +442,11 @@ auditor_serve_process_config ()
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
- parse_port_config ("auditor",
- &serve_port,
- &serve_unixpath,
- &unixpath_mode))
+ TALER_MHD_parse_config (cfg,
+ "auditor",
+ &serve_port,
+ &serve_unixpath,
+ &unixpath_mode))
{
return GNUNET_SYSERR;
}
@@ -641,141 +522,6 @@ auditor_serve_process_config ()
/**
- * Function called for logging by MHD.
- *
- * @param cls closure, NULL
- * @param fm format string (`printf()`-style)
- * @param ap arguments to @a fm
- */
-static void
-handle_mhd_logs (void *cls,
- const char *fm,
- va_list ap)
-{
- static int cache;
- char buf[2048];
-
- if (-1 == cache)
- return;
- if (0 == cache)
- {
- if (0 ==
- GNUNET_get_log_call_status (GNUNET_ERROR_TYPE_INFO,
- "auditor-httpd",
- __FILE__,
- __FUNCTION__,
- __LINE__))
- {
- cache = -1;
- return;
- }
- }
- cache = 1;
- vsnprintf (buf,
- sizeof (buf),
- fm,
- ap);
- GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_INFO,
- "auditor-httpd",
- "%s",
- buf);
-}
-
-
-/**
- * Open UNIX domain socket for listining at @a unix_path with
- * permissions @a unix_mode.
- *
- * @param unix_path where to listen
- * @param unix_mode access permissions to set
- * @return -1 on error, otherwise the listen socket
- */
-static int
-open_unix_path (const char *unix_path,
- mode_t unix_mode)
-{
- struct GNUNET_NETWORK_Handle *nh;
- struct sockaddr_un *un;
- int fd;
-
- if (sizeof (un->sun_path) <= strlen (unix_path))
- {
- fprintf (stderr,
- "unixpath `%s' too long\n",
- unix_path);
- return -1;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Creating listen socket '%s' with mode %o\n",
- unix_path,
- unix_mode);
-
- if (GNUNET_OK !=
- GNUNET_DISK_directory_create_for_file (unix_path))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "mkdir",
- unix_path);
- }
-
- un = GNUNET_new (struct sockaddr_un);
- un->sun_family = AF_UNIX;
- strncpy (un->sun_path,
- unix_path,
- sizeof (un->sun_path) - 1);
- GNUNET_NETWORK_unix_precheck (un);
-
- if (NULL == (nh = GNUNET_NETWORK_socket_create (AF_UNIX,
- SOCK_STREAM,
- 0)))
- {
- fprintf (stderr,
- "create failed for AF_UNIX\n");
- GNUNET_free (un);
- return -1;
- }
- if (GNUNET_OK !=
- GNUNET_NETWORK_socket_bind (nh,
- (void *) un,
- sizeof (struct sockaddr_un)))
- {
- fprintf (stderr,
- "bind failed for AF_UNIX\n");
- GNUNET_free (un);
- GNUNET_NETWORK_socket_close (nh);
- return -1;
- }
- GNUNET_free (un);
- if (GNUNET_OK !=
- GNUNET_NETWORK_socket_listen (nh,
- UNIX_BACKLOG))
- {
- fprintf (stderr,
- "listen failed for AF_UNIX\n");
- GNUNET_NETWORK_socket_close (nh);
- return -1;
- }
-
- if (0 != chmod (unix_path,
- unix_mode))
- {
- fprintf (stderr,
- "chmod failed: %s\n",
- strerror (errno));
- GNUNET_NETWORK_socket_close (nh);
- return -1;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "set socket '%s' to mode %o\n",
- unix_path,
- unix_mode);
- fd = GNUNET_NETWORK_get_fd (nh);
- GNUNET_NETWORK_socket_free_memory_only_ (nh);
- return fd;
-}
-
-
-/**
* The main function of the taler-auditor-httpd server ("the auditor").
*
* @param argc number of arguments from the command line
@@ -811,12 +557,17 @@ main (int argc,
const char *listen_pid;
const char *listen_fds;
int fh = -1;
+ enum TALER_MHD_GlobalOptions go;
if (0 >=
GNUNET_GETOPT_run ("taler-auditor-httpd",
options,
argc, argv))
return 1;
+ go = TALER_MHD_GO_NONE;
+ if (TAH_auditor_connection_close)
+ go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE;
+ TALER_MHD_setup (go);
GNUNET_assert (GNUNET_OK ==
GNUNET_log_setup ("taler-auditor-httpd",
(NULL == loglev) ? "INFO" : loglev,
@@ -877,8 +628,8 @@ main (int argc,
if ( (-1 == fh) &&
(NULL != serve_unixpath) )
{
- fh = open_unix_path (serve_unixpath,
- unixpath_mode);
+ fh = TALER_MHD_open_unix_path (serve_unixpath,
+ unixpath_mode);
if (-1 == fh)
return 1;
}
@@ -894,7 +645,8 @@ main (int argc,
MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) 32,
MHD_OPTION_LISTEN_BACKLOG_SIZE, (unsigned int) 1024,
MHD_OPTION_LISTEN_SOCKET, fh,
- MHD_OPTION_EXTERNAL_LOGGER, &handle_mhd_logs, NULL,
+ MHD_OPTION_EXTERNAL_LOGGER, &TALER_MHD_handle_logs,
+ NULL,
MHD_OPTION_NOTIFY_COMPLETED,
&handle_mhd_completion_callback, NULL,
MHD_OPTION_CONNECTION_TIMEOUT, connection_timeout,
diff --git a/src/auditor/taler-auditor-httpd_db.c b/src/auditor/taler-auditor-httpd_db.c
index e0ab8f2e..3433e9a9 100644
--- a/src/auditor/taler-auditor-httpd_db.c
+++ b/src/auditor/taler-auditor-httpd_db.c
@@ -23,8 +23,9 @@
#include <jansson.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler-auditor-httpd_db.h"
-#include "taler-auditor-httpd_responses.h"
+#include "taler-auditor-httpd.h"
/**
@@ -63,8 +64,10 @@ TAH_DB_run_transaction (struct MHD_Connection *connection,
{
GNUNET_break (0);
if (NULL != mhd_ret)
- *mhd_ret = TAH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DB_SETUP_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_SETUP_FAILED,
+ "failed to establish session with database");
return GNUNET_SYSERR;
}
// TAH_plugin->preflight (TAH_plugin->cls, session); // FIXME: needed?
@@ -79,8 +82,10 @@ TAH_DB_run_transaction (struct MHD_Connection *connection,
{
GNUNET_break (0);
if (NULL != mhd_ret)
- *mhd_ret = TAH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DB_START_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_START_FAILED,
+ "failed to begin transaction");
return GNUNET_SYSERR;
}
qs = cb (cb_cls,
@@ -98,8 +103,10 @@ TAH_DB_run_transaction (struct MHD_Connection *connection,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
if (NULL != mhd_ret)
- *mhd_ret = TAH_RESPONSE_reply_commit_error (connection,
- TALER_EC_DB_COMMIT_FAILED_HARD);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_COMMIT_FAILED_HARD,
+ "failed to commit transaction");
return GNUNET_SYSERR;
}
/* make sure callback did not violate invariants! */
@@ -112,8 +119,10 @@ TAH_DB_run_transaction (struct MHD_Connection *connection,
name,
MAX_TRANSACTION_COMMIT_RETRIES);
if (NULL != mhd_ret)
- *mhd_ret = TAH_RESPONSE_reply_commit_error (connection,
- TALER_EC_DB_COMMIT_FAILED_ON_RETRY);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_COMMIT_FAILED_ON_RETRY,
+ "transaction repeatedly failed to serialize");
return GNUNET_SYSERR;
}
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
index 2b73a910..0a121fda 100644
--- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c
+++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
@@ -27,11 +27,10 @@
#include <microhttpd.h>
#include <pthread.h>
#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler-auditor-httpd.h"
#include "taler-auditor-httpd_db.h"
#include "taler-auditor-httpd_deposit-confirmation.h"
-#include "taler-auditor-httpd_parsing.h"
-#include "taler-auditor-httpd_responses.h"
/**
@@ -43,10 +42,10 @@
static int
reply_deposit_confirmation_success (struct MHD_Connection *connection)
{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:s}",
- "status", "DEPOSIT_CONFIRMATION_OK");
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:s}",
+ "status", "DEPOSIT_CONFIRMATION_OK");
}
@@ -74,8 +73,10 @@ store_exchange_signing_key_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
TALER_LOG_WARNING ("Failed to store exchange signing key in database\n");
- *mhd_ret = TAH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_AUDITOR_EXCHANGE_STORE_DB_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_AUDITOR_EXCHANGE_STORE_DB_ERROR,
+ "failed to persist exchange signing key");
}
return qs;
}
@@ -111,8 +112,10 @@ deposit_confirmation_transaction (void *cls,
{
TALER_LOG_WARNING (
"Failed to store /deposit-confirmation information in database\n");
- *mhd_ret = TAH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DEPOSIT_CONFIRMATION_STORE_DB_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DEPOSIT_CONFIRMATION_STORE_DB_ERROR,
+ "failed to persist deposit-confirmation data");
}
return qs;
}
@@ -155,9 +158,10 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
&es->master_public_key.eddsa_pub))
{
TALER_LOG_WARNING ("Invalid signature on exchange signing key\n");
- return TAH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
- "master_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
+ "master_sig");
}
/* execute transaction */
@@ -187,9 +191,10 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
&dc->exchange_pub.eddsa_pub))
{
TALER_LOG_WARNING ("Invalid signature on /deposit-confirmation request\n");
- return TAH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
- "exchange_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
+ "exchange_sig");
}
/* execute transaction */
@@ -248,19 +253,19 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh,
GNUNET_JSON_spec_end ()
};
- res = TAH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) ||
(NULL == json) )
return MHD_YES;
- res = TAH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
es.exchange_pub = dc.exchange_pub; /* used twice! */
dc.master_public_key = es.master_public_key;
diff --git a/src/auditor/taler-auditor-httpd_exchanges.c b/src/auditor/taler-auditor-httpd_exchanges.c
index 881c45a2..3c6bfe68 100644
--- a/src/auditor/taler-auditor-httpd_exchanges.c
+++ b/src/auditor/taler-auditor-httpd_exchanges.c
@@ -25,11 +25,10 @@
#include <microhttpd.h>
#include <pthread.h>
#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler-auditor-httpd.h"
#include "taler-auditor-httpd_db.h"
#include "taler-auditor-httpd_exchanges.h"
-#include "taler-auditor-httpd_parsing.h"
-#include "taler-auditor-httpd_responses.h"
/**
@@ -43,10 +42,10 @@ static int
reply_exchanges_success (struct MHD_Connection *connection,
json_t *ja)
{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "exchanges", ja);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "exchanges", ja);
}
@@ -108,8 +107,10 @@ list_exchanges (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
TALER_LOG_WARNING ("Failed to handle /exchanges in database\n");
- *mhd_ret = TAH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_LIST_EXCHANGES_DB_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_LIST_EXCHANGES_DB_ERROR,
+ "Could not fetch exchange list from database");
}
return qs;
}
@@ -148,4 +149,4 @@ TAH_EXCHANGES_handler (struct TAH_RequestHandler *rh,
}
-/* end of taler-auditor-httpd_deposit-confirmation.c */
+/* end of taler-auditor-httpd_exchanges.c */
diff --git a/src/auditor/taler-auditor-httpd_mhd.c b/src/auditor/taler-auditor-httpd_mhd.c
index 5f13691f..01927469 100644
--- a/src/auditor/taler-auditor-httpd_mhd.c
+++ b/src/auditor/taler-auditor-httpd_mhd.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
+ Copyright (C) 2014-2019 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -28,7 +28,7 @@
#include <jansson.h>
#include <microhttpd.h>
#include <pthread.h>
-#include "taler-auditor-httpd_responses.h"
+#include "taler_mhd_lib.h"
#include "taler-auditor-httpd.h"
#include "taler-auditor-httpd_mhd.h"
@@ -53,6 +53,9 @@ TAH_MHD_handler_static_response (struct TAH_RequestHandler *rh,
struct MHD_Response *response;
int ret;
+ (void) connection_cls;
+ (void) upload_data;
+ (void) upload_data_size;
if (0 == rh->data_size)
rh->data_size = strlen ((const char *) rh->data);
response = MHD_create_response_from_buffer (rh->data_size,
@@ -63,7 +66,7 @@ TAH_MHD_handler_static_response (struct TAH_RequestHandler *rh,
GNUNET_break (0);
return MHD_NO;
}
- TAH_RESPONSE_add_global_headers (response);
+ TALER_MHD_add_global_headers (response);
if (NULL != rh->mime_type)
(void) MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -94,38 +97,12 @@ TAH_MHD_handler_agpl_redirect (struct TAH_RequestHandler *rh,
const char *upload_data,
size_t *upload_data_size)
{
- const char *agpl =
- "This server is licensed under the Affero GPL. You will now be redirected to the source code.";
- struct MHD_Response *response;
- int ret;
-
- response = MHD_create_response_from_buffer (strlen (agpl),
- (void *) agpl,
- MHD_RESPMEM_PERSISTENT);
- if (NULL == response)
- {
- GNUNET_break (0);
- return MHD_NO;
- }
- TAH_RESPONSE_add_global_headers (response);
- if (NULL != rh->mime_type)
- (void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- rh->mime_type);
- if (MHD_NO ==
- MHD_add_response_header (response,
- MHD_HTTP_HEADER_LOCATION,
- "http://www.git.taler.net/?p=auditor.git"))
- {
- GNUNET_break (0);
- MHD_destroy_response (response);
- return MHD_NO;
- }
- ret = MHD_queue_response (connection,
- rh->response_code,
- response);
- MHD_destroy_response (response);
- return ret;
+ (void) rh;
+ (void) connection_cls;
+ (void) upload_data;
+ (void) upload_data_size;
+ return TALER_MHD_reply_agpl (connection,
+ "http://www.git.taler.net/?p=exchange.git");
}
@@ -147,11 +124,11 @@ TAH_MHD_handler_send_json_pack_error (struct TAH_RequestHandler *rh,
const char *upload_data,
size_t *upload_data_size)
{
- return TAH_RESPONSE_reply_json_pack (connection,
- rh->response_code,
- "{s:s}",
- "error",
- rh->data);
+ return TALER_MHD_reply_json_pack (connection,
+ rh->response_code,
+ "{s:s}",
+ "error",
+ rh->data);
}
diff --git a/src/auditor/taler-auditor-httpd_parsing.c b/src/auditor/taler-auditor-httpd_parsing.c
deleted file mode 100644
index fb707c88..00000000
--- a/src/auditor/taler-auditor-httpd_parsing.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015, 2016 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-
-/**
- * @file taler-auditor-httpd_parsing.c
- * @brief functions to parse incoming requests (MHD arguments and JSON snippets)
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include "taler_json_lib.h"
-#include "taler-auditor-httpd_parsing.h"
-#include "taler-auditor-httpd_responses.h"
-
-
-/**
- * Maximum POST request size.
- */
-#define REQUEST_BUFFER_MAX (1024 * 1024)
-
-
-/**
- * Process a POST request containing a JSON object. This function
- * realizes an MHD POST processor that will (incrementally) process
- * JSON data uploaded to the HTTP server. It will store the required
- * state in the @a con_cls, which must be cleaned up using
- * #TAH_PARSE_post_cleanup_callback().
- *
- * @param connection the MHD connection
- * @param con_cls the closure (points to a `struct Buffer *`)
- * @param upload_data the POST data
- * @param upload_data_size number of bytes in @a upload_data
- * @param json the JSON object for a completed request
- * @return
- * #GNUNET_YES if json object was parsed or at least
- * may be parsed in the future (call again);
- * `*json` will be NULL if we need to be called again,
- * and non-NULL if we are done.
- * #GNUNET_NO is request incomplete or invalid
- * (error message was generated)
- * #GNUNET_SYSERR on internal error
- * (we could not even queue an error message,
- * close HTTP session with MHD_NO)
- */
-int
-TAH_PARSE_post_json (struct MHD_Connection *connection,
- void **con_cls,
- const char *upload_data,
- size_t *upload_data_size,
- json_t **json)
-{
- enum GNUNET_JSON_PostResult pr;
-
- pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX,
- connection,
- con_cls,
- upload_data,
- upload_data_size,
- json);
- switch (pr)
- {
- case GNUNET_JSON_PR_OUT_OF_MEMORY:
- return (MHD_NO ==
- TAH_RESPONSE_reply_internal_error (connection,
- TALER_EC_PARSER_OUT_OF_MEMORY,
- "out of memory"))
- ? GNUNET_SYSERR : GNUNET_NO;
- case GNUNET_JSON_PR_CONTINUE:
- return GNUNET_YES;
- case GNUNET_JSON_PR_REQUEST_TOO_LARGE:
- return (MHD_NO ==
- TAH_RESPONSE_reply_request_too_large (connection))
- ? GNUNET_SYSERR : GNUNET_NO;
- case GNUNET_JSON_PR_JSON_INVALID:
- return (MHD_YES ==
- TAH_RESPONSE_reply_invalid_json (connection))
- ? GNUNET_NO : GNUNET_SYSERR;
- case GNUNET_JSON_PR_SUCCESS:
- GNUNET_break (NULL != *json);
- return GNUNET_YES;
- }
- /* this should never happen */
- GNUNET_break (0);
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Function called whenever we are done with a request
- * to clean up our state.
- *
- * @param con_cls value as it was left by
- * #TAH_PARSE_post_json(), to be cleaned up
- */
-void
-TAH_PARSE_post_cleanup_callback (void *con_cls)
-{
- GNUNET_JSON_post_parser_cleanup (con_cls);
-}
-
-
-/**
- * Extract base32crockford encoded data from request.
- *
- * Queues an error response to the connection if the parameter is
- * missing or invalid.
- *
- * @param connection the MHD connection
- * @param param_name the name of the parameter with the key
- * @param[out] out_data pointer to store the result
- * @param out_size expected size of data
- * @return
- * #GNUNET_YES if the the argument is present
- * #GNUNET_NO if the argument is absent or malformed
- * #GNUNET_SYSERR on internal error (error response could not be sent)
- */
-int
-TAH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
- const char *param_name,
- void *out_data,
- size_t out_size)
-{
- const char *str;
-
- str = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- param_name);
- if (NULL == str)
- {
- return (MHD_NO ==
- TAH_RESPONSE_reply_arg_missing (connection,
- TALER_EC_PARAMETER_MISSING,
- param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- }
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (str,
- strlen (str),
- out_data,
- out_size))
- return (MHD_NO ==
- TAH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_PARAMETER_MALFORMED,
- param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- return GNUNET_OK;
-}
-
-
-/**
- * Parse JSON object into components based on the given field
- * specification. Generates error response on parse errors.
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param[in,out] spec field specification for the parser
- * @return
- * #GNUNET_YES if navigation was successful (caller is responsible
- * for freeing allocated variable-size data using
- * GNUNET_JSON_parse_free() when done)
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error
- */
-int
-TAH_PARSE_json_data (struct MHD_Connection *connection,
- const json_t *root,
- struct GNUNET_JSON_Specification *spec)
-{
- int ret;
- const char *error_json_name;
- unsigned int error_line;
-
- ret = GNUNET_JSON_parse (root,
- spec,
- &error_json_name,
- &error_line);
- if (GNUNET_SYSERR == ret)
- {
- if (NULL == error_json_name)
- error_json_name = "<no field>";
- ret = (MHD_YES ==
- TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I, s:s, s:I}",
- "error", "parse error",
- "code",
- (json_int_t)
- TALER_EC_JSON_INVALID_WITH_DETAILS,
- "field", error_json_name,
- "line", (json_int_t) error_line))
- ? GNUNET_NO : GNUNET_SYSERR;
- return ret;
- }
- return GNUNET_YES;
-}
-
-
-/**
- * Parse JSON array into components based on the given field
- * specification. Generates error response on parse errors.
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param[in,out] spec field specification for the parser
- * @param ... -1-terminated list of array offsets of type 'int'
- * @return
- * #GNUNET_YES if navigation was successful (caller is responsible
- * for freeing allocated variable-size data using
- * GNUNET_JSON_parse_free() when done)
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error
- */
-int
-TAH_PARSE_json_array (struct MHD_Connection *connection,
- const json_t *root,
- struct GNUNET_JSON_Specification *spec,
- ...)
-{
- int ret;
- const char *error_json_name;
- unsigned int error_line;
- va_list ap;
- json_int_t dim;
-
- va_start (ap, spec);
- dim = 0;
- while ( (-1 != (ret = va_arg (ap, int))) &&
- (NULL != root) )
- {
- dim++;
- root = json_array_get (root, ret);
- }
- va_end (ap);
- if (NULL == root)
- {
- ret = (MHD_YES ==
- TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I}",
- "error", "parse error",
- "dimension", dim))
- ? GNUNET_NO : GNUNET_SYSERR;
- return ret;
- }
- ret = GNUNET_JSON_parse (root,
- spec,
- &error_json_name,
- &error_line);
- if (GNUNET_SYSERR == ret)
- {
- if (NULL == error_json_name)
- error_json_name = "<no field>";
- ret = (MHD_YES ==
- TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s, s:I}",
- "error", "parse error",
- "field", error_json_name,
- "line", (json_int_t) error_line))
- ? GNUNET_NO : GNUNET_SYSERR;
- return ret;
- }
- return GNUNET_YES;
-}
-
-
-/* end of taler-auditor-httpd_parsing.c */
diff --git a/src/auditor/taler-auditor-httpd_parsing.h b/src/auditor/taler-auditor-httpd_parsing.h
deleted file mode 100644
index 7df76ef5..00000000
--- a/src/auditor/taler-auditor-httpd_parsing.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015, 2016 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-auditor-httpd_parsing.h
- * @brief functions to parse incoming requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_AUDITOR_HTTPD_PARSING_H
-#define TALER_AUDITOR_HTTPD_PARSING_H
-
-#include <microhttpd.h>
-#include <jansson.h>
-#include "taler_util.h"
-#include "taler_json_lib.h"
-
-
-/**
- * Process a POST request containing a JSON object. This
- * function realizes an MHD POST processor that will
- * (incrementally) process JSON data uploaded to the HTTP
- * server. It will store the required state in the
- * "connection_cls", which must be cleaned up using
- * #TAH_PARSE_post_cleanup_callback().
- *
- * @param connection the MHD connection
- * @param con_cls the closure (points to a `struct Buffer *`)
- * @param upload_data the POST data
- * @param upload_data_size number of bytes in @a upload_data
- * @param json the JSON object for a completed request
- * @return
- * #GNUNET_YES if json object was parsed or at least
- * may be parsed in the future (call again);
- * `*json` will be NULL if we need to be called again,
- * and non-NULL if we are done.
- * #GNUNET_NO is request incomplete or invalid
- * (error message was generated)
- * #GNUNET_SYSERR on internal error
- * (we could not even queue an error message,
- * close HTTP session with MHD_NO)
- */
-int
-TAH_PARSE_post_json (struct MHD_Connection *connection,
- void **con_cls,
- const char *upload_data,
- size_t *upload_data_size,
- json_t **json);
-
-
-/**
- * Function called whenever we are done with a request
- * to clean up our state.
- *
- * @param con_cls value as it was left by
- * #TAH_PARSE_post_json(), to be cleaned up
- */
-void
-TAH_PARSE_post_cleanup_callback (void *con_cls);
-
-
-/**
- * Parse JSON object into components based on the given field
- * specification.
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param spec field specification for the parser
- * @return
- * #GNUNET_YES if navigation was successful (caller is responsible
- * for freeing allocated variable-size data using
- * GNUNET_JSON_parse_free() when done)
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error
- */
-int
-TAH_PARSE_json_data (struct MHD_Connection *connection,
- const json_t *root,
- struct GNUNET_JSON_Specification *spec);
-
-
-/**
- * Parse JSON array into components based on the given field
- * specification. Generates error response on parse errors.
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param[in,out] spec field specification for the parser
- * @param ... -1-terminated list of array offsets of type 'int'
- * @return
- * #GNUNET_YES if navigation was successful (caller is responsible
- * for freeing allocated variable-size data using
- * GNUNET_JSON_parse_free() when done)
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error
- */
-int
-TAH_PARSE_json_array (struct MHD_Connection *connection,
- const json_t *root,
- struct GNUNET_JSON_Specification *spec,
- ...);
-
-
-/**
- * Extraxt fixed-size base32crockford encoded data from request.
- *
- * Queues an error response to the connection if the parameter is missing or
- * invalid.
- *
- * @param connection the MHD connection
- * @param param_name the name of the parameter with the key
- * @param[out] out_data pointer to store the result
- * @param out_size expected size of @a out_data
- * @return
- * #GNUNET_YES if the the argument is present
- * #GNUNET_NO if the argument is absent or malformed
- * #GNUNET_SYSERR on internal error (error response could not be sent)
- */
-int
-TAH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
- const char *param_name,
- void *out_data,
- size_t out_size);
-
-
-#endif /* TALER_AUDITOR_HTTPD_PARSING_H */
diff --git a/src/auditor/taler-auditor-httpd_responses.c b/src/auditor/taler-auditor-httpd_responses.c
deleted file mode 100644
index 4c7b429e..00000000
--- a/src/auditor/taler-auditor-httpd_responses.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2017 Inria & GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_responses.c
- * @brief API for generating genric replies of the exchange; these
- * functions are called TAH_RESPONSE_reply_ and they generate
- * and queue MHD response objects for a given connection.
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <zlib.h>
-#include "taler-auditor-httpd_responses.h"
-#include "taler_util.h"
-#include "taler_json_lib.h"
-
-
-/**
- * Add headers we want to return in every response.
- * Useful for testing, like if we want to always close
- * connections.
- *
- * @param response response to modify
- */
-void
-TAH_RESPONSE_add_global_headers (struct MHD_Response *response)
-{
- if (TAH_auditor_connection_close)
- GNUNET_break (MHD_YES ==
- MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONNECTION,
- "close"));
-}
-
-
-/**
- * Is HTTP body deflate compression supported by the client?
- *
- * @param connection connection to check
- * @return #MHD_YES if 'deflate' compression is allowed
- *
- * Note that right now we're ignoring q-values, which is technically
- * not correct, and also do not support "*" anywhere but in a line by
- * itself. This should eventually be fixed, see also
- * https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
- */
-int
-TAH_RESPONSE_can_compress (struct MHD_Connection *connection)
-{
- const char *ae;
- const char *de;
-
- ae = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_ACCEPT_ENCODING);
- if (NULL == ae)
- return MHD_NO;
- if (0 == strcmp (ae,
- "*"))
- return MHD_YES;
- de = strstr (ae,
- "deflate");
- if (NULL == de)
- return MHD_NO;
- if ( ( (de == ae) ||
- (de[-1] == ',') ||
- (de[-1] == ' ') ) &&
- ( (de[strlen ("deflate")] == '\0') ||
- (de[strlen ("deflate")] == ',') ||
- (de[strlen ("deflate")] == ';') ) )
- return MHD_YES;
- return MHD_NO;
-}
-
-
-/**
- * Try to compress a response body. Updates @a buf and @a buf_size.
- *
- * @param[in,out] buf pointer to body to compress
- * @param[in,out] buf_size pointer to initial size of @a buf
- * @return #MHD_YES if @a buf was compressed
- */
-int
-TAH_RESPONSE_body_compress (void **buf,
- size_t *buf_size)
-{
- Bytef *cbuf;
- uLongf cbuf_size;
- int ret;
-
- cbuf_size = compressBound (*buf_size);
- cbuf = malloc (cbuf_size);
- if (NULL == cbuf)
- return MHD_NO;
- ret = compress (cbuf,
- &cbuf_size,
- (const Bytef *) *buf,
- *buf_size);
- if ( (Z_OK != ret) ||
- (cbuf_size >= *buf_size) )
- {
- /* compression failed */
- free (cbuf);
- return MHD_NO;
- }
- free (*buf);
- *buf = (void *) cbuf;
- *buf_size = (size_t) cbuf_size;
- return MHD_YES;
-}
-
-
-/**
- * Send JSON object as response.
- *
- * @param connection the MHD connection
- * @param json the json object
- * @param response_code the http response code
- * @return MHD result code
- */
-int
-TAH_RESPONSE_reply_json (struct MHD_Connection *connection,
- const json_t *json,
- unsigned int response_code)
-{
- struct MHD_Response *resp;
- void *json_str;
- size_t json_len;
- int ret;
- int comp;
-
- json_str = json_dumps (json,
- JSON_INDENT (2));
- if (NULL == json_str)
- {
- /**
- * This log helps to figure out which
- * function called this one and assert-failed.
- */
- TALER_LOG_ERROR ("Aborting json-packing for HTTP code: %u\n",
- response_code);
-
- GNUNET_assert (0);
- return MHD_NO;
- }
- json_len = strlen (json_str);
- /* try to compress the body */
- comp = MHD_NO;
- if (MHD_YES ==
- TAH_RESPONSE_can_compress (connection))
- comp = TAH_RESPONSE_body_compress (&json_str,
- &json_len);
- resp = MHD_create_response_from_buffer (json_len,
- json_str,
- MHD_RESPMEM_MUST_FREE);
- if (NULL == resp)
- {
- free (json_str);
- GNUNET_break (0);
- return MHD_NO;
- }
- TAH_RESPONSE_add_global_headers (resp);
- (void) MHD_add_response_header (resp,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "application/json");
- if (MHD_YES == comp)
- {
- /* Need to indicate to client that body is compressed */
- if (MHD_NO ==
- MHD_add_response_header (resp,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- "deflate"))
- {
- GNUNET_break (0);
- MHD_destroy_response (resp);
- return MHD_NO;
- }
- }
- ret = MHD_queue_response (connection,
- response_code,
- resp);
- MHD_destroy_response (resp);
- return ret;
-}
-
-
-/**
- * Function to call to handle the request by building a JSON
- * reply from a format string and varargs.
- *
- * @param connection the MHD connection to handle
- * @param response_code HTTP response code to use
- * @param fmt format string for pack
- * @param ... varargs
- * @return MHD result code
- */
-int
-TAH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
- unsigned int response_code,
- const char *fmt,
- ...)
-{
- json_t *json;
- va_list argp;
- int ret;
- json_error_t jerror;
-
- va_start (argp, fmt);
- json = json_vpack_ex (&jerror, 0, fmt, argp);
- va_end (argp);
- if (NULL == json)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to pack JSON with format `%s': %s\n",
- fmt,
- jerror.text);
- GNUNET_break (0);
- return MHD_NO;
- }
- ret = TAH_RESPONSE_reply_json (connection,
- json,
- response_code);
- json_decref (json);
- return ret;
-}
-
-
-/**
- * Send a response indicating an invalid argument.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name)
-{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I, s:s}",
- "error", "invalid parameter",
- "code", (json_int_t) ec,
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating an argument refering to a
- * resource unknown to the auditor (i.e. unknown reserve or
- * denomination key).
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name)
-{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s, s:I, s:s}",
- "error", "unknown entity referenced",
- "code", (json_int_t) ec,
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating an invalid signature.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name)
-{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_UNAUTHORIZED,
- "{s:s, s:I, s:s}",
- "error", "invalid signature",
- "code", (json_int_t) ec,
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating a missing argument.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is missing
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name)
-{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I, s:s}",
- "error", "missing parameter",
- "code", (json_int_t) ec,
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating permission denied.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about why access was denied
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint)
-{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_FORBIDDEN,
- "{s:s, s:I, s:s}",
- "error", "permission denied",
- "code", (json_int_t) ec,
- "hint", hint);
-}
-
-
-/**
- * Send a response indicating an internal error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about the internal error's nature
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint)
-{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- "{s:s, s:I, s:s}",
- "error", "internal error",
- "code", (json_int_t) ec,
- "hint", hint);
-}
-
-
-/**
- * Send a response indicating an external error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about the error's nature
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint)
-{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I, s:s}",
- "error", "client error",
- "code", (json_int_t) ec,
- "hint", hint);
-}
-
-
-/**
- * Send a response indicating an error committing a
- * transaction (concurrent interference).
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec)
-{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- "{s:s, s:I}",
- "error", "commit failure",
- "code", (json_int_t) ec);
-}
-
-
-/**
- * Send a response indicating a failure to talk to the Auditor's
- * database.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec)
-{
- return TAH_RESPONSE_reply_internal_error (connection,
- ec,
- "Failure in database interaction");
-}
-
-
-/**
- * Send a response indicating that the request was too big.
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection)
-{
- struct MHD_Response *resp;
- int ret;
-
- resp = MHD_create_response_from_buffer (0,
- NULL,
- MHD_RESPMEM_PERSISTENT);
- if (NULL == resp)
- return MHD_NO;
- TAH_RESPONSE_add_global_headers (resp);
- ret = MHD_queue_response (connection,
- MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
- resp);
- MHD_destroy_response (resp);
- return ret;
-}
-
-
-/**
- * Send a response indicating that the JSON was malformed.
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection)
-{
- return TAH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I}",
- "error", "invalid json",
- "code",
- (json_int_t) TALER_EC_JSON_INVALID);
-}
-
-
-/* end of taler-auditor-httpd_responses.c */
diff --git a/src/auditor/taler-auditor-httpd_responses.h b/src/auditor/taler-auditor-httpd_responses.h
deleted file mode 100644
index 1cb5faa8..00000000
--- a/src/auditor/taler-auditor-httpd_responses.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-
-/**
- * @file taler-auditor-httpd_responses.h
- * @brief API for generating generic replies of the auditor; these
- * functions are called TAH_RESPONSE_reply_ and they generate
- * and queue MHD response objects for a given connection.
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_AUDITOR_HTTPD_RESPONSES_H
-#define TALER_AUDITOR_HTTPD_RESPONSES_H
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include <microhttpd.h>
-#include <pthread.h>
-#include "taler_error_codes.h"
-#include "taler-auditor-httpd.h"
-
-
-/**
- * Add headers we want to return in every response.
- * Useful for testing, like if we want to always close
- * connections.
- *
- * @param response response to modify
- */
-void
-TAH_RESPONSE_add_global_headers (struct MHD_Response *response);
-
-
-/**
- * Try to compress a response body. Updates @a buf and @a buf_size.
- *
- * @param[in,out] buf pointer to body to compress
- * @param[in,out] buf_size pointer to initial size of @a buf
- * @return #MHD_YES if @a buf was compressed
- */
-int
-TAH_RESPONSE_body_compress (void **buf,
- size_t *buf_size);
-
-
-/**
- * Is HTTP body deflate compression supported by the client?
- *
- * @param connection connection to check
- * @return #MHD_YES if 'deflate' compression is allowed
- */
-int
-TAH_RESPONSE_can_compress (struct MHD_Connection *connection);
-
-
-/**
- * Send JSON object as response.
- *
- * @param connection the MHD connection
- * @param json the json object
- * @param response_code the http response code
- * @return MHD result code
- */
-int
-TAH_RESPONSE_reply_json (struct MHD_Connection *connection,
- const json_t *json,
- unsigned int response_code);
-
-
-/**
- * Function to call to handle the request by building a JSON
- * reply from a format string and varargs.
- *
- * @param connection the MHD connection to handle
- * @param response_code HTTP response code to use
- * @param fmt format string for pack
- * @param ... varargs
- * @return MHD result code
- */
-int
-TAH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
- unsigned int response_code,
- const char *fmt,
- ...);
-
-
-/**
- * Send a response indicating an invalid signature.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name);
-
-
-/**
- * Send a response indicating an invalid argument.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return MHD result code
- */
-int
-TAH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name);
-
-
-/**
- * Send a response indicating an argument refering to a
- * resource unknown to the auditor (i.e. unknown reserve or
- * denomination key).
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name);
-
-
-/**
- * Send a response indicating a missing argument.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is missing
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name);
-
-
-/**
- * Send a response indicating permission denied.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about why access was denied
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint);
-
-
-/**
- * Send a response indicating an internal error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about the internal error's nature
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint);
-
-
-/**
- * Send a response indicating an external error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about the error's nature
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint);
-
-
-/**
- * Send a response indicating an error committing a
- * transaction (concurrent interference).
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec);
-
-/**
- * Send a response indicating a failure to talk to the Auditor's
- * database.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec);
-
-
-/**
- * Send a response indicating that the request was too big.
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection);
-
-
-/**
- * Send a response indicating that the JSON was malformed.
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TAH_RESPONSE_reply_invalid_json (struct MHD_Connection *connectionx);
-
-
-#endif
diff --git a/src/exchange-tools/Makefile.am b/src/exchange-tools/Makefile.am
index 409c6bfd..64b4cee8 100644
--- a/src/exchange-tools/Makefile.am
+++ b/src/exchange-tools/Makefile.am
@@ -16,6 +16,7 @@ bin_PROGRAMS = \
taler-exchange-keycheck \
taler-exchange-wire \
taler-exchange-dbinit \
+ taler-exchange-tvg \
taler-wire
taler_wire_SOURCES = \
@@ -59,6 +60,13 @@ taler_exchange_keycheck_LDADD = \
-lgnunetutil $(XLIB)
taler_exchange_keycheck_LDFLAGS = $(POSTGRESQL_LDFLAGS)
+taler_exchange_tvg_SOURCES = \
+ taler-exchange-tvg.c
+taler_exchange_tvg_LDADD = \
+ $(LIBGCRYPT_LIBS) \
+ $(top_builddir)/src/util/libtalerutil.la \
+ -lgnunetutil $(XLIB)
+
taler_exchange_dbinit_SOURCES = \
taler-exchange-dbinit.c
taler_exchange_dbinit_LDADD = \
diff --git a/src/exchange-tools/taler-exchange-tvg.c b/src/exchange-tools/taler-exchange-tvg.c
new file mode 100644
index 00000000..55e658fc
--- /dev/null
+++ b/src/exchange-tools/taler-exchange-tvg.c
@@ -0,0 +1,259 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019 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, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file exchange-tools/taler-exchange-tvg.c
+ * @brief Generate test vectors for cryptographic operations.
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "taler_util.h"
+#include "taler_signatures.h"
+#include <gnunet/gnunet_util_lib.h>
+
+
+/**
+ * Print data base32-crockford with a preceding label.
+ *
+ * @param label label to print
+ * @param data data to print
+ * @param size size of data
+ */
+static void
+display_data (char *label, void *data, size_t size)
+{
+ char *enc = GNUNET_STRINGS_data_to_string_alloc (data, size);
+ printf ("%s %s\n", label, enc);
+ GNUNET_free (enc);
+}
+
+
+/**
+ * Main function that will be run.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ {
+ struct GNUNET_HashCode hc;
+ char *str = "Hello, GNU Taler";
+
+ GNUNET_CRYPTO_hash (str, strlen (str), &hc);
+
+ printf ("hash code:\n");
+ display_data (" input", str, strlen (str));
+ display_data (" output", &hc, sizeof (struct GNUNET_HashCode));
+ }
+ {
+ struct GNUNET_CRYPTO_EcdhePrivateKey *priv1;
+ struct GNUNET_CRYPTO_EcdhePublicKey pub1;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *priv2;
+ struct GNUNET_HashCode skm;
+ priv1 = GNUNET_CRYPTO_ecdhe_key_create ();
+ priv2 = GNUNET_CRYPTO_ecdhe_key_create ();
+ GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1);
+ GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &skm));
+
+ printf ("ecdhe key:\n");
+ display_data (" priv1", priv1, sizeof (struct
+ GNUNET_CRYPTO_EcdhePrivateKey));
+ display_data (" pub1", &pub1, sizeof (struct
+ GNUNET_CRYPTO_EcdhePublicKey));
+ display_data (" priv2", priv2, sizeof (struct
+ GNUNET_CRYPTO_EcdhePrivateKey));
+ display_data (" skm", &skm, sizeof (struct GNUNET_HashCode));
+ GNUNET_free (priv1);
+ GNUNET_free (priv2);
+ }
+
+ {
+ struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
+ struct GNUNET_CRYPTO_EddsaPublicKey pub;
+ priv = GNUNET_CRYPTO_eddsa_key_create ();
+ GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
+
+ printf ("eddsa key:\n");
+ display_data (" priv", priv, sizeof (struct
+ GNUNET_CRYPTO_EddsaPrivateKey));
+ display_data (" pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
+ GNUNET_free (priv);
+ }
+ {
+ struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
+ struct GNUNET_CRYPTO_EddsaPublicKey pub;
+ struct GNUNET_CRYPTO_EddsaSignature sig;
+ struct TALER_ProposalDataPS data = { 0 };
+ priv = GNUNET_CRYPTO_eddsa_key_create ();
+ GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
+ data.purpose.size = htonl (sizeof (struct TALER_ProposalDataPS));
+ GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (priv, &data.purpose,
+ &sig));
+ GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_verify (0,
+ &data.purpose,
+ &sig,
+ &pub));
+
+ printf ("eddsa sig:\n");
+ display_data (" priv", priv, sizeof (struct
+ GNUNET_CRYPTO_EddsaPrivateKey));
+ display_data (" pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
+ display_data (" data", &data, sizeof (struct TALER_ProposalDataPS));
+ display_data (" sig", &sig, sizeof (struct GNUNET_CRYPTO_EddsaSignature));
+ GNUNET_free (priv);
+ }
+
+ {
+ size_t out_len = 64;
+ char out[out_len];
+ char *ikm = "I'm the secret input key material";
+ char *salt = "I'm very salty";
+ char *ctx = "I'm a context chunk, also known as 'info' in the RFC";
+
+ GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_kdf (&out,
+ out_len,
+ salt,
+ strlen (salt),
+ ikm,
+ strlen (ikm),
+ ctx,
+ strlen (ctx),
+ NULL));
+
+ printf ("kdf:\n");
+ display_data (" salt", salt, strlen (salt));
+ display_data (" ikm", ikm, strlen (ikm));
+ display_data (" ctx", ctx, strlen (ctx));
+ printf (" out_len %u\n", (unsigned int) out_len);
+ display_data (" out", out, out_len);
+ }
+ {
+ struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdhe;
+ struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe;
+ struct GNUNET_CRYPTO_EddsaPrivateKey *priv_eddsa;
+ struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa;
+ struct GNUNET_HashCode key_material;
+ priv_ecdhe = GNUNET_CRYPTO_ecdhe_key_create ();
+ GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdhe, &pub_ecdhe);
+ priv_eddsa = GNUNET_CRYPTO_eddsa_key_create ();
+ GNUNET_CRYPTO_eddsa_key_get_public (priv_eddsa, &pub_eddsa);
+ GNUNET_CRYPTO_ecdh_eddsa (priv_ecdhe, &pub_eddsa, &key_material);
+
+ printf ("eddsa_ecdh:\n");
+ display_data (" priv_ecdhe", priv_ecdhe, sizeof (struct
+ GNUNET_CRYPTO_EcdhePrivateKey));
+ display_data (" pub_ecdhe", &pub_ecdhe, sizeof (struct
+ GNUNET_CRYPTO_EcdhePublicKey));
+ display_data (" priv_eddsa", priv_eddsa, sizeof (struct
+ GNUNET_CRYPTO_EddsaPrivateKey));
+ display_data (" pub_eddsa", &pub_eddsa, sizeof (struct
+ GNUNET_CRYPTO_EddsaPublicKey));
+ display_data (" key_material", &key_material, sizeof (struct
+ GNUNET_HashCode));
+ }
+
+ {
+ struct GNUNET_CRYPTO_RsaPrivateKey *skey;
+ struct GNUNET_CRYPTO_RsaPublicKey *pkey;
+ struct GNUNET_HashCode message_hash;
+ struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
+ struct GNUNET_CRYPTO_RsaSignature *blinded_sig;
+ struct GNUNET_CRYPTO_RsaSignature *sig;
+ char *blinded_data;
+ size_t blinded_len;
+ char *public_enc_data;
+ size_t public_enc_len;
+ char *blinded_sig_enc_data;
+ size_t blinded_sig_enc_length;
+ char *sig_enc_data;
+ size_t sig_enc_length;
+ skey = GNUNET_CRYPTO_rsa_private_key_create (2048);
+ pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey);
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &message_hash,
+ sizeof (struct GNUNET_HashCode));
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &bks, sizeof (struct
+ GNUNET_CRYPTO_RsaBlindingKeySecret));
+ GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_blind (&message_hash, &bks,
+ pkey, &blinded_data,
+ &blinded_len));
+ blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, blinded_data,
+ blinded_len);
+ sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, &bks, pkey);
+ GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_verify (&message_hash, sig,
+ pkey));
+ public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey,
+ &public_enc_data);
+ blinded_sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig,
+ &
+ blinded_sig_enc_data);
+ sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data);
+ printf ("blind signing:\n");
+ display_data (" message_hash", &message_hash, sizeof (struct
+ GNUNET_HashCode));
+ display_data (" rsa_public_key", public_enc_data, public_enc_len);
+ display_data (" blinding_key_secret", &bks, sizeof (struct
+ GNUNET_CRYPTO_RsaBlindingKeySecret));
+ display_data (" blinded_message", blinded_data, blinded_len);
+ display_data (" blinded_sig", blinded_sig_enc_data,
+ blinded_sig_enc_length);
+ display_data (" sig", sig_enc_data, sig_enc_length);
+ GNUNET_CRYPTO_rsa_private_key_free (skey);
+ GNUNET_CRYPTO_rsa_public_key_free (pkey);
+ GNUNET_CRYPTO_rsa_signature_free (sig);
+ GNUNET_CRYPTO_rsa_signature_free (blinded_sig);
+ }
+}
+
+
+/**
+ * The main function of the test vector generation tool.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc,
+ char *const *argv)
+{
+ const struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ /* force linker to link against libtalerutil; if we do
+ not do this, the linker may "optimize" libtalerutil
+ away and skip #TALER_OS_init(), which we do need */
+ (void) TALER_project_data_default ();
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_log_setup ("taler-exchange-dbinit",
+ "INFO",
+ NULL));
+ if (GNUNET_OK !=
+ GNUNET_PROGRAM_run (argc, argv,
+ "taler-exchange-tvg",
+ "Generate test vectors",
+ options,
+ &run, NULL))
+ return 1;
+ return 0;
+}
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am
index b5419a7a..8e162182 100644
--- a/src/exchange/Makefile.am
+++ b/src/exchange/Makefile.am
@@ -47,7 +47,6 @@ taler_exchange_httpd_SOURCES = \
taler-exchange-httpd_deposit.c taler-exchange-httpd_deposit.h \
taler-exchange-httpd_keystate.c taler-exchange-httpd_keystate.h \
taler-exchange-httpd_mhd.c taler-exchange-httpd_mhd.h \
- taler-exchange-httpd_parsing.c taler-exchange-httpd_parsing.h \
taler-exchange-httpd_payback.c taler-exchange-httpd_payback.h \
taler-exchange-httpd_refresh_link.c taler-exchange-httpd_refresh_link.h \
taler-exchange-httpd_refresh_melt.c taler-exchange-httpd_refresh_melt.h \
@@ -63,6 +62,7 @@ taler_exchange_httpd_SOURCES = \
taler_exchange_httpd_LDADD = \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/wire/libtalerwire.la \
+ $(top_builddir)/src/mhd/libtalermhd.la \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/exchangedb/libtalerexchangedb.la \
$(top_builddir)/src/util/libtalerutil.la \
diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c
index 95f56d0d..98de86da 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -1960,10 +1960,10 @@ main (int argc,
options,
&run, NULL))
{
- GNUNET_free ((void*) argv);
+ GNUNET_free ((void *) argv);
return 1;
}
- GNUNET_free ((void*) argv);
+ GNUNET_free ((void *) argv);
return global_ret;
}
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index af38a605..30efb8bc 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -27,7 +27,7 @@
#include <microhttpd.h>
#include <pthread.h>
#include <sys/resource.h>
-#include "taler-exchange-httpd_parsing.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_mhd.h"
#include "taler-exchange-httpd_deposit.h"
#include "taler-exchange-httpd_refund.h"
@@ -174,7 +174,7 @@ handle_mhd_completion_callback (void *cls,
"Request completed\n");
if (NULL == ecls)
return;
- TEH_PARSE_post_cleanup_callback (ecls->opaque_post_parsing_context);
+ TALER_MHD_parse_post_cleanup_callback (ecls->opaque_post_parsing_context);
GNUNET_free (ecls);
*con_cls = NULL;
/* check that we didn't leave any transactions hanging */
@@ -487,122 +487,6 @@ handle_mhd_request (void *cls,
/**
- * Parse the configuration to determine on which port
- * or UNIX domain path we should run an HTTP service.
- *
- * @param section section of the configuration to parse (usually "exchange")
- * @param[out] rport set to the port number, or 0 for none
- * @param[out] unix_path set to the UNIX path, or NULL for none
- * @param[out] unix_mode set to the mode to be used for @a unix_path
- * @return #GNUNET_OK on success
- */
-static int
-parse_port_config (const char *section,
- uint16_t *rport,
- char **unix_path,
- mode_t *unix_mode)
-{
- const char *choices[] = {"tcp", "unix"};
- const char *serve_type;
- unsigned long long port;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_choice (cfg,
- section,
- "serve",
- choices,
- &serve_type))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section,
- "serve",
- "serve type required");
- return GNUNET_SYSERR;
- }
-
- if (0 == strcasecmp (serve_type, "tcp"))
- {
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg,
- section,
- "port",
- &port))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section,
- "port",
- "port number required");
- return GNUNET_SYSERR;
- }
-
- if ( (0 == port) ||
- (port > UINT16_MAX) )
- {
- fprintf (stderr,
- "Invalid configuration (value out of range): %llu is not a valid port\n",
- port);
- return GNUNET_SYSERR;
- }
- *rport = (uint16_t) port;
- *unix_path = NULL;
- return GNUNET_OK;
- }
- if (0 == strcmp (serve_type, "unix"))
- {
- struct sockaddr_un s_un;
- char *modestring;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (cfg,
- section,
- "unixpath",
- unix_path))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section,
- "unixpath",
- "unixpath required");
- return GNUNET_SYSERR;
- }
- if (strlen (*unix_path) >= sizeof (s_un.sun_path))
- {
- fprintf (stderr,
- "Invalid configuration: unix path too long\n");
- return GNUNET_SYSERR;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- section,
- "UNIXPATH_MODE",
- &modestring))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- section,
- "UNIXPATH_MODE");
- return GNUNET_SYSERR;
- }
- errno = 0;
- *unix_mode = (mode_t) strtoul (modestring, NULL, 8);
- if (0 != errno)
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- section,
- "UNIXPATH_MODE",
- "must be octal number");
- GNUNET_free (modestring);
- return GNUNET_SYSERR;
- }
- GNUNET_free (modestring);
- return GNUNET_OK;
- }
- /* not reached */
- GNUNET_assert (0);
- return GNUNET_SYSERR;
-}
-
-
-/**
* Load configuration parameters for the exchange
* server into the corresponding global variables.
*
@@ -717,10 +601,11 @@ exchange_serve_process_config ()
}
if (GNUNET_OK !=
- parse_port_config ("exchange",
- &serve_port,
- &serve_unixpath,
- &unixpath_mode))
+ TALER_MHD_parse_config (cfg,
+ "exchange",
+ &serve_port,
+ &serve_unixpath,
+ &unixpath_mode))
{
TEH_VALIDATION_done ();
return GNUNET_SYSERR;
@@ -843,141 +728,6 @@ connection_done (void *cls,
/* end of HAVE_DEVELOPER */
#endif
-/**
- * Function called for logging by MHD.
- *
- * @param cls closure, NULL
- * @param fm format string (`printf()`-style)
- * @param ap arguments to @a fm
- */
-static void
-handle_mhd_logs (void *cls,
- const char *fm,
- va_list ap)
-{
- static int cache;
- char buf[2048];
-
- (void) cls;
- if (-1 == cache)
- return;
- if (0 == cache)
- {
- if (0 ==
- GNUNET_get_log_call_status (GNUNET_ERROR_TYPE_INFO,
- "libmicrohttpd",
- __FILE__,
- __FUNCTION__,
- __LINE__))
- {
- cache = -1;
- return;
- }
- }
- cache = 1;
- vsnprintf (buf,
- sizeof (buf),
- fm,
- ap);
- GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_INFO,
- "libmicrohttpd",
- "%s",
- buf);
-}
-
-
-/**
- * Open UNIX domain socket for listining at @a unix_path with
- * permissions @a unix_mode.
- *
- * @param unix_path where to listen
- * @param unix_mode access permissions to set
- * @return -1 on error, otherwise the listen socket
- */
-static int
-open_unix_path (const char *unix_path,
- mode_t unix_mode)
-{
- struct GNUNET_NETWORK_Handle *nh;
- struct sockaddr_un *un;
- int fd;
-
- if (sizeof (un->sun_path) <= strlen (unix_path))
- {
- fprintf (stderr,
- "unixpath `%s' too long\n",
- unix_path);
- return -1;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Creating listen socket '%s' with mode %o\n",
- unix_path,
- unix_mode);
-
- if (GNUNET_OK !=
- GNUNET_DISK_directory_create_for_file (unix_path))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "mkdir",
- unix_path);
- }
-
- un = GNUNET_new (struct sockaddr_un);
- un->sun_family = AF_UNIX;
- strncpy (un->sun_path,
- unix_path,
- sizeof (un->sun_path) - 1);
- GNUNET_NETWORK_unix_precheck (un);
-
- if (NULL == (nh = GNUNET_NETWORK_socket_create (AF_UNIX,
- SOCK_STREAM,
- 0)))
- {
- fprintf (stderr,
- "create failed for AF_UNIX\n");
- GNUNET_free (un);
- return -1;
- }
- if (GNUNET_OK !=
- GNUNET_NETWORK_socket_bind (nh,
- (void *) un,
- sizeof (struct sockaddr_un)))
- {
- fprintf (stderr,
- "bind failed for AF_UNIX\n");
- GNUNET_free (un);
- GNUNET_NETWORK_socket_close (nh);
- return -1;
- }
- GNUNET_free (un);
- if (GNUNET_OK !=
- GNUNET_NETWORK_socket_listen (nh,
- UNIX_BACKLOG))
- {
- fprintf (stderr,
- "listen failed for AF_UNIX\n");
- GNUNET_NETWORK_socket_close (nh);
- return -1;
- }
-
- if (0 != chmod (unix_path,
- unix_mode))
- {
- fprintf (stderr,
- "chmod failed: %s\n",
- strerror (errno));
- GNUNET_NETWORK_socket_close (nh);
- return -1;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "set socket '%s' to mode %o\n",
- unix_path,
- unix_mode);
- fd = GNUNET_NETWORK_get_fd (nh);
- GNUNET_NETWORK_socket_free_memory_only_ (nh);
- return fd;
-}
-
/**
* Called when the main thread exits, writes out performance
@@ -986,7 +736,6 @@ open_unix_path (const char *unix_path,
static void
write_stats ()
{
-
struct GNUNET_DISK_FileHandle *fh;
pid_t pid = getpid ();
char *benchmark_dir;
@@ -1074,12 +823,17 @@ main (int argc,
const char *listen_pid;
const char *listen_fds;
int fh = -1;
+ enum TALER_MHD_GlobalOptions go;
if (0 >=
GNUNET_GETOPT_run ("taler-exchange-httpd",
options,
argc, argv))
return 1;
+ go = TALER_MHD_GO_NONE;
+ if (TEH_exchange_connection_close)
+ go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE;
+ TALER_MHD_setup (go);
GNUNET_assert (GNUNET_OK ==
GNUNET_log_setup ("taler-exchange-httpd",
(NULL == loglev) ? "INFO" : loglev,
@@ -1138,8 +892,8 @@ main (int argc,
if ( (-1 == fh) &&
(NULL != serve_unixpath) )
{
- fh = open_unix_path (serve_unixpath,
- unixpath_mode);
+ fh = TALER_MHD_open_unix_path (serve_unixpath,
+ unixpath_mode);
if (-1 == fh)
return 1;
}
@@ -1155,7 +909,8 @@ main (int argc,
MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) 32,
MHD_OPTION_LISTEN_BACKLOG_SIZE, (unsigned int) 1024,
MHD_OPTION_LISTEN_SOCKET, fh,
- MHD_OPTION_EXTERNAL_LOGGER, &handle_mhd_logs, NULL,
+ MHD_OPTION_EXTERNAL_LOGGER, &TALER_MHD_handle_logs,
+ NULL,
MHD_OPTION_NOTIFY_COMPLETED,
&handle_mhd_completion_callback, NULL,
MHD_OPTION_CONNECTION_TIMEOUT, connection_timeout,
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index 37bd2379..19781f97 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -23,6 +23,7 @@
#include <jansson.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd_keystate.h"
@@ -62,8 +63,10 @@ TEH_DB_know_coin_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
*mhd_ret
- = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DB_COIN_HISTORY_STORE_ERROR);
+ = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_COIN_HISTORY_STORE_ERROR,
+ "could not persist coin data");
return GNUNET_DB_STATUS_HARD_ERROR;
}
return qs;
@@ -99,8 +102,10 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
{
GNUNET_break (0);
if (NULL != mhd_ret)
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DB_SETUP_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_SETUP_FAILED,
+ "could not establish database session");
return GNUNET_SYSERR;
}
TEH_plugin->preflight (TEH_plugin->cls,
@@ -117,8 +122,10 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
{
GNUNET_break (0);
if (NULL != mhd_ret)
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DB_START_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_START_FAILED,
+ "could not begin transaction");
return GNUNET_SYSERR;
}
qs = cb (cb_cls,
@@ -136,8 +143,10 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
if (NULL != mhd_ret)
- *mhd_ret = TEH_RESPONSE_reply_commit_error (connection,
- TALER_EC_DB_COMMIT_FAILED_HARD);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_COMMIT_FAILED_HARD,
+ "could not commit database transaction");
return GNUNET_SYSERR;
}
/* make sure callback did not violate invariants! */
@@ -150,8 +159,10 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
name,
MAX_TRANSACTION_COMMIT_RETRIES);
if (NULL != mhd_ret)
- *mhd_ret = TEH_RESPONSE_reply_commit_error (connection,
- TALER_EC_DB_COMMIT_FAILED_ON_RETRY);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DB_COMMIT_FAILED_ON_RETRY,
+ "repatedly failed to serialize database transaction");
return GNUNET_SYSERR;
}
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index fd36bb4a..23a97fb1 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -29,7 +29,7 @@
#include <microhttpd.h>
#include <pthread.h>
#include "taler_json_lib.h"
-#include "taler-exchange-httpd_parsing.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_deposit.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd_keystate.h"
@@ -83,17 +83,17 @@ reply_deposit_success (struct MHD_Connection *connection,
&pub,
&sig))
{
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:s, s:o, s:o}",
- "status", "DEPOSIT_OK",
- "sig", GNUNET_JSON_from_data_auto (&sig),
- "pub", GNUNET_JSON_from_data_auto (
- &pub));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:s, s:o, s:o}",
+ "status", "DEPOSIT_OK",
+ "sig", GNUNET_JSON_from_data_auto (&sig),
+ "pub", GNUNET_JSON_from_data_auto (&pub));
}
@@ -149,8 +149,10 @@ deposit_transaction (void *cls,
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DEPOSIT_HISTORY_DB_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR,
+ "Could not check for existing identical deposit");
return GNUNET_DB_STATUS_HARD_ERROR;
}
return qs;
@@ -197,8 +199,10 @@ deposit_transaction (void *cls,
{
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DEPOSIT_HISTORY_DB_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR,
+ "could not access coin history");
return GNUNET_DB_STATUS_HARD_ERROR;
}
/* Check that cost of all transactions is smaller than
@@ -223,8 +227,10 @@ deposit_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
TALER_LOG_WARNING ("Failed to store /deposit information in database\n");
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_DEPOSIT_STORE_DB_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_DEPOSIT_STORE_DB_ERROR,
+ "Could not persist /deposit data");
}
return qs;
}
@@ -273,9 +279,10 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
&deposit->coin.coin_pub.eddsa_pub))
{
TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID,
- "coin_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_UNAUTHORIZED,
+ TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID,
+ "coin_sig");
}
/* check denomination */
@@ -283,9 +290,10 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
if (NULL == mks)
{
TALER_LOG_ERROR ("Lacking keys to operate\n");
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
dki = TEH_KS_denomination_key_lookup_by_hash (mks,
&deposit->coin.denom_pub_hash,
@@ -295,9 +303,10 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
if (NULL == dki)
{
TEH_KS_release (mks);
- return TEH_RESPONSE_reply_with_error (connection,
- ec,
- hc);
+ return TALER_MHD_reply_with_error (connection,
+ hc,
+ ec,
+ "Could not find denomination key used in deposit");
}
TALER_amount_ntoh (&dc.value,
&dki->issue.properties.value);
@@ -418,11 +427,11 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
};
(void) rh;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) ||
@@ -431,9 +440,9 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
memset (&deposit,
0,
sizeof (deposit));
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
if (GNUNET_SYSERR == res)
return MHD_NO; /* hard failure */
@@ -445,9 +454,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
- "refund_deadline");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
+ "refund_deadline");
}
if (TALER_EC_NONE !=
@@ -455,9 +465,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
&emsg)))
{
GNUNET_JSON_parse_free (spec);
- res = TEH_RESPONSE_reply_external_error (connection,
- ec,
- emsg);
+ res = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ ec,
+ emsg);
GNUNET_free (emsg);
return res;
}
@@ -466,9 +477,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_DEPOSIT_INVALID_TIMESTAMP,
- "timestamp");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_DEPOSIT_INVALID_TIMESTAMP,
+ "timestamp");
}
if (GNUNET_OK !=
TALER_JSON_merchant_wire_signature_hash (wire,
@@ -477,18 +489,20 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
TALER_LOG_WARNING (
"Failed to parse JSON wire format specification for /deposit request\n");
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON,
- "wire");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON,
+ "wire");
}
if (0 != GNUNET_memcmp (&deposit.h_wire,
&my_h_wire))
{
/* Client hashed contract differently than we did, reject */
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT,
- "H_wire");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT,
+ "H_wire");
}
/* check denomination exists and is valid */
@@ -497,9 +511,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{
TALER_LOG_ERROR ("Lacking keys to operate\n");
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
&deposit.coin.denom_pub_hash,
@@ -511,9 +526,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
TEH_KS_release (key_state);
TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_with_error (connection,
- ec,
- hc);
+ return TALER_MHD_reply_with_error (connection,
+ hc,
+ ec,
+ "Could not find denomination key used in deposit");
}
TALER_amount_ntoh (&deposit.deposit_fee,
&dki->issue.properties.fee_deposit);
@@ -525,9 +541,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
TEH_KS_release (key_state);
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID,
- "ub_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_UNAUTHORIZED,
+ TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID,
+ "ub_sig");
}
TALER_amount_ntoh (&deposit.deposit_fee,
&dki->issue.properties.fee_deposit);
@@ -538,9 +555,10 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_external_error (connection,
- TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
- "deposited amount smaller than depositing fee");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
+ "deposited amount smaller than depositing fee");
}
/* make sure coin is 'known' in database */
diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c
index bde5c7d7..cf5cbe9a 100644
--- a/src/exchange/taler-exchange-httpd_keystate.c
+++ b/src/exchange/taler-exchange-httpd_keystate.c
@@ -23,6 +23,7 @@
#include "platform.h"
#include <pthread.h>
#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_keystate.h"
#include "taler-exchange-httpd_responses.h"
#include "taler_exchangedb_plugin.h"
@@ -1242,7 +1243,7 @@ setup_general_response_headers (const struct TEH_KS_StateHandle *key_state,
{
char dat[128];
- TEH_RESPONSE_add_global_headers (response);
+ TALER_MHD_add_global_headers (response);
GNUNET_break (MHD_YES ==
MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -1545,8 +1546,8 @@ build_keys_response (const struct ResponseFactoryContext *rfc,
}
/* Also compute compressed version of /keys response */
- comp = TEH_RESPONSE_body_compress (&keys_jsonz,
- &keys_jsonz_size);
+ comp = TALER_MHD_body_compress (&keys_jsonz,
+ &keys_jsonz_size);
krd->response_compressed
= MHD_create_response_from_buffer (keys_jsonz_size,
keys_jsonz,
@@ -2378,9 +2379,10 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
&cherrypickn))
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_KEYS_HAVE_NOT_NUMERIC,
- "last_issue_date");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_KEYS_HAVE_NOT_NUMERIC,
+ "last_issue_date");
}
last_issue_date.abs_value_us = (uint64_t) cherrypickn * 1000000LLU;
}
@@ -2402,9 +2404,10 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
&fakenown))
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_KEYS_HAVE_NOT_NUMERIC,
- "now");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_KEYS_HAVE_NOT_NUMERIC,
+ "now");
}
now.abs_value_us = (uint64_t) fakenown * 1000000LLU;
}
@@ -2413,9 +2416,10 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
if (NULL == key_state)
{
TALER_LOG_ERROR ("Lacking keys to operate\n");
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
krd = bsearch (&last_issue_date,
key_state->krd_array,
@@ -2444,7 +2448,7 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
}
ret = MHD_queue_response (connection,
rh->response_code,
- (MHD_YES == TEH_RESPONSE_can_compress (connection))
+ (MHD_YES == TALER_MHD_can_compress (connection))
? krd->response_compressed
: krd->response_uncompressed);
TEH_KS_release (key_state);
diff --git a/src/exchange/taler-exchange-httpd_keystate.h b/src/exchange/taler-exchange-httpd_keystate.h
index 708b043b..5d92af2b 100644
--- a/src/exchange/taler-exchange-httpd_keystate.h
+++ b/src/exchange/taler-exchange-httpd_keystate.h
@@ -26,6 +26,7 @@
#include <gnunet/gnunet_util_lib.h>
#include <microhttpd.h>
#include "taler-exchange-httpd.h"
+#include "taler_error_codes.h"
#include "taler_exchangedb_lib.h"
diff --git a/src/exchange/taler-exchange-httpd_mhd.c b/src/exchange/taler-exchange-httpd_mhd.c
index 95e51c8e..825a1b31 100644
--- a/src/exchange/taler-exchange-httpd_mhd.c
+++ b/src/exchange/taler-exchange-httpd_mhd.c
@@ -28,6 +28,7 @@
#include <jansson.h>
#include <microhttpd.h>
#include <pthread.h>
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd.h"
#include "taler-exchange-httpd_mhd.h"
@@ -66,7 +67,7 @@ TEH_MHD_handler_static_response (struct TEH_RequestHandler *rh,
GNUNET_break (0);
return MHD_NO;
}
- TEH_RESPONSE_add_global_headers (response);
+ TALER_MHD_add_global_headers (response);
if (NULL != rh->mime_type)
(void) MHD_add_response_header (response,
MHD_HTTP_HEADER_CONTENT_TYPE,
@@ -97,41 +98,12 @@ TEH_MHD_handler_agpl_redirect (struct TEH_RequestHandler *rh,
const char *upload_data,
size_t *upload_data_size)
{
- const char *agpl =
- "This server is licensed under the Affero GPL. You will now be redirected to the source code.";
- struct MHD_Response *response;
- int ret;
-
+ (void) rh;
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
- response = MHD_create_response_from_buffer (strlen (agpl),
- (void *) agpl,
- MHD_RESPMEM_PERSISTENT);
- if (NULL == response)
- {
- GNUNET_break (0);
- return MHD_NO;
- }
- TEH_RESPONSE_add_global_headers (response);
- if (NULL != rh->mime_type)
- (void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- rh->mime_type);
- if (MHD_NO ==
- MHD_add_response_header (response,
- MHD_HTTP_HEADER_LOCATION,
- "http://www.git.taler.net/?p=exchange.git"))
- {
- GNUNET_break (0);
- MHD_destroy_response (response);
- return MHD_NO;
- }
- ret = MHD_queue_response (connection,
- rh->response_code,
- response);
- MHD_destroy_response (response);
- return ret;
+ return TALER_MHD_reply_agpl (connection,
+ "http://www.git.taler.net/?p=exchange.git");
}
@@ -156,11 +128,11 @@ TEH_MHD_handler_send_json_pack_error (struct TEH_RequestHandler *rh,
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
- return TEH_RESPONSE_reply_json_pack (connection,
- rh->response_code,
- "{s:s}",
- "error",
- rh->data);
+ return TALER_MHD_reply_json_pack (connection,
+ rh->response_code,
+ "{s:s}",
+ "error",
+ rh->data);
}
diff --git a/src/exchange/taler-exchange-httpd_parsing.h b/src/exchange/taler-exchange-httpd_parsing.h
deleted file mode 100644
index 9c538175..00000000
--- a/src/exchange/taler-exchange-httpd_parsing.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015, 2016 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-exchange-httpd_parsing.h
- * @brief functions to parse incoming requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_EXCHANGE_HTTPD_PARSING_H
-#define TALER_EXCHANGE_HTTPD_PARSING_H
-
-#include <microhttpd.h>
-#include <jansson.h>
-#include "taler_util.h"
-#include "taler_json_lib.h"
-
-
-/**
- * Process a POST request containing a JSON object. This
- * function realizes an MHD POST processor that will
- * (incrementally) process JSON data uploaded to the HTTP
- * server. It will store the required state in the
- * "connection_cls", which must be cleaned up using
- * #TEH_PARSE_post_cleanup_callback().
- *
- * @param connection the MHD connection
- * @param con_cls the closure (points to a `struct Buffer *`)
- * @param upload_data the POST data
- * @param upload_data_size number of bytes in @a upload_data
- * @param json the JSON object for a completed request
- * @return
- * #GNUNET_YES if json object was parsed or at least
- * may be parsed in the future (call again);
- * `*json` will be NULL if we need to be called again,
- * and non-NULL if we are done.
- * #GNUNET_NO is request incomplete or invalid
- * (error message was generated)
- * #GNUNET_SYSERR on internal error
- * (we could not even queue an error message,
- * close HTTP session with MHD_NO)
- */
-int
-TEH_PARSE_post_json (struct MHD_Connection *connection,
- void **con_cls,
- const char *upload_data,
- size_t *upload_data_size,
- json_t **json);
-
-
-/**
- * Function called whenever we are done with a request
- * to clean up our state.
- *
- * @param con_cls value as it was left by
- * #TEH_PARSE_post_json(), to be cleaned up
- */
-void
-TEH_PARSE_post_cleanup_callback (void *con_cls);
-
-
-/**
- * Parse JSON object into components based on the given field
- * specification.
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param spec field specification for the parser
- * @return
- * #GNUNET_YES if navigation was successful (caller is responsible
- * for freeing allocated variable-size data using
- * GNUNET_JSON_parse_free() when done)
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error
- */
-int
-TEH_PARSE_json_data (struct MHD_Connection *connection,
- const json_t *root,
- struct GNUNET_JSON_Specification *spec);
-
-
-/**
- * Parse JSON array into components based on the given field
- * specification. Generates error response on parse errors.
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param[in,out] spec field specification for the parser
- * @param ... -1-terminated list of array offsets of type 'int'
- * @return
- * #GNUNET_YES if navigation was successful (caller is responsible
- * for freeing allocated variable-size data using
- * GNUNET_JSON_parse_free() when done)
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error
- */
-int
-TEH_PARSE_json_array (struct MHD_Connection *connection,
- const json_t *root,
- struct GNUNET_JSON_Specification *spec,
- ...);
-
-
-/**
- * Extraxt fixed-size base32crockford encoded data from request.
- *
- * Queues an error response to the connection if the parameter is missing or
- * invalid.
- *
- * @param connection the MHD connection
- * @param param_name the name of the parameter with the key
- * @param[out] out_data pointer to store the result
- * @param out_size expected size of @a out_data
- * @return
- * #GNUNET_YES if the the argument is present
- * #GNUNET_NO if the argument is absent or malformed
- * #GNUNET_SYSERR on internal error (error response could not be sent)
- */
-int
-TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
- const char *param_name,
- void *out_data,
- size_t out_size);
-
-
-#endif /* TALER_EXCHANGE_HTTPD_PARSING_H */
diff --git a/src/exchange/taler-exchange-httpd_payback.c b/src/exchange/taler-exchange-httpd_payback.c
index 05a2355a..b7fe593d 100644
--- a/src/exchange/taler-exchange-httpd_payback.c
+++ b/src/exchange/taler-exchange-httpd_payback.c
@@ -27,7 +27,7 @@
#include <microhttpd.h>
#include <pthread.h>
#include "taler_json_lib.h"
-#include "taler-exchange-httpd_parsing.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_payback.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd_keystate.h"
@@ -35,26 +35,6 @@
/**
- * A wallet asked for /payback, but we do not know anything about the
- * original withdraw operation specified. Generates a 404 reply.
- *
- * @param connection connection to the client
- * @param ec Taler error code
- * @return MHD result code
- */
-static int
-reply_payback_unknown (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s, s:I}",
- "error", "blinded coin unknown",
- "code", (json_int_t) ec);
-}
-
-
-/**
* A wallet asked for /payback, return the successful response.
*
* @param connection connection to the client
@@ -88,24 +68,25 @@ reply_payback_refresh_success (struct MHD_Connection *connection,
&pub,
&sig))
{
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o, s:o, s:o, s:o}",
- "old_coin_pub",
- GNUNET_JSON_from_data_auto (
- old_coin_pub),
- "timestamp", GNUNET_JSON_from_time_abs (
- timestamp),
- "amount", TALER_JSON_from_amount (
- amount),
- "exchange_sig",
- GNUNET_JSON_from_data_auto (&sig),
- "exchange_pub",
- GNUNET_JSON_from_data_auto (&pub));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o, s:o, s:o, s:o}",
+ "old_coin_pub",
+ GNUNET_JSON_from_data_auto (
+ old_coin_pub),
+ "timestamp", GNUNET_JSON_from_time_abs (
+ timestamp),
+ "amount", TALER_JSON_from_amount (
+ amount),
+ "exchange_sig",
+ GNUNET_JSON_from_data_auto (&sig),
+ "exchange_pub",
+ GNUNET_JSON_from_data_auto (&pub));
}
@@ -142,23 +123,24 @@ reply_payback_success (struct MHD_Connection *connection,
&pub,
&sig))
{
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o, s:o, s:o, s:o}",
- "reserve_pub",
- GNUNET_JSON_from_data_auto (reserve_pub),
- "timestamp", GNUNET_JSON_from_time_abs (
- timestamp),
- "amount", TALER_JSON_from_amount (
- amount),
- "exchange_sig",
- GNUNET_JSON_from_data_auto (&sig),
- "exchange_pub",
- GNUNET_JSON_from_data_auto (&pub));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o, s:o, s:o, s:o}",
+ "reserve_pub",
+ GNUNET_JSON_from_data_auto (reserve_pub),
+ "timestamp", GNUNET_JSON_from_time_abs (
+ timestamp),
+ "amount", TALER_JSON_from_amount (
+ amount),
+ "exchange_sig",
+ GNUNET_JSON_from_data_auto (&sig),
+ "exchange_pub",
+ GNUNET_JSON_from_data_auto (&pub));
}
@@ -268,8 +250,10 @@ payback_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_PAYBACK_DB_FETCH_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_PAYBACK_DB_FETCH_FAILED,
+ "failed to fetch old coin of blind coin");
}
return qs;
}
@@ -285,8 +269,10 @@ payback_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_PAYBACK_DB_FETCH_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_PAYBACK_DB_FETCH_FAILED,
+ "failed to fetch reserve of blinded coin");
}
return qs;
}
@@ -296,8 +282,10 @@ payback_transaction (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Payback requested for unknown envelope %s\n",
GNUNET_h2s (&pc->h_blind));
- *mhd_ret = reply_payback_unknown (connection,
- TALER_EC_PAYBACK_WITHDRAW_NOT_FOUND);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_PAYBACK_WITHDRAW_NOT_FOUND,
+ "blind coin unknown");
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -312,8 +300,10 @@ payback_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_PAYBACK_DB_FETCH_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_PAYBACK_DB_FETCH_FAILED,
+ "failed to fetch old coin transaction history");
}
return qs;
}
@@ -329,8 +319,10 @@ payback_transaction (void *cls,
GNUNET_break (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_PAYBACK_HISTORY_DB_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_PAYBACK_HISTORY_DB_ERROR,
+ "failed to calculate old coin transaction history");
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (GNUNET_SYSERR ==
@@ -341,8 +333,10 @@ payback_transaction (void *cls,
GNUNET_break (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE,
+ "calculated negative old coin balance");
return GNUNET_DB_STATUS_HARD_ERROR;
}
if ( (0 == pc->amount.fraction) &&
@@ -391,8 +385,10 @@ payback_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
TALER_LOG_WARNING ("Failed to store /payback information in database\n");
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_PAYBACK_DB_PUT_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_PAYBACK_DB_PUT_FAILED,
+ "failed to persist payback data");
}
return qs;
}
@@ -437,9 +433,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
if (NULL == key_state)
{
TALER_LOG_ERROR ("Lacking keys to operate\n");
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
&coin->denom_pub_hash,
@@ -451,9 +448,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
TEH_KS_release (key_state);
TALER_LOG_WARNING (
"Denomination key in /payback request not in payback mode\n");
- return TEH_RESPONSE_reply_with_error (connection,
- ec,
- hc);
+ return TALER_MHD_reply_with_error (connection,
+ hc,
+ ec,
+ "denomination not allowing payback");
}
TALER_amount_ntoh (&pc.value,
&dki->issue.properties.value);
@@ -465,9 +463,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
{
TALER_LOG_WARNING ("Invalid coin passed for /payback\n");
TEH_KS_release (key_state);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_PAYBACK_DENOMINATION_SIGNATURE_INVALID,
- "denom_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_PAYBACK_DENOMINATION_SIGNATURE_INVALID,
+ "denom_sig");
}
/* check payback request signature */
@@ -485,9 +484,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
{
TALER_LOG_WARNING ("Invalid signature on /payback request\n");
TEH_KS_release (key_state);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_PAYBACK_SIGNATURE_INVALID,
- "coin_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_PAYBACK_SIGNATURE_INVALID,
+ "coin_sig");
}
GNUNET_CRYPTO_hash (&coin->coin_pub.eddsa_pub,
@@ -503,9 +503,10 @@ verify_and_execute_payback (struct MHD_Connection *connection,
GNUNET_break (0);
TEH_KS_release (key_state);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_PAYBACK_BLINDING_FAILED,
- "coin_bks");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_PAYBACK_BLINDING_FAILED,
+ "coin_bks");
}
TEH_KS_release (key_state);
GNUNET_CRYPTO_hash (coin_ev,
@@ -603,18 +604,18 @@ TEH_PAYBACK_handler_payback (struct TEH_RequestHandler *rh,
};
(void) rh;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
if (GNUNET_SYSERR == res)
return MHD_NO; /* hard failure */
diff --git a/src/exchange/taler-exchange-httpd_refresh_link.c b/src/exchange/taler-exchange-httpd_refresh_link.c
index c51887a9..c3d36e29 100644
--- a/src/exchange/taler-exchange-httpd_refresh_link.c
+++ b/src/exchange/taler-exchange-httpd_refresh_link.c
@@ -24,7 +24,7 @@
#include <gnunet/gnunet_util_lib.h>
#include <jansson.h>
#include <microhttpd.h>
-#include "taler-exchange-httpd_parsing.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_mhd.h"
#include "taler-exchange-httpd_refresh_link.h"
#include "taler-exchange-httpd_responses.h"
@@ -156,16 +156,18 @@ refresh_link_transaction (void *cls,
ctx);
if (NULL == ctx->mlist)
{
- *mhd_ret = TEH_RESPONSE_reply_internal_error (connection,
- ctx->ec,
- "coin_pub");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ ctx->ec,
+ "coin_pub");
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
- *mhd_ret = TEH_RESPONSE_reply_arg_unknown (connection,
- TALER_EC_REFRESH_LINK_COIN_UNKNOWN,
- "coin_pub");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_REFRESH_LINK_COIN_UNKNOWN,
+ "coin_pub");
return GNUNET_DB_STATUS_HARD_ERROR;
}
return qs;
@@ -201,11 +203,11 @@ TEH_REFRESH_handler_refresh_link (struct TEH_RequestHandler *rh,
memset (&ctx,
0,
sizeof (ctx));
- res = TEH_PARSE_mhd_request_arg_data (connection,
- "coin_pub",
- &ctx.coin_pub,
- sizeof (struct
- TALER_CoinSpendPublicKeyP));
+ res = TALER_MHD_parse_request_arg_data (connection,
+ "coin_pub",
+ &ctx.coin_pub,
+ sizeof (struct
+ TALER_CoinSpendPublicKeyP));
if (GNUNET_SYSERR == res)
return MHD_NO;
if (GNUNET_OK != res)
@@ -222,9 +224,9 @@ TEH_REFRESH_handler_refresh_link (struct TEH_RequestHandler *rh,
json_decref (ctx.mlist);
return mhd_ret;
}
- mhd_ret = TEH_RESPONSE_reply_json (connection,
- ctx.mlist,
- MHD_HTTP_OK);
+ mhd_ret = TALER_MHD_reply_json (connection,
+ ctx.mlist,
+ MHD_HTTP_OK);
json_decref (ctx.mlist);
return mhd_ret;
}
diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c b/src/exchange/taler-exchange-httpd_refresh_melt.c
index a00fda14..8fbb5851 100644
--- a/src/exchange/taler-exchange-httpd_refresh_melt.c
+++ b/src/exchange/taler-exchange-httpd_refresh_melt.c
@@ -24,7 +24,8 @@
#include <gnunet/gnunet_util_lib.h>
#include <jansson.h>
#include <microhttpd.h>
-#include "taler-exchange-httpd_parsing.h"
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_mhd.h"
#include "taler-exchange-httpd_refresh_melt.h"
#include "taler-exchange-httpd_responses.h"
@@ -60,26 +61,28 @@ reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection,
history = TEH_RESPONSE_compile_transaction_history (tl);
if (NULL == history)
- return TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_FORBIDDEN,
- "{s:s, s:I, s:o, s:o, s:o, s:o, s:o}",
- "error",
- "insufficient funds",
- "code",
- (json_int_t)
- TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS,
- "coin_pub",
- GNUNET_JSON_from_data_auto (coin_pub),
- "original_value",
- TALER_JSON_from_amount (&coin_value),
- "residual_value",
- TALER_JSON_from_amount (residual),
- "requested_value",
- TALER_JSON_from_amount (requested),
- "history",
- history);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
+ "Failed to compile transaction history");
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_CONFLICT,
+ "{s:s, s:I, s:o, s:o, s:o, s:o, s:o}",
+ "error",
+ "insufficient funds",
+ "code",
+ (json_int_t)
+ TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS,
+ "coin_pub",
+ GNUNET_JSON_from_data_auto (coin_pub),
+ "original_value",
+ TALER_JSON_from_amount (&coin_value),
+ "residual_value",
+ TALER_JSON_from_amount (residual),
+ "requested_value",
+ TALER_JSON_from_amount (requested),
+ "history",
+ history);
}
@@ -110,19 +113,20 @@ reply_refresh_melt_success (struct MHD_Connection *connection,
&pub,
&sig))
{
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
sig_json = GNUNET_JSON_from_data_auto (&sig);
GNUNET_assert (NULL != sig_json);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:i, s:o, s:o}",
- "noreveal_index", (int) noreveal_index,
- "exchange_sig", sig_json,
- "exchange_pub",
- GNUNET_JSON_from_data_auto (&pub));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:i, s:o, s:o}",
+ "noreveal_index", (int) noreveal_index,
+ "exchange_sig", sig_json,
+ "exchange_pub",
+ GNUNET_JSON_from_data_auto (&pub));
}
@@ -189,8 +193,10 @@ refresh_check_melt (struct MHD_Connection *connection,
if (0 > qs)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_MELT_DB_FETCH_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_MELT_DB_FETCH_ERROR,
+ "failed to fetch old coin history");
return qs;
}
if (rmc->zombie_required)
@@ -211,9 +217,10 @@ refresh_check_melt (struct MHD_Connection *connection,
GNUNET_break (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_external_error (connection,
- TALER_EC_REFRESH_MELT_COIN_EXPIRED_NO_ZOMBIE,
- "denomination expired");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_REFRESH_MELT_COIN_EXPIRED_NO_ZOMBIE,
+ "denomination expired");
return GNUNET_DB_STATUS_HARD_ERROR;
}
}
@@ -225,8 +232,10 @@ refresh_check_melt (struct MHD_Connection *connection,
GNUNET_break (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED,
+ "failed to compute coin transaction history");
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -310,8 +319,10 @@ refresh_melt_transaction (void *cls,
if (0 > qs)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_MELT_DB_FETCH_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_MELT_DB_FETCH_ERROR,
+ "failed to fetch melt index");
return qs;
}
@@ -335,8 +346,10 @@ refresh_melt_transaction (void *cls,
{
if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
{
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR,
+ "failed to persist melt data");
return GNUNET_DB_STATUS_HARD_ERROR;
}
return qs;
@@ -370,9 +383,10 @@ handle_refresh_melt (struct MHD_Connection *connection,
&rmc->refresh_session.amount_with_fee) > 0)
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_external_error (connection,
- TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION,
- "melt amount smaller than melting fee");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION,
+ "melt amount smaller than melting fee");
}
}
@@ -398,9 +412,10 @@ handle_refresh_melt (struct MHD_Connection *connection,
eddsa_pub))
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID,
- "confirm_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID,
+ "confirm_sig");
}
}
@@ -467,11 +482,11 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
};
(void) rh;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &root);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &root);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) ||
@@ -481,9 +496,9 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
memset (&rmc,
0,
sizeof (rmc));
- res = TEH_PARSE_json_data (connection,
- root,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ root,
+ spec);
json_decref (root);
if (GNUNET_OK != res)
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
@@ -492,9 +507,10 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
if (NULL == key_state)
{
TALER_LOG_ERROR ("Lacking keys to operate\n");
- res = TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ res = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
goto cleanup;
}
@@ -530,8 +546,10 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
if (0 > qs)
{
GNUNET_break (0);
- res = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_MELT_DB_FETCH_ERROR);
+ res = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_MELT_DB_FETCH_ERROR,
+ "failed to find information about old coin");
goto cleanup;
}
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
@@ -566,9 +584,10 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
if (NULL == rmc.dki)
{
TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
- res = TEH_RESPONSE_reply_with_error (connection,
- ec,
- hc);
+ res = TALER_MHD_reply_with_error (connection,
+ hc,
+ ec,
+ "unknown denomination");
goto cleanup;
}
@@ -579,9 +598,10 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
TEH_KS_release (key_state);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID,
- "denom_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID,
+ "denom_sig");
}
/* run actual logic, now that the request was parsed */
diff --git a/src/exchange/taler-exchange-httpd_refresh_reveal.c b/src/exchange/taler-exchange-httpd_refresh_reveal.c
index be5228dd..fb2602c6 100644
--- a/src/exchange/taler-exchange-httpd_refresh_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refresh_reveal.c
@@ -24,7 +24,7 @@
#include <gnunet/gnunet_util_lib.h>
#include <jansson.h>
#include <microhttpd.h>
-#include "taler-exchange-httpd_parsing.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_mhd.h"
#include "taler-exchange-httpd_refresh_reveal.h"
#include "taler-exchange-httpd_responses.h"
@@ -84,9 +84,9 @@ reply_refresh_reveal_success (struct MHD_Connection *connection,
json_object_set_new (root,
"ev_sigs",
list);
- ret = TEH_RESPONSE_reply_json (connection,
- root,
- MHD_HTTP_OK);
+ ret = TALER_MHD_reply_json (connection,
+ root,
+ MHD_HTTP_OK);
json_decref (root);
}
return ret;
@@ -105,15 +105,15 @@ static int
reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
const struct TALER_RefreshCommitmentP *rc)
{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_CONFLICT,
- "{s:s, s:I, s:o}",
- "error", "commitment violation",
- "code",
- (json_int_t)
- TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION,
- "rc_expected",
- GNUNET_JSON_from_data_auto (rc));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_CONFLICT,
+ "{s:s, s:I, s:o}",
+ "error", "commitment violation",
+ "code",
+ (json_int_t)
+ TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION,
+ "rc_expected",
+ GNUNET_JSON_from_data_auto (rc));
}
@@ -258,8 +258,10 @@ refresh_reveal_preflight (void *cls,
return qs;
case GNUNET_DB_STATUS_HARD_ERROR:
GNUNET_break (qs);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_DB_FETCH_REVEAL_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_REVEAL_ERROR,
+ "failed to fetch reveal data");
rctx->preflight_ok = GNUNET_SYSERR;
return GNUNET_DB_STATUS_HARD_ERROR;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
@@ -308,9 +310,10 @@ refresh_reveal_transaction (void *cls,
&refresh_melt);
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
- *mhd_ret = TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
- "rc");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
+ "rc");
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -319,8 +322,10 @@ refresh_reveal_transaction (void *cls,
(refresh_melt.session.noreveal_index >= TALER_CNC_KAPPA) )
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR,
+ "failed to fetch valid challenge from database");
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -437,9 +442,10 @@ refresh_reveal_transaction (void *cls,
&total)) )
{
GNUNET_break_op (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_REFRESH_REVEAL_COST_CALCULATION_OVERFLOW,
- "failed to add up refresh costs");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_REVEAL_COST_CALCULATION_OVERFLOW,
+ "failed to add up refresh costs");
return GNUNET_DB_STATUS_HARD_ERROR;
}
}
@@ -447,9 +453,10 @@ refresh_reveal_transaction (void *cls,
&refresh_melt.session.amount_with_fee))
{
GNUNET_break_op (0);
- *mhd_ret = TEH_RESPONSE_reply_external_error (connection,
- TALER_EC_REFRESH_REVEAL_AMOUNT_INSUFFICIENT,
- "melted coin value is insufficient to cover cost of operation");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_REVEAL_AMOUNT_INSUFFICIENT,
+ "melted coin value is insufficient to cover cost of operation");
return GNUNET_DB_STATUS_HARD_ERROR;
}
}
@@ -501,8 +508,10 @@ refresh_reveal_persist (void *cls,
}
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_DB_COMMIT_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_REVEAL_DB_COMMIT_ERROR,
+ "failed to persist reveal data");
}
return qs;
}
@@ -542,26 +551,29 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
(0 == num_fresh_coins) )
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE,
- "new_denoms_h");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE,
+ "new_denoms_h");
}
if (json_array_size (new_denoms_h_json) !=
json_array_size (coin_evs))
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH,
- "new_denoms/coin_evs");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH,
+ "new_denoms/coin_evs");
}
if (json_array_size (new_denoms_h_json) !=
json_array_size (link_sigs_json))
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH,
- "new_denoms/link_sigs");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH,
+ "new_denoms/link_sigs");
}
/* Parse transfer private keys array */
@@ -573,11 +585,11 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
};
int res;
- res = TEH_PARSE_json_array (connection,
- tp_json,
- trans_spec,
- i,
- -1);
+ res = TALER_MHD_parse_json_array (connection,
+ tp_json,
+ trans_spec,
+ i,
+ -1);
if (GNUNET_OK != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
}
@@ -597,9 +609,10 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
{
TALER_LOG_ERROR ("Lacking keys to operate\n");
/* FIXME: use correct EC code! */
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_REFRESH_REVEAL_SIGNING_ERROR,
- "exchange lacks keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_REVEAL_SIGNING_ERROR,
+ "exchange lacks keys");
}
/* Parse denomination key hashes */
@@ -613,11 +626,11 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
unsigned int hc;
enum TALER_ErrorCode ec;
- res = TEH_PARSE_json_array (connection,
- new_denoms_h_json,
- spec,
- i,
- -1);
+ res = TALER_MHD_parse_json_array (connection,
+ new_denoms_h_json,
+ spec,
+ i,
+ -1);
if (GNUNET_OK != res)
{
TEH_KS_release (key_state);
@@ -631,9 +644,10 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
if (NULL == dkis[i])
{
TEH_KS_release (key_state);
- return TEH_RESPONSE_reply_with_error (connection,
- ec,
- hc);
+ return TALER_MHD_reply_with_error (connection,
+ hc,
+ ec,
+ "failed to find denomination key");
}
GNUNET_assert (NULL != dkis[i]->denom_priv.rsa_private_key);
}
@@ -649,11 +663,11 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
GNUNET_JSON_spec_end ()
};
- res = TEH_PARSE_json_array (connection,
- coin_evs,
- spec,
- i,
- -1);
+ res = TALER_MHD_parse_json_array (connection,
+ coin_evs,
+ spec,
+ i,
+ -1);
if (GNUNET_OK != res)
{
for (unsigned int j = 0; j<i; j++)
@@ -677,19 +691,24 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
switch (qs)
{
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- res = TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
- "rc");
+ res = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
+ "rc");
break;
case GNUNET_DB_STATUS_HARD_ERROR:
- res = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR);
+ res = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR,
+ "failed to fetch session data");
break;
case GNUNET_DB_STATUS_SOFT_ERROR:
default:
GNUNET_break (0); /* should be impossible */
- res = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_INTERNAL_INVARIANT_FAILURE);
+ res = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_INTERNAL_INVARIANT_FAILURE,
+ "assertion failed");
break;
}
goto cleanup;
@@ -704,11 +723,11 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
};
int res;
- res = TEH_PARSE_json_array (connection,
- link_sigs_json,
- link_spec,
- i,
- -1);
+ res = TALER_MHD_parse_json_array (connection,
+ link_sigs_json,
+ link_spec,
+ i,
+ -1);
if (GNUNET_OK != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
/* Check link_sigs[i] signature */
@@ -731,9 +750,10 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
eddsa_pub))
{
GNUNET_break_op (0);
- res = TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_REFRESH_REVEAL_LINK_SIGNATURE_INVALID,
- "link_sig");
+ res = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_REFRESH_REVEAL_LINK_SIGNATURE_INVALID,
+ "link_sig");
goto cleanup;
}
}
@@ -757,8 +777,10 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
if (NULL == rctx->ev_sigs[i].rsa_signature)
{
GNUNET_break (0);
- res = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFRESH_REVEAL_SIGNING_ERROR);
+ res = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFRESH_REVEAL_SIGNING_ERROR,
+ "internal signing error");
goto cleanup;
}
}
@@ -879,11 +901,11 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
};
(void) rh;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &root);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &root);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) ||
@@ -893,9 +915,9 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
memset (&rctx,
0,
sizeof (rctx));
- res = TEH_PARSE_json_data (connection,
- root,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ root,
+ spec);
json_decref (root);
if (GNUNET_OK != res)
{
@@ -909,9 +931,10 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
{
GNUNET_JSON_parse_free (spec);
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID,
- "transfer_privs");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID,
+ "transfer_privs");
}
res = handle_refresh_reveal_json (connection,
&rctx,
diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c
index 48532a2c..6a96ff98 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -29,7 +29,7 @@
#include <microhttpd.h>
#include <pthread.h>
#include "taler_json_lib.h"
-#include "taler-exchange-httpd_parsing.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_refund.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd_keystate.h"
@@ -66,17 +66,17 @@ reply_refund_success (struct MHD_Connection *connection,
&pub,
&sig))
{
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:s, s:o, s:o}",
- "status", "REFUND_OK",
- "sig", GNUNET_JSON_from_data_auto (&sig),
- "pub", GNUNET_JSON_from_data_auto (
- &pub));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:s, s:o, s:o}",
+ "status", "REFUND_OK",
+ "sig", GNUNET_JSON_from_data_auto (&sig),
+ "pub", GNUNET_JSON_from_data_auto (&pub));
}
@@ -94,11 +94,11 @@ reply_refund_failure (struct MHD_Connection *connection,
unsigned int response_code,
enum TALER_ErrorCode ec)
{
- return TEH_RESPONSE_reply_json_pack (connection,
- response_code,
- "{s:s, s:I}",
- "status", "refund failure",
- "code", (json_int_t) ec);
+ return TALER_MHD_reply_json_pack (connection,
+ response_code,
+ "{s:s, s:I}",
+ "hint", "refund failure",
+ "code", (json_int_t) ec);
}
@@ -114,15 +114,15 @@ static int
reply_refund_conflict (struct MHD_Connection *connection,
const struct TALER_EXCHANGEDB_TransactionList *tl)
{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_CONFLICT,
- "{s:s, s:I, s:o}",
- "status", "conflicting refund",
- "code",
- (json_int_t) TALER_EC_REFUND_CONFLICT,
- "history",
- TEH_RESPONSE_compile_transaction_history (
- tl));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_CONFLICT,
+ "{s:s, s:I, s:o}",
+ "hint", "conflicting refund",
+ "code",
+ (json_int_t) TALER_EC_REFUND_CONFLICT,
+ "history",
+ TEH_RESPONSE_compile_transaction_history (
+ tl));
}
@@ -259,8 +259,10 @@ refund_transaction (void *cls,
TALER_LOG_WARNING ("Deposit to /refund was not found\n");
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_transaction_unknown (connection,
- TALER_EC_REFUND_DEPOSIT_NOT_FOUND);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_REFUND_DEPOSIT_NOT_FOUND,
+ "deposit unknown");
return GNUNET_DB_STATUS_HARD_ERROR;
}
/* handle if conflicting refund found */
@@ -309,9 +311,10 @@ refund_transaction (void *cls,
GNUNET_break (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_REFUND_DB_INCONSISTENT,
- "database inconsistent");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFUND_DB_INCONSISTENT,
+ "database inconsistent");
return qs;
}
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -349,9 +352,10 @@ refund_transaction (void *cls,
TALER_LOG_ERROR ("Lacking keys to operate\n");
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
return GNUNET_DB_STATUS_HARD_ERROR;
}
dki = TEH_KS_denomination_key_lookup_by_hash (mks,
@@ -367,9 +371,10 @@ refund_transaction (void *cls,
TEH_KS_release (mks);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_with_error (connection,
- ec,
- hc);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ hc,
+ ec,
+ "denomination not found, but coin known");
return GNUNET_DB_STATUS_HARD_ERROR;
}
TALER_amount_ntoh (&expect_fee,
@@ -382,9 +387,10 @@ refund_transaction (void *cls,
{
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- *mhd_ret = TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFUND_FEE_TOO_LOW,
- "refund_fee");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_REFUND_FEE_TOO_LOW,
+ "refund_fee");
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (1 == fee_cmp)
@@ -402,8 +408,10 @@ refund_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
TALER_LOG_WARNING ("Failed to store /refund information in database\n");
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_REFUND_STORE_DB_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_REFUND_STORE_DB_ERROR,
+ "could not persist store information");
return qs;
}
/* Success or soft failure */
@@ -443,17 +451,19 @@ verify_and_execute_refund (struct MHD_Connection *connection,
&refund->refund_fee) )
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH,
- "refund_fee");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH,
+ "refund_fee");
}
if (-1 == TALER_amount_cmp (&refund->refund_amount,
&refund->refund_fee) )
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_REFUND_FEE_ABOVE_AMOUNT,
- "refund_amount");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_REFUND_FEE_ABOVE_AMOUNT,
+ "refund_amount");
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
@@ -462,9 +472,10 @@ verify_and_execute_refund (struct MHD_Connection *connection,
&refund->merchant_pub.eddsa_pub))
{
TALER_LOG_WARNING ("Invalid signature on /refund request\n");
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID,
- "merchant_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID,
+ "merchant_sig");
}
if (GNUNET_OK !=
TEH_DB_run_transaction (connection,
@@ -514,18 +525,18 @@ TEH_REFUND_handler_refund (struct TEH_RequestHandler *rh,
};
(void) rh;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
if (GNUNET_SYSERR == res)
return MHD_NO; /* hard failure */
diff --git a/src/exchange/taler-exchange-httpd_reserve_status.c b/src/exchange/taler-exchange-httpd_reserve_status.c
index 4f976148..60cdd4f5 100644
--- a/src/exchange/taler-exchange-httpd_reserve_status.c
+++ b/src/exchange/taler-exchange-httpd_reserve_status.c
@@ -23,8 +23,9 @@
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include <jansson.h>
+#include "taler_mhd_lib.h"
+#include "taler_json_lib.h"
#include "taler-exchange-httpd_reserve_status.h"
-#include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd_keystate.h"
@@ -47,15 +48,16 @@ reply_reserve_status_success (struct MHD_Connection *connection,
json_history = TEH_RESPONSE_compile_reserve_history (rh,
&balance);
if (NULL == json_history)
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_RESERVE_STATUS_DB_ERROR,
- "balance calculation failure");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_RESERVE_STATUS_DB_ERROR,
+ "balance calculation failure");
json_balance = TALER_JSON_from_amount (&balance);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o}",
- "balance", json_balance,
- "history", json_history);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o}",
+ "balance", json_balance,
+ "history", json_history);
}
@@ -135,11 +137,11 @@ TEH_RESERVE_handler_reserve_status (struct TEH_RequestHandler *rh,
int res;
int mhd_ret;
- res = TEH_PARSE_mhd_request_arg_data (connection,
- "reserve_pub",
- &rsc.reserve_pub,
- sizeof (struct
- TALER_ReservePublicKeyP));
+ res = TALER_MHD_parse_request_arg_data (connection,
+ "reserve_pub",
+ &rsc.reserve_pub,
+ sizeof (struct
+ TALER_ReservePublicKeyP));
if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */
if (GNUNET_NO == res)
@@ -155,14 +157,14 @@ TEH_RESERVE_handler_reserve_status (struct TEH_RequestHandler *rh,
/* generate proper response */
if (NULL == rsc.rh)
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s, s:s, s:I}",
- "error", "Reserve not found",
- "parameter", "withdraw_pub",
- "code",
- (json_int_t)
- TALER_EC_RESERVE_STATUS_UNKNOWN);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_NOT_FOUND,
+ "{s:s, s:s, s:I}",
+ "error", "Reserve not found",
+ "parameter", "withdraw_pub",
+ "code",
+ (json_int_t)
+ TALER_EC_RESERVE_STATUS_UNKNOWN);
mhd_ret = reply_reserve_status_success (connection,
rsc.rh);
TEH_plugin->free_reserve_history (TEH_plugin->cls,
diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.c b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
index 578aace3..8b59817a 100644
--- a/src/exchange/taler-exchange-httpd_reserve_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2017 GNUnet e.V.
+ Copyright (C) 2014-2019 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
@@ -16,7 +16,6 @@
Public License along with TALER; see the file COPYING. If not,
see <http://www.gnu.org/licenses/>
*/
-
/**
* @file taler-exchange-httpd_reserve_withdraw.c
* @brief Handle /reserve/withdraw requests
@@ -27,8 +26,9 @@
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include <jansson.h>
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_reserve_withdraw.h"
-#include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd_keystate.h"
@@ -65,20 +65,21 @@ reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *connection,
/* Address the case where the ptr is not null, but
* it fails "internally" to dump as string (= corrupted). */
|| (0 == json_dumpb (json_history, NULL, 0, 0)))
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
- "balance calculation failure");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
+ "balance calculation failure");
json_balance = TALER_JSON_from_amount (&balance);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_FORBIDDEN,
- "{s:s, s:I, s:o, s:o}",
- "error", "Insufficient funds",
- "code",
- (json_int_t)
- TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS,
- "balance", json_balance,
- "history", json_history);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_CONFLICT,
+ "{s:s, s:I, s:o, s:o}",
+ "error", "Insufficient funds",
+ "code",
+ (json_int_t)
+ TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS,
+ "balance", json_balance,
+ "history", json_history);
}
@@ -98,10 +99,10 @@ reply_reserve_withdraw_success (struct MHD_Connection *connection,
json_t *sig_json;
sig_json = GNUNET_JSON_from_rsa_signature (collectable->sig.rsa_signature);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "ev_sig", sig_json);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "ev_sig", sig_json);
}
@@ -209,8 +210,10 @@ withdraw_transaction (void *cls,
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_WITHDRAW_DB_FETCH_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR,
+ "failed to fetch withdraw data");
wc->collectable.sig = denom_sig;
return qs;
}
@@ -252,15 +255,18 @@ withdraw_transaction (void *cls,
if (0 > qs)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_WITHDRAW_DB_FETCH_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR,
+ "failed to fetch reserve data");
return qs;
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
- *mhd_ret = TEH_RESPONSE_reply_arg_unknown (connection,
- TALER_EC_WITHDRAW_RESERVE_UNKNOWN,
- "reserve_pub");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_WITHDRAW_RESERVE_UNKNOWN,
+ "reserve_pub");
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (0 < TALER_amount_cmp (&wc->amount_required,
@@ -286,8 +292,10 @@ withdraw_transaction (void *cls,
if (NULL == rh)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_WITHDRAW_DB_FETCH_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR,
+ "failed to fetch reserve history");
return GNUNET_DB_STATUS_HARD_ERROR;
}
*mhd_ret = reply_reserve_withdraw_insufficient_funds (connection,
@@ -308,9 +316,10 @@ withdraw_transaction (void *cls,
if (NULL == wc->collectable.sig.rsa_signature)
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_WITHDRAW_SIGNATURE_FAILED,
- "Internal error");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_SIGNATURE_FAILED,
+ "Failed to create signature");
return GNUNET_DB_STATUS_HARD_ERROR;
}
}
@@ -330,8 +339,10 @@ withdraw_transaction (void *cls,
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_WITHDRAW_DB_STORE_ERROR);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_DB_STORE_ERROR,
+ "failed to persist withdraw data");
return qs;
}
return qs;
@@ -383,18 +394,18 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
};
(void) rh;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &root);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &root);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == root) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- root,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ root,
+ spec);
json_decref (root);
if (GNUNET_OK != res)
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
@@ -403,9 +414,10 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
{
TALER_LOG_ERROR ("Lacking keys to operate\n");
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
wc.dki = TEH_KS_denomination_key_lookup_by_hash (wc.key_state,
&wc.denom_pub_hash,
@@ -416,9 +428,10 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
{
GNUNET_JSON_parse_free (spec);
TEH_KS_release (wc.key_state);
- return TEH_RESPONSE_reply_with_error (connection,
- ec,
- hc);
+ return TALER_MHD_reply_with_error (connection,
+ hc,
+ ec,
+ "could not find denomination key");
}
GNUNET_assert (NULL != wc.dki->denom_priv.rsa_private_key);
TALER_amount_ntoh (&amount,
@@ -432,9 +445,10 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
{
GNUNET_JSON_parse_free (spec);
TEH_KS_release (wc.key_state);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW,
- "amount overflow for value plus withdraw fee");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW,
+ "amount overflow for value plus withdraw fee");
}
TALER_amount_hton (&wc.wsrd.amount_with_fee,
&wc.amount_required);
@@ -460,9 +474,10 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
"Client supplied invalid signature for /reserve/withdraw request\n");
GNUNET_JSON_parse_free (spec);
TEH_KS_release (wc.key_state);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID,
- "reserve_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID,
+ "reserve_sig");
}
#if OPTIMISTIC_SIGN
@@ -476,9 +491,10 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
TEH_KS_release (wc.key_state);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_WITHDRAW_SIGNATURE_FAILED,
- "Internal error");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_WITHDRAW_SIGNATURE_FAILED,
+ "Failed to sign");
}
#endif
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index 048a8bef..4ef0f2d1 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -27,6 +27,7 @@
#include "taler-exchange-httpd_responses.h"
#include "taler_util.h"
#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler-exchange-httpd_keystate.h"
/**
@@ -39,453 +40,6 @@
/**
- * Add headers we want to return in every response.
- * Useful for testing, like if we want to always close
- * connections.
- *
- * @param response response to modify
- */
-void
-TEH_RESPONSE_add_global_headers (struct MHD_Response *response)
-{
- if (TEH_exchange_connection_close)
- GNUNET_break (MHD_YES ==
- MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONNECTION,
- "close"));
-}
-
-
-/**
- * Is HTTP body deflate compression supported by the client?
- *
- * @param connection connection to check
- * @return #MHD_YES if 'deflate' compression is allowed
- *
- * Note that right now we're ignoring q-values, which is technically
- * not correct, and also do not support "*" anywhere but in a line by
- * itself. This should eventually be fixed, see also
- * https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
- */
-int
-TEH_RESPONSE_can_compress (struct MHD_Connection *connection)
-{
- const char *ae;
- const char *de;
-
- ae = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- MHD_HTTP_HEADER_ACCEPT_ENCODING);
- if (NULL == ae)
- return MHD_NO;
- if (0 == strcmp (ae,
- "*"))
- return MHD_YES;
- de = strstr (ae,
- "deflate");
- if (NULL == de)
- return MHD_NO;
- if ( ( (de == ae) ||
- (de[-1] == ',') ||
- (de[-1] == ' ') ) &&
- ( (de[strlen ("deflate")] == '\0') ||
- (de[strlen ("deflate")] == ',') ||
- (de[strlen ("deflate")] == ';') ) )
- return MHD_YES;
- return MHD_NO;
-}
-
-
-/**
- * Try to compress a response body. Updates @a buf and @a buf_size.
- *
- * @param[in,out] buf pointer to body to compress
- * @param[in,out] buf_size pointer to initial size of @a buf
- * @return #MHD_YES if @a buf was compressed
- */
-int
-TEH_RESPONSE_body_compress (void **buf,
- size_t *buf_size)
-{
- Bytef *cbuf;
- uLongf cbuf_size;
- int ret;
-
- cbuf_size = compressBound (*buf_size);
- cbuf = malloc (cbuf_size);
- if (NULL == cbuf)
- return MHD_NO;
- ret = compress (cbuf,
- &cbuf_size,
- (const Bytef *) *buf,
- *buf_size);
- if ( (Z_OK != ret) ||
- (cbuf_size >= *buf_size) )
- {
- /* compression failed */
- free (cbuf);
- return MHD_NO;
- }
- free (*buf);
- *buf = (void *) cbuf;
- *buf_size = (size_t) cbuf_size;
- return MHD_YES;
-}
-
-
-/**
- * Send JSON object as response.
- *
- * @param connection the MHD connection
- * @param json the json object
- * @param response_code the http response code
- * @return MHD result code
- */
-int
-TEH_RESPONSE_reply_json (struct MHD_Connection *connection,
- const json_t *json,
- unsigned int response_code)
-{
- struct MHD_Response *resp;
- void *json_str;
- size_t json_len;
- int ret;
- int comp;
-
- json_str = json_dumps (json,
- JSON_INDENT (2));
- if (NULL == json_str)
- {
- /**
- * This log helps to figure out which
- * function called this one and assert-failed.
- */
- TALER_LOG_ERROR ("Aborting json-packing for HTTP code: %u\n",
- response_code);
-
- GNUNET_assert (0);
- return MHD_NO;
- }
- json_len = strlen (json_str);
- /* try to compress the body */
- comp = MHD_NO;
- if (MHD_YES ==
- TEH_RESPONSE_can_compress (connection))
- comp = TEH_RESPONSE_body_compress (&json_str,
- &json_len);
- resp = MHD_create_response_from_buffer (json_len,
- json_str,
- MHD_RESPMEM_MUST_FREE);
- if (NULL == resp)
- {
- free (json_str);
- GNUNET_break (0);
- return MHD_NO;
- }
- TEH_RESPONSE_add_global_headers (resp);
- GNUNET_break (MHD_YES ==
- MHD_add_response_header (resp,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "application/json"));
- if (MHD_YES == comp)
- {
- /* Need to indicate to client that body is compressed */
- if (MHD_NO ==
- MHD_add_response_header (resp,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- "deflate"))
- {
- GNUNET_break (0);
- MHD_destroy_response (resp);
- return MHD_NO;
- }
- }
- ret = MHD_queue_response (connection,
- response_code,
- resp);
- MHD_destroy_response (resp);
- return ret;
-}
-
-
-/**
- * Function to call to handle the request by building a JSON
- * reply from a format string and varargs.
- *
- * @param connection the MHD connection to handle
- * @param response_code HTTP response code to use
- * @param fmt format string for pack
- * @param ... varargs
- * @return MHD result code
- */
-int
-TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
- unsigned int response_code,
- const char *fmt,
- ...)
-{
- json_t *json;
- va_list argp;
- int ret;
- json_error_t jerror;
-
- va_start (argp, fmt);
- json = json_vpack_ex (&jerror, 0, fmt, argp);
- va_end (argp);
- if (NULL == json)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to pack JSON with format `%s': %s\n",
- fmt,
- jerror.text);
- GNUNET_break (0);
- return MHD_NO;
- }
- ret = TEH_RESPONSE_reply_json (connection,
- json,
- response_code);
- json_decref (json);
- return ret;
-}
-
-
-/**
- * Send a response indicating an invalid argument.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I, s:s}",
- "error", "invalid parameter",
- "code", (json_int_t) ec,
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating an argument refering to a
- * resource unknown to the exchange (i.e. unknown reserve or
- * denomination key).
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s, s:I, s:s}",
- "error", "unknown entity referenced",
- "code", (json_int_t) ec,
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating an invalid signature.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_UNAUTHORIZED,
- "{s:s, s:I, s:s}",
- "error", "invalid signature",
- "code", (json_int_t) ec,
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating a missing argument.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is missing
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I, s:s}",
- "error", "missing parameter",
- "code", (json_int_t) ec,
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating an internal error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about the internal error's nature
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- "{s:s, s:I, s:s}",
- "error", "internal error",
- "code", (json_int_t) ec,
- "hint", hint);
-}
-
-
-/**
- * Send a response indicating an error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param http_status HTTP status code to use
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_with_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- unsigned int http_status)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- http_status,
- "{s:I}",
- "code", (json_int_t) ec);
-}
-
-
-/**
- * Send a response indicating an external error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about the error's nature
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I, s:s}",
- "error", "client error",
- "code", (json_int_t) ec,
- "hint", hint);
-}
-
-
-/**
- * Send a response indicating an error committing a
- * transaction (concurrent interference).
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- "{s:s, s:I}",
- "error", "commit failure",
- "code", (json_int_t) ec);
-}
-
-
-/**
- * Send a response indicating a failure to talk to the Exchange's
- * database.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec)
-{
- return TEH_RESPONSE_reply_internal_error (connection,
- ec,
- "Failure in database interaction");
-}
-
-
-/**
- * Send a response indicating that the request was too big.
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection)
-{
- struct MHD_Response *resp;
- int ret;
-
- resp = MHD_create_response_from_buffer (0,
- NULL,
- MHD_RESPMEM_PERSISTENT);
- if (NULL == resp)
- return MHD_NO;
- TEH_RESPONSE_add_global_headers (resp);
- ret = MHD_queue_response (connection,
- MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
- resp);
- MHD_destroy_response (resp);
- return ret;
-}
-
-
-/**
- * Send a response indicating that the JSON was malformed.
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I}",
- "error", "invalid json",
- "code",
- (json_int_t) TALER_EC_JSON_INVALID);
-}
-
-
-/**
* Compile the transaction history of a coin into a JSON object.
*
* @param tl transaction history to JSON-ify
@@ -874,15 +428,16 @@ TEH_RESPONSE_reply_coin_insufficient_funds (struct MHD_Connection *connection,
history = TEH_RESPONSE_compile_transaction_history (tl);
if (NULL == history)
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_COIN_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
- "failed to convert transaction history to JSON");
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_FORBIDDEN,
- "{s:s, s:I, s:o}",
- "error", "insufficient funds",
- "code", (json_int_t) ec,
- "history", history);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_COIN_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
+ "failed to convert transaction history to JSON");
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_CONFLICT,
+ "{s:s, s:I, s:o}",
+ "error", "insufficient funds",
+ "code", (json_int_t) ec,
+ "history", history);
}
@@ -1170,25 +725,4 @@ TEH_RESPONSE_compile_reserve_history (const struct
}
-/**
- * A merchant asked for details about a deposit, but
- * we do not know anything about the deposit. Generate the
- * 404 reply.
- *
- * @param connection connection to the client
- * @param ec Taler error code
- * @return MHD result code
- */
-int
-TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec)
-{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s, s:I}",
- "error", "Deposit unknown",
- "code", (json_int_t) ec);
-}
-
-
/* end of taler-exchange-httpd_responses.c */
diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h
index 9b6a7885..ec051582 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
+ Copyright (C) 2014-2019 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -13,7 +13,6 @@
You should have received a copy of the GNU Affero General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-
/**
* @file taler-exchange-httpd_responses.h
* @brief API for generating generic replies of the exchange; these
@@ -35,216 +34,6 @@
/**
- * Add headers we want to return in every response.
- * Useful for testing, like if we want to always close
- * connections.
- *
- * @param response response to modify
- */
-void
-TEH_RESPONSE_add_global_headers (struct MHD_Response *response);
-
-
-/**
- * Try to compress a response body. Updates @a buf and @a buf_size.
- *
- * @param[in,out] buf pointer to body to compress
- * @param[in,out] buf_size pointer to initial size of @a buf
- * @return #MHD_YES if @a buf was compressed
- */
-int
-TEH_RESPONSE_body_compress (void **buf,
- size_t *buf_size);
-
-
-/**
- * Is HTTP body deflate compression supported by the client?
- *
- * @param connection connection to check
- * @return #MHD_YES if 'deflate' compression is allowed
- */
-int
-TEH_RESPONSE_can_compress (struct MHD_Connection *connection);
-
-
-/**
- * Send JSON object as response.
- *
- * @param connection the MHD connection
- * @param json the json object
- * @param response_code the http response code
- * @return MHD result code
- */
-int
-TEH_RESPONSE_reply_json (struct MHD_Connection *connection,
- const json_t *json,
- unsigned int response_code);
-
-
-/**
- * Function to call to handle the request by building a JSON
- * reply from a format string and varargs.
- *
- * @param connection the MHD connection to handle
- * @param response_code HTTP response code to use
- * @param fmt format string for pack
- * @param ... varargs
- * @return MHD result code
- */
-int
-TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
- unsigned int response_code,
- const char *fmt,
- ...);
-
-
-/**
- * Send a response indicating an invalid signature.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name);
-
-
-/**
- * Send a response indicating an invalid argument.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return MHD result code
- */
-int
-TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name);
-
-
-/**
- * Send a response indicating an argument refering to a
- * resource unknown to the exchange (i.e. unknown reserve or
- * denomination key).
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name);
-
-
-/**
- * Send a response indicating a missing argument.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param param_name the parameter that is missing
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *param_name);
-
-
-/**
- * Send a response indicating an internal error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about the internal error's nature
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint);
-
-
-/**
- * Send a response indicating an error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param http_status HTTP status code to use
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_with_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- unsigned int http_status);
-
-
-/**
- * Send a response indicating an external error.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @param hint hint about the error's nature
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec,
- const char *hint);
-
-
-/**
- * Send a response indicating an error committing a
- * transaction (concurrent interference).
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec);
-
-
-/**
- * Send a response indicating a failure to talk to the Exchange's
- * database.
- *
- * @param connection the MHD connection to use
- * @param ec error code uniquely identifying the error
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec);
-
-
-/**
- * Send a response indicating that the request was too big.
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection);
-
-
-/**
- * Send a response indicating that the JSON was malformed.
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connectionx);
-
-
-/**
* Compile the history of a reserve into a JSON object
* and calculate the total balance.
*
@@ -277,20 +66,6 @@ TEH_RESPONSE_reply_coin_insufficient_funds (struct MHD_Connection *connection,
/**
- * A merchant asked for details about a deposit, but
- * we do not know anything about the deposit. Generate the
- * 404 reply.
- *
- * @param connection connection to the client
- * @param ec Taler error code
- * @return MHD result code
- */
-int
-TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection,
- enum TALER_ErrorCode ec);
-
-
-/**
* Compile the transaction history of a coin into a JSON object.
*
* @param tl transaction history to JSON-ify
diff --git a/src/exchange/taler-exchange-httpd_test.c b/src/exchange/taler-exchange-httpd_test.c
index 0a64f267..4b3c50b2 100644
--- a/src/exchange/taler-exchange-httpd_test.c
+++ b/src/exchange/taler-exchange-httpd_test.c
@@ -24,9 +24,9 @@
#include <gnunet/gnunet_json_lib.h>
#include <jansson.h>
#include <microhttpd.h>
+#include "taler_mhd_lib.h"
#include "taler_signatures.h"
#include "taler-exchange-httpd_test.h"
-#include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_responses.h"
@@ -69,18 +69,18 @@ TEH_TEST_handler_test_base32 (struct TEH_RequestHandler *rh,
};
(void) rh;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
if (GNUNET_YES != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
GNUNET_CRYPTO_hash (in_ptr,
@@ -88,11 +88,11 @@ TEH_TEST_handler_test_base32 (struct TEH_RequestHandler *rh,
&hc);
GNUNET_JSON_parse_free (spec);
json_decref (json);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "output",
- GNUNET_JSON_from_data_auto (&hc));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "output",
+ GNUNET_JSON_from_data_auto (&hc));
}
@@ -134,18 +134,18 @@ TEH_TEST_handler_test_encrypt (struct TEH_RequestHandler *rh,
};
char *out;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
if (GNUNET_YES != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
@@ -172,11 +172,11 @@ TEH_TEST_handler_test_encrypt (struct TEH_RequestHandler *rh,
in_ptr_size);
GNUNET_free (out);
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "output",
- json);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "output",
+ json);
}
@@ -214,18 +214,18 @@ TEH_TEST_handler_test_hkdf (struct TEH_RequestHandler *rh,
GNUNET_JSON_spec_end ()
};
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
if (GNUNET_YES != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
@@ -237,11 +237,11 @@ TEH_TEST_handler_test_hkdf (struct TEH_RequestHandler *rh,
NULL, 0));
GNUNET_JSON_parse_free (spec);
json = GNUNET_JSON_from_data_auto (&hc);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "output",
- json);
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "output",
+ json);
}
@@ -277,18 +277,18 @@ TEH_TEST_handler_test_ecdhe (struct TEH_RequestHandler *rh,
GNUNET_JSON_spec_end ()
};
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
if (GNUNET_YES != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
@@ -298,16 +298,17 @@ TEH_TEST_handler_test_ecdhe (struct TEH_RequestHandler *rh,
&hc))
{
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_TEST_ECDH_ERROR,
- "Failed to perform ECDH");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TEST_ECDH_ERROR,
+ "Failed to perform ECDH");
}
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "ecdh_hash",
- GNUNET_JSON_from_data_auto (&hc));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "ecdh_hash",
+ GNUNET_JSON_from_data_auto (&hc));
}
@@ -345,18 +346,18 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh,
};
struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
if (GNUNET_YES != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
@@ -369,9 +370,10 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh,
&pub))
{
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_TEST_EDDSA_INVALID,
- "eddsa_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_TEST_EDDSA_INVALID,
+ "eddsa_sig");
}
GNUNET_JSON_parse_free (spec);
pk = GNUNET_CRYPTO_eddsa_key_create ();
@@ -382,20 +384,21 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh,
&sig))
{
GNUNET_free (pk);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_TEST_EDDSA_ERROR,
- "Failed to EdDSA-sign");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TEST_EDDSA_ERROR,
+ "Failed to EdDSA-sign");
}
GNUNET_CRYPTO_eddsa_key_get_public (pk,
&pub);
GNUNET_free (pk);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o}",
- "eddsa_pub",
- GNUNET_JSON_from_data_auto (&pub),
- "eddsa_sig",
- GNUNET_JSON_from_data_auto (&sig));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o}",
+ "eddsa_pub",
+ GNUNET_JSON_from_data_auto (&pub),
+ "eddsa_sig",
+ GNUNET_JSON_from_data_auto (&sig));
}
@@ -425,23 +428,25 @@ TEH_TEST_handler_test_rsa_get (struct TEH_RequestHandler *rh,
if (NULL == rsa_pk)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_TEST_RSA_GEN_ERROR,
- "Failed to create RSA key");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TEST_RSA_GEN_ERROR,
+ "Failed to create RSA key");
}
pub = GNUNET_CRYPTO_rsa_private_key_get_public (rsa_pk);
if (NULL == pub)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_TEST_RSA_PUB_ERROR,
- "Failed to get public RSA key");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TEST_RSA_PUB_ERROR,
+ "Failed to get public RSA key");
}
- res = TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "rsa_pub",
- GNUNET_JSON_from_rsa_public_key (pub));
+ res = TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "rsa_pub",
+ GNUNET_JSON_from_rsa_public_key (pub));
GNUNET_CRYPTO_rsa_public_key_free (pub);
return res;
}
@@ -476,18 +481,18 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh,
GNUNET_JSON_spec_end ()
};
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
if (GNUNET_YES != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
@@ -497,9 +502,10 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh,
{
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_TEST_RSA_GEN_ERROR,
- "Failed to create RSA key");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TEST_RSA_GEN_ERROR,
+ "Failed to create RSA key");
}
sig = GNUNET_CRYPTO_rsa_sign_blinded (rsa_pk,
in_ptr,
@@ -508,16 +514,17 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh,
{
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_TEST_RSA_SIGN_ERROR,
- "Failed to RSA-sign");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TEST_RSA_SIGN_ERROR,
+ "Failed to RSA-sign");
}
GNUNET_JSON_parse_free (spec);
- res = TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "rsa_blind_sig",
- GNUNET_JSON_from_rsa_signature (sig));
+ res = TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "rsa_blind_sig",
+ GNUNET_JSON_from_rsa_signature (sig));
GNUNET_CRYPTO_rsa_signature_free (sig);
return res;
}
@@ -555,29 +562,29 @@ TEH_TEST_handler_test_transfer (struct TEH_RequestHandler *rh,
};
struct TALER_TransferSecretP secret;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
json_decref (json);
if (GNUNET_YES != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
TALER_link_reveal_transfer_secret (&trans_priv,
&coin_pub,
&secret);
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "secret",
- GNUNET_JSON_from_data_auto (&secret));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o}",
+ "secret",
+ GNUNET_JSON_from_data_auto (&secret));
}
@@ -601,11 +608,11 @@ TEH_TEST_handler_test (struct TEH_RequestHandler *rh,
json_t *json;
int res;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
diff --git a/src/exchange/taler-exchange-httpd_track_transaction.c b/src/exchange/taler-exchange-httpd_track_transaction.c
index 3b8d14a0..757f28ba 100644
--- a/src/exchange/taler-exchange-httpd_track_transaction.c
+++ b/src/exchange/taler-exchange-httpd_track_transaction.c
@@ -23,8 +23,9 @@
#include <jansson.h>
#include <microhttpd.h>
#include <pthread.h>
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler_signatures.h"
-#include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_keystate.h"
#include "taler-exchange-httpd_track_transaction.h"
#include "taler-exchange-httpd_responses.h"
@@ -42,12 +43,12 @@ static int
reply_transfer_pending (struct MHD_Connection *connection,
struct GNUNET_TIME_Absolute planned_exec_time)
{
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_ACCEPTED,
- "{s:o}",
- "execution_time",
- GNUNET_JSON_from_time_abs (
- planned_exec_time));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_ACCEPTED,
+ "{s:o}",
+ "execution_time",
+ GNUNET_JSON_from_time_abs (
+ planned_exec_time));
}
@@ -92,24 +93,25 @@ reply_track_transaction (struct MHD_Connection *connection,
&pub,
&sig))
{
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o, s:o, s:o, s:o}",
- "wtid", GNUNET_JSON_from_data_auto (
- wtid),
- "execution_time",
- GNUNET_JSON_from_time_abs (exec_time),
- "coin_contribution",
- TALER_JSON_from_amount (
- coin_contribution),
- "exchange_sig",
- GNUNET_JSON_from_data_auto (&sig),
- "exchange_pub",
- GNUNET_JSON_from_data_auto (&pub));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o, s:o, s:o, s:o}",
+ "wtid", GNUNET_JSON_from_data_auto (
+ wtid),
+ "execution_time",
+ GNUNET_JSON_from_time_abs (exec_time),
+ "coin_contribution",
+ TALER_JSON_from_amount (
+ coin_contribution),
+ "exchange_sig",
+ GNUNET_JSON_from_data_auto (&sig),
+ "exchange_pub",
+ GNUNET_JSON_from_data_auto (&pub));
}
@@ -249,15 +251,19 @@ track_transaction_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED,
+ "failed to fetch transaction data");
}
return qs;
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
- *mhd_ret = TEH_RESPONSE_reply_transaction_unknown (connection,
- TALER_EC_TRACK_TRANSACTION_NOT_FOUND);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_TRACK_TRANSACTION_NOT_FOUND,
+ "transaction unknown");
return GNUNET_DB_STATUS_HARD_ERROR;
}
return qs;
@@ -295,9 +301,10 @@ check_and_handle_track_transaction_request (struct MHD_Connection *connection,
&merchant_pub->eddsa_pub))
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID,
- "merchant_sig");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID,
+ "merchant_sig");
}
ctx.pending = GNUNET_NO;
ctx.tps = tps;
@@ -314,8 +321,10 @@ check_and_handle_track_transaction_request (struct MHD_Connection *connection,
return reply_transfer_pending (connection,
ctx.execution_time);
if (GNUNET_SYSERR == ctx.pending)
- return TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT,
+ "fees are inconsistent");
return reply_track_transaction (connection,
&tps->h_contract_terms,
&tps->h_wire,
@@ -357,18 +366,18 @@ TEH_TRACKING_handler_track_transaction (struct TEH_RequestHandler *rh,
};
(void) rh;
- res = TEH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
+ res = TALER_MHD_parse_post_json (connection,
+ connection_cls,
+ upload_data,
+ upload_data_size,
+ &json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
- res = TEH_PARSE_json_data (connection,
- json,
- spec);
+ res = TALER_MHD_parse_json_data (connection,
+ json,
+ spec);
if (GNUNET_OK != res)
{
json_decref (json);
diff --git a/src/exchange/taler-exchange-httpd_track_transfer.c b/src/exchange/taler-exchange-httpd_track_transfer.c
index cacbfaa8..f40d7c81 100644
--- a/src/exchange/taler-exchange-httpd_track_transfer.c
+++ b/src/exchange/taler-exchange-httpd_track_transfer.c
@@ -24,10 +24,11 @@
#include <microhttpd.h>
#include <pthread.h>
#include "taler_signatures.h"
-#include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_keystate.h"
#include "taler-exchange-httpd_track_transfer.h"
#include "taler-exchange-httpd_responses.h"
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include "taler_wire_lib.h"
@@ -148,29 +149,30 @@ reply_track_transfer_details (struct MHD_Connection *connection,
&sig))
{
json_decref (deposits);
- return TEH_RESPONSE_reply_internal_error (connection,
- TALER_EC_EXCHANGE_BAD_CONFIGURATION,
- "no keys");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+ "no keys");
}
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
- "total", TALER_JSON_from_amount (total),
- "wire_fee", TALER_JSON_from_amount (
- wire_fee),
- "merchant_pub",
- GNUNET_JSON_from_data_auto (
- merchant_pub),
- "H_wire", GNUNET_JSON_from_data_auto (
- h_wire),
- "execution_time",
- GNUNET_JSON_from_time_abs (exec_time),
- "deposits", deposits,
- "exchange_sig",
- GNUNET_JSON_from_data_auto (&sig),
- "exchange_pub",
- GNUNET_JSON_from_data_auto (&pub));
+ return TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_OK,
+ "{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
+ "total", TALER_JSON_from_amount (total),
+ "wire_fee", TALER_JSON_from_amount (
+ wire_fee),
+ "merchant_pub",
+ GNUNET_JSON_from_data_auto (
+ merchant_pub),
+ "H_wire", GNUNET_JSON_from_data_auto (
+ h_wire),
+ "execution_time",
+ GNUNET_JSON_from_time_abs (exec_time),
+ "deposits", deposits,
+ "exchange_sig",
+ GNUNET_JSON_from_data_auto (&sig),
+ "exchange_pub",
+ GNUNET_JSON_from_data_auto (&pub));
}
@@ -396,23 +398,28 @@ track_transfer_transaction (void *cls,
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED,
+ "failed to fetch transaction data");
}
return qs;
}
if (GNUNET_SYSERR == ctx->is_valid)
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT,
+ "exchange database internally inconsistent");
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (GNUNET_NO == ctx->is_valid)
{
- *mhd_ret = TEH_RESPONSE_reply_arg_unknown (connection,
- TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND,
- "wtid");
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND,
+ "wtid");
return GNUNET_DB_STATUS_HARD_ERROR;
}
qs = TEH_plugin->get_wire_fee (TEH_plugin->cls,
@@ -430,8 +437,10 @@ track_transfer_transaction (void *cls,
(GNUNET_DB_STATUS_SUCCESS_NO_RESULTS) )
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_TRACK_TRANSFER_WIRE_FEE_NOT_FOUND);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSFER_WIRE_FEE_NOT_FOUND,
+ "did not find wire fee");
}
return qs;
}
@@ -441,8 +450,10 @@ track_transfer_transaction (void *cls,
&ctx->wire_fee))
{
GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_TRACK_TRANSFER_WIRE_FEE_INCONSISTENT);
+ *mhd_ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_TRACK_TRANSFER_WIRE_FEE_INCONSISTENT,
+ "could not subtract wire fee");
return GNUNET_DB_STATUS_HARD_ERROR;
}
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
@@ -492,11 +503,11 @@ TEH_TRACKING_handler_track_transfer (struct TEH_RequestHandler *rh,
int mhd_ret;
memset (&ctx, 0, sizeof (ctx));
- res = TEH_PARSE_mhd_request_arg_data (connection,
- "wtid",
- &ctx.wtid,
- sizeof (struct
- TALER_WireTransferIdentifierRawP));
+ res = TALER_MHD_parse_request_arg_data (connection,
+ "wtid",
+ &ctx.wtid,
+ sizeof (struct
+ TALER_WireTransferIdentifierRawP));
if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */
if (GNUNET_NO == res)
diff --git a/src/exchange/taler-exchange-httpd_wire.c b/src/exchange/taler-exchange-httpd_wire.c
index 91c928f9..4e4c34db 100644
--- a/src/exchange/taler-exchange-httpd_wire.c
+++ b/src/exchange/taler-exchange-httpd_wire.c
@@ -25,6 +25,7 @@
#include "taler-exchange-httpd_validation.h"
#include "taler-exchange-httpd_wire.h"
#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
#include <jansson.h>
/**
@@ -140,9 +141,9 @@ TEH_WIRE_handler_wire (struct TEH_RequestHandler *rh,
(void) upload_data;
(void) upload_data_size;
GNUNET_assert (NULL != wire_methods);
- return TEH_RESPONSE_reply_json (connection,
- wire_methods,
- MHD_HTTP_OK);
+ return TALER_MHD_reply_json (connection,
+ wire_methods,
+ MHD_HTTP_OK);
}
diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c
index 3699c9d3..21f62cd8 100644
--- a/src/exchange/taler-exchange-wirewatch.c
+++ b/src/exchange/taler-exchange-wirewatch.c
@@ -733,10 +733,10 @@ main (int argc,
options,
&run, NULL))
{
- GNUNET_free ((void*) argv);
+ GNUNET_free ((void *) argv);
return 1;
}
- GNUNET_free ((void*) argv);
+ GNUNET_free ((void *) argv);
return global_ret;
}
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 1e624caa..645bdc9f 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -27,6 +27,7 @@ talerinclude_HEADERS = \
taler_json_lib.h \
taler_testing_lib.h \
taler_util.h \
+ taler_mhd_lib.h \
taler_pq_lib.h \
taler_signatures.h \
taler_wire_lib.h \
diff --git a/src/include/gauger.h b/src/include/gauger.h
index 7d66051b..36dc055b 100644
--- a/src/include/gauger.h
+++ b/src/include/gauger.h
@@ -35,7 +35,7 @@
__gauger_v[7] = "-c"; \
__gauger_v[8] = (char *) category; \
__gauger_v[9] = (char *) NULL; \
- execvp ("gauger", (char*const*) __gauger_v); \
+ execvp ("gauger", (char *const *) __gauger_v); \
perror ("gauger"); \
_exit (1); \
}else{ \
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index 917f3fc9..9986c9d1 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -188,7 +188,7 @@ enum TALER_ErrorCode
* requested withdraw operation at this time. The response includes
* the current "balance" of the reserve as well as the transaction
* "history" that lead to this balance. This response is provided
- * with HTTP status code MHD_HTTP_FORBIDDEN.
+ * with HTTP status code MHD_HTTP_CONFLICT.
*/
TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS = 1100,
@@ -340,7 +340,7 @@ enum TALER_ErrorCode
* for the /deposit operation (i.e. due to double spending).
* The "history" in the respose provides the transaction history
* of the coin proving this fact. This response is provided
- * with HTTP status code MHD_HTTP_FORBIDDEN.
+ * with HTTP status code MHD_HTTP_CONFLICT.
*/
TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS = 1200,
@@ -496,7 +496,7 @@ enum TALER_ErrorCode
* for the /refresh/melt operation. The "history" in this
* response provdes the "residual_value" of the coin, which may
* be less than its "original_value". This response is provided
- * with HTTP status code MHD_HTTP_FORBIDDEN.
+ * with HTTP status code MHD_HTTP_CONFLICT.
*/
TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS = 1300,
@@ -929,7 +929,7 @@ enum TALER_ErrorCode
/**
* The given coin signature is invalid for the request.
* This response is provided with an
- * HTTP status code of MHD_HTTP_UNAUTHORIZED.
+ * HTTP status code of MHD_HTTP_FORBIDDEN.
*/
TALER_EC_PAYBACK_SIGNATURE_INVALID = 1851,
@@ -1442,6 +1442,7 @@ enum TALER_ErrorCode
* The amount to be refunded is inconsistent: either is lower than
* the previous amount being awarded, or it is too big to be paid back.
* In this second case, the fault stays on the business dept. side.
+ * Returned with an HTTP status of #MHD_HTTP_CONFLICT.
*/
TALER_EC_REFUND_INCONSISTENT_AMOUNT = 2602,
@@ -1851,7 +1852,7 @@ enum TALER_ErrorCode
/**
* The sync service failed to access its database.
* This response is provided with HTTP status code
- * MHD_HTTP_INTERNAL_ERROR.
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
*/
TALER_EC_SYNC_DB_FETCH_ERROR = 6000,
@@ -1905,7 +1906,7 @@ enum TALER_ErrorCode
* The signature provided in the "Sync-Signature" header
* does not match the account, old or new Etags.
* This response is provided with HTTP status code
- * MHD_HTTP_UNAUTHORIZED.
+ * MHD_HTTP_FORBIDDEN.
*/
TALER_EC_SYNC_INVALID_SIGNATURE = 6007,
@@ -1985,7 +1986,6 @@ enum TALER_ErrorCode
*/
TALER_EC_SYNC_PAYMENT_CHECK_ORDER_DB_ERROR = 6017,
-
/**
* End of error code range.
*/
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index 382bb19e..6adb76b2 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -126,6 +126,19 @@ enum TALER_ErrorCode
TALER_JSON_get_error_code (const json_t *json);
+/**
+ * Extract the Taler error code from the given @a data object, which is expected to be in JSON.
+ * Note that #TALER_EC_INVALID is returned if no "code" is present or if @a data is not in JSON.
+ *
+ * @param data response to extract the error code from
+ * @param data_size number of bytes in @a data
+ * @return the "code" value from @a json
+ */
+enum TALER_ErrorCode
+TALER_JSON_get_error_code2 (const void *data,
+ size_t data_size);
+
+
/* **************** /wire account offline signing **************** */
/**
diff --git a/src/include/taler_mhd_lib.h b/src/include/taler_mhd_lib.h
new file mode 100644
index 00000000..cdbc8d29
--- /dev/null
+++ b/src/include/taler_mhd_lib.h
@@ -0,0 +1,393 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler_mhd_lib.h
+ * @brief API for generating MHD replies
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#ifndef TALER_MHD_LIB_H
+#define TALER_MHD_LIB_H
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_json_lib.h>
+#include <jansson.h>
+#include <microhttpd.h>
+#include "taler_error_codes.h"
+
+/**
+ * Global options for response generation.
+ */
+enum TALER_MHD_GlobalOptions
+{
+
+ /**
+ * Use defaults.
+ */
+ TALER_MHD_GO_NONE = 0,
+
+ /**
+ * Add "Connection: Close" header.
+ */
+ TALER_MHD_GO_FORCE_CONNECTION_CLOSE = 1,
+
+ /**
+ * Disable use of compression, even if the client
+ * supports it.
+ */
+ TALER_MHD_GO_DISABLE_COMPRESSION = 2
+
+};
+
+
+/**
+ * Set global options for response generation
+ * within libtalermhd.
+ *
+ * @param go global options to use
+ */
+void
+TALER_MHD_setup (enum TALER_MHD_GlobalOptions go);
+
+
+/**
+ * Add headers we want to return in every response.
+ * Useful for testing, like if we want to always close
+ * connections.
+ *
+ * @param response response to modify
+ */
+void
+TALER_MHD_add_global_headers (struct MHD_Response *response);
+
+
+/**
+ * Try to compress a response body. Updates @a buf and @a buf_size.
+ *
+ * @param[in,out] buf pointer to body to compress
+ * @param[in,out] buf_size pointer to initial size of @a buf
+ * @return #MHD_YES if @a buf was compressed
+ */
+int
+TALER_MHD_body_compress (void **buf,
+ size_t *buf_size);
+
+
+/**
+ * Is HTTP body deflate compression supported by the client?
+ *
+ * @param connection connection to check
+ * @return #MHD_YES if 'deflate' compression is allowed
+ */
+int
+TALER_MHD_can_compress (struct MHD_Connection *connection);
+
+
+/**
+ * Send JSON object as response.
+ *
+ * @param connection the MHD connection
+ * @param json the json object
+ * @param response_code the http response code
+ * @return MHD result code
+ */
+int
+TALER_MHD_reply_json (struct MHD_Connection *connection,
+ const json_t *json,
+ unsigned int response_code);
+
+
+/**
+ * Function to call to handle the request by building a JSON
+ * reply from a format string and varargs.
+ *
+ * @param connection the MHD connection to handle
+ * @param response_code HTTP response code to use
+ * @param fmt format string for pack
+ * @param ... varargs
+ * @return MHD result code
+ */
+int
+TALER_MHD_reply_json_pack (struct MHD_Connection *connection,
+ unsigned int response_code,
+ const char *fmt,
+ ...);
+
+
+/**
+ * Send a response indicating an error.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
+ * @param http_status HTTP status code to use
+ * @param hint human readable hint about the error
+ * @return a MHD result code
+ */
+int
+TALER_MHD_reply_with_error (struct MHD_Connection *connection,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const char *hint);
+
+
+/**
+ * Make JSON response object.
+ *
+ * @param json the json object
+ * @return MHD response object
+ */
+struct MHD_Response *
+TALER_MHD_make_json (const json_t *json);
+
+
+/**
+ * Make JSON response object.
+ *
+ * @param fmt format string for pack
+ * @param ... varargs
+ * @return MHD response object
+ */
+struct MHD_Response *
+TALER_MHD_make_json_pack (const char *fmt,
+ ...);
+
+
+/**
+ * Create a response indicating an internal error.
+ *
+ * @param ec error code to return
+ * @param hint hint about the internal error's nature
+ * @return a MHD response object
+ */
+struct MHD_Response *
+TALER_MHD_make_error (enum TALER_ErrorCode ec,
+ const char *hint);
+
+
+/**
+ * Send a response indicating that the request was too big.
+ *
+ * @param connection the MHD connection to use
+ * @return a MHD result code
+ */
+int
+TALER_MHD_reply_request_too_large (struct MHD_Connection *connection);
+
+
+/**
+ * Function to call to handle the request by sending
+ * back a redirect to the AGPL source code.
+ *
+ * @param connection the MHD connection to handle
+ * @param url where to redirect for the sources
+ * @return MHD result code
+ */
+int
+TALER_MHD_reply_agpl (struct MHD_Connection *connection,
+ const char *url);
+
+
+/**
+ * Function to call to handle the request by sending
+ * back static data.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param http_status status code to return
+ * @param mime_type content-type to use
+ * @param body response payload
+ * @param body_size number of bytes in @a body
+ * @return MHD result code
+ */
+int
+TALER_MHD_reply_static (struct MHD_Connection *connection,
+ unsigned int http_status,
+ const char *mime_type,
+ const char *body,
+ size_t body_size);
+
+
+/**
+ * Process a POST request containing a JSON object. This
+ * function realizes an MHD POST processor that will
+ * (incrementally) process JSON data uploaded to the HTTP
+ * server. It will store the required state in the
+ * "connection_cls", which must be cleaned up using
+ * #TALER_MHD_post_cleanup_callback().
+ *
+ * @param connection the MHD connection
+ * @param con_cls the closure (points to a `struct Buffer *`)
+ * @param upload_data the POST data
+ * @param upload_data_size number of bytes in @a upload_data
+ * @param json the JSON object for a completed request
+ * @return
+ * #GNUNET_YES if json object was parsed or at least
+ * may be parsed in the future (call again);
+ * `*json` will be NULL if we need to be called again,
+ * and non-NULL if we are done.
+ * #GNUNET_NO is request incomplete or invalid
+ * (error message was generated)
+ * #GNUNET_SYSERR on internal error
+ * (we could not even queue an error message,
+ * close HTTP session with MHD_NO)
+ */
+int
+TALER_MHD_parse_post_json (struct MHD_Connection *connection,
+ void **con_cls,
+ const char *upload_data,
+ size_t *upload_data_size,
+ json_t **json);
+
+
+/**
+ * Function called whenever we are done with a request
+ * to clean up our state.
+ *
+ * @param con_cls value as it was left by
+ * #TALER_MHD_post_json(), to be cleaned up
+ */
+void
+TALER_MHD_parse_post_cleanup_callback (void *con_cls);
+
+
+/**
+ * Parse JSON object into components based on the given field
+ * specification.
+ *
+ * @param connection the connection to send an error response to
+ * @param root the JSON node to start the navigation at.
+ * @param spec field specification for the parser
+ * @return
+ * #GNUNET_YES if navigation was successful (caller is responsible
+ * for freeing allocated variable-size data using
+ * GNUNET_JSON_parse_free() when done)
+ * #GNUNET_NO if json is malformed, error response was generated
+ * #GNUNET_SYSERR on internal error
+ */
+int
+TALER_MHD_parse_json_data (struct MHD_Connection *connection,
+ const json_t *root,
+ struct GNUNET_JSON_Specification *spec);
+
+
+/**
+ * Parse JSON array into components based on the given field
+ * specification. Generates error response on parse errors.
+ *
+ * @param connection the connection to send an error response to
+ * @param root the JSON node to start the navigation at.
+ * @param[in,out] spec field specification for the parser
+ * @param ... -1-terminated list of array offsets of type 'int'
+ * @return
+ * #GNUNET_YES if navigation was successful (caller is responsible
+ * for freeing allocated variable-size data using
+ * GNUNET_JSON_parse_free() when done)
+ * #GNUNET_NO if json is malformed, error response was generated
+ * #GNUNET_SYSERR on internal error
+ */
+int
+TALER_MHD_parse_json_array (struct MHD_Connection *connection,
+ const json_t *root,
+ struct GNUNET_JSON_Specification *spec,
+ ...);
+
+
+/**
+ * Extraxt fixed-size base32crockford encoded data from request.
+ *
+ * Queues an error response to the connection if the parameter is missing or
+ * invalid.
+ *
+ * @param connection the MHD connection
+ * @param param_name the name of the parameter with the key
+ * @param[out] out_data pointer to store the result
+ * @param out_size expected size of @a out_data
+ * @return
+ * #GNUNET_YES if the the argument is present
+ * #GNUNET_NO if the argument is absent or malformed
+ * #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+int
+TALER_MHD_parse_request_arg_data (struct MHD_Connection *connection,
+ const char *param_name,
+ void *out_data,
+ size_t out_size);
+
+
+/**
+ * Parse the configuration to determine on which port
+ * or UNIX domain path we should run an HTTP service.
+ *
+ * @param cfg configuration to parse
+ * @param section section of the configuration to parse (usually "exchange")
+ * @param[out] rport set to the port number, or 0 for none
+ * @param[out] unix_path set to the UNIX path, or NULL for none
+ * @param[out] unix_mode set to the mode to be used for @a unix_path
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_MHD_parse_config (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *section,
+ uint16_t *rport,
+ char **unix_path,
+ mode_t *unix_mode);
+
+
+/**
+ * Function called for logging by MHD.
+ *
+ * @param cls closure, NULL
+ * @param fm format string (`printf()`-style)
+ * @param ap arguments to @a fm
+ */
+void
+TALER_MHD_handle_logs (void *cls,
+ const char *fm,
+ va_list ap);
+
+
+/**
+ * Open UNIX domain socket for listining at @a unix_path with
+ * permissions @a unix_mode.
+ *
+ * @param unix_path where to listen
+ * @param unix_mode access permissions to set
+ * @return -1 on error, otherwise the listen socket
+ */
+int
+TALER_MHD_open_unix_path (const char *unix_path,
+ mode_t unix_mode);
+
+
+/**
+ * Bind a listen socket to the UNIX domain path
+ * or the TCP port and IP address as specified
+ * in @a cfg in section @a section. IF only a
+ * port was specified, set @a port and return -1.
+ * Otherwise, return the bound file descriptor.
+ *
+ * @param cfg configuration to parse
+ * @param section configuration section to use
+ * @param port[out] port to set, if TCP without BINDTO
+ * @return -1 and a port of zero on error, otherwise
+ * either -1 and a port, or a bound stream socket
+ */
+int
+TALER_MHD_bind (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *section,
+ uint16_t *port);
+
+#endif
diff --git a/src/json/json.c b/src/json/json.c
index 90fe3dd4..8d408979 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -80,4 +80,33 @@ TALER_JSON_get_error_code (const json_t *json)
}
+/**
+ * Extract the Taler error code from the given @a data object, which is expected to be in JSON.
+ * Note that #TALER_EC_INVALID is returned if no "code" is present or if @a data is not in JSON.
+ *
+ * @param data response to extract the error code from
+ * @param data_size number of bytes in @a data
+ * @return the "code" value from @a json
+ */
+enum TALER_ErrorCode
+TALER_JSON_get_error_code2 (const void *data,
+ size_t data_size)
+{
+ json_t *json;
+ enum TALER_ErrorCode ec;
+ json_error_t err;
+
+ json = json_loads (data,
+ data_size,
+ &err);
+ if (NULL == json)
+ return TALER_EC_INVALID;
+ ec = TALER_JSON_get_error_code (json);
+ json_decref (json);
+ if (ec == TALER_EC_NONE)
+ return TALER_EC_INVALID;
+ return ec;
+}
+
+
/* End of json/json.c */
diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c
index f221b7fd..73173cc3 100644
--- a/src/lib/auditor_api_deposit_confirmation.c
+++ b/src/lib/auditor_api_deposit_confirmation.c
@@ -99,7 +99,7 @@ handle_deposit_confirmation_finished (void *cls,
/* This should never happen, either us or the auditor is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_UNAUTHORIZED:
+ case MHD_HTTP_FORBIDDEN:
/* Nothing really to verify, auditor says one of the signatures is
invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */
diff --git a/src/lib/exchange_api_curl_defaults.c b/src/lib/exchange_api_curl_defaults.c
index 36d1edf7..7b642bc8 100644
--- a/src/lib/exchange_api_curl_defaults.c
+++ b/src/lib/exchange_api_curl_defaults.c
@@ -35,7 +35,6 @@ TEL_curl_easy_get (const char *url)
CURL *eh;
eh = curl_easy_init ();
-
GNUNET_assert (CURLE_OK ==
curl_easy_setopt (eh,
CURLOPT_URL,
diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c
index 48f9a06b..30bb6c97 100644
--- a/src/lib/exchange_api_deposit.c
+++ b/src/lib/exchange_api_deposit.c
@@ -325,7 +325,7 @@ handle_deposit_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_FORBIDDEN:
+ case MHD_HTTP_CONFLICT:
/* Double spending; check signatures on transaction history */
if (GNUNET_OK !=
verify_deposit_signature_forbidden (dh,
@@ -335,7 +335,7 @@ handle_deposit_finished (void *cls,
response_code = 0;
}
break;
- case MHD_HTTP_UNAUTHORIZED:
+ case MHD_HTTP_FORBIDDEN:
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */
diff --git a/src/lib/exchange_api_payback.c b/src/lib/exchange_api_payback.c
index 912548cf..f9df27e7 100644
--- a/src/lib/exchange_api_payback.c
+++ b/src/lib/exchange_api_payback.c
@@ -226,7 +226,7 @@ handle_payback_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_FORBIDDEN:
+ case MHD_HTTP_CONFLICT:
{
/* Insufficient funds, proof attached */
json_t *history;
@@ -256,7 +256,7 @@ handle_payback_finished (void *cls,
TALER_EXCHANGE_payback_cancel (ph);
return;
}
- case MHD_HTTP_UNAUTHORIZED:
+ case MHD_HTTP_FORBIDDEN:
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */
diff --git a/src/lib/exchange_api_refresh.c b/src/lib/exchange_api_refresh.c
index db3692bc..a75baec8 100644
--- a/src/lib/exchange_api_refresh.c
+++ b/src/lib/exchange_api_refresh.c
@@ -939,7 +939,7 @@ verify_refresh_melt_signature_ok (struct TALER_EXCHANGE_RefreshMeltHandle *rmh,
/**
- * Verify that the signatures on the "403 FORBIDDEN" response from the
+ * Verify that the signatures on the "409 CONFLICT" response from the
* exchange demonstrating customer double-spending are valid.
*
* @param rmh melt handle
@@ -947,9 +947,9 @@ verify_refresh_melt_signature_ok (struct TALER_EXCHANGE_RefreshMeltHandle *rmh,
* @return #GNUNET_OK if the signature(s) is valid, #GNUNET_SYSERR if not
*/
static int
-verify_refresh_melt_signature_forbidden (struct
- TALER_EXCHANGE_RefreshMeltHandle *rmh,
- const json_t *json)
+verify_refresh_melt_signature_conflict (struct
+ TALER_EXCHANGE_RefreshMeltHandle *rmh,
+ const json_t *json)
{
json_t *history;
struct TALER_Amount original_value;
@@ -1083,17 +1083,17 @@ handle_refresh_melt_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_FORBIDDEN:
+ case MHD_HTTP_CONFLICT:
/* Double spending; check signatures on transaction history */
if (GNUNET_OK !=
- verify_refresh_melt_signature_forbidden (rmh,
- j))
+ verify_refresh_melt_signature_conflict (rmh,
+ j))
{
GNUNET_break_op (0);
response_code = 0;
}
break;
- case MHD_HTTP_UNAUTHORIZED:
+ case MHD_HTTP_FORBIDDEN:
/* Nothing really to verify, exchange says one of the signatures is
invalid; assuming we checked them, this should never happen, we
should pass the JSON reply to the application */
diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c
index e8ae6b74..b8c422e8 100644
--- a/src/lib/exchange_api_refund.c
+++ b/src/lib/exchange_api_refund.c
@@ -169,7 +169,7 @@ handle_refund_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_UNAUTHORIZED:
+ case MHD_HTTP_FORBIDDEN:
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */
diff --git a/src/lib/exchange_api_reserve.c b/src/lib/exchange_api_reserve.c
index a57d4e9d..2c62cac2 100644
--- a/src/lib/exchange_api_reserve.c
+++ b/src/lib/exchange_api_reserve.c
@@ -797,7 +797,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
/**
- * We got a 403 FORBIDDEN response for the /reserve/withdraw operation.
+ * We got a 409 CONFLICT response for the /reserve/withdraw operation.
* Check the signatures on the withdraw transactions in the provided
* history and that the balances add up. We don't do anything directly
* with the information, as the JSON will be returned to the application.
@@ -941,7 +941,7 @@ handle_reserve_withdraw_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_FORBIDDEN:
+ case MHD_HTTP_CONFLICT:
/* The exchange says that the reserve has insufficient funds;
check the signatures in the history... */
if (GNUNET_OK !=
@@ -952,7 +952,7 @@ handle_reserve_withdraw_finished (void *cls,
response_code = 0;
}
break;
- case MHD_HTTP_UNAUTHORIZED:
+ case MHD_HTTP_FORBIDDEN:
GNUNET_break (0);
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
diff --git a/src/lib/exchange_api_track_transaction.c b/src/lib/exchange_api_track_transaction.c
index 29b85fac..de3f98b6 100644
--- a/src/lib/exchange_api_track_transaction.c
+++ b/src/lib/exchange_api_track_transaction.c
@@ -217,7 +217,7 @@ handle_deposit_wtid_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_UNAUTHORIZED:
+ case MHD_HTTP_FORBIDDEN:
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */
diff --git a/src/lib/exchange_api_track_transfer.c b/src/lib/exchange_api_track_transfer.c
index 419998a2..2c90bf19 100644
--- a/src/lib/exchange_api_track_transfer.c
+++ b/src/lib/exchange_api_track_transfer.c
@@ -279,7 +279,7 @@ handle_track_transfer_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_UNAUTHORIZED:
+ case MHD_HTTP_FORBIDDEN:
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */
diff --git a/src/lib/test_auditor_api.conf b/src/lib/test_auditor_api.conf
index e01cbfcb..3a12b3c5 100644
--- a/src/lib/test_auditor_api.conf
+++ b/src/lib/test_auditor_api.conf
@@ -15,6 +15,8 @@ BASE_URL = "http://localhost:8083/"
# HTTP port the auditor listens to
PORT = 8083
+TINY_AMOUNT = EUR:0.01
+
[exchange]
# how long is one signkey valid?
diff --git a/src/lib/test_exchange_api.c b/src/lib/test_exchange_api.c
index 23a52be1..4e8eb7e0 100644
--- a/src/lib/test_exchange_api.c
+++ b/src/lib/test_exchange_api.c
@@ -228,7 +228,7 @@ run (void *cls,
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
"create-reserve-1",
"EUR:5",
- MHD_HTTP_FORBIDDEN),
+ MHD_HTTP_CONFLICT),
/**
* Try to double spend using different wire details.
@@ -238,7 +238,7 @@ run (void *cls,
TALER_TESTING_make_wire_details (43,
fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
- GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_FORBIDDEN),
+ GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_CONFLICT),
/**
* Try to double spend using a different transaction id.
@@ -253,7 +253,7 @@ run (void *cls,
TALER_TESTING_make_wire_details (43,
fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
- GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_FORBIDDEN),
+ GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_CONFLICT),
/**
* Try to double spend with different proposal.
@@ -263,7 +263,7 @@ run (void *cls,
TALER_TESTING_make_wire_details (43,
fakebank_url),
"{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}",
- GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_FORBIDDEN),
+ GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_CONFLICT),
TALER_TESTING_cmd_end ()
};
@@ -364,7 +364,7 @@ run (void *cls,
TALER_TESTING_cmd_refresh_melt
("refresh-melt-failing",
"refresh-withdraw-coin-1",
- MHD_HTTP_FORBIDDEN,
+ MHD_HTTP_CONFLICT,
NULL),
/* FIXME: also test with coin that was already melted
@@ -708,7 +708,7 @@ run (void *cls,
("payback-withdraw-coin-2-over",
"payback-create-reserve-1",
"EUR:10",
- MHD_HTTP_FORBIDDEN),
+ MHD_HTTP_CONFLICT),
TALER_TESTING_cmd_status ("payback-reserve-status-2",
"payback-create-reserve-1",
@@ -740,7 +740,7 @@ run (void *cls,
("expired-withdraw",
"short-lived-reserve",
"EUR:1",
- MHD_HTTP_FORBIDDEN),
+ MHD_HTTP_CONFLICT),
TALER_TESTING_cmd_check_bank_transfer
("check_bank_short-lived_transfer",
@@ -798,7 +798,7 @@ run (void *cls,
"EUR:0.5",
NULL),
- TALER_TESTING_cmd_payback ("payback-2b", MHD_HTTP_FORBIDDEN,
+ TALER_TESTING_cmd_payback ("payback-2b", MHD_HTTP_CONFLICT,
"payback-withdraw-coin-2a",
"EUR:0.5",
NULL),
diff --git a/src/lib/test_exchange_api_twisted.c b/src/lib/test_exchange_api_twisted.c
index 739669b9..f648b871 100644
--- a/src/lib/test_exchange_api_twisted.c
+++ b/src/lib/test_exchange_api_twisted.c
@@ -16,9 +16,8 @@
License along with TALER; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>
*/
-
/**
- * @file exchange/test_exchange_api_twister.c
+ * @file exchange/test_exchange_api_twisted.c
* @brief testcase to test exchange's HTTP API interface
* @author Marcello Stanisci
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
@@ -262,7 +261,7 @@ run (void *cls,
TALER_TESTING_cmd_refund
("refund-bad-sig",
- MHD_HTTP_UNAUTHORIZED,
+ MHD_HTTP_FORBIDDEN,
"EUR:5",
"EUR:0.01",
"deposit-refund-1"),
@@ -285,7 +284,7 @@ run (void *cls,
"\"value\":\"EUR:5\"}]}",
GNUNET_TIME_UNIT_MINUTES,
"EUR:5",
- MHD_HTTP_FORBIDDEN),
+ MHD_HTTP_CONFLICT),
TALER_TESTING_cmd_refund
("refund-deposit-not-found",
@@ -350,7 +349,7 @@ main (int argc,
/* These environment variables get in the way... */
unsetenv ("XDG_DATA_HOME");
unsetenv ("XDG_CONFIG_HOME");
- GNUNET_log_setup ("test-exchange-api-new-twisted",
+ GNUNET_log_setup ("test-exchange-api-twisted",
"DEBUG", NULL);
if (NULL == (fakebank_url = TALER_TESTING_prepare_fakebank
diff --git a/src/mhd/Makefile.am b/src/mhd/Makefile.am
new file mode 100644
index 00000000..cc4c7073
--- /dev/null
+++ b/src/mhd/Makefile.am
@@ -0,0 +1,26 @@
+# This Makefile.am is in the public domain
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+if USE_COVERAGE
+ AM_CFLAGS = --coverage -O0
+ XLIB = -lgcov
+endif
+
+lib_LTLIBRARIES = \
+ libtalermhd.la
+
+libtalermhd_la_SOURCES = \
+ mhd_config.c \
+ mhd_parsing.c \
+ mhd_responses.c
+libtalermhd_la_LDFLAGS = \
+ -version-info 0:0:0 \
+ -export-dynamic -no-undefined
+libtalermhd_la_LIBADD = \
+ -lgnunetjson \
+ $(top_builddir)/src/json/libtalerjson.la \
+ $(top_builddir)/src/util/libtalerutil.la \
+ -lgnunetutil \
+ -ljansson \
+ $(XLIB)
+
diff --git a/src/mhd/mhd_config.c b/src/mhd/mhd_config.c
new file mode 100644
index 00000000..d4b0e979
--- /dev/null
+++ b/src/mhd/mhd_config.c
@@ -0,0 +1,396 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014--2019 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file mhd_config.c
+ * @brief functions to configure and setup MHD
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include "taler_mhd_lib.h"
+
+
+/**
+ * Backlog for listen operation on UNIX domain sockets.
+ */
+#define UNIX_BACKLOG 500
+
+
+/**
+ * Parse the configuration to determine on which port
+ * or UNIX domain path we should run an HTTP service.
+ *
+ * @param cfg configuration to parse
+ * @param section section of the configuration to parse (usually "exchange")
+ * @param[out] rport set to the port number, or 0 for none
+ * @param[out] unix_path set to the UNIX path, or NULL for none
+ * @param[out] unix_mode set to the mode to be used for @a unix_path
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_MHD_parse_config (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *section,
+ uint16_t *rport,
+ char **unix_path,
+ mode_t *unix_mode)
+{
+ const char *choices[] = {"tcp", "unix"};
+ const char *serve_type;
+ unsigned long long port;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_choice (cfg,
+ section,
+ "serve",
+ choices,
+ &serve_type))
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ section,
+ "serve",
+ "serve type required");
+ return GNUNET_SYSERR;
+ }
+
+ if (0 == strcasecmp (serve_type, "tcp"))
+ {
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_number (cfg,
+ section,
+ "port",
+ &port))
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ section,
+ "port",
+ "port number required");
+ return GNUNET_SYSERR;
+ }
+
+ if ( (0 == port) ||
+ (port > UINT16_MAX) )
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ section,
+ "port",
+ "value not in [1,65535]");
+ return GNUNET_SYSERR;
+ }
+ *rport = (uint16_t) port;
+ *unix_path = NULL;
+ return GNUNET_OK;
+ }
+ if (0 == strcmp (serve_type, "unix"))
+ {
+ struct sockaddr_un s_un;
+ char *modestring;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (cfg,
+ section,
+ "unixpath",
+ unix_path))
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ section,
+ "unixpath",
+ "unixpath required");
+ return GNUNET_SYSERR;
+ }
+ if (strlen (*unix_path) >= sizeof (s_un.sun_path))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "unixpath `%s' is too long\n",
+ *unix_path);
+ return GNUNET_SYSERR;
+ }
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ section,
+ "UNIXPATH_MODE",
+ &modestring))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ section,
+ "UNIXPATH_MODE");
+ return GNUNET_SYSERR;
+ }
+ errno = 0;
+ *unix_mode = (mode_t) strtoul (modestring, NULL, 8);
+ if (0 != errno)
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ section,
+ "UNIXPATH_MODE",
+ "must be octal number");
+ GNUNET_free (modestring);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_free (modestring);
+ return GNUNET_OK;
+ }
+ /* not reached */
+ GNUNET_assert (0);
+ return GNUNET_SYSERR;
+}
+
+
+/**
+ * Function called for logging by MHD.
+ *
+ * @param cls closure, NULL
+ * @param fm format string (`printf()`-style)
+ * @param ap arguments to @a fm
+ */
+void
+TALER_MHD_handle_logs (void *cls,
+ const char *fm,
+ va_list ap)
+{
+ static int cache;
+ char buf[2048];
+
+ (void) cls;
+ if (-1 == cache)
+ return;
+ if (0 == cache)
+ {
+ if (0 ==
+ GNUNET_get_log_call_status (GNUNET_ERROR_TYPE_INFO,
+ "libmicrohttpd",
+ __FILE__,
+ __FUNCTION__,
+ __LINE__))
+ {
+ cache = -1;
+ return;
+ }
+ }
+ cache = 1;
+ vsnprintf (buf,
+ sizeof (buf),
+ fm,
+ ap);
+ GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_INFO,
+ "libmicrohttpd",
+ "%s",
+ buf);
+}
+
+
+/**
+ * Open UNIX domain socket for listining at @a unix_path with
+ * permissions @a unix_mode.
+ *
+ * @param unix_path where to listen
+ * @param unix_mode access permissions to set
+ * @return -1 on error, otherwise the listen socket
+ */
+int
+TALER_MHD_open_unix_path (const char *unix_path,
+ mode_t unix_mode)
+{
+ struct GNUNET_NETWORK_Handle *nh;
+ struct sockaddr_un *un;
+ int fd;
+
+ if (sizeof (un->sun_path) <= strlen (unix_path))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "unixpath `%s' is too long\n",
+ unix_path);
+ return -1;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating listen socket '%s' with mode %o\n",
+ unix_path,
+ unix_mode);
+
+ if (GNUNET_OK !=
+ GNUNET_DISK_directory_create_for_file (unix_path))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "mkdir",
+ unix_path);
+ }
+
+ un = GNUNET_new (struct sockaddr_un);
+ un->sun_family = AF_UNIX;
+ strncpy (un->sun_path,
+ unix_path,
+ sizeof (un->sun_path) - 1);
+ GNUNET_NETWORK_unix_precheck (un);
+
+ if (NULL == (nh = GNUNET_NETWORK_socket_create (AF_UNIX,
+ SOCK_STREAM,
+ 0)))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "socket");
+ GNUNET_free (un);
+ return -1;
+ }
+ if (GNUNET_OK !=
+ GNUNET_NETWORK_socket_bind (nh,
+ (void *) un,
+ sizeof (struct sockaddr_un)))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "bind",
+ unix_path);
+ GNUNET_free (un);
+ GNUNET_NETWORK_socket_close (nh);
+ return -1;
+ }
+ GNUNET_free (un);
+ if (GNUNET_OK !=
+ GNUNET_NETWORK_socket_listen (nh,
+ UNIX_BACKLOG))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "listen");
+ GNUNET_NETWORK_socket_close (nh);
+ return -1;
+ }
+
+ if (0 != chmod (unix_path,
+ unix_mode))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "chmod");
+ GNUNET_NETWORK_socket_close (nh);
+ return -1;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "set socket '%s' to mode %o\n",
+ unix_path,
+ unix_mode);
+ fd = GNUNET_NETWORK_get_fd (nh);
+ GNUNET_NETWORK_socket_free_memory_only_ (nh);
+ return fd;
+}
+
+
+/**
+ * Bind a listen socket to the UNIX domain path
+ * or the TCP port and IP address as specified
+ * in @a cfg in section @a section. IF only a
+ * port was specified, set @a port and return -1.
+ * Otherwise, return the bound file descriptor.
+ *
+ * @param cfg configuration to parse
+ * @param section configuration section to use
+ * @param port[out] port to set, if TCP without BINDTO
+ * @return -1 and a port of zero on error, otherwise
+ * either -1 and a port, or a bound stream socket
+ */
+int
+TALER_MHD_bind (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *section,
+ uint16_t *port)
+{
+ char *bind_to;
+ char *serve_unixpath;
+ mode_t unixpath_mode;
+ int fh;
+ char port_str[6];
+ struct addrinfo hints;
+ struct addrinfo *res;
+ int ec;
+ struct GNUNET_NETWORK_Handle *nh;
+
+ *port = 0;
+ if (GNUNET_OK !=
+ TALER_MHD_parse_config (cfg,
+ section,
+ port,
+ &serve_unixpath,
+ &unixpath_mode))
+ return -1;
+ if (NULL != serve_unixpath)
+ return TALER_MHD_open_unix_path (serve_unixpath,
+ unixpath_mode);
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ section,
+ "BIND_TO",
+ &bind_to))
+ return -1; /* only set port */
+ /* let's have fun binding... */
+ GNUNET_snprintf (port_str,
+ sizeof (port_str),
+ "%u",
+ (unsigned int) *port);
+ *port = 0; /* do NOT return port in case of errors */
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_flags = AI_PASSIVE
+#ifdef AI_IDN
+ | AI_IDN
+#endif
+ ;
+ if (0 !=
+ (ec = getaddrinfo (bind_to,
+ port_str,
+ &hints,
+ &res)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to resolve BIND_TO address `%s': %s\n",
+ bind_to, gai_strerror (ec));
+ GNUNET_free (bind_to);
+ return -1;
+ }
+ GNUNET_free (bind_to);
+
+ if (NULL == (nh = GNUNET_NETWORK_socket_create (res->ai_family,
+ res->ai_socktype,
+ res->ai_protocol)))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "socket");
+ freeaddrinfo (res);
+ return -1;
+ }
+ if (GNUNET_OK !=
+ GNUNET_NETWORK_socket_bind (nh,
+ res->ai_addr,
+ res->ai_addrlen))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "bind");
+ freeaddrinfo (res);
+ return -1;
+ }
+ freeaddrinfo (res);
+ if (GNUNET_OK !=
+ GNUNET_NETWORK_socket_listen (nh,
+ UNIX_BACKLOG))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "listen");
+ GNUNET_SCHEDULER_shutdown ();
+ return -1;
+ }
+ fh = GNUNET_NETWORK_get_fd (nh);
+ GNUNET_NETWORK_socket_free_memory_only_ (nh);
+ return fh;
+}
diff --git a/src/exchange/taler-exchange-httpd_parsing.c b/src/mhd/mhd_parsing.c
index fb8932b9..0b070ffe 100644
--- a/src/exchange/taler-exchange-httpd_parsing.c
+++ b/src/mhd/mhd_parsing.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015, 2016 GNUnet e.V.
+ Copyright (C) 2014--2019 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -13,21 +13,18 @@
You should have received a copy of the GNU Affero General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-
/**
- * @file taler-exchange-httpd_parsing.c
+ * @file mhd_parsing.c
* @brief functions to parse incoming requests (MHD arguments and JSON snippets)
* @author Florian Dold
* @author Benedikt Mueller
* @author Christian Grothoff
*/
-
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_json_lib.h"
-#include "taler-exchange-httpd_parsing.h"
-#include "taler-exchange-httpd_responses.h"
+#include "taler_mhd_lib.h"
/**
@@ -41,7 +38,7 @@
* realizes an MHD POST processor that will (incrementally) process
* JSON data uploaded to the HTTP server. It will store the required
* state in the @a con_cls, which must be cleaned up using
- * #TEH_PARSE_post_cleanup_callback().
+ * #TALER_MHD_post_cleanup_callback().
*
* @param connection the MHD connection
* @param con_cls the closure (points to a `struct Buffer *`)
@@ -60,11 +57,11 @@
* close HTTP session with MHD_NO)
*/
int
-TEH_PARSE_post_json (struct MHD_Connection *connection,
- void **con_cls,
- const char *upload_data,
- size_t *upload_data_size,
- json_t **json)
+TALER_MHD_parse_post_json (struct MHD_Connection *connection,
+ void **con_cls,
+ const char *upload_data,
+ size_t *upload_data_size,
+ json_t **json)
{
enum GNUNET_JSON_PostResult pr;
@@ -76,23 +73,26 @@ TEH_PARSE_post_json (struct MHD_Connection *connection,
json);
switch (pr)
{
-
case GNUNET_JSON_PR_OUT_OF_MEMORY:
- return (MHD_NO == TEH_RESPONSE_reply_internal_error
+ return (MHD_NO ==
+ TALER_MHD_reply_with_error
(connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_PARSER_OUT_OF_MEMORY,
"out of memory")) ? GNUNET_SYSERR : GNUNET_NO;
case GNUNET_JSON_PR_CONTINUE:
return GNUNET_YES;
-
case GNUNET_JSON_PR_REQUEST_TOO_LARGE:
- return (MHD_NO == TEH_RESPONSE_reply_request_too_large
+ return (MHD_NO ==
+ TALER_MHD_reply_request_too_large
(connection)) ? GNUNET_SYSERR : GNUNET_NO;
-
case GNUNET_JSON_PR_JSON_INVALID:
return (MHD_YES ==
- TEH_RESPONSE_reply_invalid_json (connection))
+ TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_JSON_INVALID,
+ "invalid JSON uploaded"))
? GNUNET_NO : GNUNET_SYSERR;
case GNUNET_JSON_PR_SUCCESS:
GNUNET_break (NULL != *json);
@@ -109,11 +109,12 @@ TEH_PARSE_post_json (struct MHD_Connection *connection,
* to clean up our state.
*
* @param con_cls value as it was left by
- * #TEH_PARSE_post_json(), to be cleaned up
+ * #TALER_MHD_post_json(), to be cleaned up
*/
void
-TEH_PARSE_post_cleanup_callback (void *con_cls)
+TALER_MHD_parse_post_cleanup_callback (void *con_cls)
{
+ // FIXME: this should probably NOT be done with a 'void *' like this!
GNUNET_JSON_post_parser_cleanup (con_cls);
}
@@ -134,10 +135,10 @@ TEH_PARSE_post_cleanup_callback (void *con_cls)
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
int
-TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
- const char *param_name,
- void *out_data,
- size_t out_size)
+TALER_MHD_parse_request_arg_data (struct MHD_Connection *connection,
+ const char *param_name,
+ void *out_data,
+ size_t out_size)
{
const char *str;
@@ -147,9 +148,10 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
if (NULL == str)
{
return (MHD_NO ==
- TEH_RESPONSE_reply_arg_missing (connection,
- TALER_EC_PARAMETER_MISSING,
- param_name))
+ TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_PARAMETER_MISSING,
+ param_name))
? GNUNET_SYSERR : GNUNET_NO;
}
if (GNUNET_OK !=
@@ -158,9 +160,10 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
out_data,
out_size))
return (MHD_NO ==
- TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_PARAMETER_MALFORMED,
- param_name))
+ TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_PARAMETER_MALFORMED,
+ param_name))
? GNUNET_SYSERR : GNUNET_NO;
return GNUNET_OK;
}
@@ -181,9 +184,9 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
* #GNUNET_SYSERR on internal error
*/
int
-TEH_PARSE_json_data (struct MHD_Connection *connection,
- const json_t *root,
- struct GNUNET_JSON_Specification *spec)
+TALER_MHD_parse_json_data (struct MHD_Connection *connection,
+ const json_t *root,
+ struct GNUNET_JSON_Specification *spec)
{
int ret;
const char *error_json_name;
@@ -198,15 +201,15 @@ TEH_PARSE_json_data (struct MHD_Connection *connection,
if (NULL == error_json_name)
error_json_name = "<no field>";
ret = (MHD_YES ==
- TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I, s:s, s:I}",
- "error", "parse error",
- "code",
- (json_int_t)
- TALER_EC_JSON_INVALID_WITH_DETAILS,
- "field", error_json_name,
- "line", (json_int_t) error_line))
+ TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:I, s:s, s:I}",
+ "hint", "JSON parse error",
+ "code",
+ (json_int_t)
+ TALER_EC_JSON_INVALID_WITH_DETAILS,
+ "field", error_json_name,
+ "line", (json_int_t) error_line))
? GNUNET_NO : GNUNET_SYSERR;
return ret;
}
@@ -230,10 +233,10 @@ TEH_PARSE_json_data (struct MHD_Connection *connection,
* #GNUNET_SYSERR on internal error
*/
int
-TEH_PARSE_json_array (struct MHD_Connection *connection,
- const json_t *root,
- struct GNUNET_JSON_Specification *spec,
- ...)
+TALER_MHD_parse_json_array (struct MHD_Connection *connection,
+ const json_t *root,
+ struct GNUNET_JSON_Specification *spec,
+ ...)
{
int ret;
const char *error_json_name;
@@ -253,11 +256,14 @@ TEH_PARSE_json_array (struct MHD_Connection *connection,
if (NULL == root)
{
ret = (MHD_YES ==
- TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:I}",
- "error", "parse error",
- "dimension", dim))
+ TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:I, s:I}",
+ "hint", "expected array",
+ "code",
+ (json_int_t)
+ TALER_EC_JSON_INVALID_WITH_DETAILS,
+ "dimension", dim))
? GNUNET_NO : GNUNET_SYSERR;
return ret;
}
@@ -270,12 +276,14 @@ TEH_PARSE_json_array (struct MHD_Connection *connection,
if (NULL == error_json_name)
error_json_name = "<no field>";
ret = (MHD_YES ==
- TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s, s:I}",
- "error", "parse error",
- "field", error_json_name,
- "line", (json_int_t) error_line))
+ TALER_MHD_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:I, s:I}",
+ "hint", error_json_name,
+ "code",
+ (json_int_t)
+ TALER_EC_JSON_INVALID_WITH_DETAILS,
+ "line", (json_int_t) error_line))
? GNUNET_NO : GNUNET_SYSERR;
return ret;
}
@@ -283,4 +291,4 @@ TEH_PARSE_json_array (struct MHD_Connection *connection,
}
-/* end of taler-exchange-httpd_parsing.c */
+/* end of mhd_parsing.c */
diff --git a/src/mhd/mhd_responses.c b/src/mhd/mhd_responses.c
new file mode 100644
index 00000000..3642e7d5
--- /dev/null
+++ b/src/mhd/mhd_responses.c
@@ -0,0 +1,501 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2019 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file mhd_responses.c
+ * @brief API for generating HTTP replies
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <zlib.h>
+#include "taler_util.h"
+#include "taler_mhd_lib.h"
+
+
+/**
+ * Enable checking signatures before we hand them out
+ * (even though we should have checked them before).
+ * So technically these checks are redundant, but good
+ * during testing.
+ */
+#define SANITY_CHECKS_ON 1
+
+
+/**
+ * Global options for response generation.
+ */
+static enum TALER_MHD_GlobalOptions TM_go;
+
+
+/**
+ * Set global options for response generation
+ * within libtalermhd.
+ *
+ * @param go global options to use
+ */
+void
+TALER_MHD_setup (enum TALER_MHD_GlobalOptions go)
+{
+ TM_go = go;
+}
+
+
+/**
+ * Add headers we want to return in every response.
+ * Useful for testing, like if we want to always close
+ * connections.
+ *
+ * @param response response to modify
+ */
+void
+TALER_MHD_add_global_headers (struct MHD_Response *response)
+{
+ if (0 != (TM_go & TALER_MHD_GO_FORCE_CONNECTION_CLOSE))
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONNECTION,
+ "close"));
+}
+
+
+/**
+ * Is HTTP body deflate compression supported by the client?
+ *
+ * @param connection connection to check
+ * @return #MHD_YES if 'deflate' compression is allowed
+ *
+ * Note that right now we're ignoring q-values, which is technically
+ * not correct, and also do not support "*" anywhere but in a line by
+ * itself. This should eventually be fixed, see also
+ * https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+ */
+int
+TALER_MHD_can_compress (struct MHD_Connection *connection)
+{
+ const char *ae;
+ const char *de;
+
+ if (0 != (TM_go & TALER_MHD_GO_DISABLE_COMPRESSION))
+ return MHD_NO;
+ ae = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_ACCEPT_ENCODING);
+ if (NULL == ae)
+ return MHD_NO;
+ if (0 == strcmp (ae,
+ "*"))
+ return MHD_YES;
+ de = strstr (ae,
+ "deflate");
+ if (NULL == de)
+ return MHD_NO;
+ if ( ( (de == ae) ||
+ (de[-1] == ',') ||
+ (de[-1] == ' ') ) &&
+ ( (de[strlen ("deflate")] == '\0') ||
+ (de[strlen ("deflate")] == ',') ||
+ (de[strlen ("deflate")] == ';') ) )
+ return MHD_YES;
+ return MHD_NO;
+}
+
+
+/**
+ * Try to compress a response body. Updates @a buf and @a buf_size.
+ *
+ * @param[in,out] buf pointer to body to compress
+ * @param[in,out] buf_size pointer to initial size of @a buf
+ * @return #MHD_YES if @a buf was compressed
+ */
+int
+TALER_MHD_body_compress (void **buf,
+ size_t *buf_size)
+{
+ Bytef *cbuf;
+ uLongf cbuf_size;
+ int ret;
+
+ cbuf_size = compressBound (*buf_size);
+ cbuf = malloc (cbuf_size);
+ if (NULL == cbuf)
+ return MHD_NO;
+ ret = compress (cbuf,
+ &cbuf_size,
+ (const Bytef *) *buf,
+ *buf_size);
+ if ( (Z_OK != ret) ||
+ (cbuf_size >= *buf_size) )
+ {
+ /* compression failed */
+ free (cbuf);
+ return MHD_NO;
+ }
+ free (*buf);
+ *buf = (void *) cbuf;
+ *buf_size = (size_t) cbuf_size;
+ return MHD_YES;
+}
+
+
+/**
+ * Make JSON response object.
+ *
+ * @param json the json object
+ * @return MHD response object
+ */
+struct MHD_Response *
+TALER_MHD_make_json (const json_t *json)
+{
+ struct MHD_Response *resp;
+ char *json_str;
+
+ json_str = json_dumps (json,
+ JSON_INDENT (2));
+ if (NULL == json_str)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ resp = MHD_create_response_from_buffer (strlen (json_str),
+ json_str,
+ MHD_RESPMEM_MUST_FREE);
+ if (NULL == resp)
+ {
+ free (json_str);
+ GNUNET_break (0);
+ return NULL;
+ }
+ TALER_MHD_add_global_headers (resp);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "application/json"));
+ return resp;
+}
+
+
+/**
+ * Send JSON object as response.
+ *
+ * @param connection the MHD connection
+ * @param json the json object
+ * @param response_code the http response code
+ * @return MHD result code
+ */
+int
+TALER_MHD_reply_json (struct MHD_Connection *connection,
+ const json_t *json,
+ unsigned int response_code)
+{
+ struct MHD_Response *resp;
+ void *json_str;
+ size_t json_len;
+ int ret;
+ int comp;
+
+ json_str = json_dumps (json,
+ JSON_INDENT (2));
+ if (NULL == json_str)
+ {
+ /**
+ * This log helps to figure out which
+ * function called this one and assert-failed.
+ */
+ TALER_LOG_ERROR ("Aborting json-packing for HTTP code: %u\n",
+ response_code);
+
+ GNUNET_assert (0);
+ return MHD_NO;
+ }
+ json_len = strlen (json_str);
+ /* try to compress the body */
+ comp = MHD_NO;
+ if (MHD_YES ==
+ TALER_MHD_can_compress (connection))
+ comp = TALER_MHD_body_compress (&json_str,
+ &json_len);
+ resp = MHD_create_response_from_buffer (json_len,
+ json_str,
+ MHD_RESPMEM_MUST_FREE);
+ if (NULL == resp)
+ {
+ free (json_str);
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ TALER_MHD_add_global_headers (resp);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "application/json"));
+ if (MHD_YES == comp)
+ {
+ /* Need to indicate to client that body is compressed */
+ if (MHD_NO ==
+ MHD_add_response_header (resp,
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ "deflate"))
+ {
+ GNUNET_break (0);
+ MHD_destroy_response (resp);
+ return MHD_NO;
+ }
+ }
+ ret = MHD_queue_response (connection,
+ response_code,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+}
+
+
+/**
+ * Function to call to handle the request by building a JSON
+ * reply from a format string and varargs.
+ *
+ * @param connection the MHD connection to handle
+ * @param response_code HTTP response code to use
+ * @param fmt format string for pack
+ * @param ... varargs
+ * @return MHD result code
+ */
+int
+TALER_MHD_reply_json_pack (struct MHD_Connection *connection,
+ unsigned int response_code,
+ const char *fmt,
+ ...)
+{
+ json_t *json;
+ va_list argp;
+ int ret;
+ json_error_t jerror;
+
+ va_start (argp, fmt);
+ json = json_vpack_ex (&jerror, 0, fmt, argp);
+ va_end (argp);
+ if (NULL == json)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to pack JSON with format `%s': %s\n",
+ fmt,
+ jerror.text);
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ ret = TALER_MHD_reply_json (connection,
+ json,
+ response_code);
+ json_decref (json);
+ return ret;
+}
+
+
+/**
+ * Make JSON response object.
+ *
+ * @param fmt format string for pack
+ * @param ... varargs
+ * @return MHD response object
+ */
+struct MHD_Response *
+TALER_MHD_make_json_pack (const char *fmt,
+ ...)
+{
+ json_t *json;
+ va_list argp;
+ struct MHD_Response *ret;
+ json_error_t jerror;
+
+ va_start (argp, fmt);
+ json = json_vpack_ex (&jerror,
+ 0,
+ fmt,
+ argp);
+ va_end (argp);
+ if (NULL == json)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to pack JSON with format `%s': %s\n",
+ fmt,
+ jerror.text);
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ ret = TALER_MHD_make_json (json);
+ json_decref (json);
+ return ret;
+}
+
+
+/**
+ * Create a response indicating an internal error.
+ *
+ * @param ec error code to return
+ * @param hint hint about the internal error's nature
+ * @return a MHD response object
+ */
+struct MHD_Response *
+TALER_MHD_make_error (enum TALER_ErrorCode ec,
+ const char *hint)
+{
+ return TALER_MHD_make_json_pack ("{s:I, s:s}",
+ "code", (json_int_t) ec,
+ "hint", hint);
+}
+
+
+/**
+ * Send a response indicating an error.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
+ * @param http_status HTTP status code to use
+ * @param hint human readable hint about the error
+ * @return a MHD result code
+ */
+int
+TALER_MHD_reply_with_error (struct MHD_Connection *connection,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const char *hint)
+{
+ return TALER_MHD_reply_json_pack (connection,
+ http_status,
+ "{s:I, s:s}",
+ "code", (json_int_t) ec,
+ "hint", hint);
+}
+
+
+/**
+ * Send a response indicating that the request was too big.
+ *
+ * @param connection the MHD connection to use
+ * @return a MHD result code
+ */
+int
+TALER_MHD_reply_request_too_large (struct MHD_Connection *connection)
+{
+ struct MHD_Response *resp;
+ int ret;
+
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == resp)
+ return MHD_NO;
+ TALER_MHD_add_global_headers (resp);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+}
+
+
+/**
+ * Function to call to handle the request by sending
+ * back a redirect to the AGPL source code.
+ *
+ * @param connection the MHD connection to handle
+ * @param url where to redirect for the sources
+ * @return MHD result code
+ */
+int
+TALER_MHD_reply_agpl (struct MHD_Connection *connection,
+ const char *url)
+{
+ const char *agpl =
+ "This server is licensed under the Affero GPL. You will now be redirected to the source code.";
+ struct MHD_Response *response;
+ int ret;
+
+ response = MHD_create_response_from_buffer (strlen (agpl),
+ (void *) agpl,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ TALER_MHD_add_global_headers (response);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/plain"));
+ if (MHD_NO ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_LOCATION,
+ url))
+ {
+ GNUNET_break (0);
+ MHD_destroy_response (response);
+ return MHD_NO;
+ }
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_FOUND,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+/**
+ * Function to call to handle the request by sending
+ * back static data.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param http_status status code to return
+ * @param mime_type content-type to use
+ * @param body response payload
+ * @param body_size number of bytes in @a body
+ * @return MHD result code
+ */
+int
+TALER_MHD_reply_static (struct MHD_Connection *connection,
+ unsigned int http_status,
+ const char *mime_type,
+ const char *body,
+ size_t body_size)
+{
+ struct MHD_Response *response;
+ int ret;
+
+ response = MHD_create_response_from_buffer (body_size,
+ (void *) body,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ TALER_MHD_add_global_headers (response);
+ if (NULL != mime_type)
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ mime_type));
+ ret = MHD_queue_response (connection,
+ http_status,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
+/* end of mhd_responses.c */
diff --git a/src/util/crypto.c b/src/util/crypto.c
index 077f049e..cf351d3f 100644
--- a/src/util/crypto.c
+++ b/src/util/crypto.c
@@ -191,32 +191,6 @@ TALER_link_recover_transfer_secret (const struct
/**
- * Set the bits in the private EdDSA key so that they match
- * the specification.
- *
- * @param[in,out] pk private key to patch
- */
-static void
-patch_private_key (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
-{
- uint8_t *p = (uint8_t *) pk;
-
- /* Taken from like 170-172 of libgcrypt/cipher/ecc.c
- * We note that libgcrypt stores the private key in the reverse order
- * from many Ed25519 implementatons. */
- p[0] &= 0x7f; /* Clear bit 255. */
- p[0] |= 0x40; /* Set bit 254. */
- p[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0 */
-
- /* FIXME: Run GNUNET_CRYPTO_ecdhe_key_create several times and inspect
- * the output to verify that the same bits are set and cleared.
- * Is it worth also adding a test case that runs gcry_pk_testkey on
- * this key after first parsing it into libgcrypt's s-expression mess
- * ala decode_private_eddsa_key from gnunet/src/util/crypto_ecc.c?
- * It'd run check_secret_key but not test_keys from libgcrypt/cipher/ecc.c */}
-
-
-/**
* Setup information for a fresh coin.
*
* @param secret_seed seed to use for KDF to derive coin keys
@@ -240,7 +214,6 @@ TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
"taler-coin-derivation",
strlen ("taler-coin-derivation"),
NULL, 0));
- patch_private_key (&ps->coin_priv.eddsa_priv);
}
@@ -255,7 +228,6 @@ TALER_planchet_setup_random (struct TALER_PlanchetSecretsP *ps)
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
ps,
sizeof (*ps));
- patch_private_key (&ps->coin_priv.eddsa_priv);
}