summaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-12-14 13:49:24 +0100
committerChristian Grothoff <christian@grothoff.org>2017-12-14 13:49:24 +0100
commit1897d65af506f083d8296e6184c9633d0fb5bae0 (patch)
tree1cd759568689c450e0147d992d45a138211d3389 /src/exchange
parentf7c9de73e197b6cc6308ad3322f4a75dfe2f33b5 (diff)
downloadexchange-1897d65af506f083d8296e6184c9633d0fb5bae0.tar.gz
exchange-1897d65af506f083d8296e6184c9633d0fb5bae0.tar.bz2
exchange-1897d65af506f083d8296e6184c9633d0fb5bae0.zip
eliminate /admin/add/incoming (fixes #5172)
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/Makefile.am1
-rw-r--r--src/exchange/exchange.conf15
-rw-r--r--src/exchange/taler-exchange-httpd.c237
-rw-r--r--src/exchange/taler-exchange-httpd_admin.c218
-rw-r--r--src/exchange/taler-exchange-httpd_admin.h46
5 files changed, 20 insertions, 497 deletions
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am
index 9ff98d12b..b5419a7a6 100644
--- a/src/exchange/Makefile.am
+++ b/src/exchange/Makefile.am
@@ -43,7 +43,6 @@ taler_exchange_wirewatch_LDADD = \
taler_exchange_httpd_SOURCES = \
taler-exchange-httpd.c taler-exchange-httpd.h \
- taler-exchange-httpd_admin.c taler-exchange-httpd_admin.h \
taler-exchange-httpd_db.c taler-exchange-httpd_db.h \
taler-exchange-httpd_deposit.c taler-exchange-httpd_deposit.h \
taler-exchange-httpd_keystate.c taler-exchange-httpd_keystate.h \
diff --git a/src/exchange/exchange.conf b/src/exchange/exchange.conf
index 4c10b31aa..39c496ec5 100644
--- a/src/exchange/exchange.conf
+++ b/src/exchange/exchange.conf
@@ -36,18 +36,3 @@ PORT = 8081
# Required for wire transfers as we need to include it in the wire
# transfers to enable tracking.
BASE_URL = http://localhost:8081/
-
-
-[exchange-admin]
-# Network configuration for the /admin HTTP server
-
-# serve via tcp socket (on PORT)
-SERVE = tcp
-
-# Unix domain socket to listen on,
-# only effective with "SERVE = unix"
-UNIXPATH = ${TALER_RUNTIME_DIR}/exchange-admin.http
-UNIXPATH_MODE = 660
-
-# HTTP port the exchange listens to
-PORT = 18080
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 42fe16b22..f45b5470d 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -28,7 +28,6 @@
#include <pthread.h>
#include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_mhd.h"
-#include "taler-exchange-httpd_admin.h"
#include "taler-exchange-httpd_deposit.h"
#include "taler-exchange-httpd_refund.h"
#include "taler-exchange-httpd_reserve_status.h"
@@ -96,16 +95,6 @@ static unsigned int connection_timeout = 30;
static struct MHD_Daemon *mhd;
/**
- * The HTTP Daemon for /admin-requests.
- */
-static struct MHD_Daemon *mhd_admin;
-
-/**
- * Do not offer /admin API.
- */
-static int no_admin;
-
-/**
* Initialize the database by creating tables and indices.
*/
static int init_db;
@@ -116,32 +105,16 @@ static int init_db;
static uint16_t serve_port;
/**
- * Port to run the admin daemon on.
- */
-static uint16_t serve_admin_port;
-
-/**
* Path for the unix domain-socket
* to run the daemon on.
*/
static char *serve_unixpath;
/**
- * Path for the unix domain-socket
- * to run the admin daemon on.
- */
-static char *serve_admin_unixpath;
-
-/**
* File mode for unix-domain socket.
*/
static mode_t unixpath_mode;
-/**
- * File mode for unix-domain socket.
- */
-static mode_t unixpath_admin_mode;
-
/**
* Function called whenever MHD is done with a request. If the
@@ -307,76 +280,6 @@ handle_mhd_request (void *cls,
"Only GET is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
- { NULL, NULL, NULL, NULL, 0, 0 }
- };
- static struct TEH_RequestHandler h404 =
- {
- "", NULL, "text/html",
- "<html><title>404: not found</title></html>", 0,
- &TEH_MHD_handler_static_response, MHD_HTTP_NOT_FOUND
- };
- struct TEH_RequestHandler *rh;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Handling request for URL '%s'\n",
- url);
- if (0 == strcasecmp (method,
- MHD_HTTP_METHOD_HEAD))
- method = MHD_HTTP_METHOD_GET; /* treat HEAD as GET here, MHD will do the rest */
- for (unsigned int i=0;NULL != handlers[i].url;i++)
- {
- rh = &handlers[i];
- if ( (0 == strcasecmp (url,
- rh->url)) &&
- ( (NULL == rh->method) ||
- (0 == strcasecmp (method,
- rh->method)) ) )
- return rh->handler (rh,
- connection,
- con_cls,
- upload_data,
- upload_data_size);
- }
- return TEH_MHD_handler_static_response (&h404,
- connection,
- con_cls,
- upload_data,
- upload_data_size);
-}
-
-
-/**
- * Handle incoming administrative HTTP request.
- *
- * @param cls closure for MHD daemon (unused)
- * @param connection the connection
- * @param url the requested url
- * @param method the method (POST, GET, ...)
- * @param version HTTP version (ignored)
- * @param upload_data request data
- * @param upload_data_size size of @a upload_data in bytes
- * @param con_cls closure for request (a `struct Buffer *`)
- * @return MHD result code
- */
-static int
-handle_mhd_admin_request (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size,
- void **con_cls)
-{
- static struct TEH_RequestHandler handlers[] =
- {
- { "/admin/add/incoming", MHD_HTTP_METHOD_POST, "application/json",
- NULL, 0,
- &TEH_ADMIN_handler_admin_add_incoming, MHD_HTTP_OK },
- { "/admin/add/incoming", NULL, "text/plain",
- "Only POST is allowed", 0,
- &TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
-
#if HAVE_DEVELOPER
/* Client crypto-interoperability test functions */
{ "/test", MHD_HTTP_METHOD_POST, "application/json",
@@ -452,12 +355,14 @@ handle_mhd_admin_request (void *cls,
&TEH_MHD_handler_static_response, MHD_HTTP_NOT_FOUND
};
struct TEH_RequestHandler *rh;
- unsigned int i;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Handling request for URL '%s'\n",
url);
- for (i=0;NULL != handlers[i].url;i++)
+ if (0 == strcasecmp (method,
+ MHD_HTTP_METHOD_HEAD))
+ method = MHD_HTTP_METHOD_GET; /* treat HEAD as GET here, MHD will do the rest */
+ for (unsigned int i=0;NULL != handlers[i].url;i++)
{
rh = &handlers[i];
if ( (0 == strcasecmp (url,
@@ -691,15 +596,6 @@ exchange_serve_process_config ()
TEH_VALIDATION_done ();
return GNUNET_SYSERR;
}
- if (GNUNET_OK !=
- parse_port_config ("exchange-admin",
- &serve_admin_port,
- &serve_admin_unixpath,
- &unixpath_admin_mode))
- {
- TEH_VALIDATION_done ();
- return GNUNET_SYSERR;
- }
return GNUNET_OK;
}
@@ -948,23 +844,19 @@ main (int argc,
char *logfile = NULL;
const struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_flag ('C',
- "connection-close",
- "force HTTP connections to be closed after each request",
- &TEH_exchange_connection_close),
+ "connection-close",
+ "force HTTP connections to be closed after each request",
+ &TEH_exchange_connection_close),
GNUNET_GETOPT_option_cfgfile (&cfgfile),
- GNUNET_GETOPT_option_flag ('D',
- "disable-admin",
- "do not run the /admin-HTTP server",
- &no_admin),
GNUNET_GETOPT_option_flag ('i',
- "init-db",
- "create database tables and indicies if necessary",
- &init_db),
+ "init-db",
+ "create database tables and indicies if necessary",
+ &init_db),
GNUNET_GETOPT_option_uint ('t',
- "timeout",
- "SECONDS",
- "after how long do connections timeout by default (in seconds)",
- &connection_timeout),
+ "timeout",
+ "SECONDS",
+ "after how long do connections timeout by default (in seconds)",
+ &connection_timeout),
#if HAVE_DEVELOPER
GNUNET_GETOPT_option_filename ('f',
"file-input",
@@ -982,7 +874,6 @@ main (int argc,
const char *listen_pid;
const char *listen_fds;
int fh = -1;
- int fh_admin = -1;
if (0 >=
GNUNET_GETOPT_run ("taler-exchange-httpd",
@@ -1018,12 +909,9 @@ main (int argc,
(getpid() == strtol (listen_pid,
NULL,
10)) &&
- ( (1 == strtoul (listen_fds,
- NULL,
- 10)) ||
- (2 == strtoul (listen_fds,
- NULL,
- 10)) ) )
+ (1 == strtoul (listen_fds,
+ NULL,
+ 10)) )
{
int flags;
@@ -1044,29 +932,6 @@ main (int argc,
flags)) )
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"fcntl");
-
- if (2 == strtoul (listen_fds,
- NULL,
- 10))
- {
- fh_admin = 4;
- flags = fcntl (fh_admin,
- F_GETFD);
- if ( (-1 == flags) &&
- (EBADF == errno) )
- {
- fprintf (stderr,
- "Bad listen socket passed, ignored\n");
- fh_admin = -1;
- }
- flags |= FD_CLOEXEC;
- if ( (-1 != fh_admin) &&
- (0 != fcntl (fh_admin,
- F_SETFD,
- flags)) )
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "fcntl");
- }
}
/* consider unix path */
@@ -1078,19 +943,6 @@ main (int argc,
if (-1 == fh)
return 1;
}
- if ( (-1 == fh_admin) &&
- (0 == no_admin) &&
- (NULL != serve_admin_unixpath) )
- {
- fh_admin = open_unix_path (serve_admin_unixpath,
- unixpath_admin_mode);
- if (-1 == fh_admin)
- {
- if (-1 != fh)
- GNUNET_break (0 == close (fh));
- return 1;
- }
- }
mhd
= MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_PIPE_FOR_SHUTDOWN | MHD_USE_DEBUG | MHD_USE_DUAL_STACK,
@@ -1112,30 +964,6 @@ main (int argc,
return 1;
}
- if (0 == no_admin)
- {
- mhd_admin
- = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_PIPE_FOR_SHUTDOWN | MHD_USE_DEBUG,
- (-1 == fh) ? serve_admin_port : 0,
- NULL, NULL,
- &handle_mhd_admin_request, NULL,
- MHD_OPTION_LISTEN_SOCKET, fh_admin,
- MHD_OPTION_EXTERNAL_LOGGER, &handle_mhd_logs, NULL,
- MHD_OPTION_NOTIFY_COMPLETED, &handle_mhd_completion_callback, NULL,
- MHD_OPTION_CONNECTION_TIMEOUT, connection_timeout,
-#if HAVE_DEVELOPER
- MHD_OPTION_NOTIFY_CONNECTION, &connection_done, NULL,
-#endif
- MHD_OPTION_END);
- if (NULL == mhd_admin)
- {
- fprintf (stderr,
- "Failed to start administrative HTTP server.\n");
- MHD_stop_daemon (mhd);
- return 1;
- }
- }
-
#if HAVE_DEVELOPER
if (NULL != input_filename)
{
@@ -1157,23 +985,14 @@ main (int argc,
case GNUNET_OK:
case GNUNET_SYSERR:
MHD_stop_daemon (mhd);
- if (NULL != mhd_admin)
- MHD_stop_daemon (mhd_admin);
break;
case GNUNET_NO:
{
MHD_socket sock = MHD_quiesce_daemon (mhd);
- MHD_socket admin_sock;
- int admin_sock_opened = GNUNET_NO;
pid_t chld;
int flags;
/* Set flags to make 'sock' inherited by child */
- if (NULL != mhd_admin)
- {
- admin_sock = MHD_quiesce_daemon (mhd_admin);
- admin_sock_opened = GNUNET_YES;
- }
flags = fcntl (sock, F_GETFD);
GNUNET_assert (-1 != flags);
flags &= ~FD_CLOEXEC;
@@ -1197,20 +1016,13 @@ main (int argc,
"dup2");
_exit (1);
}
- if ( (GNUNET_YES == admin_sock_opened) &&
- (4 != dup2 (admin_sock, 4)) )
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "dup2");
- _exit (1);
- }
/* Tell the child that it is the desired recipient for FD #3 */
GNUNET_snprintf (pids,
sizeof (pids),
"%u",
getpid ());
setenv ("LISTEN_PID", pids, 1);
- setenv ("LISTEN_FDS", (NULL != mhd_admin) ? "2" : "1", 1);
+ setenv ("LISTEN_FDS", "1", 1);
/* Finally, exec the (presumably) more recent exchange binary */
execvp ("taler-exchange-httpd",
argv);
@@ -1222,25 +1034,16 @@ main (int argc,
before exiting; as the listen socket is no longer used,
close it here */
GNUNET_break (0 == close (sock));
- if (GNUNET_YES == admin_sock_opened)
- GNUNET_break (0 == close (admin_sock));
- while ( (0 != MHD_get_daemon_info (mhd,
- MHD_DAEMON_INFO_CURRENT_CONNECTIONS)->num_connections) ||
- ( (NULL != mhd_admin) &&
- (0 != MHD_get_daemon_info (mhd_admin,
- MHD_DAEMON_INFO_CURRENT_CONNECTIONS)->num_connections) ) )
+ while (0 != MHD_get_daemon_info (mhd,
+ MHD_DAEMON_INFO_CURRENT_CONNECTIONS)->num_connections)
sleep (1);
/* Now we're really done, practice clean shutdown */
MHD_stop_daemon (mhd);
- if (NULL != mhd_admin)
- MHD_stop_daemon (mhd_admin);
}
break;
default:
GNUNET_break (0);
MHD_stop_daemon (mhd);
- if (NULL != mhd_admin)
- MHD_stop_daemon (mhd_admin);
break;
}
TALER_EXCHANGEDB_plugin_unload (TEH_plugin);
diff --git a/src/exchange/taler-exchange-httpd_admin.c b/src/exchange/taler-exchange-httpd_admin.c
deleted file mode 100644
index f65b9c38a..000000000
--- a/src/exchange/taler-exchange-httpd_admin.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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_admin.c
- * @brief Handle /admin/ requests
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include "taler-exchange-httpd_admin.h"
-#include "taler-exchange-httpd_parsing.h"
-#include "taler-exchange-httpd_responses.h"
-#include "taler-exchange-httpd_validation.h"
-
-
-/**
- * Closure for #admin_add_incoming_transaction()
- */
-struct AddIncomingContext
-{
- /**
- * public key of the reserve
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-
- /**
- * amount to add to the reserve
- */
- struct TALER_Amount amount;
-
- /**
- * When did we receive the wire transfer
- */
- struct GNUNET_TIME_Absolute execution_time;
-
- /**
- * which account send the funds
- */
- json_t *sender_account_details;
-
- /**
- * Information that uniquely identifies the transfer
- */
- json_t *transfer_details;
-
- /**
- * Set to the transaction status.
- */
- enum GNUNET_DB_QueryStatus qs;
-};
-
-
-/**
- * Add an incoming transaction to the database. Checks if the
- * transaction is fresh (not a duplicate) and if so adds it to the
- * database.
- *
- * If it returns a non-error code, the transaction logic MUST
- * NOT queue a MHD response. IF it returns an hard error, the
- * transaction logic MUST queue a MHD response and set @a mhd_ret. IF
- * it returns the soft error code, the function MAY be called again to
- * retry and MUST not queue a MHD response.
- *
- * @param cls closure with the `struct AddIncomingContext *`
- * @param connection MHD request which triggered the transaction
- * @param session database session to use
- * @param[out] mhd_ret set to MHD response status for @a connection,
- * if transaction failed (!)
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-admin_add_incoming_transaction (void *cls,
- struct MHD_Connection *connection,
- struct TALER_EXCHANGEDB_Session *session,
- int *mhd_ret)
-{
- struct AddIncomingContext *aic = cls;
- void *json_str;
-
- json_str = json_dumps (aic->transfer_details,
- JSON_INDENT(2));
- if (NULL == json_str)
- {
- GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_PARSER_OUT_OF_MEMORY);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- aic->qs = TEH_plugin->reserves_in_insert (TEH_plugin->cls,
- session,
- &aic->reserve_pub,
- &aic->amount,
- aic->execution_time,
- aic->sender_account_details,
- json_str,
- strlen (json_str));
- free (json_str);
-
- if (GNUNET_DB_STATUS_HARD_ERROR == aic->qs)
- {
- GNUNET_break (0);
- *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
- TALER_EC_ADMIN_ADD_INCOMING_DB_STORE);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- return aic->qs;
-}
-
-
-/**
- * Handle a "/admin/add/incoming" request. Parses the
- * given "reserve_pub", "amount", "transaction" and "h_wire"
- * details and adds the respective transaction to the database.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- struct AddIncomingContext aic;
- enum TALER_ErrorCode ec;
- char *emsg;
- json_t *root;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("reserve_pub", &aic.reserve_pub),
- TALER_JSON_spec_amount ("amount", &aic.amount),
- GNUNET_JSON_spec_absolute_time ("execution_date", &aic.execution_time),
- GNUNET_JSON_spec_json ("sender_account_details", &aic.sender_account_details),
- GNUNET_JSON_spec_json ("transfer_details", &aic.transfer_details),
- GNUNET_JSON_spec_end ()
- };
- int res;
- int mhd_ret;
-
- res = TEH_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);
- json_decref (root);
- if (GNUNET_OK != res)
- {
- GNUNET_break_op (0);
- json_decref (root);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- if (TALER_EC_NONE !=
- (ec = TEH_json_validate_wireformat (aic.sender_account_details,
- GNUNET_NO,
- &emsg)))
- {
- GNUNET_JSON_parse_free (spec);
- mhd_ret = TEH_RESPONSE_reply_external_error (connection,
- ec,
- emsg);
- GNUNET_free (emsg);
- return mhd_ret;
- }
- if (0 != strcasecmp (aic.amount.currency,
- TEH_exchange_currency_string))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Exchange uses currency `%s', but /admin/add/incoming tried to use currency `%s'\n",
- TEH_exchange_currency_string,
- aic.amount.currency);
- GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED,
- "amount:currency");
- }
- res = TEH_DB_run_transaction (connection,
- &mhd_ret,
- &admin_add_incoming_transaction,
- &aic);
- GNUNET_JSON_parse_free (spec);
- if (GNUNET_OK != res)
- return mhd_ret;
- return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:s}",
- "status",
- (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == aic.qs)
- ? "NEW"
- : "DUP");
-}
-
-/* end of taler-exchange-httpd_admin.c */
diff --git a/src/exchange/taler-exchange-httpd_admin.h b/src/exchange/taler-exchange-httpd_admin.h
deleted file mode 100644
index 8ed1e3d54..000000000
--- a/src/exchange/taler-exchange-httpd_admin.h
+++ /dev/null
@@ -1,46 +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-exchange-httpd_admin.h
- * @brief Handle /admin/ requests
- * @author Christian Grothoff
- */
-#ifndef TALER_EXCHANGE_HTTPD_ADMIN_H
-#define TALER_EXCHANGE_HTTPD_ADMIN_H
-
-#include <microhttpd.h>
-#include "taler-exchange-httpd.h"
-
-/**
- * Handle a "/admin/add/incoming" request. Parses the
- * given "reserve_pub", "amount", "transaction" and "h_wire"
- * details and adds the respective transaction to the database.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-#endif