From 8e8e59917a09298f0e8d46884a93bef14c2ae98b Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 25 Nov 2015 13:38:54 +0100 Subject: rename fest to satisfy naming conventions --- configure.ac | 6 +- src/backend/Makefile.am | 13 +- src/backend/merchant.c | 36 - src/backend/taler-merchant-httpd.c | 20 +- src/backend/taler-merchant-httpd.h | 67 ++ src/backend/taler-merchant-httpd_contract.c | 8 +- src/backend/taler-merchant-httpd_contract.h | 4 +- src/backend/taler-merchant-httpd_mhd.c | 154 ++++ src/backend/taler-merchant-httpd_mhd.h | 111 +++ src/backend/taler-merchant-httpd_parsing.c | 1060 +++++++++++++++++++++++++ src/backend/taler-merchant-httpd_parsing.h | 424 ++++++++++ src/backend/taler-merchant-httpd_pay.c | 12 +- src/backend/taler-merchant-httpd_pay.h | 4 +- src/backend/taler-merchant-httpd_responses.c | 206 +++++ src/backend/taler-merchant-httpd_responses.h | 112 +++ src/backend/taler-mint-httpd.h | 85 --- src/backend/taler-mint-httpd_mhd.c | 154 ---- src/backend/taler-mint-httpd_mhd.h | 111 --- src/backend/taler-mint-httpd_parsing.c | 1061 -------------------------- src/backend/taler-mint-httpd_parsing.h | 424 ---------- src/backend/taler-mint-httpd_responses.c | 206 ----- src/backend/taler-mint-httpd_responses.h | 112 --- src/backenddb/merchant_db.c | 29 +- src/include/platform.h | 4 +- src/include/taler_merchantdb_lib.h | 26 +- src/merchant/merchant_db.c | 12 +- src/merchant/merchant_db.h | 12 +- src/merchant/taler_merchant_dbinit.c | 4 +- src/merchant/taler_merchant_serve.c | 10 +- src/merchant/test_merchant_db.c | 12 +- src/tests/test_contract.c | 10 +- 31 files changed, 2223 insertions(+), 2286 deletions(-) delete mode 100644 src/backend/merchant.c create mode 100644 src/backend/taler-merchant-httpd_mhd.c create mode 100644 src/backend/taler-merchant-httpd_mhd.h create mode 100644 src/backend/taler-merchant-httpd_parsing.c create mode 100644 src/backend/taler-merchant-httpd_parsing.h create mode 100644 src/backend/taler-merchant-httpd_responses.c create mode 100644 src/backend/taler-merchant-httpd_responses.h delete mode 100644 src/backend/taler-mint-httpd.h delete mode 100644 src/backend/taler-mint-httpd_mhd.c delete mode 100644 src/backend/taler-mint-httpd_mhd.h delete mode 100644 src/backend/taler-mint-httpd_parsing.c delete mode 100644 src/backend/taler-mint-httpd_parsing.h delete mode 100644 src/backend/taler-mint-httpd_responses.c delete mode 100644 src/backend/taler-mint-httpd_responses.h diff --git a/configure.ac b/configure.ac index 89cfe25d..b66b8b00 100644 --- a/configure.ac +++ b/configure.ac @@ -2,9 +2,9 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([taler], [0.0.0], [taler-bug@gnunet.org]) -AC_CONFIG_SRCDIR([src/merchant/merchant.c]) -AC_CONFIG_HEADERS([taler_config.h]) +AC_INIT([taler-merchant], [0.0.0], [taler-bug@gnunet.org]) +AC_CONFIG_SRCDIR([src/backend/taler-merchant-httpd.c]) +AC_CONFIG_HEADERS([taler_merchant_config.h]) # support for non-recursive builds AM_INIT_AUTOMAKE([subdir-objects]) diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index 81fbd4ed..b1936990 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -6,14 +6,11 @@ bin_PROGRAMS = \ taler_merchant_httpd_SOURCES = \ taler-merchant-httpd.c taler-merchant-httpd.h \ - taler-mint-httpd_parsing.c taler-mint-httpd_parsing.h \ - taler-mint-httpd_responses.c taler-mint-httpd_responses.h \ - taler-mint-httpd.h \ - taler-mint-httpd_mhd.c taler-mint-httpd_mhd.h \ - taler-merchant-httpd_contract.c \ - taler-merchant-httpd_contract.h \ - taler-merchant-httpd_pay.c \ - taler-merchant-httpd_pay.h + taler-merchant-httpd_parsing.c taler-merchant-httpd_parsing.h \ + taler-merchant-httpd_responses.c taler-merchant-httpd_responses.h \ + taler-merchant-httpd_mhd.c taler-merchant-httpd_mhd.h \ + taler-merchant-httpd_contract.c taler-merchant-httpd_contract.h \ + taler-merchant-httpd_pay.c taler-merchant-httpd_pay.h taler_merchant_httpd_LDADD = \ diff --git a/src/backend/merchant.c b/src/backend/merchant.c deleted file mode 100644 index b0ab811f..00000000 --- a/src/backend/merchant.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - This file is part of TALER - (C) 2014 Christian Grothoff (and other contributing authors) - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, If not, see -*/ - -/** - * @file merchant/merchant.c - * @brief Common utility functions for merchant - * @author Sree Harsha Totakura - */ - -#include "platform.h" -#include -#include "merchant.h" - - -#define EXITIF(cond) \ - do { \ - if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ - } while (0) - - - - -/* end of merchant.c */ diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index d135a7c5..d24f10a9 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -28,11 +28,11 @@ #include #include #include -#include "taler-mint-httpd_parsing.h" -#include "taler-mint-httpd_responses.h" +#include "taler-merchant-httpd_parsing.h" +#include "taler-merchant-httpd_responses.h" #include "taler_merchantdb_lib.h" #include "taler-merchant-httpd.h" -#include "taler-mint-httpd_mhd.h" +#include "taler-merchant-httpd_mhd.h" #include "taler-merchant-httpd_contract.h" #include "taler-merchant-httpd_pay.h" @@ -351,7 +351,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } if (NULL != db_conn) { - MERCHANT_DB_disconnect (db_conn); + TALER_MERCHANTDB_disconnect (db_conn); db_conn = NULL; } if (NULL != keyfile) @@ -618,8 +618,8 @@ parse_auditors (const struct GNUNET_CONFIGURATION_Handle *cfg, /** - * Parse the SEPA information from the configuration. If any of the required - * fileds is missing return NULL. + * Parse the SEPA information from the configuration. If any of the + * required fields is missing return NULL. * * @param cfg the configuration * @return Sepa details as a structure; NULL upon error @@ -740,10 +740,6 @@ run (void *cls, GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown, NULL); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "merchant launched\n"); - EXITIF (GNUNET_SYSERR == (nmints = parse_mints (config))); @@ -763,9 +759,9 @@ run (void *cls, (privkey = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile))); EXITIF (NULL == - (db_conn = MERCHANT_DB_connect (config))); + (db_conn = TALER_MERCHANTDB_connect (config))); EXITIF (GNUNET_OK != - MERCHANT_DB_initialize (db_conn, dry)); + TALER_MERCHANTDB_initialize (db_conn, dry)); EXITIF (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (config, "merchant", diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h index 7dc1b647..d2fe3921 100644 --- a/src/backend/taler-merchant-httpd.h +++ b/src/backend/taler-merchant-httpd.h @@ -18,9 +18,12 @@ * @brief HTTP serving layer mainly intended to communicate with the frontend * @author Marcello Stanisci */ +#ifndef TALER_MERCHANT_HTTPD_H +#define TALER_MERCHANT_HTTPD_H #include "platform.h" #include "taler_merchantdb_lib.h" +#include /** * Shorthand for exit jumps. @@ -31,6 +34,64 @@ } while (0) + + +/** + * @brief Struct describing an URL and the handler for it. + */ +struct TMH_RequestHandler +{ + + /** + * URL the handler is for. + */ + const char *url; + + /** + * Method the handler is for, NULL for "all". + */ + const char *method; + + /** + * Mime type to use in reply (hint, can be NULL). + */ + const char *mime_type; + + /** + * Raw data for the @e handler + */ + const void *data; + + /** + * Number of bytes in @e data, 0 for 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 + */ + int (*handler)(struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + + /** + * Default response code. + */ + int response_code; +}; + + + /** * Mint */ @@ -122,6 +183,9 @@ struct TM_HandlerContext }; +extern struct MERCHANT_Auditor *auditors; +extern unsigned int nauditors; + extern struct MERCHANT_WIREFORMAT_Sepa *wire; @@ -164,3 +228,6 @@ MERCHANT_get_wire_json (const struct MERCHANT_WIREFORMAT_Sepa *wire, */ void TM_trigger_daemon (void); + + +#endif diff --git a/src/backend/taler-merchant-httpd_contract.c b/src/backend/taler-merchant-httpd_contract.c index d6c1b8fd..88757b53 100644 --- a/src/backend/taler-merchant-httpd_contract.c +++ b/src/backend/taler-merchant-httpd_contract.c @@ -29,14 +29,12 @@ #include #include #include -#include "taler-mint-httpd.h" -#include "taler-mint-httpd_parsing.h" -#include "taler-mint-httpd_responses.h" +#include "taler-merchant-httpd.h" +#include "taler-merchant-httpd_parsing.h" +#include "taler-merchant-httpd_responses.h" #include "taler_merchantdb_lib.h" #include "taler-merchant-httpd.h" -extern struct MERCHANT_Auditor *auditors; -extern unsigned int nauditors; /** * Manage a contract request. In practical terms, it adds the fields 'mints', diff --git a/src/backend/taler-merchant-httpd_contract.h b/src/backend/taler-merchant-httpd_contract.h index 5e72c514..5a1aa6dd 100644 --- a/src/backend/taler-merchant-httpd_contract.h +++ b/src/backend/taler-merchant-httpd_contract.h @@ -23,7 +23,7 @@ #ifndef TALER_MINT_HTTPD_CONTRACT_H #define TALER_MINT_HTTPD_CONTRACT_H #include -#include "taler-mint-httpd.h" +#include "taler-merchant-httpd.h" /** * Manage a contract request @@ -33,7 +33,7 @@ * @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 diff --git a/src/backend/taler-merchant-httpd_mhd.c b/src/backend/taler-merchant-httpd_mhd.c new file mode 100644 index 00000000..7b47bc9d --- /dev/null +++ b/src/backend/taler-merchant-httpd_mhd.c @@ -0,0 +1,154 @@ +/* + 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, If not, see +*/ + +/** + * @file taler-merchant-httpd_mhd.c + * @brief helpers for MHD interaction; these are TALER_MINT_handler_ functions + * that generate simple MHD replies that do not require any real operations + * to be performed (error handling, static pages, etc.) + * @author Florian Dold + * @author Benedikt Mueller + * @author Christian Grothoff + */ +#include "platform.h" +#include +#include +#include +#include +#include "taler-merchant-httpd_responses.h" +#include "taler-merchant-httpd.h" +#include "taler-merchant-httpd_mhd.h" +#include "taler-merchant-httpd_responses.h" + + +/** + * Function to call to handle the request by sending + * back static data from the @a 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 + * @return MHD result code + */ +int +TMH_MHD_handler_static_response (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + struct MHD_Response *response; + int ret; + + if (0 == rh->data_size) + rh->data_size = strlen ((const char *) rh->data); + response = MHD_create_response_from_buffer (rh->data_size, + (void *) rh->data, + MHD_RESPMEM_PERSISTENT); + if (NULL == response) + { + GNUNET_break (0); + return MHD_NO; + } + TMH_RESPONSE_add_global_headers (response); + if (NULL != rh->mime_type) + (void) MHD_add_response_header (response, + MHD_HTTP_HEADER_CONTENT_TYPE, + rh->mime_type); + ret = MHD_queue_response (connection, + rh->response_code, + response); + MHD_destroy_response (response); + return ret; +} + + +/** + * Function to call to handle the request by sending + * back a redirect to the AGPL source code. + * + * @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 +TMH_MHD_handler_agpl_redirect (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + 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; + } + TMH_RESPONSE_add_global_headers (response); + if (NULL != rh->mime_type) + (void) MHD_add_response_header (response, + MHD_HTTP_HEADER_CONTENT_TYPE, + rh->mime_type); + MHD_add_response_header (response, + MHD_HTTP_HEADER_LOCATION, + "http://www.git.taler.net/?p=mint.git"); + ret = MHD_queue_response (connection, + rh->response_code, + response); + MHD_destroy_response (response); + return ret; +} + + +/** + * Function to call to handle the request by building a JSON + * reply with an error message from @a 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 + * @return MHD result code + */ +int +TMH_MHD_handler_send_json_pack_error (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) +{ + return TMH_RESPONSE_reply_json_pack (connection, + rh->response_code, + "{s:s}", + "error", + rh->data); +} + + +/* end of taler-mint-httpd_mhd.c */ diff --git a/src/backend/taler-merchant-httpd_mhd.h b/src/backend/taler-merchant-httpd_mhd.h new file mode 100644 index 00000000..3fe137db --- /dev/null +++ b/src/backend/taler-merchant-httpd_mhd.h @@ -0,0 +1,111 @@ +/* + 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, If not, see +*/ + +/** + * @file taler-merchant-httpd_mhd.h + * @brief helpers for MHD interaction, used to generate simple responses + * @author Florian Dold + * @author Benedikt Mueller + * @author Christian Grothoff + */ +#ifndef TALER_MINT_HTTPD_MHD_H +#define TALER_MINT_HTTPD_MHD_H +#include +#include +#include "taler-merchant-httpd.h" + + +/** + * Function to call to handle the request by sending + * back static data from the @a 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 + * @return MHD result code + */ +int +TMH_MHD_handler_static_response (struct TMH_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 sending + * back a redirect to the AGPL source code. + * + * @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 +TMH_MHD_handler_agpl_redirect (struct TMH_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 +TMH_MHD_helper_send_json_pack (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void *connection_cls, + int response_code, + int do_cache, + const char *fmt, + ...); + + +/** + * Function to call to handle the request by building a JSON + * reply with an error message from @a 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 + * @return MHD result code + */ +int +TMH_MHD_handler_send_json_pack_error (struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size); + + +#endif diff --git a/src/backend/taler-merchant-httpd_parsing.c b/src/backend/taler-merchant-httpd_parsing.c new file mode 100644 index 00000000..e7141b64 --- /dev/null +++ b/src/backend/taler-merchant-httpd_parsing.c @@ -0,0 +1,1060 @@ +/* + 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, If not, see +*/ + +/** + * @file taler-mint-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 +#include "taler-merchant-httpd_parsing.h" +#include "taler-merchant-httpd_responses.h" + +/* Although the following declaration isn't in any case useful + to a merchant's activity, it's needed here to make the function + 'TMH_PARSE_nagivate_json ()' compile fine; so its value will be + kept on some merchant's accepted currency. For multi currencies + merchants, that of course would require a patch */ +extern char *TMH_merchant_currency_string; + +/** + * Initial size for POST request buffer. + */ +#define REQUEST_BUFFER_INITIAL (2*1024) + +/** + * Maximum POST request size. + */ +#define REQUEST_BUFFER_MAX (1024*1024) + + +/** + * Buffer for POST requests. + */ +struct Buffer +{ + /** + * Allocated memory + */ + char *data; + + /** + * Number of valid bytes in buffer. + */ + size_t fill; + + /** + * Number of allocated bytes in buffer. + */ + size_t alloc; +}; + + +/** + * Initialize a buffer. + * + * @param buf the buffer to initialize + * @param data the initial data + * @param data_size size of the initial data + * @param alloc_size size of the buffer + * @param max_size maximum size that the buffer can grow to + * @return a GNUnet result code + */ +static int +buffer_init (struct Buffer *buf, + const void *data, + size_t data_size, + size_t alloc_size, + size_t max_size) +{ + if (data_size > max_size || alloc_size > max_size) + return GNUNET_SYSERR; + if (data_size > alloc_size) + alloc_size = data_size; + buf->data = GNUNET_malloc (alloc_size); + memcpy (buf->data, data, data_size); + return GNUNET_OK; +} + + +/** + * Free the data in a buffer. Does *not* free + * the buffer object itself. + * + * @param buf buffer to de-initialize + */ +static void +buffer_deinit (struct Buffer *buf) +{ + GNUNET_free (buf->data); + buf->data = NULL; +} + + +/** + * Append data to a buffer, growing the buffer if necessary. + * + * @param buf the buffer to append to + * @param data the data to append + * @param data_size the size of @a data + * @param max_size maximum size that the buffer can grow to + * @return #GNUNET_OK on success, + * #GNUNET_NO if the buffer can't accomodate for the new data + */ +static int +buffer_append (struct Buffer *buf, + const void *data, + size_t data_size, + size_t max_size) +{ + if (buf->fill + data_size > max_size) + return GNUNET_NO; + if (data_size + buf->fill > buf->alloc) + { + char *new_buf; + size_t new_size = buf->alloc; + while (new_size < buf->fill + data_size) + new_size += 2; + if (new_size > max_size) + return GNUNET_NO; + new_buf = GNUNET_malloc (new_size); + memcpy (new_buf, buf->data, buf->fill); + GNUNET_free (buf->data); + buf->data = new_buf; + buf->alloc = new_size; + } + memcpy (buf->data + buf->fill, data, data_size); + buf->fill += data_size; + return GNUNET_OK; +} + +/** + * Function called whenever we are done with a request + * to clean up our state. + * + * @param con_cls value as it was left by + * #TMH_PARSE_post_json(), to be cleaned up + */ +void +TMH_PARSE_post_cleanup_callback (void *con_cls) +{ + struct Buffer *r = con_cls; + + if (NULL != r) + { + buffer_deinit (r); + GNUNET_free (r); + } +} + +/** + * Release all memory allocated for the variable-size fields in + * the parser specification. + * + * @param spec specification to free + * @param spec_len number of items in @a spec to look at + */ +static void +release_data (struct TMH_PARSE_FieldSpecification *spec, + unsigned int spec_len) +{ + unsigned int i; + + for (i=0; i < spec_len; i++) + { + switch (spec[i].command) + { + case TMH_PARSE_JNC_FIELD: + GNUNET_break (0); + return; + case TMH_PARSE_JNC_RET_STRING: + GNUNET_break (0); + return; + case TMH_PARSE_JNC_INDEX: + GNUNET_break (0); + return; + case TMH_PARSE_JNC_RET_DATA: + break; + case TMH_PARSE_JNC_RET_DATA_VAR: + if (NULL != spec[i].destination) + { + GNUNET_free (* (void**) spec[i].destination); + *(void**) spec[i].destination = NULL; + *spec[i].destination_size_out = 0; + } + break; + case TMH_PARSE_JNC_RET_TYPED_JSON: + { + json_t *json; + + json = *(json_t **) spec[i].destination; + if (NULL != json) + { + json_decref (json); + *(json_t**) spec[i].destination = NULL; + } + } + break; + case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY: + { + struct TALER_DenominationPublicKey *pk; + + pk = spec[i].destination; + if (NULL != pk->rsa_public_key) + { + GNUNET_CRYPTO_rsa_public_key_free (pk->rsa_public_key); + pk->rsa_public_key = NULL; + } + } + break; + case TMH_PARSE_JNC_RET_RSA_SIGNATURE: + { + struct TALER_DenominationSignature *sig; + + sig = spec[i].destination; + if (NULL != sig->rsa_signature) + { + GNUNET_CRYPTO_rsa_signature_free (sig->rsa_signature); + sig->rsa_signature = NULL; + } + } + break; + case TMH_PARSE_JNC_RET_AMOUNT: + memset (spec[i].destination, + 0, + sizeof (struct TALER_Amount)); + break; + case TMH_PARSE_JNC_RET_TIME_ABSOLUTE: + break; + case TMH_PARSE_JNC_RET_UINT64: + break; + } + } +} + +/** + * 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 + * #TMH_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 +TMH_PARSE_post_json (struct MHD_Connection *connection, + void **con_cls, + const char *upload_data, + size_t *upload_data_size, + json_t **json) +{ + struct Buffer *r = *con_cls; + + *json = NULL; + if (NULL == *con_cls) + { + /* We are seeing a fresh POST request. */ + r = GNUNET_new (struct Buffer); + if (GNUNET_OK != + buffer_init (r, + upload_data, + *upload_data_size, + REQUEST_BUFFER_INITIAL, + REQUEST_BUFFER_MAX)) + { + *con_cls = NULL; + buffer_deinit (r); + GNUNET_free (r); + return (MHD_NO == + TMH_RESPONSE_reply_internal_error (connection, + "out of memory")) + ? GNUNET_SYSERR : GNUNET_NO; + } + /* everything OK, wait for more POST data */ + *upload_data_size = 0; + *con_cls = r; + return GNUNET_YES; + } + if (0 != *upload_data_size) + { + /* We are seeing an old request with more data available. */ + + if (GNUNET_OK != + buffer_append (r, + upload_data, + *upload_data_size, + REQUEST_BUFFER_MAX)) + { + /* Request too long */ + *con_cls = NULL; + buffer_deinit (r); + GNUNET_free (r); + return (MHD_NO == + TMH_RESPONSE_reply_request_too_large (connection)) + ? GNUNET_SYSERR : GNUNET_NO; + } + /* everything OK, wait for more POST data */ + *upload_data_size = 0; + return GNUNET_YES; + } + + /* We have seen the whole request. */ + + *json = json_loadb (r->data, + r->fill, + 0, + NULL); + if (NULL == *json) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to parse JSON request body\n"); + return (MHD_YES == + TMH_RESPONSE_reply_invalid_json (connection)) + ? GNUNET_NO : GNUNET_SYSERR; + } + buffer_deinit (r); + GNUNET_free (r); + *con_cls = NULL; + + return GNUNET_YES; +} + +/** + * Generate line in parser specification for string. The returned + * string is already nul-terminated internally by JSON, so no length + * information is provided. The string will live as long as the containg + * JSON will, and must not be freed by the user + * @param field name of the field + * @param[out] pointer to the string + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_string (const char *field, + char **out) +{ + struct TMH_PARSE_FieldSpecification ret = + {field, (void **) out, 0, NULL, TMH_PARSE_JNC_RET_STRING, 0}; + return ret; +} + +/** + * Generate line in parser specification for 64-bit integer + * given as an integer in JSON. + * + * @param field name of the field + * @param[out] u64 integer to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_uint64 (const char *field, + uint64_t *u64) +{ + struct TMH_PARSE_FieldSpecification ret = + { field, (void *) u64, sizeof (uint64_t), NULL, TMH_PARSE_JNC_RET_UINT64, 0 }; + return ret; +} + + +/** + * Generate line in parser specification for JSON object value. + * + * @param field name of the field + * @param[out] jsonp address of pointer to JSON to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_object (const char *field, + json_t **jsonp) +{ + struct TMH_PARSE_FieldSpecification ret = + { field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_OBJECT }; + *jsonp = NULL; + return ret; +} + + +/** + * Generate line in parser specification for JSON array value. + * + * @param field name of the field + * @param[out] jsonp address of JSON pointer to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_array (const char *field, + json_t **jsonp) +{ + struct TMH_PARSE_FieldSpecification ret = + { field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_ARRAY }; + *jsonp = NULL; + return ret; +} + + +/** + * Generate line in parser specification for an absolute time. + * + * @param field name of the field + * @param[out] atime time to initialize + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_time_abs (const char *field, + struct GNUNET_TIME_Absolute *atime) +{ + struct TMH_PARSE_FieldSpecification ret = + { field, atime, sizeof(struct GNUNET_TIME_Absolute), NULL, TMH_PARSE_JNC_RET_TIME_ABSOLUTE, 0 }; + return ret; +} + + +/** + * Generate line in parser specification for RSA public key. + * + * @param field name of the field + * @param[out] pk key to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_denomination_public_key (const char *field, + struct TALER_DenominationPublicKey *pk) +{ + struct TMH_PARSE_FieldSpecification ret = + { field, pk, 0, NULL, TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, 0 }; + pk->rsa_public_key = NULL; + return ret; +} + + +/** + * Generate line in parser specification for RSA public key. + * + * @param field name of the field + * @param sig the signature to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_denomination_signature (const char *field, + struct TALER_DenominationSignature *sig) +{ + struct TMH_PARSE_FieldSpecification ret = + { field, sig, 0, NULL, TMH_PARSE_JNC_RET_RSA_SIGNATURE, 0 }; + sig->rsa_signature = NULL; + return ret; +} + + +/** + * Generate line in parser specification for an amount. + * + * @param field name of the field + * @param amount a `struct TALER_Amount *` to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_amount (const char *field, + struct TALER_Amount *amount) +{ + struct TMH_PARSE_FieldSpecification ret = + { field, amount, sizeof(struct TALER_Amount), NULL, TMH_PARSE_JNC_RET_AMOUNT, 0 }; + memset (amount, 0, sizeof (struct TALER_Amount)); + return ret; +} + + +/** + * Generate line in parser specification for variable-size value. + * + * @param field name of the field + * @param[out] ptr pointer to initialize + * @param[out] ptr_size size to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_variable (const char *field, + void **ptr, + size_t *ptr_size) +{ + struct TMH_PARSE_FieldSpecification ret = + { field, ptr, 0, ptr_size, TMH_PARSE_JNC_RET_DATA_VAR, 0 }; + *ptr = NULL; + return ret; +} + +/** + * Navigate through a JSON tree. + * + * Sends an error response if navigation is impossible (i.e. + * the JSON object is invalid) + * + * @param connection the connection to send an error response to + * @param root the JSON node to start the navigation at. + * @param ... navigation specification (see + * `enum TMH_PARSE_JsonNavigationCommand`) + * @return + * #GNUNET_YES if navigation was successful + * #GNUNET_NO if json is malformed, error response was generated + * #GNUNET_SYSERR on internal error (no response was generated, + * connection must be closed) + */ +int +TMH_PARSE_navigate_json (struct MHD_Connection *connection, + const json_t *root, + ...) +{ + va_list argp; + int ret; + json_t *path; /* what's our current path from 'root'? */ + + path = json_array (); + va_start (argp, root); + ret = 2; /* just not any of the valid return values */ + while (2 == ret) + { + enum TMH_PARSE_JsonNavigationCommand command + = va_arg (argp, + enum TMH_PARSE_JsonNavigationCommand); + + switch (command) + { + case TMH_PARSE_JNC_FIELD: + { + const char *fname = va_arg(argp, const char *); + + json_array_append_new (path, + json_string (fname)); + root = json_object_get (root, + fname); + if (NULL == root) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:s, s:O}", + "error", "missing field in JSON", + "field", fname, + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + } + break; + + case TMH_PARSE_JNC_INDEX: + { + int fnum = va_arg(argp, int); + + json_array_append_new (path, + json_integer (fnum)); + root = json_array_get (root, + fnum); + if (NULL == root) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "missing index in JSON", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + } + break; + + case TMH_PARSE_JNC_RET_DATA: + { + void *where = va_arg (argp, void *); + size_t len = va_arg (argp, size_t); + const char *str; + int res; + + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "string expected", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + res = GNUNET_STRINGS_string_to_data (str, strlen (str), + where, len); + if (GNUNET_OK != res) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "malformed binary data in JSON", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + ret = GNUNET_OK; + } + break; + + case TMH_PARSE_JNC_RET_STRING: + { + void **where = va_arg (argp, void **); + *where = (void*) json_string_value (root); + ret = GNUNET_OK; + } + break; + case TMH_PARSE_JNC_RET_DATA_VAR: + { + void **where = va_arg (argp, void **); + size_t *len = va_arg (argp, size_t *); + const char *str; + int res; + + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_internal_error (connection, + "json_string_value() failed")) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + *len = (strlen (str) * 5) / 8; + if (NULL != where) + { + *where = GNUNET_malloc (*len); + res = GNUNET_STRINGS_string_to_data (str, + strlen (str), + *where, + *len); + if (GNUNET_OK != res) + { + GNUNET_break_op (0); + GNUNET_free (*where); + *where = NULL; + *len = 0; + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "malformed binary data in JSON", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + } + ret = GNUNET_OK; + } + break; + + case TMH_PARSE_JNC_RET_TYPED_JSON: + { + int typ = va_arg (argp, int); + const json_t **r_json = va_arg (argp, const json_t **); + + if ( (NULL == root) || + ( (-1 != typ) && + (json_typeof (root) != typ)) ) + { + GNUNET_break_op (0); + *r_json = NULL; + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:i, s:i, s:O}", + "error", "wrong JSON field type", + "type_expected", typ, + "type_actual", json_typeof (root), + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + *r_json = root; + json_incref ((json_t *) root); + ret = GNUNET_OK; + } + break; + + case TMH_PARSE_JNC_RET_UINT64: + { + uint64_t *r_u64 = va_arg (argp, uint64_t *); + + if (json_typeof (root) != JSON_INTEGER) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:s, s:i, s:O}", + "error", "wrong JSON field type", + "type_expected", "integer", + "type_actual", json_typeof (root), + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + *r_u64 = (uint64_t) json_integer_value (root); + ret = GNUNET_OK; + } + break; + + case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY: + { + struct TALER_DenominationPublicKey *where; + size_t len; + const char *str; + int res; + void *buf; + + where = va_arg (argp, + struct TALER_DenominationPublicKey *); + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "string expected", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + len = (strlen (str) * 5) / 8; + buf = GNUNET_malloc (len); + res = GNUNET_STRINGS_string_to_data (str, + strlen (str), + buf, + len); + if (GNUNET_OK != res) + { + GNUNET_break_op (0); + GNUNET_free (buf); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "malformed binary data in JSON", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + where->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (buf, + len); + GNUNET_free (buf); + if (NULL == where->rsa_public_key) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "malformed RSA public key in JSON", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + ret = GNUNET_OK; + break; + } + + case TMH_PARSE_JNC_RET_RSA_SIGNATURE: + { + struct TALER_DenominationSignature *where; + size_t len; + const char *str; + int res; + void *buf; + + where = va_arg (argp, + struct TALER_DenominationSignature *); + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "string expected", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + len = (strlen (str) * 5) / 8; + buf = GNUNET_malloc (len); + res = GNUNET_STRINGS_string_to_data (str, + strlen (str), + buf, + len); + if (GNUNET_OK != res) + { + GNUNET_break_op (0); + GNUNET_free (buf); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "malformed binary data in JSON", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + where->rsa_signature = GNUNET_CRYPTO_rsa_signature_decode (buf, + len); + GNUNET_free (buf); + if (NULL == where->rsa_signature) + { + GNUNET_break_op (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "malformed RSA signature in JSON", + "path", path)) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + ret = GNUNET_OK; + break; + } + + case TMH_PARSE_JNC_RET_AMOUNT: + { + struct TALER_Amount *where = va_arg (argp, void *); + + if (GNUNET_OK != + TALER_json_to_amount ((json_t *) root, + where)) + { + GNUNET_break_op (0); + ret = (MHD_YES != + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O}", + "error", "Bad format", + "path", path)) + ? GNUNET_SYSERR : GNUNET_NO; + break; + } + if (0 != strcmp (where->currency, + TMH_merchant_currency_string)) + { + GNUNET_break_op (0); + ret = (MHD_YES != + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:O, s:s}", + "error", "Currency not supported", + "path", path, + "currency", where->currency)) + ? GNUNET_SYSERR : GNUNET_NO; + memset (where, 0, sizeof (struct TALER_Amount)); + break; + } + ret = GNUNET_OK; + break; + } + + case TMH_PARSE_JNC_RET_TIME_ABSOLUTE: + { + struct GNUNET_TIME_Absolute *where = va_arg (argp, void *); + + if (GNUNET_OK != + TALER_json_to_abs ((json_t *) root, + where)) + { + GNUNET_break_op (0); + ret = (MHD_YES != + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:s, s:O}", + "error", "Bad format", + "hint", "expected absolute time", + "path", path)) + ? GNUNET_SYSERR : GNUNET_NO; + break; + } + ret = GNUNET_OK; + break; + } + + default: + GNUNET_break (0); + ret = (MHD_YES == + TMH_RESPONSE_reply_internal_error (connection, + "unhandled value in switch")) + ? GNUNET_NO : GNUNET_SYSERR; + break; + } + } + va_end (argp); + json_decref (path); + return ret; +} + + + +/** + * 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 + * #TMH_PARSE_release_data() when done) + * #GNUNET_NO if json is malformed, error response was generated + * #GNUNET_SYSERR on internal error + */ +int +TMH_PARSE_json_data (struct MHD_Connection *connection, + const json_t *root, + struct TMH_PARSE_FieldSpecification *spec) +{ + unsigned int i; + int ret; + + ret = GNUNET_YES; + for (i=0; NULL != spec[i].field_name; i++) + { + if (GNUNET_YES != ret) + break; + switch (spec[i].command) + { + case TMH_PARSE_JNC_FIELD: + GNUNET_break (0); + return GNUNET_SYSERR; + case TMH_PARSE_JNC_INDEX: + GNUNET_break (0); + return GNUNET_SYSERR; + case TMH_PARSE_JNC_RET_DATA: + ret = TMH_PARSE_navigate_json (connection, + root, + TMH_PARSE_JNC_FIELD, + spec[i].field_name, + TMH_PARSE_JNC_RET_DATA, + spec[i].destination, + spec[i].destination_size_in); + break; + case TMH_PARSE_JNC_RET_DATA_VAR: + ret = TMH_PARSE_navigate_json (connection, + root, + TMH_PARSE_JNC_FIELD, + spec[i].field_name, + TMH_PARSE_JNC_RET_DATA_VAR, + (void **) spec[i].destination, + spec[i].destination_size_out); + break; + case TMH_PARSE_JNC_RET_STRING: + ret = TMH_PARSE_navigate_json (connection, + root, + TMH_PARSE_JNC_FIELD, + spec[i].field_name, + TMH_PARSE_JNC_RET_STRING, + spec[i].destination); + break; + case TMH_PARSE_JNC_RET_TYPED_JSON: + ret = TMH_PARSE_navigate_json (connection, + root, + TMH_PARSE_JNC_FIELD, + spec[i].field_name, + TMH_PARSE_JNC_RET_TYPED_JSON, + spec[i].type, + spec[i].destination); + break; + case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY: + ret = TMH_PARSE_navigate_json (connection, + root, + TMH_PARSE_JNC_FIELD, + spec[i].field_name, + TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, + spec[i].destination); + break; + case TMH_PARSE_JNC_RET_RSA_SIGNATURE: + ret = TMH_PARSE_navigate_json (connection, + root, + TMH_PARSE_JNC_FIELD, + spec[i].field_name, + TMH_PARSE_JNC_RET_RSA_SIGNATURE, + spec[i].destination); + break; + case TMH_PARSE_JNC_RET_AMOUNT: + GNUNET_assert (sizeof (struct TALER_Amount) == + spec[i].destination_size_in); + ret = TMH_PARSE_navigate_json (connection, + root, + TMH_PARSE_JNC_FIELD, + spec[i].field_name, + TMH_PARSE_JNC_RET_AMOUNT, + spec[i].destination); + break; + case TMH_PARSE_JNC_RET_TIME_ABSOLUTE: + GNUNET_assert (sizeof (struct GNUNET_TIME_Absolute) == + spec[i].destination_size_in); + ret = TMH_PARSE_navigate_json (connection, + root, + TMH_PARSE_JNC_FIELD, + spec[i].field_name, + TMH_PARSE_JNC_RET_TIME_ABSOLUTE, + spec[i].destination); + break; + case TMH_PARSE_JNC_RET_UINT64: + GNUNET_assert (sizeof (uint64_t) == + spec[i].destination_size_in); + ret = TMH_PARSE_navigate_json (connection, + root, + TMH_PARSE_JNC_FIELD, + spec[i].field_name, + TMH_PARSE_JNC_RET_UINT64, + spec[i].destination); + break; + } + } + if (GNUNET_YES != ret) + release_data (spec, + i - 1); + return ret; +} + + +/* end of taler-mint-httpd_parsing.c */ diff --git a/src/backend/taler-merchant-httpd_parsing.h b/src/backend/taler-merchant-httpd_parsing.h new file mode 100644 index 00000000..dae65092 --- /dev/null +++ b/src/backend/taler-merchant-httpd_parsing.h @@ -0,0 +1,424 @@ +/* + 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, If not, see +*/ +/** + * @file taler-mint-httpd_parsing.h + * @brief functions to parse incoming requests + * @author Florian Dold + * @author Benedikt Mueller + * @author Christian Grothoff + */ +#ifndef TALER_MINT_HTTPD_PARSING_H +#define TALER_MINT_HTTPD_PARSING_H + +#include +#include +#include + +/** + * 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 + * #TMH_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 +TMH_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 + * #TMH_PARSE_post_json(), to be cleaned up + */ +void +TMH_PARSE_post_cleanup_callback (void *con_cls); + + +/** + * Constants for JSON navigation description. + */ +enum TMH_PARSE_JsonNavigationCommand +{ + /** + * Access a field. + * Param: const char * + */ + TMH_PARSE_JNC_FIELD, + + /** + * Access an array index. + * Param: int + */ + TMH_PARSE_JNC_INDEX, + + /** + * Return base32crockford encoded data of + * constant size. + * Params: (void *, size_t) + */ + TMH_PARSE_JNC_RET_DATA, + + /** + * Return base32crockford encoded data of + * variable size. + * Params: (void **, size_t *) + */ + TMH_PARSE_JNC_RET_DATA_VAR, + + /** + * Return a json object, which must be + * of the given type (JSON_* type constants, + * or -1 for any type). + * Params: (int, json_t **) + */ + TMH_PARSE_JNC_RET_TYPED_JSON, + + /** + * Return a `struct GNUNET_CRYPTO_rsa_PublicKey` which was + * encoded as variable-size base32crockford encoded data. + */ + TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, + + /** + * Return a `struct GNUNET_CRYPTO_rsa_Signature` which was + * encoded as variable-size base32crockford encoded data. + */ + TMH_PARSE_JNC_RET_RSA_SIGNATURE, + + /** + * Return a `struct TALER_Amount` which was + * encoded within its own json object. + */ + TMH_PARSE_JNC_RET_AMOUNT, + + /** + * Return a `struct GNUNET_TIME_Absolute` which was + * encoded within its own json object. + * Param: struct GNUNET_TIME_Absolute * + */ + TMH_PARSE_JNC_RET_TIME_ABSOLUTE, + + /** + * Return a `uint64_t` which was + * encoded as a JSON integer. + * Param: uint64_t * + */ + TMH_PARSE_JNC_RET_UINT64, + /** + * Return a 'char *' as returned from 'json_string_value ()'. + * So it will live as long as the containg JSON is not freed, + * and must not be freed by the user + */ + TMH_PARSE_JNC_RET_STRING + +}; + + +/** + * Navigate through a JSON tree. + * + * Sends an error response if navigation is impossible (i.e. + * the JSON object is invalid) + * + * @param connection the connection to send an error response to + * @param root the JSON node to start the navigation at. + * @param ... navigation specification (see `enum TMH_PARSE_JsonNavigationCommand`) + * @return + * #GNUNET_YES if navigation was successful + * #GNUNET_NO if json is malformed, error response was generated + * #GNUNET_SYSERR on internal error + */ +int +TMH_PARSE_navigate_json (struct MHD_Connection *connection, + const json_t *root, + ...); + + +/** + * @brief Specification for how to parse a JSON field. + */ +struct TMH_PARSE_FieldSpecification +{ + /** + * Name of the field. NULL only to terminate array. + */ + const char *field_name; + + /** + * Where to store the result. Must have exactly + * @e destination_size bytes, except if @e destination_size is zero. + * NULL to skip assignment (but check presence of the value). + */ + void *destination; + + /** + * How big should the result be, 0 for variable size. In + * this case, @e destination must be a "void **", pointing + * to a location that is currently NULL and is to be allocated. + */ + size_t destination_size_in; + + /** + * @e destination_size_out will then be set to the size of the + * value that was stored in @e destination (useful for + * variable-size allocations). + */ + size_t *destination_size_out; + + /** + * Navigation command to use to extract the value. Note that + * #TMH_PARSE_JNC_RET_DATA or #TMH_PARSE_JNC_RET_DATA_VAR must be used for @e + * destination_size_in and @e destination_size_out to have a + * meaning. #TMH_PARSE_JNC_FIELD and #TMH_PARSE_JNC_INDEX must not be used here! + */ + enum TMH_PARSE_JsonNavigationCommand command; + + /** + * JSON type to use, only meaningful in connection with a @e command + * value of #TMH_PARSE_JNC_RET_TYPED_JSON. Typical values are + * #JSON_ARRAY and #JSON_OBJECT. + */ + int type; + +}; + + +/** + * 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 + * #TMH_PARSE_release_data() when done) + * #GNUNET_NO if json is malformed, error response was generated + * #GNUNET_SYSERR on internal error + */ +int +TMH_PARSE_json_data (struct MHD_Connection *connection, + const json_t *root, + struct TMH_PARSE_FieldSpecification *spec); + + +/** + * Release all memory allocated for the variable-size fields in + * the parser specification. + * + * @param spec specification to free + */ +void +TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec); + + +/** + * Generate line in parser specification for fixed-size value. + * + * @param field name of the field + * @param value where to store the value + */ +#define TMH_PARSE_member_fixed(field,value) { field, value, sizeof (*value), NULL, TMH_PARSE_JNC_RET_DATA, 0 } + + +/** + * Generate line in parser specification for variable-size value. + * + * @param field name of the field + * @param[out] ptr pointer to initialize + * @param[out] ptr_size size to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_variable (const char *field, + void **ptr, + size_t *ptr_size); + +/** + * Generate line in parser specification for string. The returned + * string is already nul-terminated internally by JSON, so no length + * information is provided. The string will live as long as the containg + * JSON will, and must not be freed by the user + * @param field name of the field + * @param[out] pointer to the string + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_string (const char *field, + char **out); +/** + * Generate line in parser specification for 64-bit integer + * given as an integer in JSON. + * + * @param field name of the field + * @param[out] u64 integer to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_uint64 (const char *field, + uint64_t *u64); + + +/** + * Generate line in parser specification for JSON array value. + * + * @param field name of the field + * @param[out] jsonp address of JSON pointer to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_array (const char *field, + json_t **jsonp); + + +/** + * Generate line in parser specification for JSON object value. + * + * @param field name of the field + * @param[out] jsonp address of pointer to JSON to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_object (const char *field, + json_t **jsonp); + + +/** + * Generate line in parser specification for RSA public key. + * + * @param field name of the field + * @param[out] pk key to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_denomination_public_key (const char *field, + struct TALER_DenominationPublicKey *pk); + + +/** + * Generate line in parser specification for RSA public key. + * + * @param field name of the field + * @param sig the signature to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_denomination_signature (const char *field, + struct TALER_DenominationSignature *sig); + + +/** + * Generate line in parser specification for an amount. + * + * @param field name of the field + * @param[out] amount a `struct TALER_Amount *` to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_amount (const char *field, + struct TALER_Amount *amount); + + +/** + * Generate line in parser specification for an absolute time. + * + * @param field name of the field + * @param[out] atime time to initialize + * @return corresponding field spec + */ +struct TMH_PARSE_FieldSpecification +TMH_PARSE_member_time_abs (const char *field, + struct GNUNET_TIME_Absolute *atime); + + + +/** + * Generate line in parser specification indicating the end of the spec. + */ +#define TMH_PARSE_MEMBER_END { NULL, NULL, 0, NULL, TMH_PARSE_JNC_FIELD, 0 } + + +/** + * 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 +TMH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection, + const char *param_name, + void *out_data, + size_t out_size); + + +/** + * Extraxt variable-size base32crockford encoded data from request. + * + * Queues an error response to the connection if the parameter is missing + * or the encoding is invalid. + * + * @param connection the MHD connection + * @param param_name the name of the parameter with the key + * @param[out] out_data pointer to allocate buffer and store the result + * @param[out] out_size set to the size of the buffer allocated in @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 +TMH_PARSE_mhd_request_var_arg_data (struct MHD_Connection *connection, + const char *param_name, + void **out_data, + size_t *out_size); + + + + +#endif /* TALER_MINT_HTTPD_PARSING_H */ diff --git a/src/backend/taler-merchant-httpd_pay.c b/src/backend/taler-merchant-httpd_pay.c index 1885c59c..5191d711 100644 --- a/src/backend/taler-merchant-httpd_pay.c +++ b/src/backend/taler-merchant-httpd_pay.c @@ -28,10 +28,10 @@ #include #include #include "taler-merchant-httpd.h" -#include "taler-mint-httpd.h" -#include "taler-mint-httpd_parsing.h" -#include "taler-mint-httpd_responses.h" -#include "taler-mint-httpd_mhd.h" +#include "taler-merchant-httpd.h" +#include "taler-merchant-httpd_parsing.h" +#include "taler-merchant-httpd_responses.h" +#include "taler-merchant-httpd_mhd.h" #include "taler_merchantdb_lib.h" @@ -214,7 +214,7 @@ deposit_cb (void *cls, /*FIXME the index is the same for every individual cb */ if (GNUNET_SYSERR == - MERCHANT_DB_update_deposit_permission (db_conn, + TALER_MERCHANTDB_deposit_permission_update (db_conn, dcc->pc->transaction_id, 0)) /* TODO */ @@ -525,7 +525,7 @@ MH_handler_pay (struct TMH_RequestHandler *rh, /* b */ char *deposit_permission_str = json_dumps (root, JSON_COMPACT); - if (GNUNET_OK != MERCHANT_DB_store_deposit_permission (db_conn, + if (GNUNET_OK != TALER_MERCHANTDB_deposit_permission_store (db_conn, deposit_permission_str, transaction_id, 1, diff --git a/src/backend/taler-merchant-httpd_pay.h b/src/backend/taler-merchant-httpd_pay.h index 6a796e06..6fa7b8f3 100644 --- a/src/backend/taler-merchant-httpd_pay.h +++ b/src/backend/taler-merchant-httpd_pay.h @@ -23,7 +23,7 @@ #ifndef TALER_MINT_HTTPD_PAY_H #define TALER_MINT_HTTPD_PAY_H #include -#include "taler-mint-httpd.h" +#include "taler-merchant-httpd.h" /** * Manage a payment @@ -33,7 +33,7 @@ * @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 diff --git a/src/backend/taler-merchant-httpd_responses.c b/src/backend/taler-merchant-httpd_responses.c new file mode 100644 index 00000000..1e2902c2 --- /dev/null +++ b/src/backend/taler-merchant-httpd_responses.c @@ -0,0 +1,206 @@ +/* + 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, If not, see +*/ +/** + * @file taler-merchant-httpd_responses.c + * @brief API for generating the various replies of the mint; these + * functions are called TMH_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 "taler-merchant-httpd_responses.h" +#include +#include + + +/** + * 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 +TMH_RESPONSE_reply_json (struct MHD_Connection *connection, + const json_t *json, + unsigned int response_code) +{ + struct MHD_Response *resp; + char *json_str; + int ret; + + json_str = json_dumps (json, JSON_INDENT(2)); + GNUNET_assert (NULL != json_str); + 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 MHD_NO; + } + (void) MHD_add_response_header (resp, + MHD_HTTP_HEADER_CONTENT_TYPE, + "application/json"); + 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 +TMH_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 = TMH_RESPONSE_reply_json (connection, + json, + response_code); + json_decref (json); + return ret; +} + +/** + * Send a response indicating an internal error. + * + * @param connection the MHD connection to use + * @param hint hint about the internal error's nature + * @return a MHD result code + */ +int +TMH_RESPONSE_reply_internal_error (struct MHD_Connection *connection, + const char *hint) +{ + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + "{s:s, s:s}", + "error", "internal error", + "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 +TMH_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; + 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 +TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection) +{ + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s}", + "error", + "invalid json"); +} + +/** + * 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 +TMH_RESPONSE_add_global_headers (struct MHD_Response *response) +{ + int TMH_mint_connection_close; + TMH_mint_connection_close = 0; + + /* this test is taken verbatim from the mint's code, + so there is no particular need to do that for a merchant */ + if (TMH_mint_connection_close) + (void) MHD_add_response_header (response, + MHD_HTTP_HEADER_CONNECTION, + "close"); +} + +/** + * Send a response indicating an external error. + * + * @param connection the MHD connection to use + * @param hint hint about the error's nature + * @return a MHD result code + */ +int +TMH_RESPONSE_reply_external_error (struct MHD_Connection *connection, + const char *hint) +{ + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:s}", + "error", "client error", + "hint", hint); +} +/* end of taler-mint-httpd_responses.c */ diff --git a/src/backend/taler-merchant-httpd_responses.h b/src/backend/taler-merchant-httpd_responses.h new file mode 100644 index 00000000..ad063eb8 --- /dev/null +++ b/src/backend/taler-merchant-httpd_responses.h @@ -0,0 +1,112 @@ +/* + 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, If not, see +*/ + +/** + * @file taler-merchant-httpd_responses.h + * @brief API for generating the various replies of the mint; these + * functions are called TMH_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_MINT_HTTPD_RESPONSES_H +#define TALER_MINT_HTTPD_RESPONSES_H +#include +#include +#include +#include + +/** + * 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 +TMH_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 +TMH_RESPONSE_reply_json_pack (struct MHD_Connection *connection, + unsigned int response_code, + const char *fmt, + ...); + + +/** + * Send a response indicating that the JSON was malformed. + * + * @param connection the MHD connection to use + * @return a MHD result code + */ +int +TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection); + +/** + * Send a response indicating an internal error. + * + * @param connection the MHD connection to use + * @param hint hint about the internal error's nature + * @return a MHD result code + */ +int +TMH_RESPONSE_reply_internal_error (struct MHD_Connection *connection, + const char *hint); +/** + * Send a response indicating an external error. + * + * @param connection the MHD connection to use + * @param hint hint about the error's nature + * @return a MHD result code + */ +int +TMH_RESPONSE_reply_external_error (struct MHD_Connection *connection, + 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 +TMH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection); + +/** + * 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 +TMH_RESPONSE_add_global_headers (struct MHD_Response *response); + +#endif diff --git a/src/backend/taler-mint-httpd.h b/src/backend/taler-mint-httpd.h deleted file mode 100644 index ad8702f0..00000000 --- a/src/backend/taler-mint-httpd.h +++ /dev/null @@ -1,85 +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, If not, see -*/ -/** - * @file taler-mint-httpd.h - * @brief Global declarations for the mint - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - * - * FIXME: Consider which of these need to really be globals... - */ -#ifndef TALER_MINT_HTTPD_H -#define TALER_MINT_HTTPD_H - -#include - -/** - * @brief Struct describing an URL and the handler for it. - */ -struct TMH_RequestHandler -{ - - /** - * URL the handler is for. - */ - const char *url; - - /** - * Method the handler is for, NULL for "all". - */ - const char *method; - - /** - * Mime type to use in reply (hint, can be NULL). - */ - const char *mime_type; - - /** - * Raw data for the @e handler - */ - const void *data; - - /** - * Number of bytes in @e data, 0 for 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 - */ - int (*handler)(struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size); - - /** - * Default response code. - */ - int response_code; -}; - - -#endif diff --git a/src/backend/taler-mint-httpd_mhd.c b/src/backend/taler-mint-httpd_mhd.c deleted file mode 100644 index 419c4fb0..00000000 --- a/src/backend/taler-mint-httpd_mhd.c +++ /dev/null @@ -1,154 +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, If not, see -*/ - -/** - * @file taler-mint-httpd_mhd.c - * @brief helpers for MHD interaction; these are TALER_MINT_handler_ functions - * that generate simple MHD replies that do not require any real operations - * to be performed (error handling, static pages, etc.) - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#include "platform.h" -#include -#include -#include -#include -#include "taler-mint-httpd_responses.h" -#include "taler-mint-httpd.h" -#include "taler-mint-httpd_mhd.h" -#include "taler-mint-httpd_responses.h" - - -/** - * Function to call to handle the request by sending - * back static data from the @a 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 - * @return MHD result code - */ -int -TMH_MHD_handler_static_response (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) -{ - struct MHD_Response *response; - int ret; - - if (0 == rh->data_size) - rh->data_size = strlen ((const char *) rh->data); - response = MHD_create_response_from_buffer (rh->data_size, - (void *) rh->data, - MHD_RESPMEM_PERSISTENT); - if (NULL == response) - { - GNUNET_break (0); - return MHD_NO; - } - TMH_RESPONSE_add_global_headers (response); - if (NULL != rh->mime_type) - (void) MHD_add_response_header (response, - MHD_HTTP_HEADER_CONTENT_TYPE, - rh->mime_type); - ret = MHD_queue_response (connection, - rh->response_code, - response); - MHD_destroy_response (response); - return ret; -} - - -/** - * Function to call to handle the request by sending - * back a redirect to the AGPL source code. - * - * @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 -TMH_MHD_handler_agpl_redirect (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - 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; - } - TMH_RESPONSE_add_global_headers (response); - if (NULL != rh->mime_type) - (void) MHD_add_response_header (response, - MHD_HTTP_HEADER_CONTENT_TYPE, - rh->mime_type); - MHD_add_response_header (response, - MHD_HTTP_HEADER_LOCATION, - "http://www.git.taler.net/?p=mint.git"); - ret = MHD_queue_response (connection, - rh->response_code, - response); - MHD_destroy_response (response); - return ret; -} - - -/** - * Function to call to handle the request by building a JSON - * reply with an error message from @a 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 - * @return MHD result code - */ -int -TMH_MHD_handler_send_json_pack_error (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) -{ - return TMH_RESPONSE_reply_json_pack (connection, - rh->response_code, - "{s:s}", - "error", - rh->data); -} - - -/* end of taler-mint-httpd_mhd.c */ diff --git a/src/backend/taler-mint-httpd_mhd.h b/src/backend/taler-mint-httpd_mhd.h deleted file mode 100644 index a9f575df..00000000 --- a/src/backend/taler-mint-httpd_mhd.h +++ /dev/null @@ -1,111 +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, If not, see -*/ - -/** - * @file taler-mint-httpd_mhd.h - * @brief helpers for MHD interaction, used to generate simple responses - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#ifndef TALER_MINT_HTTPD_MHD_H -#define TALER_MINT_HTTPD_MHD_H -#include -#include -#include "taler-mint-httpd.h" - - -/** - * Function to call to handle the request by sending - * back static data from the @a 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 - * @return MHD result code - */ -int -TMH_MHD_handler_static_response (struct TMH_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 sending - * back a redirect to the AGPL source code. - * - * @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 -TMH_MHD_handler_agpl_redirect (struct TMH_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 -TMH_MHD_helper_send_json_pack (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void *connection_cls, - int response_code, - int do_cache, - const char *fmt, - ...); - - -/** - * Function to call to handle the request by building a JSON - * reply with an error message from @a 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 - * @return MHD result code - */ -int -TMH_MHD_handler_send_json_pack_error (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size); - - -#endif diff --git a/src/backend/taler-mint-httpd_parsing.c b/src/backend/taler-mint-httpd_parsing.c deleted file mode 100644 index 314d8839..00000000 --- a/src/backend/taler-mint-httpd_parsing.c +++ /dev/null @@ -1,1061 +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, If not, see -*/ - -/** - * @file taler-mint-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 -#include "taler-mint-httpd_parsing.h" -#include "taler-mint-httpd_responses.h" - -/* Although the following declaration isn't in any case useful - to a merchant's activity, it's needed here to make the function - 'TMH_PARSE_nagivate_json ()' compile fine; so its value will be - kept on some merchant's accepted currency. For multi currencies - merchants, that of course would require a patch */ -extern char *TMH_merchant_currency_string; - -/** - * Initial size for POST request buffer. - */ -#define REQUEST_BUFFER_INITIAL (2*1024) - -/** - * Maximum POST request size. - */ -#define REQUEST_BUFFER_MAX (1024*1024) - - -/** - * Buffer for POST requests. - */ -struct Buffer -{ - /** - * Allocated memory - */ - char *data; - - /** - * Number of valid bytes in buffer. - */ - size_t fill; - - /** - * Number of allocated bytes in buffer. - */ - size_t alloc; -}; - - -/** - * Initialize a buffer. - * - * @param buf the buffer to initialize - * @param data the initial data - * @param data_size size of the initial data - * @param alloc_size size of the buffer - * @param max_size maximum size that the buffer can grow to - * @return a GNUnet result code - */ -static int -buffer_init (struct Buffer *buf, - const void *data, - size_t data_size, - size_t alloc_size, - size_t max_size) -{ - if (data_size > max_size || alloc_size > max_size) - return GNUNET_SYSERR; - if (data_size > alloc_size) - alloc_size = data_size; - buf->data = GNUNET_malloc (alloc_size); - memcpy (buf->data, data, data_size); - return GNUNET_OK; -} - - -/** - * Free the data in a buffer. Does *not* free - * the buffer object itself. - * - * @param buf buffer to de-initialize - */ -static void -buffer_deinit (struct Buffer *buf) -{ - GNUNET_free (buf->data); - buf->data = NULL; -} - - -/** - * Append data to a buffer, growing the buffer if necessary. - * - * @param buf the buffer to append to - * @param data the data to append - * @param data_size the size of @a data - * @param max_size maximum size that the buffer can grow to - * @return #GNUNET_OK on success, - * #GNUNET_NO if the buffer can't accomodate for the new data - */ -static int -buffer_append (struct Buffer *buf, - const void *data, - size_t data_size, - size_t max_size) -{ - if (buf->fill + data_size > max_size) - return GNUNET_NO; - if (data_size + buf->fill > buf->alloc) - { - char *new_buf; - size_t new_size = buf->alloc; - while (new_size < buf->fill + data_size) - new_size += 2; - if (new_size > max_size) - return GNUNET_NO; - new_buf = GNUNET_malloc (new_size); - memcpy (new_buf, buf->data, buf->fill); - GNUNET_free (buf->data); - buf->data = new_buf; - buf->alloc = new_size; - } - memcpy (buf->data + buf->fill, data, data_size); - buf->fill += data_size; - return GNUNET_OK; -} - -/** - * Function called whenever we are done with a request - * to clean up our state. - * - * @param con_cls value as it was left by - * #TMH_PARSE_post_json(), to be cleaned up - */ -void -TMH_PARSE_post_cleanup_callback (void *con_cls) -{ - struct Buffer *r = con_cls; - - if (NULL != r) - { - buffer_deinit (r); - GNUNET_free (r); - } -} - -/** - * Release all memory allocated for the variable-size fields in - * the parser specification. - * - * @param spec specification to free - * @param spec_len number of items in @a spec to look at - */ -static void -release_data (struct TMH_PARSE_FieldSpecification *spec, - unsigned int spec_len) -{ - unsigned int i; - - for (i=0; i < spec_len; i++) - { - switch (spec[i].command) - { - case TMH_PARSE_JNC_FIELD: - GNUNET_break (0); - return; - case TMH_PARSE_JNC_RET_STRING: - GNUNET_break (0); - return; - case TMH_PARSE_JNC_INDEX: - GNUNET_break (0); - return; - case TMH_PARSE_JNC_RET_DATA: - break; - case TMH_PARSE_JNC_RET_DATA_VAR: - if (NULL != spec[i].destination) - { - GNUNET_free (* (void**) spec[i].destination); - *(void**) spec[i].destination = NULL; - *spec[i].destination_size_out = 0; - } - break; - case TMH_PARSE_JNC_RET_TYPED_JSON: - { - json_t *json; - - json = *(json_t **) spec[i].destination; - if (NULL != json) - { - json_decref (json); - *(json_t**) spec[i].destination = NULL; - } - } - break; - case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY: - { - struct TALER_DenominationPublicKey *pk; - - pk = spec[i].destination; - if (NULL != pk->rsa_public_key) - { - GNUNET_CRYPTO_rsa_public_key_free (pk->rsa_public_key); - pk->rsa_public_key = NULL; - } - } - break; - case TMH_PARSE_JNC_RET_RSA_SIGNATURE: - { - struct TALER_DenominationSignature *sig; - - sig = spec[i].destination; - if (NULL != sig->rsa_signature) - { - GNUNET_CRYPTO_rsa_signature_free (sig->rsa_signature); - sig->rsa_signature = NULL; - } - } - break; - case TMH_PARSE_JNC_RET_AMOUNT: - memset (spec[i].destination, - 0, - sizeof (struct TALER_Amount)); - break; - case TMH_PARSE_JNC_RET_TIME_ABSOLUTE: - break; - case TMH_PARSE_JNC_RET_UINT64: - break; - } - } -} - -/** - * 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 - * #TMH_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 -TMH_PARSE_post_json (struct MHD_Connection *connection, - void **con_cls, - const char *upload_data, - size_t *upload_data_size, - json_t **json) -{ - struct Buffer *r = *con_cls; - - *json = NULL; - if (NULL == *con_cls) - { - /* We are seeing a fresh POST request. */ - r = GNUNET_new (struct Buffer); - if (GNUNET_OK != - buffer_init (r, - upload_data, - *upload_data_size, - REQUEST_BUFFER_INITIAL, - REQUEST_BUFFER_MAX)) - { - *con_cls = NULL; - buffer_deinit (r); - GNUNET_free (r); - return (MHD_NO == - TMH_RESPONSE_reply_internal_error (connection, - "out of memory")) - ? GNUNET_SYSERR : GNUNET_NO; - } - /* everything OK, wait for more POST data */ - *upload_data_size = 0; - *con_cls = r; - return GNUNET_YES; - } - if (0 != *upload_data_size) - { - /* We are seeing an old request with more data available. */ - - if (GNUNET_OK != - buffer_append (r, - upload_data, - *upload_data_size, - REQUEST_BUFFER_MAX)) - { - /* Request too long */ - *con_cls = NULL; - buffer_deinit (r); - GNUNET_free (r); - return (MHD_NO == - TMH_RESPONSE_reply_request_too_large (connection)) - ? GNUNET_SYSERR : GNUNET_NO; - } - /* everything OK, wait for more POST data */ - *upload_data_size = 0; - return GNUNET_YES; - } - - /* We have seen the whole request. */ - - *json = json_loadb (r->data, - r->fill, - 0, - NULL); - if (NULL == *json) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to parse JSON request body\n"); - return (MHD_YES == - TMH_RESPONSE_reply_invalid_json (connection)) - ? GNUNET_NO : GNUNET_SYSERR; - } - buffer_deinit (r); - GNUNET_free (r); - *con_cls = NULL; - - return GNUNET_YES; -} - -/** - * Generate line in parser specification for string. The returned - * string is already nul-terminated internally by JSON, so no length - * information is provided. The string will live as long as the containg - * JSON will, and must not be freed by the user - * @param field name of the field - * @param[out] pointer to the string - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_string (const char *field, - char **out) -{ - struct TMH_PARSE_FieldSpecification ret = - {field, (void **) out, 0, NULL, TMH_PARSE_JNC_RET_STRING, 0}; - return ret; -} - -/** - * Generate line in parser specification for 64-bit integer - * given as an integer in JSON. - * - * @param field name of the field - * @param[out] u64 integer to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_uint64 (const char *field, - uint64_t *u64) -{ - struct TMH_PARSE_FieldSpecification ret = - { field, (void *) u64, sizeof (uint64_t), NULL, TMH_PARSE_JNC_RET_UINT64, 0 }; - return ret; -} - - -/** - * Generate line in parser specification for JSON object value. - * - * @param field name of the field - * @param[out] jsonp address of pointer to JSON to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_object (const char *field, - json_t **jsonp) -{ - struct TMH_PARSE_FieldSpecification ret = - { field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_OBJECT }; - *jsonp = NULL; - return ret; -} - - -/** - * Generate line in parser specification for JSON array value. - * - * @param field name of the field - * @param[out] jsonp address of JSON pointer to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_array (const char *field, - json_t **jsonp) -{ - struct TMH_PARSE_FieldSpecification ret = - { field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_ARRAY }; - *jsonp = NULL; - return ret; -} - - -/** - * Generate line in parser specification for an absolute time. - * - * @param field name of the field - * @param[out] atime time to initialize - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_time_abs (const char *field, - struct GNUNET_TIME_Absolute *atime) -{ - struct TMH_PARSE_FieldSpecification ret = - { field, atime, sizeof(struct GNUNET_TIME_Absolute), NULL, TMH_PARSE_JNC_RET_TIME_ABSOLUTE, 0 }; - return ret; -} - - -/** - * Generate line in parser specification for RSA public key. - * - * @param field name of the field - * @param[out] pk key to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_denomination_public_key (const char *field, - struct TALER_DenominationPublicKey *pk) -{ - struct TMH_PARSE_FieldSpecification ret = - { field, pk, 0, NULL, TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, 0 }; - pk->rsa_public_key = NULL; - return ret; -} - - -/** - * Generate line in parser specification for RSA public key. - * - * @param field name of the field - * @param sig the signature to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_denomination_signature (const char *field, - struct TALER_DenominationSignature *sig) -{ - struct TMH_PARSE_FieldSpecification ret = - { field, sig, 0, NULL, TMH_PARSE_JNC_RET_RSA_SIGNATURE, 0 }; - sig->rsa_signature = NULL; - return ret; -} - - -/** - * Generate line in parser specification for an amount. - * - * @param field name of the field - * @param amount a `struct TALER_Amount *` to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_amount (const char *field, - struct TALER_Amount *amount) -{ - struct TMH_PARSE_FieldSpecification ret = - { field, amount, sizeof(struct TALER_Amount), NULL, TMH_PARSE_JNC_RET_AMOUNT, 0 }; - memset (amount, 0, sizeof (struct TALER_Amount)); - return ret; -} - - -/** - * Generate line in parser specification for variable-size value. - * - * @param field name of the field - * @param[out] ptr pointer to initialize - * @param[out] ptr_size size to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_variable (const char *field, - void **ptr, - size_t *ptr_size) -{ - struct TMH_PARSE_FieldSpecification ret = - { field, ptr, 0, ptr_size, TMH_PARSE_JNC_RET_DATA_VAR, 0 }; - *ptr = NULL; - return ret; -} - -/** - * Navigate through a JSON tree. - * - * Sends an error response if navigation is impossible (i.e. - * the JSON object is invalid) - * - * @param connection the connection to send an error response to - * @param root the JSON node to start the navigation at. - * @param ... navigation specification (see - * `enum TMH_PARSE_JsonNavigationCommand`) - * @return - * #GNUNET_YES if navigation was successful - * #GNUNET_NO if json is malformed, error response was generated - * #GNUNET_SYSERR on internal error (no response was generated, - * connection must be closed) - */ -int -TMH_PARSE_navigate_json (struct MHD_Connection *connection, - const json_t *root, - ...) -{ - va_list argp; - int ret; - json_t *path; /* what's our current path from 'root'? */ - - path = json_array (); - va_start (argp, root); - ret = 2; /* just not any of the valid return values */ - while (2 == ret) - { - enum TMH_PARSE_JsonNavigationCommand command - = va_arg (argp, - enum TMH_PARSE_JsonNavigationCommand); - - switch (command) - { - case TMH_PARSE_JNC_FIELD: - { - const char *fname = va_arg(argp, const char *); - - json_array_append_new (path, - json_string (fname)); - root = json_object_get (root, - fname); - if (NULL == root) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:s, s:O}", - "error", "missing field in JSON", - "field", fname, - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - } - break; - - case TMH_PARSE_JNC_INDEX: - { - int fnum = va_arg(argp, int); - - json_array_append_new (path, - json_integer (fnum)); - root = json_array_get (root, - fnum); - if (NULL == root) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "missing index in JSON", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - } - break; - - case TMH_PARSE_JNC_RET_DATA: - { - void *where = va_arg (argp, void *); - size_t len = va_arg (argp, size_t); - const char *str; - int res; - - str = json_string_value (root); - if (NULL == str) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "string expected", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - res = GNUNET_STRINGS_string_to_data (str, strlen (str), - where, len); - if (GNUNET_OK != res) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "malformed binary data in JSON", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - ret = GNUNET_OK; - } - break; - - case TMH_PARSE_JNC_RET_STRING: - { - void **where = va_arg (argp, void **); - *where = (void*) json_string_value (root); - ret = GNUNET_OK; - } - break; - case TMH_PARSE_JNC_RET_DATA_VAR: - { - void **where = va_arg (argp, void **); - size_t *len = va_arg (argp, size_t *); - const char *str; - int res; - - str = json_string_value (root); - if (NULL == str) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_internal_error (connection, - "json_string_value() failed")) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - *len = (strlen (str) * 5) / 8; - if (NULL != where) - { - *where = GNUNET_malloc (*len); - res = GNUNET_STRINGS_string_to_data (str, - strlen (str), - *where, - *len); - if (GNUNET_OK != res) - { - GNUNET_break_op (0); - GNUNET_free (*where); - *where = NULL; - *len = 0; - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "malformed binary data in JSON", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - } - ret = GNUNET_OK; - } - break; - - case TMH_PARSE_JNC_RET_TYPED_JSON: - { - int typ = va_arg (argp, int); - const json_t **r_json = va_arg (argp, const json_t **); - - if ( (NULL == root) || - ( (-1 != typ) && - (json_typeof (root) != typ)) ) - { - GNUNET_break_op (0); - *r_json = NULL; - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:i, s:i, s:O}", - "error", "wrong JSON field type", - "type_expected", typ, - "type_actual", json_typeof (root), - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - *r_json = root; - json_incref ((json_t *) root); - ret = GNUNET_OK; - } - break; - - case TMH_PARSE_JNC_RET_UINT64: - { - uint64_t *r_u64 = va_arg (argp, uint64_t *); - - if (json_typeof (root) != JSON_INTEGER) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:s, s:i, s:O}", - "error", "wrong JSON field type", - "type_expected", "integer", - "type_actual", json_typeof (root), - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - *r_u64 = (uint64_t) json_integer_value (root); - ret = GNUNET_OK; - } - break; - - case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY: - { - struct TALER_DenominationPublicKey *where; - size_t len; - const char *str; - int res; - void *buf; - - where = va_arg (argp, - struct TALER_DenominationPublicKey *); - str = json_string_value (root); - if (NULL == str) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "string expected", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - len = (strlen (str) * 5) / 8; - buf = GNUNET_malloc (len); - res = GNUNET_STRINGS_string_to_data (str, - strlen (str), - buf, - len); - if (GNUNET_OK != res) - { - GNUNET_break_op (0); - GNUNET_free (buf); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "malformed binary data in JSON", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - where->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (buf, - len); - GNUNET_free (buf); - if (NULL == where->rsa_public_key) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "malformed RSA public key in JSON", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - ret = GNUNET_OK; - break; - } - - case TMH_PARSE_JNC_RET_RSA_SIGNATURE: - { - struct TALER_DenominationSignature *where; - size_t len; - const char *str; - int res; - void *buf; - - where = va_arg (argp, - struct TALER_DenominationSignature *); - str = json_string_value (root); - if (NULL == str) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "string expected", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - len = (strlen (str) * 5) / 8; - buf = GNUNET_malloc (len); - res = GNUNET_STRINGS_string_to_data (str, - strlen (str), - buf, - len); - if (GNUNET_OK != res) - { - GNUNET_break_op (0); - GNUNET_free (buf); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "malformed binary data in JSON", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - where->rsa_signature = GNUNET_CRYPTO_rsa_signature_decode (buf, - len); - GNUNET_free (buf); - if (NULL == where->rsa_signature) - { - GNUNET_break_op (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "malformed RSA signature in JSON", - "path", path)) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - ret = GNUNET_OK; - break; - } - - case TMH_PARSE_JNC_RET_AMOUNT: - { - struct TALER_Amount *where = va_arg (argp, void *); - - if (GNUNET_OK != - TALER_json_to_amount ((json_t *) root, - where)) - { - GNUNET_break_op (0); - ret = (MHD_YES != - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O}", - "error", "Bad format", - "path", path)) - ? GNUNET_SYSERR : GNUNET_NO; - break; - } - if (0 != strcmp (where->currency, - TMH_merchant_currency_string)) - { - GNUNET_break_op (0); - ret = (MHD_YES != - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:O, s:s}", - "error", "Currency not supported", - "path", path, - "currency", where->currency)) - ? GNUNET_SYSERR : GNUNET_NO; - memset (where, 0, sizeof (struct TALER_Amount)); - break; - } - ret = GNUNET_OK; - break; - } - - case TMH_PARSE_JNC_RET_TIME_ABSOLUTE: - { - struct GNUNET_TIME_Absolute *where = va_arg (argp, void *); - - if (GNUNET_OK != - TALER_json_to_abs ((json_t *) root, - where)) - { - GNUNET_break_op (0); - ret = (MHD_YES != - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:s, s:O}", - "error", "Bad format", - "hint", "expected absolute time", - "path", path)) - ? GNUNET_SYSERR : GNUNET_NO; - break; - } - ret = GNUNET_OK; - break; - } - - default: - GNUNET_break (0); - ret = (MHD_YES == - TMH_RESPONSE_reply_internal_error (connection, - "unhandled value in switch")) - ? GNUNET_NO : GNUNET_SYSERR; - break; - } - } - va_end (argp); - json_decref (path); - return ret; -} - - - -/** - * 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 - * #TMH_PARSE_release_data() when done) - * #GNUNET_NO if json is malformed, error response was generated - * #GNUNET_SYSERR on internal error - */ -int -TMH_PARSE_json_data (struct MHD_Connection *connection, - const json_t *root, - struct TMH_PARSE_FieldSpecification *spec) -{ - unsigned int i; - int ret; - - ret = GNUNET_YES; - for (i=0; NULL != spec[i].field_name; i++) - { - if (GNUNET_YES != ret) - break; - switch (spec[i].command) - { - case TMH_PARSE_JNC_FIELD: - GNUNET_break (0); - return GNUNET_SYSERR; - case TMH_PARSE_JNC_INDEX: - GNUNET_break (0); - return GNUNET_SYSERR; - case TMH_PARSE_JNC_RET_DATA: - ret = TMH_PARSE_navigate_json (connection, - root, - TMH_PARSE_JNC_FIELD, - spec[i].field_name, - TMH_PARSE_JNC_RET_DATA, - spec[i].destination, - spec[i].destination_size_in); - break; - case TMH_PARSE_JNC_RET_DATA_VAR: - ret = TMH_PARSE_navigate_json (connection, - root, - TMH_PARSE_JNC_FIELD, - spec[i].field_name, - TMH_PARSE_JNC_RET_DATA_VAR, - (void **) spec[i].destination, - spec[i].destination_size_out); - break; - case TMH_PARSE_JNC_RET_STRING: - ret = TMH_PARSE_navigate_json (connection, - root, - TMH_PARSE_JNC_FIELD, - spec[i].field_name, - TMH_PARSE_JNC_RET_STRING, - spec[i].destination); - break; - case TMH_PARSE_JNC_RET_TYPED_JSON: - ret = TMH_PARSE_navigate_json (connection, - root, - TMH_PARSE_JNC_FIELD, - spec[i].field_name, - TMH_PARSE_JNC_RET_TYPED_JSON, - spec[i].type, - spec[i].destination); - break; - case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY: - ret = TMH_PARSE_navigate_json (connection, - root, - TMH_PARSE_JNC_FIELD, - spec[i].field_name, - TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, - spec[i].destination); - break; - case TMH_PARSE_JNC_RET_RSA_SIGNATURE: - ret = TMH_PARSE_navigate_json (connection, - root, - TMH_PARSE_JNC_FIELD, - spec[i].field_name, - TMH_PARSE_JNC_RET_RSA_SIGNATURE, - spec[i].destination); - break; - case TMH_PARSE_JNC_RET_AMOUNT: - GNUNET_assert (sizeof (struct TALER_Amount) == - spec[i].destination_size_in); - ret = TMH_PARSE_navigate_json (connection, - root, - TMH_PARSE_JNC_FIELD, - spec[i].field_name, - TMH_PARSE_JNC_RET_AMOUNT, - spec[i].destination); - break; - case TMH_PARSE_JNC_RET_TIME_ABSOLUTE: - GNUNET_assert (sizeof (struct GNUNET_TIME_Absolute) == - spec[i].destination_size_in); - ret = TMH_PARSE_navigate_json (connection, - root, - TMH_PARSE_JNC_FIELD, - spec[i].field_name, - TMH_PARSE_JNC_RET_TIME_ABSOLUTE, - spec[i].destination); - break; - case TMH_PARSE_JNC_RET_UINT64: - GNUNET_assert (sizeof (uint64_t) == - spec[i].destination_size_in); - ret = TMH_PARSE_navigate_json (connection, - root, - TMH_PARSE_JNC_FIELD, - spec[i].field_name, - TMH_PARSE_JNC_RET_UINT64, - spec[i].destination); - break; - } - } - if (GNUNET_YES != ret) - release_data (spec, - i - 1); - return ret; -} - - -/* end of taler-mint-httpd_parsing.c */ diff --git a/src/backend/taler-mint-httpd_parsing.h b/src/backend/taler-mint-httpd_parsing.h deleted file mode 100644 index dae65092..00000000 --- a/src/backend/taler-mint-httpd_parsing.h +++ /dev/null @@ -1,424 +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, If not, see -*/ -/** - * @file taler-mint-httpd_parsing.h - * @brief functions to parse incoming requests - * @author Florian Dold - * @author Benedikt Mueller - * @author Christian Grothoff - */ -#ifndef TALER_MINT_HTTPD_PARSING_H -#define TALER_MINT_HTTPD_PARSING_H - -#include -#include -#include - -/** - * 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 - * #TMH_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 -TMH_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 - * #TMH_PARSE_post_json(), to be cleaned up - */ -void -TMH_PARSE_post_cleanup_callback (void *con_cls); - - -/** - * Constants for JSON navigation description. - */ -enum TMH_PARSE_JsonNavigationCommand -{ - /** - * Access a field. - * Param: const char * - */ - TMH_PARSE_JNC_FIELD, - - /** - * Access an array index. - * Param: int - */ - TMH_PARSE_JNC_INDEX, - - /** - * Return base32crockford encoded data of - * constant size. - * Params: (void *, size_t) - */ - TMH_PARSE_JNC_RET_DATA, - - /** - * Return base32crockford encoded data of - * variable size. - * Params: (void **, size_t *) - */ - TMH_PARSE_JNC_RET_DATA_VAR, - - /** - * Return a json object, which must be - * of the given type (JSON_* type constants, - * or -1 for any type). - * Params: (int, json_t **) - */ - TMH_PARSE_JNC_RET_TYPED_JSON, - - /** - * Return a `struct GNUNET_CRYPTO_rsa_PublicKey` which was - * encoded as variable-size base32crockford encoded data. - */ - TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, - - /** - * Return a `struct GNUNET_CRYPTO_rsa_Signature` which was - * encoded as variable-size base32crockford encoded data. - */ - TMH_PARSE_JNC_RET_RSA_SIGNATURE, - - /** - * Return a `struct TALER_Amount` which was - * encoded within its own json object. - */ - TMH_PARSE_JNC_RET_AMOUNT, - - /** - * Return a `struct GNUNET_TIME_Absolute` which was - * encoded within its own json object. - * Param: struct GNUNET_TIME_Absolute * - */ - TMH_PARSE_JNC_RET_TIME_ABSOLUTE, - - /** - * Return a `uint64_t` which was - * encoded as a JSON integer. - * Param: uint64_t * - */ - TMH_PARSE_JNC_RET_UINT64, - /** - * Return a 'char *' as returned from 'json_string_value ()'. - * So it will live as long as the containg JSON is not freed, - * and must not be freed by the user - */ - TMH_PARSE_JNC_RET_STRING - -}; - - -/** - * Navigate through a JSON tree. - * - * Sends an error response if navigation is impossible (i.e. - * the JSON object is invalid) - * - * @param connection the connection to send an error response to - * @param root the JSON node to start the navigation at. - * @param ... navigation specification (see `enum TMH_PARSE_JsonNavigationCommand`) - * @return - * #GNUNET_YES if navigation was successful - * #GNUNET_NO if json is malformed, error response was generated - * #GNUNET_SYSERR on internal error - */ -int -TMH_PARSE_navigate_json (struct MHD_Connection *connection, - const json_t *root, - ...); - - -/** - * @brief Specification for how to parse a JSON field. - */ -struct TMH_PARSE_FieldSpecification -{ - /** - * Name of the field. NULL only to terminate array. - */ - const char *field_name; - - /** - * Where to store the result. Must have exactly - * @e destination_size bytes, except if @e destination_size is zero. - * NULL to skip assignment (but check presence of the value). - */ - void *destination; - - /** - * How big should the result be, 0 for variable size. In - * this case, @e destination must be a "void **", pointing - * to a location that is currently NULL and is to be allocated. - */ - size_t destination_size_in; - - /** - * @e destination_size_out will then be set to the size of the - * value that was stored in @e destination (useful for - * variable-size allocations). - */ - size_t *destination_size_out; - - /** - * Navigation command to use to extract the value. Note that - * #TMH_PARSE_JNC_RET_DATA or #TMH_PARSE_JNC_RET_DATA_VAR must be used for @e - * destination_size_in and @e destination_size_out to have a - * meaning. #TMH_PARSE_JNC_FIELD and #TMH_PARSE_JNC_INDEX must not be used here! - */ - enum TMH_PARSE_JsonNavigationCommand command; - - /** - * JSON type to use, only meaningful in connection with a @e command - * value of #TMH_PARSE_JNC_RET_TYPED_JSON. Typical values are - * #JSON_ARRAY and #JSON_OBJECT. - */ - int type; - -}; - - -/** - * 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 - * #TMH_PARSE_release_data() when done) - * #GNUNET_NO if json is malformed, error response was generated - * #GNUNET_SYSERR on internal error - */ -int -TMH_PARSE_json_data (struct MHD_Connection *connection, - const json_t *root, - struct TMH_PARSE_FieldSpecification *spec); - - -/** - * Release all memory allocated for the variable-size fields in - * the parser specification. - * - * @param spec specification to free - */ -void -TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec); - - -/** - * Generate line in parser specification for fixed-size value. - * - * @param field name of the field - * @param value where to store the value - */ -#define TMH_PARSE_member_fixed(field,value) { field, value, sizeof (*value), NULL, TMH_PARSE_JNC_RET_DATA, 0 } - - -/** - * Generate line in parser specification for variable-size value. - * - * @param field name of the field - * @param[out] ptr pointer to initialize - * @param[out] ptr_size size to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_variable (const char *field, - void **ptr, - size_t *ptr_size); - -/** - * Generate line in parser specification for string. The returned - * string is already nul-terminated internally by JSON, so no length - * information is provided. The string will live as long as the containg - * JSON will, and must not be freed by the user - * @param field name of the field - * @param[out] pointer to the string - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_string (const char *field, - char **out); -/** - * Generate line in parser specification for 64-bit integer - * given as an integer in JSON. - * - * @param field name of the field - * @param[out] u64 integer to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_uint64 (const char *field, - uint64_t *u64); - - -/** - * Generate line in parser specification for JSON array value. - * - * @param field name of the field - * @param[out] jsonp address of JSON pointer to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_array (const char *field, - json_t **jsonp); - - -/** - * Generate line in parser specification for JSON object value. - * - * @param field name of the field - * @param[out] jsonp address of pointer to JSON to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_object (const char *field, - json_t **jsonp); - - -/** - * Generate line in parser specification for RSA public key. - * - * @param field name of the field - * @param[out] pk key to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_denomination_public_key (const char *field, - struct TALER_DenominationPublicKey *pk); - - -/** - * Generate line in parser specification for RSA public key. - * - * @param field name of the field - * @param sig the signature to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_denomination_signature (const char *field, - struct TALER_DenominationSignature *sig); - - -/** - * Generate line in parser specification for an amount. - * - * @param field name of the field - * @param[out] amount a `struct TALER_Amount *` to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_amount (const char *field, - struct TALER_Amount *amount); - - -/** - * Generate line in parser specification for an absolute time. - * - * @param field name of the field - * @param[out] atime time to initialize - * @return corresponding field spec - */ -struct TMH_PARSE_FieldSpecification -TMH_PARSE_member_time_abs (const char *field, - struct GNUNET_TIME_Absolute *atime); - - - -/** - * Generate line in parser specification indicating the end of the spec. - */ -#define TMH_PARSE_MEMBER_END { NULL, NULL, 0, NULL, TMH_PARSE_JNC_FIELD, 0 } - - -/** - * 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 -TMH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection, - const char *param_name, - void *out_data, - size_t out_size); - - -/** - * Extraxt variable-size base32crockford encoded data from request. - * - * Queues an error response to the connection if the parameter is missing - * or the encoding is invalid. - * - * @param connection the MHD connection - * @param param_name the name of the parameter with the key - * @param[out] out_data pointer to allocate buffer and store the result - * @param[out] out_size set to the size of the buffer allocated in @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 -TMH_PARSE_mhd_request_var_arg_data (struct MHD_Connection *connection, - const char *param_name, - void **out_data, - size_t *out_size); - - - - -#endif /* TALER_MINT_HTTPD_PARSING_H */ diff --git a/src/backend/taler-mint-httpd_responses.c b/src/backend/taler-mint-httpd_responses.c deleted file mode 100644 index 00a4d25f..00000000 --- a/src/backend/taler-mint-httpd_responses.c +++ /dev/null @@ -1,206 +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, If not, see -*/ -/** - * @file taler-mint-httpd_responses.c - * @brief API for generating the various replies of the mint; these - * functions are called TMH_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 "taler-mint-httpd_responses.h" -#include -#include - - -/** - * 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 -TMH_RESPONSE_reply_json (struct MHD_Connection *connection, - const json_t *json, - unsigned int response_code) -{ - struct MHD_Response *resp; - char *json_str; - int ret; - - json_str = json_dumps (json, JSON_INDENT(2)); - GNUNET_assert (NULL != json_str); - 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 MHD_NO; - } - (void) MHD_add_response_header (resp, - MHD_HTTP_HEADER_CONTENT_TYPE, - "application/json"); - 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 -TMH_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 = TMH_RESPONSE_reply_json (connection, - json, - response_code); - json_decref (json); - return ret; -} - -/** - * Send a response indicating an internal error. - * - * @param connection the MHD connection to use - * @param hint hint about the internal error's nature - * @return a MHD result code - */ -int -TMH_RESPONSE_reply_internal_error (struct MHD_Connection *connection, - const char *hint) -{ - return TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - "{s:s, s:s}", - "error", "internal error", - "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 -TMH_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; - 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 -TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection) -{ - return TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s}", - "error", - "invalid json"); -} - -/** - * 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 -TMH_RESPONSE_add_global_headers (struct MHD_Response *response) -{ - int TMH_mint_connection_close; - TMH_mint_connection_close = 0; - - /* this test is taken verbatim from the mint's code, - so there is no particular need to do that for a merchant */ - if (TMH_mint_connection_close) - (void) MHD_add_response_header (response, - MHD_HTTP_HEADER_CONNECTION, - "close"); -} - -/** - * Send a response indicating an external error. - * - * @param connection the MHD connection to use - * @param hint hint about the error's nature - * @return a MHD result code - */ -int -TMH_RESPONSE_reply_external_error (struct MHD_Connection *connection, - const char *hint) -{ - return TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:s}", - "error", "client error", - "hint", hint); -} -/* end of taler-mint-httpd_responses.c */ diff --git a/src/backend/taler-mint-httpd_responses.h b/src/backend/taler-mint-httpd_responses.h deleted file mode 100644 index f947bd57..00000000 --- a/src/backend/taler-mint-httpd_responses.h +++ /dev/null @@ -1,112 +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, If not, see -*/ - -/** - * @file taler-mint-httpd_responses.h - * @brief API for generating the various replies of the mint; these - * functions are called TMH_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_MINT_HTTPD_RESPONSES_H -#define TALER_MINT_HTTPD_RESPONSES_H -#include -#include -#include -#include - -/** - * 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 -TMH_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 -TMH_RESPONSE_reply_json_pack (struct MHD_Connection *connection, - unsigned int response_code, - const char *fmt, - ...); - - -/** - * Send a response indicating that the JSON was malformed. - * - * @param connection the MHD connection to use - * @return a MHD result code - */ -int -TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection); - -/** - * Send a response indicating an internal error. - * - * @param connection the MHD connection to use - * @param hint hint about the internal error's nature - * @return a MHD result code - */ -int -TMH_RESPONSE_reply_internal_error (struct MHD_Connection *connection, - const char *hint); -/** - * Send a response indicating an external error. - * - * @param connection the MHD connection to use - * @param hint hint about the error's nature - * @return a MHD result code - */ -int -TMH_RESPONSE_reply_external_error (struct MHD_Connection *connection, - 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 -TMH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection); - -/** - * 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 -TMH_RESPONSE_add_global_headers (struct MHD_Response *response); - -#endif diff --git a/src/backenddb/merchant_db.c b/src/backenddb/merchant_db.c index 6575b9ed..d8bef636 100644 --- a/src/backenddb/merchant_db.c +++ b/src/backenddb/merchant_db.c @@ -56,7 +56,7 @@ * @return connection to the postgresql database; NULL upon error */ PGconn * -MERCHANT_DB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) +TALER_MERCHANTDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) { return GNUNET_POSTGRES_connect (cfg, "merchant-db"); } @@ -68,7 +68,7 @@ MERCHANT_DB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) * @param conn database handle to close */ void -MERCHANT_DB_disconnect (PGconn *conn) +TALER_MERCHANTDB_disconnect (PGconn *conn) { PQfinish (conn); } @@ -83,7 +83,7 @@ MERCHANT_DB_disconnect (PGconn *conn) * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure */ int -MERCHANT_DB_initialize (PGconn *conn, int tmp) +TALER_MERCHANTDB_initialize (PGconn *conn, int tmp) { const char *tmp_str = (1 == tmp) ? "TEMPORARY" : ""; char *sql; @@ -264,7 +264,7 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp) * @return #GNUNET_OK if successful, #GNUNET_SYSERR upon errors */ uint32_t -MERCHANT_DB_update_deposit_permission (PGconn *conn, +TALER_MERCHANTDB_deposit_permission_update (PGconn *conn, uint64_t transaction_id, unsigned int pending) { @@ -299,6 +299,7 @@ MERCHANT_DB_update_deposit_permission (PGconn *conn, PQclear (res); return GNUNET_SYSERR; } + return GNUNET_OK; } @@ -315,7 +316,7 @@ MERCHANT_DB_update_deposit_permission (PGconn *conn, * @return #GNUNET_OK if successful, #GNUNET_SYSERR upon errors */ uint32_t -MERCHANT_DB_store_deposit_permission (PGconn *conn, +TALER_MERCHANTDB_deposit_permission_store (PGconn *conn, const char *deposit_permission, uint64_t transaction_id, unsigned int pending, @@ -390,7 +391,7 @@ MERCHANT_DB_store_deposit_permission (PGconn *conn, * already inserted @a c_id, #GNUNET_SYSERR for other errors. */ uint32_t -MERCHANT_DB_contract_create (PGconn *conn, +TALER_MERCHANTDB_contract_create (PGconn *conn, const struct GNUNET_TIME_Absolute timestamp, const struct GNUNET_TIME_Absolute expiry, struct GNUNET_TIME_Absolute edate, @@ -428,7 +429,7 @@ MERCHANT_DB_contract_create (PGconn *conn, TALER_PQ_query_param_end }; - /* NOTE: the statement is prepared by MERCHANT_DB_initialize function */ + /* NOTE: the statement is prepared by TALER_MERCHANTDB_initialize function */ res = TALER_PQ_exec_prepared (conn, "contract_create", params); status = PQresultStatus (res); @@ -465,7 +466,7 @@ MERCHANT_DB_contract_create (PGconn *conn, long long -MERCHANT_DB_get_contract_product (PGconn *conn, +TALER_MERCHANTDB_contract_get_product (PGconn *conn, uint64_t contract_id) { PGresult *res; @@ -496,7 +497,7 @@ MERCHANT_DB_get_contract_product (PGconn *conn, unsigned int -MERCHANT_DB_checkout_create (PGconn *conn, +TALER_MERCHANTDB_checkout_create (PGconn *conn, struct GNUNET_CRYPTO_rsa_PublicKey *coin_pub, uint64_t transaction_id, struct TALER_Amount *amount, @@ -531,7 +532,7 @@ MERCHANT_DB_checkout_create (PGconn *conn, long long -MERCHANT_DB_get_checkout_product (PGconn *conn, +TALER_MERCHANTDB_checkout_get_product (PGconn *conn, struct GNUNET_CRYPTO_rsa_PublicKey *coin_pub) { PGresult *res; @@ -578,7 +579,7 @@ MERCHANT_DB_get_checkout_product (PGconn *conn, * @return #GNUNET_OK on success, #GNUNET_SYSERR upon errors */ uint32_t -MERCHANT_DB_get_contract_values (PGconn *conn, +TALER_MERCHANTDB_contract_get_values (PGconn *conn, const struct GNUNET_HashCode *h_contract, uint64_t *nounce, struct GNUNET_TIME_Absolute *edate) @@ -627,11 +628,11 @@ MERCHANT_DB_get_contract_values (PGconn *conn, * upon errors */ uint32_t -MERCHANT_DB_get_contract_handle (PGconn *conn, +TALER_MERCHANTDB_contract_get_handle (PGconn *conn, const struct GNUNET_HashCode *h_contract, - struct MERCHANT_contract_handle *contract_handle) + struct TALER_MERCHANTDB_ContractHandle *contract_handle) { - struct MERCHANT_contract_handle ch; + struct TALER_MERCHANTDB_ContractHandle ch; PGresult *res; ExecStatusType status; diff --git a/src/include/platform.h b/src/include/platform.h index 4cba7abf..6e4baec6 100644 --- a/src/include/platform.h +++ b/src/include/platform.h @@ -18,7 +18,7 @@ * @file include/platform.h * @brief This file contains the includes and definitions which are used by the * rest of the modules - * @author Sree Harsha Totakura + * @author Sree Harsha Totakura */ #ifndef PLATFORM_H_ @@ -28,7 +28,7 @@ #ifndef HAVE_USED_CONFIG_H # define HAVE_USED_CONFIG_H # ifdef HAVE_CONFIG_H -# include "taler_config.h" +# include "taler_merchant_config.h" # endif #endif diff --git a/src/include/taler_merchantdb_lib.h b/src/include/taler_merchantdb_lib.h index f650a8aa..fe5adffc 100644 --- a/src/include/taler_merchantdb_lib.h +++ b/src/include/taler_merchantdb_lib.h @@ -30,7 +30,7 @@ /* Set of values that represent a contract. To be expanded on an as-needed basis */ -struct MERCHANT_contract_handle +struct TALER_MERCHANTDB_ContractHandle { /* The nounce used when hashing the wire details for this contract */ @@ -59,7 +59,7 @@ struct MERCHANT_contract_handle * @return connection to the postgresql database; NULL upon error */ PGconn * -MERCHANT_DB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); +TALER_MERCHANTDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); /** @@ -68,7 +68,7 @@ MERCHANT_DB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); * @param conn database handle to close */ void -MERCHANT_DB_disconnect (PGconn *conn); +TALER_MERCHANTDB_disconnect (PGconn *conn); /** @@ -80,7 +80,7 @@ MERCHANT_DB_disconnect (PGconn *conn); * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure */ int -MERCHANT_DB_initialize (PGconn *conn, int tmp); +TALER_MERCHANTDB_initialize (PGconn *conn, int tmp); /** @@ -102,7 +102,7 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp); * @return #GNUNET_OK on success, #GNUNET_SYSERR upon error */ uint32_t -MERCHANT_DB_contract_create (PGconn *conn, +TALER_MERCHANTDB_contract_create (PGconn *conn, const struct GNUNET_TIME_Absolute timestamp, const struct GNUNET_TIME_Absolute expiry, struct GNUNET_TIME_Absolute edate, @@ -116,7 +116,7 @@ MERCHANT_DB_contract_create (PGconn *conn, long long -MERCHANT_DB_get_contract_product (PGconn *conn, +TALER_MERCHANTDB_contract_get_product (PGconn *conn, uint64_t contract_id); @@ -131,12 +131,12 @@ MERCHANT_DB_get_contract_product (PGconn *conn, * @return #GNUNET_OK if successful, #GNUNET_SYSERR upon errors */ uint32_t -MERCHANT_DB_update_deposit_permission (PGconn *conn, +TALER_MERCHANTDB_deposit_permission_update (PGconn *conn, uint64_t transaction_id, unsigned int pending); unsigned int -MERCHANT_DB_checkout_create (PGconn *conn, +TALER_MERCHANTDB_checkout_create (PGconn *conn, struct GNUNET_CRYPTO_rsa_PublicKey *coin_pub, uint64_t transaction_id, struct TALER_Amount *amount, @@ -144,7 +144,7 @@ MERCHANT_DB_checkout_create (PGconn *conn, long long -MERCHANT_DB_get_checkout_product (PGconn *conn, +TALER_MERCHANTDB_checkout_get_product (PGconn *conn, struct GNUNET_CRYPTO_rsa_PublicKey *coin_pub); /** @@ -159,7 +159,7 @@ MERCHANT_DB_get_checkout_product (PGconn *conn, * @return #GNUNET_OK on success, #GNUNET_SYSERR upon errors */ uint32_t -MERCHANT_DB_get_contract_values (PGconn *conn, +TALER_MERCHANTDB_contract_get_values (PGconn *conn, const struct GNUNET_HashCode *h_contract, uint64_t *nounce, struct GNUNET_TIME_Absolute *edate); @@ -176,9 +176,9 @@ MERCHANT_DB_get_contract_values (PGconn *conn, * upon errors */ uint32_t -MERCHANT_DB_get_contract_handle (PGconn *conn, +TALER_MERCHANTDB_contract_get_handle (PGconn *conn, const struct GNUNET_HashCode *h_contract, - struct MERCHANT_contract_handle *contract_handle); + struct TALER_MERCHANTDB_ContractHandle *contract_handle); /** * Store a deposit permission in DB. To be mainly used if /deposit should @@ -192,7 +192,7 @@ MERCHANT_DB_get_contract_handle (PGconn *conn, * @return #GNUNET_OK if successful, #GNUNET_SYSERR upon errors */ uint32_t -MERCHANT_DB_store_deposit_permission (PGconn *conn, +TALER_MERCHANTDB_deposit_permission_store (PGconn *conn, const char *deposit_permission, uint64_t transaction_id, unsigned int pending, diff --git a/src/merchant/merchant_db.c b/src/merchant/merchant_db.c index e87dbcc8..0fed805d 100644 --- a/src/merchant/merchant_db.c +++ b/src/merchant/merchant_db.c @@ -48,7 +48,7 @@ * @return connection to the postgresql database; NULL upon error */ PGconn * -MERCHANT_DB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) +TALER_MERCHANTDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) { return GNUNET_POSTGRES_connect (cfg, "merchant-db"); } @@ -60,7 +60,7 @@ MERCHANT_DB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) * @param conn database handle to close */ void -MERCHANT_DB_disconnect (PGconn *conn) +TALER_MERCHANTDB_disconnect (PGconn *conn) { PQfinish (conn); } @@ -195,7 +195,7 @@ MERCHANT_DB_initialise (PGconn *conn, int tmp) * @return -1 upon error; the serial id of the inserted contract upon success */ long long -MERCHANT_DB_contract_create (PGconn *conn, +TALER_MERCHANTDB_contract_create (PGconn *conn, struct GNUNET_TIME_Absolute expiry, struct TALER_Amount *amount, const char *desc, @@ -242,7 +242,7 @@ MERCHANT_DB_contract_create (PGconn *conn, } long long -MERCHANT_DB_get_contract_product (PGconn *conn, +TALER_MERCHANTDB_contract_get_product (PGconn *conn, uint64_t contract_id) { PGresult *res; @@ -272,7 +272,7 @@ MERCHANT_DB_get_contract_product (PGconn *conn, } unsigned int -MERCHANT_DB_checkout_create (PGconn *conn, +TALER_MERCHANTDB_checkout_create (PGconn *conn, struct GNUNET_CRYPTO_EddsaPublicKey *coin_pub, uint64_t transaction_id, struct TALER_Amount *amount, @@ -307,7 +307,7 @@ MERCHANT_DB_checkout_create (PGconn *conn, long long -MERCHANT_DB_get_checkout_product (PGconn *conn, +TALER_MERCHANTDB_checkout_get_product (PGconn *conn, struct GNUNET_CRYPTO_EddsaPublicKey *coin_pub) { PGresult *res; diff --git a/src/merchant/merchant_db.h b/src/merchant/merchant_db.h index 734d547f..463eeb07 100644 --- a/src/merchant/merchant_db.h +++ b/src/merchant/merchant_db.h @@ -33,7 +33,7 @@ * @return connection to the postgresql database; NULL upon error */ PGconn * -MERCHANT_DB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); +TALER_MERCHANTDB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); /** @@ -42,7 +42,7 @@ MERCHANT_DB_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); * @param conn database handle to close */ void -MERCHANT_DB_disconnect (PGconn *conn); +TALER_MERCHANTDB_disconnect (PGconn *conn); /** @@ -70,7 +70,7 @@ MERCHANT_DB_initialise (PGconn *conn, int tmp); * @return -1 upon error; the serial id of the inserted contract upon success */ long long -MERCHANT_DB_contract_create (PGconn *conn, +TALER_MERCHANTDB_contract_create (PGconn *conn, struct GNUNET_TIME_Absolute expiry, struct TALER_Amount *amount, const char *desc, @@ -78,11 +78,11 @@ MERCHANT_DB_contract_create (PGconn *conn, uint64_t product); long long -MERCHANT_DB_get_contract_product (PGconn *conn, +TALER_MERCHANTDB_contract_get_product (PGconn *conn, uint64_t contract_id); unsigned int -MERCHANT_DB_checkout_create (PGconn *conn, +TALER_MERCHANTDB_checkout_create (PGconn *conn, struct GNUNET_CRYPTO_EddsaPublicKey *coin_pub, uint64_t transaction_id, struct TALER_Amount *amount, @@ -90,7 +90,7 @@ MERCHANT_DB_checkout_create (PGconn *conn, long long -MERCHANT_DB_get_checkout_product (PGconn *conn, +TALER_MERCHANTDB_checkout_get_product (PGconn *conn, struct GNUNET_CRYPTO_EddsaPublicKey *coin_pub); #endif /* MERCHANT_DB_H */ diff --git a/src/merchant/taler_merchant_dbinit.c b/src/merchant/taler_merchant_dbinit.c index e6d0af9d..21e28f9d 100644 --- a/src/merchant/taler_merchant_dbinit.c +++ b/src/merchant/taler_merchant_dbinit.c @@ -45,12 +45,12 @@ run (void *cls, char *const *args, const char *cfgfile, { PGconn *conn; - conn = MERCHANT_DB_connect (config); + conn = TALER_MERCHANTDB_connect (config); if (NULL == conn) return; if (GNUNET_OK == MERCHANT_DB_initialise (conn, GNUNET_NO)) result = GNUNET_OK; - MERCHANT_DB_disconnect (conn); + TALER_MERCHANTDB_disconnect (conn); } diff --git a/src/merchant/taler_merchant_serve.c b/src/merchant/taler_merchant_serve.c index 0f00a8c2..345e01bb 100644 --- a/src/merchant/taler_merchant_serve.c +++ b/src/merchant/taler_merchant_serve.c @@ -511,7 +511,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } if (NULL != db_conn) { - MERCHANT_DB_disconnect (db_conn); + TALER_MERCHANTDB_disconnect (db_conn); db_conn = NULL; } if (NULL != mints_map) @@ -792,7 +792,7 @@ handle_get_contract (struct MHD_Connection *connection, template, hostname, port); - contract_id = MERCHANT_DB_contract_create (db_conn, + contract_id = TALER_MERCHANTDB_contract_create (db_conn, expiry, &amount, desc, @@ -881,7 +881,7 @@ handle_download (struct MHD_Connection *conn, GNUNET_CRYPTO_eddsa_public_key_from_string (coin_pub_enc, strlen (coin_pub_enc), &coin_pub)); - product_id = MERCHANT_DB_get_checkout_product (db_conn, + product_id = TALER_MERCHANTDB_checkout_get_product (db_conn, &coin_pub); EXITIF (-1 == product_id); EXITIF (NULL == (item = find_product ((unsigned int) product_id))); @@ -1117,7 +1117,7 @@ handle_checkout (struct MHD_Connection *conn, emsg = "Contract not found"; status = MHD_HTTP_NOT_FOUND; LOG_DEBUG ("Looking for product associated with transaction %u\n", tid); - EXITIF (-1 == (product_id = MERCHANT_DB_get_contract_product (db_conn, tid))); + EXITIF (-1 == (product_id = TALER_MERCHANTDB_contract_get_product (db_conn, tid))); emsg = "Could not find the downloadable product. Sorry :("; EXITIF (NULL == (product = find_product (product_id))); @@ -1452,7 +1452,7 @@ run (void *cls, char *const *args, const char *cfgfile, &add_download_file, NULL)); EXITIF (GNUNET_SYSERR == build_list_product_response ()); - EXITIF (NULL == (db_conn = MERCHANT_DB_connect (config))); + EXITIF (NULL == (db_conn = TALER_MERCHANTDB_connect (config))); EXITIF (GNUNET_OK != MERCHANT_DB_initialise (db_conn, dry)); EXITIF (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (config, diff --git a/src/merchant/test_merchant_db.c b/src/merchant/test_merchant_db.c index caaa1be4..505b12c3 100644 --- a/src/merchant/test_merchant_db.c +++ b/src/merchant/test_merchant_db.c @@ -52,7 +52,7 @@ static void do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { if (NULL != conn) - MERCHANT_DB_disconnect (conn); + TALER_MERCHANTDB_disconnect (conn); conn = NULL; } @@ -76,7 +76,7 @@ run (void *cls, char *const *args, const char *cfgfile, uint64_t product; long long transaction_id; - conn = MERCHANT_DB_connect (config); + conn = TALER_MERCHANTDB_connect (config); EXITIF (NULL == conn); GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); EXITIF (GNUNET_OK != MERCHANT_DB_initialise (conn, GNUNET_YES)); @@ -88,7 +88,7 @@ run (void *cls, char *const *args, const char *cfgfile, nounce = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); product = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); product &= (UINT64_MAX >> 1); - EXITIF (-1 == (transaction_id = MERCHANT_DB_contract_create (conn, + EXITIF (-1 == (transaction_id = TALER_MERCHANTDB_contract_create (conn, expiry, &amount, desc, @@ -103,19 +103,19 @@ run (void *cls, char *const *args, const char *cfgfile, &coin_pub, sizeof (coin_pub)); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &coin_sig, sizeof (coin_sig)); - EXITIF (GNUNET_SYSERR == MERCHANT_DB_checkout_create (conn, + EXITIF (GNUNET_SYSERR == TALER_MERCHANTDB_checkout_create (conn, &coin_pub, transaction_id, &amount, &coin_sig)); - EXITIF (-1 == (paid_product = MERCHANT_DB_get_checkout_product (conn, + EXITIF (-1 == (paid_product = TALER_MERCHANTDB_checkout_get_product (conn, &coin_pub))); EXITIF (paid_product < 0); EXITIF (((uint64_t) paid_product) != product); /* We should get -1 for product if a coin is not paid to us */ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &coin_pub, sizeof (coin_pub)); - EXITIF (-1 != (product = MERCHANT_DB_get_checkout_product (conn, + EXITIF (-1 != (product = TALER_MERCHANTDB_checkout_get_product (conn, &coin_pub))); } result = GNUNET_OK; diff --git a/src/tests/test_contract.c b/src/tests/test_contract.c index 147ea4f3..68572a38 100644 --- a/src/tests/test_contract.c +++ b/src/tests/test_contract.c @@ -54,13 +54,13 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (NULL != db_conn) { - MERCHANT_DB_disconnect (db_conn); + TALER_MERCHANTDB_disconnect (db_conn); db_conn = NULL; } } extern uint32_t -MERCHANT_DB_get_contract_values (PGconn *conn, +TALER_MERCHANTDB_contract_get_values (PGconn *conn, const struct GNUNET_HashCode *h_contract, uint64_t *nounce, struct GNUNET_TIME_Absolute *edate); @@ -116,8 +116,8 @@ run (void *cls, char *const *args, const char *cfgfile, wire = NULL; - db_conn = MERCHANT_DB_connect (config); - if (GNUNET_OK != MERCHANT_DB_initialize (db_conn, GNUNET_NO)) + db_conn = TALER_MERCHANTDB_connect (config); + if (GNUNET_OK != TALER_MERCHANTDB_initialize (db_conn, GNUNET_NO)) { printf ("no db init'd\n"); result = GNUNET_SYSERR; @@ -293,7 +293,7 @@ run (void *cls, char *const *args, const char *cfgfile, printf ("contract string : %s\n", aa); GNUNET_CRYPTO_hash (aa, strlen (aa) + 1, &h_contract_str); - if (GNUNET_SYSERR == MERCHANT_DB_get_contract_values (db_conn, &h_contract_str, &nounce, &edate)) + if (GNUNET_SYSERR == TALER_MERCHANTDB_contract_get_values (db_conn, &h_contract_str, &nounce, &edate)) printf ("no hash found\n"); else { -- cgit v1.2.3