phase 1 of #6067: update exchange HTTPD to new API style

This commit is contained in:
Christian Grothoff 2020-02-26 17:00:41 +01:00
parent 30b24448c8
commit fb9324338d
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
32 changed files with 869 additions and 727 deletions

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015, 2016, 2019 Taler Systems SA
Copyright (C) 2014-2020 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
@ -147,6 +147,92 @@ static unsigned long long req_count;
static unsigned long long req_max;
/**
* Handle a "/coins/$COIN_PUB/$OP" POST request. Parses the "coin_pub"
* EdDSA key of the coin and demultiplexes based on $OP.
*
* @param rh context of the handler
* @param connection the MHD connection to handle
* @param root uploaded JSON data
* @param args array of additional options (first must be the
* reserve public key, the second one should be "withdraw")
* @return MHD result code
*/
static int
handle_post_coins (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
const json_t *root,
const char *const args[2])
{
struct TALER_CoinSpendPublicKeyP coin_pub;
static const struct
{
/**
* Name of the operation (args[1])
*/
const char *op;
/**
* Function to call to perform the operation.
*
* @param connection the MHD connection to handle
* @param coin_pub the public key of the coin
* @param root uploaded JSON data
* @return MHD result code
*///
int
(*handler)(struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root);
} h[] = {
{
.op = "deposit",
.handler = &TEH_DEPOSIT_handler_deposit
},
{
.op = "melt",
.handler = &TEH_REFRESH_handler_melt
},
{
.op = "recoup",
.handler = &TEH_RECOUP_handler_recoup
},
{
.op = "refund",
.handler = &TEH_REFUND_handler_refund
},
{
.op = NULL,
.handler = NULL
},
};
(void) rh;
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
&coin_pub,
sizeof (coin_pub)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_COINS_INVALID_COIN_PUB,
"coin public key malformed");
}
for (unsigned int i = 0; NULL != h[i].op; i++)
if (0 == strcmp (h[i].op,
args[1]))
return h[i].handler (connection,
&coin_pub,
root);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_OPERATION_INVALID,
"requested operation on coin unknown");
}
/**
* Function called whenever MHD is done with a request. If the
* request was a POST, we may have stored a `struct Buffer *` in the
@ -205,6 +291,120 @@ is_valid_correlation_id (const char *correlation_id)
}
/**
* We found @a rh responsible for handling a request. Parse the
* @a upload_data (if applicable) and the @a url and call the
* handler.
*
* @param rh request handler to call
* @param connection connection being handled
* @param url rest of the URL to parse
* @param inner_cls closure for the handler, if needed
* @param upload_data upload data to parse (if available)
* @param upload_data_size[in,out] number of bytes in @a upload_data
* @return MHD result code
*/
static int
proceed_with_handler (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
const char *url,
void **inner_cls,
const char *upload_data,
size_t *upload_data_size)
{
const char *args[rh->nargs + 1];
size_t ulen = strlen (url) + 1;
json_t *root;
int ret;
/* We do check for "ulen" here, because we'll later stack-allocate a buffer
of that size and don't want to enable malicious clients to cause us
huge stack allocations. */
if (ulen > 512)
{
/* 512 is simply "big enough", as it is bigger than "6 * 54",
which is the longest URL format we ever get (for
/deposits/). The value should be adjusted if we ever define protocol
endpoints with plausibly longer inputs. */
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_URI_TOO_LONG,
TALER_EC_URI_TOO_LONG,
"The URI given is too long");
}
/* All POST endpoints come with a body in JSON format. So we parse
the JSON here. */
if (0 == strcasecmp (rh->method,
MHD_HTTP_METHOD_POST))
{
int res;
res = TALER_MHD_parse_post_json (connection,
inner_cls,
upload_data,
upload_data_size,
&root);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == root) )
return MHD_YES;
}
{
char d[ulen];
/* Parse command-line arguments, if applicable */
if (rh->nargs > 0)
{
unsigned int i;
/* make a copy of 'url' because 'strtok()' will modify */
memcpy (d,
url,
ulen);
i = 0;
args[i++] = strtok (d, "/");
while ( (NULL != args[i - 1]) &&
(i < rh->nargs) )
args[i++] = strtok (NULL, "/");
/* make sure above loop ran nicely until completion, and also
that there is no excess data in 'd' afterwards */
if ( (i != rh->nargs) ||
(NULL == args[i - 1]) ||
(NULL != strtok (NULL, "/")) )
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_WRONG_NUMBER_OF_SEGMENTS,
"Number of segments does not match");
}
}
/* just to be safe(r), we always terminate the array with a NULL
(which handlers should not read, but at least if they do, they'll
crash pretty reliably... */
args[rh->nargs] = NULL;
/* Above logic ensures that 'root' is exactly non-NULL for POST operations */
if (NULL != root)
ret = rh->handler.post (rh,
connection,
root,
args);
else /* and we only have "POST" or "GET" in the API for at this point
(OPTIONS/HEAD are taken care of earlier) */
ret = rh->handler.get (rh,
connection,
args);
}
if (NULL != root)
json_decref (root);
return ret;
}
/**
* Handle incoming HTTP request.
*
@ -229,134 +429,111 @@ handle_mhd_request (void *cls,
void **con_cls)
{
static struct TEH_RequestHandler handlers[] = {
/* Landing page, tell humans to go away. */
{ "/", MHD_HTTP_METHOD_GET, "text/plain",
"Hello, I'm the Taler exchange. This HTTP server is not for humans.\n", 0,
&TEH_MHD_handler_static_response, MHD_HTTP_OK },
/* /robots.txt: disallow everything */
{ "/robots.txt", MHD_HTTP_METHOD_GET, "text/plain",
"User-agent: *\nDisallow: /\n", 0,
&TEH_MHD_handler_static_response, MHD_HTTP_OK },
{
.url = "robots.txt",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_MHD_handler_static_response,
.mime_type = "text/plain",
.data = "User-agent: *\nDisallow: /\n",
.response_code = MHD_HTTP_OK
},
/* Landing page, tell humans to go away. */
{
.url = "",
.method = MHD_HTTP_METHOD_GET,
.handler.get = TEH_MHD_handler_static_response,
.mime_type = "text/plain",
.data =
"Hello, I'm the Taler exchange. This HTTP server is not for humans.\n",
.response_code = 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
here. */
{ "/agpl", MHD_HTTP_METHOD_GET, "text/plain",
NULL, 0,
&TEH_MHD_handler_agpl_redirect, MHD_HTTP_FOUND },
{
.url = "agpl",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_MHD_handler_agpl_redirect
},
/* Terms of service */
{ "/terms", MHD_HTTP_METHOD_GET, NULL,
NULL, 0,
&TEH_handler_terms, MHD_HTTP_OK },
{
.url = "terms",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_handler_terms
},
/* Privacy policy */
{ "/privacy", MHD_HTTP_METHOD_GET, NULL,
NULL, 0,
&TEH_handler_privacy, MHD_HTTP_OK },
{
.url = "privacy",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_handler_privacy
},
/* Return key material and fundamental properties for this exchange */
{ "/keys", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0,
&TEH_KS_handler_keys, MHD_HTTP_OK },
{ "/keys", NULL, "text/plain",
"Only GET is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{
.url = "/keys",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_KS_handler_keys,
},
/* Requests for wiring information */
{ "/wire", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0,
&TEH_WIRE_handler_wire, MHD_HTTP_OK },
{ "/wire", NULL, "text/plain",
"Only GET is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{
.url = "wire",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_WIRE_handler_wire
},
/* Withdrawing coins / interaction with reserves */
{ "/reserve/status", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0,
&TEH_RESERVE_handler_reserve_status, MHD_HTTP_OK },
{ "/reserve/status", NULL, "text/plain",
"Only GET is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/reserve/withdraw", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TEH_RESERVE_handler_reserve_withdraw, MHD_HTTP_OK },
{ "/reserve/withdraw", NULL, "text/plain",
"Only POST is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
/* Depositing coins */
{ "/deposit", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TEH_DEPOSIT_handler_deposit, MHD_HTTP_OK },
{ "/deposit", NULL, "text/plain",
"Only POST is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
/* Refunding coins */
{ "/refund", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TEH_REFUND_handler_refund, MHD_HTTP_OK },
{ "/refund", NULL, "text/plain",
"Only POST is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
/* Dealing with change */
{ "/refresh/melt", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TEH_REFRESH_handler_refresh_melt, MHD_HTTP_OK },
{ "/refresh/melt", NULL, "text/plain",
"Only POST is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/reveal", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TEH_REFRESH_handler_refresh_reveal, MHD_HTTP_OK },
{ "/refresh/reveal", NULL, "text/plain",
"Only POST is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/reveal", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TEH_REFRESH_handler_refresh_reveal, MHD_HTTP_OK },
{ "/refresh/reveal", NULL, "text/plain",
"Only POST is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/link", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0,
&TEH_REFRESH_handler_refresh_link, MHD_HTTP_OK },
{ "/refresh/link", NULL, "text/plain",
"Only GET is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/track/transfer", MHD_HTTP_METHOD_GET, "application/json",
NULL, 0,
&TEH_TRACKING_handler_track_transfer, MHD_HTTP_OK },
{ "/track/transfer", NULL, "text/plain",
"Only GET is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/track/transaction", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TEH_TRACKING_handler_track_transaction, MHD_HTTP_OK },
{ "/track/transaction", NULL, "text/plain",
"Only POST is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/recoup", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TEH_RECOUP_handler_recoup, MHD_HTTP_OK },
{ "/refresh/link", NULL, "text/plain",
"Only GET is allowed", 0,
&TEH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ NULL, NULL, NULL, NULL, 0, NULL, 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
{
.url = "reserves",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_RESERVE_handler_reserve_status,
.nargs = 1
},
{
.url = "reserves",
.method = MHD_HTTP_METHOD_POST,
.handler.post = &TEH_RESERVE_handler_reserve_withdraw,
.nargs = 2
},
/* coins */
{
.url = "coins",
.method = MHD_HTTP_METHOD_POST,
.handler.post = &handle_post_coins,
.nargs = 2
},
{
.url = "coins",
.method = MHD_HTTP_METHOD_GET,
.handler.get = TEH_REFRESH_handler_link,
.nargs = 2,
},
/* refreshing */
{
.url = "refreshes",
.method = MHD_HTTP_METHOD_POST,
.handler.post = &TEH_REFRESH_handler_reveal,
.nargs = 2
},
/* tracking transfers */
{
.url = "transfers",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_TRACKING_handler_track_transfer,
.nargs = 1
},
/* tracking deposits */
{
.url = "deposits",
.method = MHD_HTTP_METHOD_GET,
.handler.get = &TEH_TRACKING_handler_track_transaction,
.nargs = 4
},
/* mark end of list */
{
.url = NULL
}
};
struct ExchangeHttpRequestClosure *ecls = *con_cls;
int ret;
void **inner_cls;
struct GNUNET_AsyncScopeSave old_scope;
const char *correlation_id = NULL;
@ -367,7 +544,8 @@ handle_mhd_request (void *cls,
{
unsigned long long cnt;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Handling new request\n");
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Handling new request\n");
cnt = __sync_add_and_fetch (&req_count, 1LLU);
if (req_max == cnt)
{
@ -395,7 +573,8 @@ handle_mhd_request (void *cls,
}
inner_cls = &ecls->opaque_post_parsing_context;
GNUNET_async_scope_enter (&ecls->async_scope_id, &old_scope);
GNUNET_async_scope_enter (&ecls->async_scope_id,
&old_scope);
if (NULL != correlation_id)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Handling request (%s) for URL '%s', correlation_id=%s\n",
@ -410,40 +589,70 @@ handle_mhd_request (void *cls,
/* on repeated requests, check our cache first */
if (NULL != ecls->rh)
{
ret = ecls->rh->handler (ecls->rh,
int ret;
ret = proceed_with_handler (ecls->rh,
connection,
url,
inner_cls,
upload_data,
upload_data_size);
GNUNET_async_scope_restore (&old_scope);
return ret;
}
if (0 == strcasecmp (method,
MHD_HTTP_METHOD_HEAD))
method = MHD_HTTP_METHOD_GET; /* treat HEAD as GET here, MHD will do the rest */
/* parse first part of URL */
{
int found = GNUNET_NO;
size_t tok_size;
const char *tok;
const char *rest;
if ('\0' == url[0])
/* strange, should start with '/', treat as just "/" */
url = "/";
tok = url + 1;
rest = strchr (tok, '/');
if (NULL == rest)
{
tok_size = 0;
}
else
{
tok_size = rest - tok;
rest++; /* skip over '/' */
}
for (unsigned int i = 0; NULL != handlers[i].url; i++)
{
struct TEH_RequestHandler *rh = &handlers[i];
if (0 != strcmp (url, rh->url))
if (0 != strncmp (tok,
rh->url,
tok_size))
continue;
found = GNUNET_YES;
/* The URL is a match! What we now do depends on the method. */
if (0 == strcasecmp (method, MHD_HTTP_METHOD_OPTIONS))
{
GNUNET_async_scope_restore (&old_scope);
return TALER_MHD_reply_cors_preflight (connection);
}
if ( (NULL == rh->method) ||
(0 == strcasecmp (method,
rh->method)) )
GNUNET_assert (NULL != rh->method);
if (0 == strcasecmp (method,
rh->method))
{
int ret;
/* cache to avoid the loop next time */
ecls->rh = rh;
/* run handler */
ret = rh->handler (rh,
ret = proceed_with_handler (rh,
connection,
url,
inner_cls,
upload_data,
upload_data_size);
@ -451,15 +660,30 @@ handle_mhd_request (void *cls,
return ret;
}
}
if (GNUNET_YES == found)
{
/* we found a matching address, but the method is wrong */
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_METHOD_NOT_ALLOWED,
TALER_EC_METHOD_INVALID,
"The HTTP method used is invalid for this URL");
}
}
/* No handler matches, generate not found */
ret = TEH_MHD_handler_static_response (&h404,
connection,
inner_cls,
upload_data,
upload_data_size);
{
int ret;
ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_ENDPOINT_UNKNOWN,
"No handler found for the given URL");
GNUNET_async_scope_restore (&old_scope);
return ret;
}
}
/**

View File

@ -24,6 +24,8 @@
#define TALER_EXCHANGE_HTTPD_H
#include <microhttpd.h>
#include "taler_json_lib.h"
#include "taler_crypto_lib.h"
/**
@ -65,51 +67,77 @@ struct TEH_RequestHandler
{
/**
* URL the handler is for.
* URL the handler is for (first part only).
*/
const char *url;
/**
* Method the handler is for, NULL for "all".
* Method the handler is for.
*/
const char *method;
/**
* Callbacks for handling of the request. Which one is used
* depends on @e method.
*/
union
{
/**
* Function to call to handle a GET requests (and those
* with @e method NULL).
*
* @param rh this struct
* @param mime_type the @e mime_type for the reply (hint, can be NULL)
* @param connection the MHD connection to handle
* @param args array of arguments, needs to be of length @e args_expected
* @return MHD result code
*/
int (*get)(const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
const char *const args[]);
/**
* Function to call to handle a POST request.
*
* @param rh this struct
* @param mime_type the @e mime_type for the reply (hint, can be NULL)
* @param connection the MHD connection to handle
* @param json uploaded JSON data
* @param args array of arguments, needs to be of length @e args_expected
* @return MHD result code
*/
int (*post)(const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
const json_t *root,
const char *const args[]);
} handler;
/**
* Number of arguments this handler expects in the @a args array.
*/
unsigned int nargs;
/**
* Mime type to use in reply (hint, can be NULL).
*/
const char *mime_type;
/**
* Raw data for the @e handler
* Raw data for the @e handler, can be NULL for none provided.
*/
const void *data;
/**
* Number of bytes in @e data, 0 for 0-terminated.
* Number of bytes in @e data, 0 for data is 0-terminated (!).
*/
size_t data_size;
/**
* Function to call to handle the request.
*
* @param rh this struct
* @param mime_type the @e mime_type for the reply (hint, can be NULL)
* @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
* Default response code. 0 for none provided.
*/
int (*handler)(struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
/**
* Default response code.
*/
int response_code;
unsigned int response_code;
};

View File

@ -381,27 +381,22 @@ check_timestamp_current (struct GNUNET_TIME_Absolute ts)
/**
* Handle a "/deposit" request. Parses the JSON, and, if successful,
* passes the JSON data to #verify_and_execute_deposit() to further
* check the details of the operation specified. If everything checks
* Handle a "/coins/$COIN_PUB/deposit" request. Parses the JSON, and, if
* successful, passes the JSON data to #verify_and_execute_deposit() to
* further check the details of the operation specified. If everything checks
* out, this will ultimately lead to the "/deposit" being executed, or
* rejected.
*
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @return MHD result code
*/
int
TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
TEH_DEPOSIT_handler_deposit (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root)
{
json_t *json;
int res;
json_t *wire;
enum TALER_ErrorCode ec;
@ -415,7 +410,6 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
&deposit.coin.denom_pub_hash),
TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig),
GNUNET_JSON_spec_fixed_auto ("coin_pub", &deposit.coin.coin_pub),
GNUNET_JSON_spec_fixed_auto ("merchant_pub", &deposit.merchant_pub),
GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &deposit.h_contract_terms),
GNUNET_JSON_spec_fixed_auto ("h_wire", &deposit.h_wire),
@ -428,27 +422,13 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
GNUNET_JSON_spec_end ()
};
(void) rh;
res = TALER_MHD_parse_post_json (connection,
connection_cls,
upload_data,
upload_data_size,
&json);
if (GNUNET_SYSERR == res)
{
GNUNET_break (0);
return MHD_NO;
}
if ( (GNUNET_NO == res) ||
(NULL == json) )
return MHD_YES;
memset (&deposit,
0,
sizeof (deposit));
deposit.coin.coin_pub = *coin_pub;
res = TALER_MHD_parse_json_data (connection,
json,
root,
spec);
json_decref (json);
if (GNUNET_SYSERR == res)
{
GNUNET_break (0);

View File

@ -29,22 +29,21 @@
/**
* Handle a "/deposit" request. Parses the JSON, and, if successful,
* checks the signatures. If everything checks out, this will
* ultimately lead to the "/deposit" being executed, or rejected.
* Handle a "/coins/$COIN_PUB/deposit" request. Parses the JSON, and, if
* successful, passes the JSON data to #verify_and_execute_deposit() to
* further check the details of the operation specified. If everything checks
* out, this will ultimately lead to the "/deposit" being executed, or
* rejected.
*
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @return MHD result code
*/
int
TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
TEH_DEPOSIT_handler_deposit (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root);
#endif

View File

@ -2381,17 +2381,13 @@ krd_search_comparator (const void *key,
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
TEH_KS_handler_keys (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[])
{
int ret;
const char *have_cherrypick;
@ -2400,9 +2396,8 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
struct GNUNET_TIME_Absolute now;
const struct KeysResponseData *krd;
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
(void) rh;
(void) args;
have_cherrypick = MHD_lookup_connection_value (connection,
MHD_GET_ARGUMENT_KIND,
"last_issue_date");
@ -2493,7 +2488,7 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
"no key response found");
}
ret = MHD_queue_response (connection,
rh->response_code,
MHD_HTTP_OK,
(MHD_YES == TALER_MHD_can_compress (connection))
? krd->response_compressed
: krd->response_uncompressed);

View File

@ -188,17 +188,13 @@ TEH_KS_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
TEH_KS_handler_keys (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[]);
#endif

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014 Taler Systems SA
Copyright (C) 2014-2020 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
@ -39,27 +39,23 @@
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_MHD_handler_static_response (struct TEH_RequestHandler *rh,
TEH_MHD_handler_static_response (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[])
{
struct MHD_Response *response;
int ret;
size_t dlen;
(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,
(void) args;
dlen = (0 == rh->data_size)
? strlen ((const char *) rh->data)
: rh->data_size;
response = MHD_create_response_from_buffer (dlen,
(void *) rh->data,
MHD_RESPMEM_PERSISTENT);
if (NULL == response)
@ -86,22 +82,16 @@ TEH_MHD_handler_static_response (struct TEH_RequestHandler *rh,
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_MHD_handler_agpl_redirect (struct TEH_RequestHandler *rh,
TEH_MHD_handler_agpl_redirect (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[])
{
(void) rh;
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
(void) args;
return TALER_MHD_reply_agpl (connection,
"http://www.git.taler.net/?p=exchange.git");
}
@ -113,21 +103,15 @@ TEH_MHD_handler_agpl_redirect (struct TEH_RequestHandler *rh,
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_MHD_handler_send_json_pack_error (struct TEH_RequestHandler *rh,
TEH_MHD_handler_send_json_pack_error (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[])
{
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
(void) args;
return TALER_MHD_reply_with_error (connection,
rh->response_code,
TALER_EC_METHOD_INVALID,

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014 Taler Systems SA
Copyright (C) 2014-2020 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
@ -34,17 +34,13 @@
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_MHD_handler_static_response (struct TEH_RequestHandler *rh,
TEH_MHD_handler_static_response (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[]);
/**
@ -53,40 +49,13 @@ TEH_MHD_handler_static_response (struct TEH_RequestHandler *rh,
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_MHD_handler_agpl_redirect (struct TEH_RequestHandler *rh,
TEH_MHD_handler_agpl_redirect (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
/**
* Function to call to handle the request by building a JSON
* reply from varargs.
*
* @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 response_code HTTP response code to use
* @param do_cache can the response be cached? (0: no, 1: yes)
* @param fmt format string for pack
* @param ... varargs
* @return MHD result code
*/
int
TEH_MHD_helper_send_json_pack (struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void *connection_cls,
int response_code,
int do_cache,
const char *fmt,
...);
const char *const args[]);
/**
@ -95,17 +64,13 @@ TEH_MHD_helper_send_json_pack (struct TEH_RequestHandler *rh,
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_MHD_handler_send_json_pack_error (struct TEH_RequestHandler *rh,
TEH_MHD_handler_send_json_pack_error (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[]);
#endif

View File

@ -562,27 +562,21 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
/**
* Handle a "/recoup" request. Parses the JSON, and, if successful,
* passes the JSON data to #verify_and_execute_recoup() to
* further check the details of the operation specified. If
* everything checks out, this will ultimately lead to the "/refund"
* being executed, or rejected.
* Handle a "/coins/$COIN_PUB/recoup" request. Parses the JSON, and, if
* successful, passes the JSON data to #verify_and_execute_recoup() to further
* check the details of the operation specified. If everything checks out,
* this will ultimately lead to the refund being executed, or rejected.
*
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @return MHD result code
*/
int
TEH_RECOUP_handler_recoup (struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
TEH_RECOUP_handler_recoup (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root)
{
json_t *json;
int res;
struct TALER_CoinPublicInfo coin;
struct TALER_DenominationBlindingKeyP coin_bks;
@ -593,8 +587,6 @@ TEH_RECOUP_handler_recoup (struct TEH_RequestHandler *rh,
&coin.denom_pub_hash),
TALER_JSON_spec_denomination_signature ("denom_sig",
&coin.denom_sig),
GNUNET_JSON_spec_fixed_auto ("coin_pub",
&coin.coin_pub),
GNUNET_JSON_spec_fixed_auto ("coin_blind_key_secret",
&coin_bks),
GNUNET_JSON_spec_fixed_auto ("coin_sig",
@ -605,20 +597,10 @@ TEH_RECOUP_handler_recoup (struct TEH_RequestHandler *rh,
GNUNET_JSON_spec_end ()
};
(void) rh;
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;
coin.coin_pub = *coin_pub;
res = TALER_MHD_parse_json_data (connection,
json,
root,
spec);
json_decref (json);
if (GNUNET_SYSERR == res)
return MHD_NO; /* hard failure */
if (GNUNET_NO == res)

View File

@ -27,25 +27,20 @@
/**
* Handle a "/recoup" request. Parses the JSON, and, if successful,
* passes the JSON data to #verify_and_execute_recoup() to
* further check the details of the operation specified. If
* everything checks out, this will ultimately lead to the "/refund"
* being executed, or rejected.
* Handle a "/coins/$COIN_PUB/recoup" request. Parses the JSON, and, if
* successful, passes the JSON data to #verify_and_execute_recoup() to further
* check the details of the operation specified. If everything checks out,
* this will ultimately lead to the refund being executed, or rejected.
*
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @return MHD result code
*/
int
TEH_RECOUP_handler_recoup (struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
TEH_RECOUP_handler_recoup (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root);
#endif

View File

@ -172,43 +172,37 @@ refresh_link_transaction (void *cls,
/**
* Handle a "/refresh/link" request. Note that for "/refresh/link"
* we do use a simple HTTP GET, and a HTTP POST!
* Handle a "/coins/$COIN_PUB/link" request.
*
* @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
* @param args array of additional options (length: 2, first is the coin_pub, second must be "link")
* @return MHD result code
*/
int
TEH_REFRESH_handler_refresh_link (struct TEH_RequestHandler *rh,
TEH_REFRESH_handler_link (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[2])
{
int mhd_ret;
int res;
struct HTD_Context ctx;
int mhd_ret;
(void) rh;
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
memset (&ctx,
0,
sizeof (ctx));
res = TALER_MHD_parse_request_arg_data (connection,
"coin_pub",
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
&ctx.coin_pub,
sizeof (struct
TALER_CoinSpendPublicKeyP));
if (GNUNET_SYSERR == res)
return MHD_NO;
if (GNUNET_OK != res)
return MHD_YES;
sizeof (ctx.coin_pub)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_COINS_INVALID_COIN_PUB,
"coin public key malformed");
}
ctx.mlist = json_array ();
if (GNUNET_OK !=
TEH_DB_run_transaction (connection,

View File

@ -29,21 +29,17 @@
/**
* Handle a "/refresh/link" request
* Handle a "/coins/$COIN_PUB/link" request.
*
* @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
* @param args array of additional options (length: 2, first is the coin_pub, second must be "link")
* @return MHD result code
*/
int
TEH_REFRESH_handler_refresh_link (struct TEH_RequestHandler *rh,
TEH_REFRESH_handler_link (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[2]);
#endif

View File

@ -577,31 +577,24 @@ check_for_denomination_key (struct MHD_Connection *connection,
/**
* Handle a "/refresh/melt" request. Parses the request into the JSON
* components and then hands things of to #check_for_denomination_key()
* to validate the melted coins, the signature and execute the melt
* using handle_refresh_melt().
*
* @param rh context of the handler
* Handle a "/coins/$COIN_PUB/melt" request. Parses the request into the JSON
* components and then hands things of to #check_for_denomination_key() to
* validate the melted coins, the signature and execute the melt using
* handle_refresh_melt().
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @return MHD result code
*/
int
TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
TEH_REFRESH_handler_melt (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root)
{
json_t *root;
struct RefreshMeltContext rmc;
int res;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("coin_pub",
&rmc.refresh_session.coin.coin_pub),
TALER_JSON_spec_denomination_signature ("denom_sig",
&rmc.refresh_session.coin.denom_sig),
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
@ -615,25 +608,13 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
GNUNET_JSON_spec_end ()
};
(void) rh;
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;
memset (&rmc,
0,
sizeof (rmc));
rmc.refresh_session.coin.coin_pub = *coin_pub;
res = TALER_MHD_parse_json_data (connection,
root,
spec);
json_decref (root);
if (GNUNET_OK != res)
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;

View File

@ -29,25 +29,20 @@
/**
* Handle a "/refresh/melt" request after the first parsing has
* happened. We now need to validate the coins being melted and the
* session signature and then hand things of to execute the melt
* operation. This function parses the JSON arrays and then passes
* processing on to #refresh_melt_transaction().
*
* @param rh context of the handler
* Handle a "/coins/$COIN_PUB/melt" request. Parses the request into the JSON
* components and then hands things of to #check_for_denomination_key() to
* validate the melted coins, the signature and execute the melt using
* handle_refresh_melt().
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @return MHD result code
*/
int
TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
TEH_REFRESH_handler_melt (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root);
#endif

View File

@ -884,30 +884,27 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
/**
* Handle a "/refresh/reveal" request. This time, the client reveals the
* Handle a "/refreshes/$RCH/reveal" request. This time, the client reveals the
* private transfer keys except for the cut-and-choose value returned from
* "/refresh/melt". This function parses the revealed keys and secrets and
* "/coins/$COIN_PUB/melt". This function parses the revealed keys and secrets and
* ultimately passes everything to #resolve_refresh_reveal_denominations()
* which will verify that the revealed information is valid then runs the
* transaction in #refresh_reveal_transaction() and finally returns the signed
* refreshed coins.
*
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @param args array of additional options (length: 2, session hash and the string "reveal")
* @return MHD result code
*/
int
TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
TEH_REFRESH_handler_reveal (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const json_t *root,
const char *const args[2])
{
int res;
json_t *root;
json_t *coin_evs;
json_t *transfer_privs;
json_t *link_sigs;
@ -924,24 +921,34 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
};
(void) rh;
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;
memset (&rctx,
0,
sizeof (rctx));
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
&rctx.rc,
sizeof (rctx.rc)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_REFRESHES_INVALID_RCH,
"refresh commitment hash malformed");
}
if (0 != strcmp (args[1],
"reveal"))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_OPERATION_INVALID,
"expected 'reveal' operation");
}
res = TALER_MHD_parse_json_data (connection,
root,
spec);
json_decref (root);
if (GNUNET_OK != res)
{
GNUNET_break_op (0);

View File

@ -29,26 +29,25 @@
/**
* Handle a "/refresh/reveal" request. This time, the client reveals the
* Handle a "/refreshes/$RCH/reveal" request. This time, the client reveals the
* private transfer keys except for the cut-and-choose value returned from
* "/refresh/melt". This function parses the revealed keys and secrets and
* "/coins/$COIN_PUB/melt". This function parses the revealed keys and secrets and
* ultimately passes everything to #resolve_refresh_reveal_denominations()
* which will verify that the revealed information is valid then runs the
* transaction in #refresh_reveal_transaction() and finally returns the signed
* refreshed coins.
*
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @param args array of additional options (length: 2, session hash and the string "reveal")
* @return MHD result code
*/
int
TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
TEH_REFRESH_handler_reveal (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const json_t *root,
const char *const args[2]);
#endif

View File

@ -532,27 +532,21 @@ verify_and_execute_refund (struct MHD_Connection *connection,
/**
* Handle a "/refund" request. Parses the JSON, and, if successful,
* passes the JSON data to #verify_and_execute_refund() to
* further check the details of the operation specified. If
* everything checks out, this will ultimately lead to the "/refund"
* being executed, or rejected.
* Handle a "/coins/$COIN_PUB/refund" request. Parses the JSON, and, if
* successful, passes the JSON data to #verify_and_execute_refund() to further
* check the details of the operation specified. If everything checks out,
* this will ultimately lead to the refund being executed, or rejected.
*
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @return MHD result code
*/
int
TEH_REFUND_handler_refund (struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
TEH_REFUND_handler_refund (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root)
{
json_t *json;
int res;
struct TALER_EXCHANGEDB_Refund refund;
struct GNUNET_JSON_Specification spec[] = {
@ -560,7 +554,6 @@ TEH_REFUND_handler_refund (struct TEH_RequestHandler *rh,
TALER_JSON_spec_amount ("refund_fee", &refund.details.refund_fee),
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
&refund.details.h_contract_terms),
GNUNET_JSON_spec_fixed_auto ("coin_pub", &refund.coin.coin_pub),
GNUNET_JSON_spec_fixed_auto ("merchant_pub", &refund.details.merchant_pub),
GNUNET_JSON_spec_uint64 ("rtransaction_id",
&refund.details.rtransaction_id),
@ -568,20 +561,10 @@ TEH_REFUND_handler_refund (struct TEH_RequestHandler *rh,
GNUNET_JSON_spec_end ()
};
(void) rh;
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;
refund.coin.coin_pub = *coin_pub;
res = TALER_MHD_parse_json_data (connection,
json,
root,
spec);
json_decref (json);
if (GNUNET_SYSERR == res)
return MHD_NO; /* hard failure */
if (GNUNET_NO == res)

View File

@ -29,24 +29,19 @@
/**
* Handle a "/refund" request. Parses the JSON, and, if successful,
* passes the JSON data to #verify_and_execute_refund() to
* further check the details of the operation specified. If
* everything checks out, this will ultimately lead to the "/refund"
* being executed, or rejected.
* Handle a "/coins/$COIN_PUB/refund" request. Parses the JSON, and, if
* successful, passes the JSON data to #verify_and_execute_refund() to further
* check the details of the operation specified. If everything checks out,
* this will ultimately lead to the refund being executed, or rejected.
*
* @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
* @param coin_pub public key of the coin
* @param root uploaded JSON data
* @return MHD result code
*/
int
TEH_REFUND_handler_refund (struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
TEH_REFUND_handler_refund (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root);
#endif

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014-2017 Taler Systems SA
Copyright (C) 2014-2020 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
@ -15,7 +15,7 @@
*/
/**
* @file taler-exchange-httpd_reserve_status.c
* @brief Handle /reserve/status requests
* @brief Handle /reserves/$RESERVE_PUB GET requests
* @author Florian Dold
* @author Benedikt Mueller
* @author Christian Grothoff
@ -114,42 +114,37 @@ reserve_status_transaction (void *cls,
/**
* Handle a "/reserve/status" request. Parses the
* given "reserve_pub" argument (which should contain the
* Handle a GET "/reserves/" request. Parses the
* given "reserve_pub" in @a args (which should contain the
* EdDSA public key of a reserve) and then respond with the
* status of the reserve.
*
* @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
* @param args array of additional options (length: 1, just the reserve_pub)
* @return MHD result code
*/
int
TEH_RESERVE_handler_reserve_status (struct TEH_RequestHandler *rh,
TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[1])
{
struct ReserveStatusContext rsc;
int res;
int mhd_ret;
(void) rh;
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
res = TALER_MHD_parse_request_arg_data (connection,
"reserve_pub",
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
&rsc.reserve_pub,
sizeof (struct
TALER_ReservePublicKeyP));
if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */
if (GNUNET_NO == res)
return MHD_YES; /* parse error */
sizeof (rsc.reserve_pub)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_RESERVES_INVALID_RESERVE_PUB,
"reserve public key malformed");
}
rsc.rh = NULL;
if (GNUNET_OK !=
TEH_DB_run_transaction (connection,

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014-2017 Taler Systems SA
Copyright (C) 2014-2020 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
@ -15,7 +15,7 @@
*/
/**
* @file taler-exchange-httpd_reserve_status.h
* @brief Handle /reserve/status requests
* @brief Handle /reserves/$RESERVE_PUB GET requests
* @author Florian Dold
* @author Benedikt Mueller
* @author Christian Grothoff
@ -26,24 +26,21 @@
#include <microhttpd.h>
#include "taler-exchange-httpd.h"
/**
* Handle a "/reserve/status" request. Parses the
* given "reserve_pub" argument (which should contain the
* Handle a GET "/reserves/" request. Parses the
* given "reserve_pub" in @a args (which should contain the
* EdDSA public key of a reserve) and then respond with the
* status of the reserve.
*
* @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
* @param args array of additional options (length: 1, just the reserve_pub)
* @return MHD result code
*/
int
TEH_RESERVE_handler_reserve_status (struct TEH_RequestHandler *rh,
TEH_RESERVE_handler_reserve_status (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[1]);
#endif

View File

@ -335,30 +335,27 @@ withdraw_transaction (void *cls,
/**
* Handle a "/reserve/withdraw" request. Parses the "reserve_pub"
* EdDSA key of the reserve and the requested "denom_pub" which
* specifies the key/value of the coin to be withdrawn, and checks
* that the signature "reserve_sig" makes this a valid withdrawal
* request from the specified reserve. If so, the envelope
* with the blinded coin "coin_ev" is passed down to execute the
* withdrawl operation.
* Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the
* "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which
* specifies the key/value of the coin to be withdrawn, and checks that the
* signature "reserve_sig" makes this a valid withdrawal request from the
* specified reserve. If so, the envelope with the blinded coin "coin_ev" is
* passed down to execute the withdrawl operation.
*
* @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
* @param root uploaded JSON data
* @param args array of additional options (first must be the
* reserve public key, the second one should be "withdraw")
* @return MHD result code
*/
int
TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const json_t *root,
const char *const args[2])
{
struct WithdrawContext wc;
json_t *root;
int res;
int mhd_ret;
unsigned int hc;
@ -369,8 +366,6 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
GNUNET_JSON_spec_varsize ("coin_ev",
(void **) &wc.blinded_msg,
&wc.blinded_msg_len),
GNUNET_JSON_spec_fixed_auto ("reserve_pub",
&wc.wsrd.reserve_pub),
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
&wc.signature),
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
@ -379,19 +374,22 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
};
(void) rh;
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;
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
&wc.wsrd.reserve_pub,
sizeof (wc.wsrd.reserve_pub)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_RESERVES_INVALID_RESERVE_PUB,
"reserve public key malformed");
}
res = TALER_MHD_parse_json_data (connection,
root,
spec);
json_decref (root);
if (GNUNET_OK != res)
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
wc.key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014-2017 Taler Systems SA
Copyright (C) 2014-2020 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,26 +28,24 @@
/**
* Handle a "/reserve/withdraw" request. Parses the "reserve_pub"
* EdDSA key of the reserve and the requested "denom_pub" which
* specifies the key/value of the coin to be withdrawn, and checks
* that the signature "reserve_sig" makes this a valid withdrawl
* request from the specified reserve. If so, the envelope
* with the blinded coin "coin_ev" is passed down to execute the
* withdrawl operation.
* Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the
* "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which
* specifies the key/value of the coin to be withdrawn, and checks that the
* signature "reserve_sig" makes this a valid withdrawl request from the
* specified reserve. If so, the envelope with the blinded coin "coin_ev" is
* passed down to execute the withdrawl operation.
*
* @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
* @param root uploaded JSON data
* @param args array of additional options (first must be the
* reserve public key, the second one should be "withdraw")
* @return MHD result code
*/
int
TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
TEH_RESERVE_handler_reserve_withdraw (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const json_t *root,
const char *const args[2]);
#endif

View File

@ -43,22 +43,16 @@ static struct TALER_MHD_Legal *pp;
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_handler_terms (struct TEH_RequestHandler *rh,
TEH_handler_terms (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[])
{
(void) rh;
(void) upload_data;
(void) upload_data_size;
(void) connection_cls;
(void) args;
return TALER_MHD_reply_legal (connection,
tos);
}
@ -69,22 +63,16 @@ TEH_handler_terms (struct TEH_RequestHandler *rh,
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_handler_privacy (struct TEH_RequestHandler *rh,
TEH_handler_privacy (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[])
{
(void) rh;
(void) upload_data;
(void) upload_data_size;
(void) connection_cls;
(void) args;
return TALER_MHD_reply_legal (connection,
pp);
}

View File

@ -34,34 +34,27 @@
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_handler_terms (struct TEH_RequestHandler *rh,
TEH_handler_terms (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[]);
/**
* Handle a "/privacy" request.
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_handler_privacy (struct TEH_RequestHandler *rh,
TEH_handler_privacy (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[]);
/**

View File

@ -336,62 +336,86 @@ check_and_handle_track_transaction_request (struct MHD_Connection *connection,
/**
* Handle a "/track/transaction" request.
* Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB"
* request.
*
* @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
* @param args array of additional options (length: 4, contains:
* h_wire, merchant_pub, h_contract_terms and coin_pub)
* @return MHD result code
*/
int
TEH_TRACKING_handler_track_transaction (struct TEH_RequestHandler *rh,
TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[4])
{
int res;
json_t *json;
struct TALER_DepositTrackPS tps;
struct TALER_MerchantSignatureP merchant_sig;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("h_wire", &tps.h_wire),
GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &tps.h_contract_terms),
GNUNET_JSON_spec_fixed_auto ("coin_pub", &tps.coin_pub),
GNUNET_JSON_spec_fixed_auto ("merchant_pub", &tps.merchant),
GNUNET_JSON_spec_fixed_auto ("merchant_sig", &merchant_sig),
GNUNET_JSON_spec_end ()
};
(void) rh;
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 = TALER_MHD_parse_json_data (connection,
json,
spec);
if (GNUNET_OK != res)
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
&tps.h_wire,
sizeof (tps.h_wire)))
{
json_decref (json);
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_DEPOSITS_INVALID_H_WIRE,
"wire hash malformed");
}
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[1],
strlen (args[1]),
&tps.merchant,
sizeof (tps.merchant)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_DEPOSITS_INVALID_MERCHANT_PUB,
"merchant public key malformed");
}
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[2],
strlen (args[2]),
&tps.h_contract_terms,
sizeof (tps.h_contract_terms)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_DEPOSITS_INVALID_H_CONTRACT_TERMS,
"contract terms hash malformed");
}
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[3],
strlen (args[3]),
&tps.coin_pub,
sizeof (tps.coin_pub)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_DEPOSITS_INVALID_COIN_PUB,
"coin public key malformed");
}
res = TALER_MHD_parse_request_arg_data (connection,
"merchant_sig",
&merchant_sig,
sizeof (merchant_sig));
if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */
if (GNUNET_NO == res)
return MHD_YES; /* parse error */
tps.purpose.size = htonl (sizeof (struct TALER_DepositTrackPS));
tps.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION);
res = check_and_handle_track_transaction_request (connection,
return check_and_handle_track_transaction_request (connection,
&tps,
&tps.merchant,
&merchant_sig);
GNUNET_JSON_parse_free (spec);
json_decref (json);
return res;
}

View File

@ -27,21 +27,19 @@
/**
* Handle a "/track/transaction" request.
* Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB"
* request.
*
* @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
* @param args array of additional options (length: 4, contains:
* h_wire, merchant_pub, h_contract_terms and coin_pub)
* @return MHD result code
*/
int
TEH_TRACKING_handler_track_transaction (struct TEH_RequestHandler *rh,
TEH_TRACKING_handler_track_transaction (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[4]);
#endif

View File

@ -482,40 +482,37 @@ free_ctx (struct WtidTransactionContext *ctx)
/**
* Handle a "/track/transfer" request.
* Handle a GET "/transfers/$WTID" request.
*
* @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
* @param args array of additional options (length: 1, just the wtid)
* @return MHD result code
*/
int
TEH_TRACKING_handler_track_transfer (struct TEH_RequestHandler *rh,
TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[1])
{
struct WtidTransactionContext ctx;
int res;
int mhd_ret;
(void) rh;
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
memset (&ctx, 0, sizeof (ctx));
res = TALER_MHD_parse_request_arg_data (connection,
"wtid",
memset (&ctx,
0,
sizeof (ctx));
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
&ctx.wtid,
sizeof (struct
TALER_WireTransferIdentifierRawP));
if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */
if (GNUNET_NO == res)
return MHD_YES; /* parse error */
sizeof (ctx.wtid)))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_TRANSFERS_INVALID_WTID,
"wire transfer identifier malformed");
}
if (GNUNET_OK !=
TEH_DB_run_transaction (connection,
"run track transfer",

View File

@ -27,20 +27,17 @@
/**
* Handle a "/track/transfer" request.
* Handle a GET "/transfers/$WTID" request.
*
* @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
* @param args array of additional options (length: 1, just the wtid)
* @return MHD result code
*/
int
TEH_TRACKING_handler_track_transfer (struct TEH_RequestHandler *rh,
TEH_TRACKING_handler_track_transfer (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[1]);
#endif

View File

@ -25,7 +25,6 @@
#include "taler-exchange-httpd_validation.h"
#include "taler-exchange-httpd_wire.h"
#include "taler_exchangedb_lib.h"
#include "taler_json_lib.h"
/**

View File

@ -124,22 +124,16 @@ TEH_WIRE_get_fees (const char *method)
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_WIRE_handler_wire (struct TEH_RequestHandler *rh,
TEH_WIRE_handler_wire (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
const char *const args[])
{
(void) rh;
(void) connection_cls;
(void) upload_data;
(void) upload_data_size;
(void) args;
GNUNET_assert (NULL != wire_methods);
return TALER_MHD_reply_json (connection,
wire_methods,

View File

@ -51,17 +51,13 @@ TEH_WIRE_get_fees (const char *method);
*
* @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
* @param args array of additional options (must be empty for this function)
* @return MHD result code
*/
int
TEH_WIRE_handler_wire (struct TEH_RequestHandler *rh,
TEH_WIRE_handler_wire (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
const char *const args[]);
#endif

View File

@ -85,6 +85,32 @@ enum TALER_ErrorCode
*/
TALER_EC_METHOD_INVALID = 8,
/**
* Operation specified invalid for this URL (resulting in a "NOT
* FOUND" for the overall response).
*/
TALER_EC_OPERATION_INVALID = 9,
/**
* There is no endpoint defined for the URL provided by the client
* (returned together with a MHD_HTTP_NOT FOUND status code).
*/
TALER_EC_ENDPOINT_UNKNOWN = 10,
/**
* The URI is longer than the longest URI the HTTP server is willing
* to parse. Returned together with an HTTP status code of
* MHD_HTTP_URI_TOO_LONG.
*/
TALER_EC_URI_TOO_LONG = 11,
/**
* The number of segments included in the URI does not match the
* number of segments expected by the endpoint. (returned together
* with a MHD_HTTP_NOT FOUND status code).
*/
TALER_EC_WRONG_NUMBER_OF_SEGMENTS = 12,
/**
* The exchange failed to even just initialize its connection to the
* database. This response is provided with HTTP status code
@ -181,6 +207,50 @@ enum TALER_ErrorCode
*/
TALER_EC_DB_COIN_HISTORY_STORE_ERROR = 1014,
/**
* The public key of given to a /coins/ handler was malformed.
*/
TALER_EC_COINS_INVALID_COIN_PUB = 1050,
/**
* The public key of given to a /reserves/ handler was malformed.
*/
TALER_EC_RESERVES_INVALID_RESERVE_PUB = 1051,
/**
* The public key of given to a /transfers/ handler was malformed.
*/
TALER_EC_TRANSFERS_INVALID_WTID = 1052,
/**
* The hash of the wire details of given to a /deposits/ handler was
* malformed.
*/
TALER_EC_DEPOSITS_INVALID_H_WIRE = 1053,
/**
* The merchant public key given to a /deposits/ handler was
* malformed.
*/
TALER_EC_DEPOSITS_INVALID_MERCHANT_PUB = 1054,
/**
* The hash of the contract given to a /deposits/ handler was
* malformed.
*/
TALER_EC_DEPOSITS_INVALID_H_CONTRACT_TERMS = 1055,
/**
* The coin public key given to a /deposits/ handler was malformed.
*/
TALER_EC_DEPOSITS_INVALID_COIN_PUB = 1056,
/**
* The hash of the refresh commitment given to a /refreshes/ handler
* was malformed.
*/
TALER_EC_REFRESHES_INVALID_RCH = 1057,
/**
* The given reserve does not have sufficient funds to admit the
* requested withdraw operation at this time. The response includes