From 6362ade0e6ee926beab51000ad27ae3d2bcb190c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 23 Nov 2019 23:04:11 +0100 Subject: adapt to exchange API changes --- src/backend/taler-merchant-httpd.c | 320 ++++++++------------------- src/backend/taler-merchant-httpd.h | 5 - src/backend/taler-merchant-httpd_responses.c | 6 +- src/lib/merchant_api_pay.c | 18 +- src/lib/merchant_api_proposal.c | 4 +- src/lib/test_merchant_api.c | 6 +- 6 files changed, 108 insertions(+), 251 deletions(-) (limited to 'src') diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index d5dfb02b..f94613d8 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -72,7 +73,7 @@ struct GNUNET_CONTAINER_MultiHashMap *by_kpub_map; /** * The port we are running on */ -static long long unsigned port; +static uint16_t port; /** * This value tells the exchange by which date this merchant would like @@ -113,7 +114,7 @@ unsigned long long default_wire_fee_amortization; /** * Should a "Connection: close" header be added to each HTTP response? */ -int TMH_merchant_connection_close; +static int TMH_merchant_connection_close; /** * Which currency do we use? @@ -1573,12 +1574,18 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *config) { int fh; + enum TALER_MHD_GlobalOptions go; + char *bind_to; (void) cls; (void) args; (void) cfgfile; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting taler-merchant-httpd\n"); + go = TALER_MHD_GO_NONE; + if (TMH_merchant_connection_close) + go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE; + TALER_MHD_setup (go); result = GNUNET_SYSERR; GNUNET_SCHEDULER_add_shutdown (&do_shutdown, @@ -1709,243 +1716,103 @@ run (void *cls, return; } + if (GNUNET_OK != + TALER_MHD_parse_config (config, + "merchant", + &port, + &serve_unixpath, + &unixpath_mode)) { - const char *choices[] = {"tcp", - "unix", - NULL}; - const char *serve_type; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_choice (config, - "merchant", - "serve", - choices, - &serve_type)) + GNUNET_SCHEDULER_shutdown (); + return; + } + fh = -1; + if (NULL != serve_unixpath) + { + fh = TALER_MHD_open_unix_path (serve_unixpath, + unixpath_mode); + if (-1 == fh) { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "merchant", - "serve", - "serve type required"); GNUNET_SCHEDULER_shutdown (); return; } - - if (0 == strcasecmp (serve_type, "unix")) + } + else if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (config, + "merchant", + "BIND_TO", + &bind_to)) + { + char port_str[6]; + struct addrinfo hints; + struct addrinfo *res; + int ec; + struct GNUNET_NETWORK_Handle *nh; + + GNUNET_snprintf (port_str, + sizeof (port_str), + "%u", + (uint16_t) port); + memset (&hints, 0, sizeof (hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE +#ifdef AI_IDN + | AI_IDN +#endif + ; + if (0 != + (ec = getaddrinfo (bind_to, + port_str, + &hints, + &res))) { - struct sockaddr_un *un; - char *mode; - struct GNUNET_NETWORK_Handle *nh; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (config, - "merchant", - "unixpath", - &serve_unixpath)) - { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "merchant", - "unixpath", - "unixpath required"); - GNUNET_SCHEDULER_shutdown (); - return; - } - - if (strlen (serve_unixpath) >= sizeof (un->sun_path)) - { - fprintf (stderr, - "Invalid configuration: unix path too long\n"); - GNUNET_SCHEDULER_shutdown (); - return; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (config, - "merchant", - "UNIXPATH_MODE", - &mode)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "merchant", - "UNIXPATH_MODE"); - GNUNET_SCHEDULER_shutdown (); - return; - } - errno = 0; - unixpath_mode = (mode_t) strtoul (mode, NULL, 8); - if (0 != errno) - { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "merchant", - "UNIXPATH_MODE", - "must be octal number"); - GNUNET_free (mode); - GNUNET_SCHEDULER_shutdown (); - return; - } - GNUNET_free (mode); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Creating listen socket '%s' with mode %o\n", - serve_unixpath, unixpath_mode); - - if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (serve_unixpath)) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, - "mkdir", - serve_unixpath); - } - - un = GNUNET_new (struct sockaddr_un); - un->sun_family = AF_UNIX; - strncpy (un->sun_path, - serve_unixpath, - sizeof (un->sun_path) - 1); - - GNUNET_NETWORK_unix_precheck (un); - - if (NULL == (nh = GNUNET_NETWORK_socket_create (AF_UNIX, - SOCK_STREAM, - 0))) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "socket(AF_UNIX)"); - GNUNET_SCHEDULER_shutdown (); - return; - } - if (GNUNET_OK != - GNUNET_NETWORK_socket_bind (nh, - (void *) un, - sizeof (struct sockaddr_un))) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "bind(AF_UNIX)"); - GNUNET_SCHEDULER_shutdown (); - return; - } - if (GNUNET_OK != - GNUNET_NETWORK_socket_listen (nh, - UNIX_BACKLOG)) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "listen(AF_UNIX)"); - GNUNET_SCHEDULER_shutdown (); - return; - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to resolve BIND_TO address `%s': %s\n", + bind_to, + gai_strerror (ec)); + GNUNET_free (bind_to); + GNUNET_SCHEDULER_shutdown (); + return; + } + GNUNET_free (bind_to); - fh = GNUNET_NETWORK_get_fd (nh); - GNUNET_NETWORK_socket_free_memory_only_ (nh); - if (0 != chmod (serve_unixpath, - unixpath_mode)) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "chmod"); - GNUNET_SCHEDULER_shutdown (); - return; - } - port = 0; + if (NULL == (nh = GNUNET_NETWORK_socket_create (res->ai_family, + res->ai_socktype, + res->ai_protocol))) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, + "socket"); + freeaddrinfo (res); + GNUNET_SCHEDULER_shutdown (); + return; } - else if (0 == strcasecmp (serve_type, "tcp")) + if (GNUNET_OK != + GNUNET_NETWORK_socket_bind (nh, + res->ai_addr, + res->ai_addrlen)) { - char *bind_to; - - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (config, - "merchant", - "PORT", - &port)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "merchant", - "PORT"); - GNUNET_SCHEDULER_shutdown (); - return; - } - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (config, - "merchant", - "BIND_TO", - &bind_to)) - { - char port_str[6]; - struct addrinfo hints; - struct addrinfo *res; - int ec; - struct GNUNET_NETWORK_Handle *nh; - - GNUNET_snprintf (port_str, - sizeof (port_str), - "%u", - (uint16_t) port); - memset (&hints, 0, sizeof (hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE -#ifdef AI_IDN - | AI_IDN -#endif - ; - if (0 != - (ec = getaddrinfo (bind_to, - port_str, - &hints, - &res))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to resolve BIND_TO address `%s': %s\n", - bind_to, - gai_strerror (ec)); - GNUNET_free (bind_to); - GNUNET_SCHEDULER_shutdown (); - return; - } - GNUNET_free (bind_to); - - if (NULL == (nh = GNUNET_NETWORK_socket_create (res->ai_family, - res->ai_socktype, - res->ai_protocol))) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "socket"); - freeaddrinfo (res); - GNUNET_SCHEDULER_shutdown (); - return; - } - if (GNUNET_OK != - GNUNET_NETWORK_socket_bind (nh, - res->ai_addr, - res->ai_addrlen)) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "bind"); - freeaddrinfo (res); - GNUNET_SCHEDULER_shutdown (); - return; - } - freeaddrinfo (res); - if (GNUNET_OK != - GNUNET_NETWORK_socket_listen (nh, - UNIX_BACKLOG)) - { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "listen"); - GNUNET_SCHEDULER_shutdown (); - return; - } - fh = GNUNET_NETWORK_get_fd (nh); - GNUNET_NETWORK_socket_free_memory_only_ (nh); - } - else - { - fh = -1; - } + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, + "bind"); + freeaddrinfo (res); + GNUNET_SCHEDULER_shutdown (); + return; } - else + freeaddrinfo (res); + if (GNUNET_OK != + GNUNET_NETWORK_socket_listen (nh, + UNIX_BACKLOG)) { - // not reached - GNUNET_assert (0); + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, + "listen"); + GNUNET_SCHEDULER_shutdown (); + return; } + fh = GNUNET_NETWORK_get_fd (nh); + GNUNET_NETWORK_socket_free_memory_only_ (nh); } + resume_timeout_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); payment_trigger_map @@ -1985,7 +1852,6 @@ main (int argc, char *const *argv) { struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_option_flag ('C', "connection-close", "force HTTP connections to be closed after each request", diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h index 82c080e9..db01ea3c 100644 --- a/src/backend/taler-merchant-httpd.h +++ b/src/backend/taler-merchant-httpd.h @@ -362,11 +362,6 @@ extern struct TALER_MerchantPrivateKeyP privkey; */ extern struct TALER_MerchantPublicKeyP pubkey; -/** - * Should a "Connection: close" header be added to each HTTP response? - */ -extern int TMH_merchant_connection_close; - /** * Handle to the database backend. */ diff --git a/src/backend/taler-merchant-httpd_responses.c b/src/backend/taler-merchant-httpd_responses.c index 9c847f3a..3be9cab5 100644 --- a/src/backend/taler-merchant-httpd_responses.c +++ b/src/backend/taler-merchant-httpd_responses.c @@ -332,11 +332,7 @@ TMH_RESPONSE_reply_bad_request (struct MHD_Connection *connection, void TMH_RESPONSE_add_global_headers (struct MHD_Response *response) { - if (TMH_merchant_connection_close) - GNUNET_break (MHD_YES == - MHD_add_response_header (response, - MHD_HTTP_HEADER_CONNECTION, - "close")); + TALER_MHD_add_global_headers (response); } diff --git a/src/lib/merchant_api_pay.c b/src/lib/merchant_api_pay.c index cf25337e..45fa769c 100644 --- a/src/lib/merchant_api_pay.c +++ b/src/lib/merchant_api_pay.c @@ -274,7 +274,7 @@ check_coin_history (const struct TALER_MERCHANT_PaidCoin *pc, /** - * We got a 403 response back from the exchange (or the merchant). + * We got a 409 response back from the exchange (or the merchant). * Now we need to check the provided cryptographic proof that the * coin was actually already spent! * @@ -284,8 +284,8 @@ check_coin_history (const struct TALER_MERCHANT_PaidCoin *pc, * @return #GNUNET_OK if proof checks out */ static int -check_forbidden (struct TALER_MERCHANT_Pay *ph, - const json_t *json) +check_conflict (struct TALER_MERCHANT_Pay *ph, + const json_t *json) { json_t *history; struct TALER_CoinSpendPublicKeyP coin_pub; @@ -361,15 +361,15 @@ handle_pay_finished (void *cls, * or the merchant is buggy (or API version conflict); * just pass JSON reply to the application */ break; - case MHD_HTTP_FORBIDDEN: - if (GNUNET_OK != check_forbidden (ph, - json)) + case MHD_HTTP_CONFLICT: + if (GNUNET_OK != check_conflict (ph, + json)) { GNUNET_break_op (0); response_code = 0; } break; - case MHD_HTTP_UNAUTHORIZED: + case MHD_HTTP_FORBIDDEN: /* Nothing really to verify, merchant says one of the * signatures is invalid; as we checked them, this * should never happen, we should pass the JSON reply @@ -426,9 +426,9 @@ handle_pay_finished (void *cls, merchant is buggy (or API version conflict); just pass JSON reply to the application */ break; - case MHD_HTTP_FORBIDDEN: + case MHD_HTTP_CONFLICT: break; - case MHD_HTTP_UNAUTHORIZED: + case MHD_HTTP_FORBIDDEN: /* Nothing really to verify, merchant says one of the signatures is invalid; as we checked them, this should never happen, we should pass the JSON diff --git a/src/lib/merchant_api_proposal.c b/src/lib/merchant_api_proposal.c index 72a603a3..e63986e1 100644 --- a/src/lib/merchant_api_proposal.c +++ b/src/lib/merchant_api_proposal.c @@ -167,9 +167,9 @@ handle_proposal_finished (void *cls, the merchant is buggy (or API version conflict); just pass JSON reply to the application */ break; - case MHD_HTTP_FORBIDDEN: + case MHD_HTTP_CONFLICT: break; - case MHD_HTTP_UNAUTHORIZED: + case MHD_HTTP_FORBIDDEN: /* Nothing really to verify, merchant says one of the signatures is invalid; as we checked them, this should never happen, we should pass the JSON diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c index 359f20d0..69ed400b 100644 --- a/src/lib/test_merchant_api.c +++ b/src/lib/test_merchant_api.c @@ -370,7 +370,7 @@ run (void *cls, TALER_TESTING_cmd_pay ("deposit-double-2", merchant_url, - MHD_HTTP_FORBIDDEN, + MHD_HTTP_CONFLICT, "create-proposal-2", "withdraw-coin-1", "EUR:5", @@ -889,7 +889,7 @@ run (void *cls, TALER_TESTING_cmd_pay ("pay-fail-partial-double-10", merchant_url, - MHD_HTTP_FORBIDDEN, + MHD_HTTP_CONFLICT, "create-proposal-10", "withdraw-coin-10a;withdraw-coin-1", "EUR:5", @@ -976,7 +976,7 @@ run (void *cls, "EUR:0.01"), TALER_TESTING_cmd_pay ("pay-fail-partial-double-11-bad", merchant_url, - MHD_HTTP_FORBIDDEN, + MHD_HTTP_CONFLICT, "create-proposal-11", "withdraw-coin-1", "EUR:5", -- cgit v1.2.3