diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 4a206b138..c39df21a4 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -56,33 +56,6 @@ #define UNIX_BACKLOG 500 -/** - * Type of the closure associated with each HTTP request to the exchange. - */ -struct ExchangeHttpRequestClosure -{ - /** - * Async Scope ID associated with this request. - */ - struct GNUNET_AsyncScopeId async_scope_id; - - /** - * Opaque parsing context. - */ - void *opaque_post_parsing_context; - - /** - * Cached request handler for this request (once we have found one). - */ - struct TEH_RequestHandler *rh; - - /** - * Request URL (for logging). - */ - const char *url; -}; - - /** * Are clients allowed to request /keys for times other than the * current time? Allowing this could be abused in a DoS-attack @@ -204,16 +177,14 @@ r404 (struct MHD_Connection *connection, * Handle a "/coins/$COIN_PUB/$OP" POST request. Parses the "coin_pub" * EdDSA key of the coin and demultiplexes based on $OP. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param root uploaded JSON data * @param args array of additional options (first must be the * reserve public key, the second one should be "withdraw") * @return MHD result code */ static MHD_RESULT -handle_post_coins (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +handle_post_coins (struct TEH_RequestContext *rc, const json_t *root, const char *const args[2]) { @@ -253,7 +224,6 @@ handle_post_coins (const struct TEH_RequestHandler *rh, }, }; - (void) rh; if (GNUNET_OK != GNUNET_STRINGS_string_to_data (args[0], strlen (args[0]), @@ -261,7 +231,7 @@ handle_post_coins (const struct TEH_RequestHandler *rh, sizeof (coin_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_GENERIC_COINS_INVALID_COIN_PUB, args[0]); @@ -269,10 +239,11 @@ handle_post_coins (const struct TEH_RequestHandler *rh, for (unsigned int i = 0; NULL != h[i].op; i++) if (0 == strcmp (h[i].op, args[1])) - return h[i].handler (connection, + return h[i].handler (rc->connection, &coin_pub, root); - return r404 (connection, args[1]); + return r404 (rc->connection, + args[1]); } @@ -296,14 +267,16 @@ handle_mhd_completion_callback (void *cls, void **con_cls, enum MHD_RequestTerminationCode toe) { - struct ExchangeHttpRequestClosure *ecls = *con_cls; + struct TEH_RequestContext *rc = *con_cls; struct GNUNET_AsyncScopeSave old_scope; (void) cls; - if (NULL == ecls) + if (NULL == rc) return; - GNUNET_async_scope_enter (&ecls->async_scope_id, + GNUNET_async_scope_enter (&rc->async_scope_id, &old_scope); + if (NULL != rc->rh_cleaner) + rc->rh_cleaner (rc); { #if MHD_VERSION >= 0x00097304 const union MHD_ConnectionInfo *ci; @@ -315,52 +288,49 @@ handle_mhd_completion_callback (void *cls, http_status = ci->http_status; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Request for `%s' completed with HTTP status %u (%d)\n", - ecls->url, + rc->url, http_status, toe); #else (void) connection; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Request for `%s' completed (%d)\n", - ecls->url, + rc->url, toe); #endif } - TALER_MHD_parse_post_cleanup_callback (ecls->opaque_post_parsing_context); + TALER_MHD_parse_post_cleanup_callback (rc->opaque_post_parsing_context); /* Sanity-check that we didn't leave any transactions hanging */ /* NOTE: In high-performance production, we could consider removing this as it should not be needed and might be costly (to be benchmarked). */ TEH_plugin->preflight (TEH_plugin->cls, TEH_plugin->get_session (TEH_plugin->cls)); - GNUNET_free (ecls); + GNUNET_free (rc); *con_cls = NULL; GNUNET_async_scope_restore (&old_scope); } /** - * We found @a rh responsible for handling a request. Parse the + * We found a request handler responsible for handling a request. Parse the * @a upload_data (if applicable) and the @a url and call the * handler. * - * @param rh request handler to call - * @param connection connection being handled + * @param rc request context * @param url rest of the URL to parse - * @param inner_cls closure for the handler, if needed * @param upload_data upload data to parse (if available) * @param[in,out] upload_data_size number of bytes in @a upload_data * @return MHD result code */ static MHD_RESULT -proceed_with_handler (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +proceed_with_handler (struct TEH_RequestContext *rc, const char *url, - void **inner_cls, const char *upload_data, size_t *upload_data_size) { + const struct TEH_RequestHandler *rh = rc->rh; const char *args[rh->nargs + 1]; size_t ulen = strlen (url) + 1; json_t *root = NULL; @@ -376,7 +346,7 @@ proceed_with_handler (const struct TEH_RequestHandler *rh, /deposits/). The value should be adjusted if we ever define protocol endpoints with plausibly longer inputs. */ GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_URI_TOO_LONG, TALER_EC_GENERIC_URI_TOO_LONG, url); @@ -389,8 +359,8 @@ proceed_with_handler (const struct TEH_RequestHandler *rh, { enum GNUNET_GenericReturnValue res; - res = TALER_MHD_parse_post_json (connection, - inner_cls, + res = TALER_MHD_parse_post_json (rc->connection, + &rc->opaque_post_parsing_context, upload_data, upload_data_size, &root); @@ -447,7 +417,7 @@ proceed_with_handler (const struct TEH_RequestHandler *rh, url); GNUNET_break_op (0); json_decref (root); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_NOT_FOUND, TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS, emsg); @@ -458,18 +428,15 @@ proceed_with_handler (const struct TEH_RequestHandler *rh, args[i] = NULL; } - /* Above logic ensures that 'root' is exactly non-NULL for POST operations, so we test for 'root' to decide which handler to invoke. */ if (NULL != root) - ret = rh->handler.post (rh, - connection, + ret = rh->handler.post (rc, root, args); else /* We also only have "POST" or "GET" in the API for at this point (OPTIONS/HEAD are taken care of earlier) */ - ret = rh->handler.get (rh, - connection, + ret = rh->handler.get (rc, args); } json_decref (root); @@ -480,14 +447,13 @@ proceed_with_handler (const struct TEH_RequestHandler *rh, /** * Handle a "/seed" request. * - * @param rh context of the handler + * @param rc request context * @param connection the MHD connection to handle * @param args array of additional options (must be empty for this function) * @return MHD result code */ static MHD_RESULT -handler_seed (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +handler_seed (struct TEH_RequestContext *rc, const char *const args[]) { #define SEED_SIZE 32 @@ -495,7 +461,6 @@ handler_seed (const struct TEH_RequestHandler *rh, MHD_RESULT ret; struct MHD_Response *resp; - (void) rh; body = malloc (SEED_SIZE); /* must use malloc(), because MHD will use free() */ if (NULL == body) return MHD_NO; @@ -506,7 +471,7 @@ handler_seed (const struct TEH_RequestHandler *rh, body, MHD_RESPMEM_MUST_FREE); TALER_MHD_add_global_headers (resp); - ret = MHD_queue_response (connection, + ret = MHD_queue_response (rc->connection, MHD_HTTP_OK, resp); GNUNET_break (MHD_YES == ret); @@ -519,22 +484,21 @@ handler_seed (const struct TEH_RequestHandler *rh, /** * Handle POST "/management/..." requests. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param root uploaded JSON data * @param args array of additional options * @return MHD result code */ static MHD_RESULT -handle_post_management (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +handle_post_management (struct TEH_RequestContext *rc, const json_t *root, const char *const args[]) { if (NULL == args[0]) { GNUNET_break_op (0); - return r404 (connection, "/management"); + return r404 (rc->connection, + "/management"); } if (0 == strcmp (args[0], "auditors")) @@ -542,14 +506,14 @@ handle_post_management (const struct TEH_RequestHandler *rh, struct TALER_AuditorPublicKeyP auditor_pub; if (NULL == args[1]) - return TEH_handler_management_auditors (connection, + return TEH_handler_management_auditors (rc->connection, root); if ( (NULL == args[1]) || (NULL == args[2]) || (0 != strcmp (args[2], "disable")) || (NULL != args[3]) ) - return r404 (connection, + return r404 (rc->connection, "/management/auditors/$AUDITOR_PUB/disable"); if (GNUNET_OK != GNUNET_STRINGS_string_to_data (args[1], @@ -558,12 +522,12 @@ handle_post_management (const struct TEH_RequestHandler *rh, sizeof (auditor_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, args[1]); } - return TEH_handler_management_auditors_AP_disable (connection, + return TEH_handler_management_auditors_AP_disable (rc->connection, &auditor_pub, root); } @@ -578,7 +542,7 @@ handle_post_management (const struct TEH_RequestHandler *rh, (0 != strcmp (args[2], "revoke")) || (NULL != args[3]) ) - return r404 (connection, + return r404 (rc->connection, "/management/denominations/$HDP/revoke"); if (GNUNET_OK != GNUNET_STRINGS_string_to_data (args[1], @@ -587,12 +551,12 @@ handle_post_management (const struct TEH_RequestHandler *rh, sizeof (h_denom_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, args[1]); } - return TEH_handler_management_denominations_HDP_revoke (connection, + return TEH_handler_management_denominations_HDP_revoke (rc->connection, &h_denom_pub, root); } @@ -607,7 +571,7 @@ handle_post_management (const struct TEH_RequestHandler *rh, (0 != strcmp (args[2], "revoke")) || (NULL != args[3]) ) - return r404 (connection, + return r404 (rc->connection, "/management/signkeys/$HDP/revoke"); if (GNUNET_OK != GNUNET_STRINGS_string_to_data (args[1], @@ -616,12 +580,12 @@ handle_post_management (const struct TEH_RequestHandler *rh, sizeof (exchange_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, args[1]); } - return TEH_handler_management_signkeys_EP_revoke (connection, + return TEH_handler_management_signkeys_EP_revoke (rc->connection, &exchange_pub, root); } @@ -631,25 +595,27 @@ handle_post_management (const struct TEH_RequestHandler *rh, if (NULL != args[1]) { GNUNET_break_op (0); - return r404 (connection, "/management/keys/*"); + return r404 (rc->connection, + "/management/keys/*"); } - return TEH_handler_management_post_keys (connection, + return TEH_handler_management_post_keys (rc->connection, root); } if (0 == strcmp (args[0], "wire")) { if (NULL == args[1]) - return TEH_handler_management_post_wire (connection, + return TEH_handler_management_post_wire (rc->connection, root); if ( (0 != strcmp (args[1], "disable")) || (NULL != args[2]) ) { GNUNET_break_op (0); - return r404 (connection, "/management/wire/disable"); + return r404 (rc->connection, + "/management/wire/disable"); } - return TEH_handler_management_post_wire_disable (connection, + return TEH_handler_management_post_wire_disable (rc->connection, root); } if (0 == strcmp (args[0], @@ -658,27 +624,28 @@ handle_post_management (const struct TEH_RequestHandler *rh, if (NULL != args[1]) { GNUNET_break_op (0); - return r404 (connection, "/management/wire-fee/*"); + return r404 (rc->connection, + "/management/wire-fee/*"); } - return TEH_handler_management_post_wire_fees (connection, + return TEH_handler_management_post_wire_fees (rc->connection, root); } GNUNET_break_op (0); - return r404 (connection, "/management/*"); + return r404 (rc->connection, + "/management/*"); } /** * Handle a get "/management" request. * - * @param rh context of the handler + * @param rc request context * @param connection the MHD connection to handle * @param args array of additional options (must be empty for this function) * @return MHD result code */ static MHD_RESULT -handle_get_management (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +handle_get_management (struct TEH_RequestContext *rc, const char *const args[1]) { if ( (NULL != args[0]) && @@ -686,26 +653,25 @@ handle_get_management (const struct TEH_RequestHandler *rh, "keys")) && (NULL == args[1]) ) { - return TEH_keys_management_get_keys_handler (rh, - connection); + return TEH_keys_management_get_keys_handler (rc->rh, + rc->connection); } GNUNET_break_op (0); - return r404 (connection, "/management/*"); + return r404 (rc->connection, + "/management/*"); } /** * Handle POST "/auditors/..." requests. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param root uploaded JSON data * @param args array of additional options * @return MHD result code */ static MHD_RESULT -handle_post_auditors (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +handle_post_auditors (struct TEH_RequestContext *rc, const json_t *root, const char *const args[]) { @@ -717,7 +683,8 @@ handle_post_auditors (const struct TEH_RequestHandler *rh, (NULL != args[2]) ) { GNUNET_break_op (0); - return r404 (connection, "/auditors/$AUDITOR_PUB/$H_DENOM_PUB"); + return r404 (rc->connection, + "/auditors/$AUDITOR_PUB/$H_DENOM_PUB"); } if (GNUNET_OK != @@ -727,7 +694,7 @@ handle_post_auditors (const struct TEH_RequestHandler *rh, sizeof (auditor_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, args[0]); @@ -739,12 +706,12 @@ handle_post_auditors (const struct TEH_RequestHandler *rh, sizeof (h_denom_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, args[1]); } - return TEH_handler_auditors (connection, + return TEH_handler_auditors (rc->connection, &auditor_pub, &h_denom_pub, root); @@ -761,7 +728,7 @@ handle_post_auditors (const struct TEH_RequestHandler *rh, * @param version HTTP version (ignored) * @param upload_data request data * @param upload_data_size size of @a upload_data in bytes - * @param con_cls closure for request (a `struct Buffer *`) + * @param con_cls closure for request (a `struct TEH_RequestContext *`) * @return MHD result code */ static MHD_RESULT @@ -907,14 +874,13 @@ handle_mhd_request (void *cls, .url = NULL } }; - struct ExchangeHttpRequestClosure *ecls = *con_cls; - void **inner_cls; + struct TEH_RequestContext *rc = *con_cls; struct GNUNET_AsyncScopeSave old_scope; const char *correlation_id = NULL; (void) cls; (void) version; - if (NULL == ecls) + if (NULL == rc) { unsigned long long cnt; @@ -933,15 +899,17 @@ handle_mhd_request (void *cls, } /* We're in a new async scope! */ - ecls = *con_cls = GNUNET_new (struct ExchangeHttpRequestClosure); - GNUNET_async_scope_fresh (&ecls->async_scope_id); - ecls->url = url; + rc = *con_cls = GNUNET_new (struct TEH_RequestContext); + GNUNET_async_scope_fresh (&rc->async_scope_id); + rc->url = url; + rc->connection = connection; /* We only read the correlation ID on the first callback for every client */ correlation_id = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, "Taler-Correlation-Id"); - if ((NULL != correlation_id) && - (GNUNET_YES != GNUNET_CURL_is_valid_scope_id (correlation_id))) + if ( (NULL != correlation_id) && + (GNUNET_YES != + GNUNET_CURL_is_valid_scope_id (correlation_id)) ) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "illegal incoming correlation ID\n"); @@ -949,8 +917,7 @@ handle_mhd_request (void *cls, } } - inner_cls = &ecls->opaque_post_parsing_context; - GNUNET_async_scope_enter (&ecls->async_scope_id, + GNUNET_async_scope_enter (&rc->async_scope_id, &old_scope); if (NULL != correlation_id) GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -964,7 +931,7 @@ handle_mhd_request (void *cls, method, url); /* on repeated requests, check our cache first */ - if (NULL != ecls->rh) + if (NULL != rc->rh) { MHD_RESULT ret; const char *start; @@ -975,10 +942,8 @@ handle_mhd_request (void *cls, start = strchr (url + 1, '/'); if (NULL == start) start = ""; - ret = proceed_with_handler (ecls->rh, - connection, + ret = proceed_with_handler (rc, start, - inner_cls, upload_data, upload_data_size); GNUNET_async_scope_restore (&old_scope); @@ -1039,12 +1004,10 @@ handle_mhd_request (void *cls, MHD_RESULT ret; /* cache to avoid the loop next time */ - ecls->rh = rh; + rc->rh = rh; /* run handler */ - ret = proceed_with_handler (rh, - connection, + ret = proceed_with_handler (rc, url + tok_size + 1, - inner_cls, upload_data, upload_data_size); GNUNET_async_scope_restore (&old_scope); diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h index 497ff16a7..eaecc9720 100644 --- a/src/exchange/taler-exchange-httpd.h +++ b/src/exchange/taler-exchange-httpd.h @@ -83,6 +83,62 @@ extern char *TEH_currency; */ extern volatile bool MHD_terminating; + +/** + * @brief Struct describing an URL and the handler for it. + */ +struct TEH_RequestHandler; + + +/** + * @brief Context in which the exchange is processing + * all requests + */ +struct TEH_RequestContext +{ + + /** + * Async Scope ID associated with this request. + */ + struct GNUNET_AsyncScopeId async_scope_id; + + /** + * Opaque parsing context. + */ + void *opaque_post_parsing_context; + + /** + * Request handler responsible for this request. + */ + const struct TEH_RequestHandler *rh; + + /** + * Request URL (for logging). + */ + const char *url; + + /** + * Connection we are processing. + */ + struct MHD_Connection *connection; + + /** + * @e rh-specific cleanup routine. Function called + * upon completion of the request that should + * clean up @a rh_ctx. Can be NULL. + */ + void + (*rh_cleaner)(struct TEH_RequestContext *rc); + + /** + * @e rh-specific context. Place where the request + * handler can associate state with this request. + * Can be NULL. + */ + void *rh_ctx; +}; + + /** * @brief Struct describing an URL and the handler for it. */ @@ -109,31 +165,28 @@ struct TEH_RequestHandler * Function to call to handle a GET requests (and those * with @e method NULL). * - * @param rh this struct + * @param rc context for the request * @param mime_type the @e mime_type for the reply (hint, can be NULL) - * @param connection the MHD connection to handle * @param args array of arguments, needs to be of length @e args_expected * @return MHD result code */ - MHD_RESULT (*get)(const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const char *const args[]); + MHD_RESULT + (*get)(struct TEH_RequestContext *rc, + const char *const args[]); /** * Function to call to handle a POST request. * - * @param rh this struct - * @param mime_type the @e mime_type for the reply (hint, can be NULL) - * @param connection the MHD connection to handle + * @param rc context for the request * @param json uploaded JSON data * @param args array of arguments, needs to be of length @e args_expected * @return MHD result code */ - MHD_RESULT (*post)(const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, - const json_t *root, - const char *const args[]); + MHD_RESULT + (*post)(struct TEH_RequestContext *rc, + const json_t *root, + const char *const args[]); } handler; diff --git a/src/exchange/taler-exchange-httpd_deposits_get.c b/src/exchange/taler-exchange-httpd_deposits_get.c index c51e0f426..f32b88b6d 100644 --- a/src/exchange/taler-exchange-httpd_deposits_get.c +++ b/src/exchange/taler-exchange-httpd_deposits_get.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2017 Taler Systems SA + Copyright (C) 2014-2017, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -298,19 +298,8 @@ handle_track_transaction_request ( } -/** - * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB" - * request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 4, contains: - * h_wire, merchant_pub, h_contract_terms and coin_pub) - * @return MHD result code - */ MHD_RESULT -TEH_handler_deposits_get (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_deposits_get (struct TEH_RequestContext *rc, const char *const args[4]) { enum GNUNET_GenericReturnValue res; @@ -320,7 +309,6 @@ TEH_handler_deposits_get (const struct TEH_RequestHandler *rh, .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION) }; - (void) rh; if (GNUNET_OK != GNUNET_STRINGS_string_to_data (args[0], strlen (args[0]), @@ -328,7 +316,7 @@ TEH_handler_deposits_get (const struct TEH_RequestHandler *rh, sizeof (tps.h_wire))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_H_WIRE, args[0]); @@ -340,7 +328,7 @@ TEH_handler_deposits_get (const struct TEH_RequestHandler *rh, sizeof (tps.merchant))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_MERCHANT_PUB, args[1]); @@ -352,7 +340,7 @@ TEH_handler_deposits_get (const struct TEH_RequestHandler *rh, sizeof (tps.h_contract_terms))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_H_CONTRACT_TERMS, args[2]); @@ -364,12 +352,12 @@ TEH_handler_deposits_get (const struct TEH_RequestHandler *rh, sizeof (tps.coin_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_COIN_PUB, args[3]); } - res = TALER_MHD_parse_request_arg_data (connection, + res = TALER_MHD_parse_request_arg_data (rc->connection, "merchant_sig", &merchant_sig, sizeof (merchant_sig)); @@ -384,13 +372,13 @@ TEH_handler_deposits_get (const struct TEH_RequestHandler *rh, &tps.merchant.eddsa_pub)) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_FORBIDDEN, TALER_EC_EXCHANGE_DEPOSITS_GET_MERCHANT_SIGNATURE_INVALID, NULL); } - return handle_track_transaction_request (connection, + return handle_track_transaction_request (rc->connection, &tps, &tps.merchant); } diff --git a/src/exchange/taler-exchange-httpd_deposits_get.h b/src/exchange/taler-exchange-httpd_deposits_get.h index a745c5de2..aee7521a5 100644 --- a/src/exchange/taler-exchange-httpd_deposits_get.h +++ b/src/exchange/taler-exchange-httpd_deposits_get.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2017 Taler Systems SA + Copyright (C) 2014-2017, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -30,15 +30,13 @@ * Handle a "/deposits/$H_WIRE/$MERCHANT_PUB/$H_CONTRACT_TERMS/$COIN_PUB" * request. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param args array of additional options (length: 4, contains: * h_wire, merchant_pub, h_contract_terms and coin_pub) * @return MHD result code */ MHD_RESULT -TEH_handler_deposits_get (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_deposits_get (struct TEH_RequestContext *rc, const char *const args[4]); diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 0cc8c831c..216afd7c5 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -2053,18 +2053,16 @@ krd_search_comparator (const void *key, MHD_RESULT -TEH_keys_get_handler (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_keys_get_handler (struct TEH_RequestContext *rc, const char *const args[]) { struct GNUNET_TIME_Absolute last_issue_date; - (void) rh; (void) args; { const char *have_cherrypick; - have_cherrypick = MHD_lookup_connection_value (connection, + have_cherrypick = MHD_lookup_connection_value (rc->connection, MHD_GET_ARGUMENT_KIND, "last_issue_date"); if (NULL != have_cherrypick) @@ -2077,7 +2075,7 @@ TEH_keys_get_handler (const struct TEH_RequestHandler *rh, &cherrypickn)) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, have_cherrypick); @@ -2103,16 +2101,16 @@ TEH_keys_get_handler (const struct TEH_RequestHandler *rh, { GNUNET_assert (0 == pthread_mutex_lock (&skr_mutex)); if ( (SKR_LIMIT == skr_size) && - (connection == skr_connection) ) + (rc->connection == skr_connection) ) { GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex)); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, "too many connections suspended on /keys"); } GNUNET_assert (0 == pthread_mutex_unlock (&skr_mutex)); - return suspend_request (connection); + return suspend_request (rc->connection); } krd = bsearch (&last_issue_date, ksh->krd_array, @@ -2140,14 +2138,15 @@ TEH_keys_get_handler (const struct TEH_RequestHandler *rh, NOT_FOUND situation. But, OTOH, for 'sane' clients it is more likely to be our fault, so let's speculatively assume we are to blame ;-) */// GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, "no key data for given timestamp"); } - return MHD_queue_response (connection, + return MHD_queue_response (rc->connection, MHD_HTTP_OK, - (MHD_YES == TALER_MHD_can_compress (connection)) + (MHD_YES == + TALER_MHD_can_compress (rc->connection)) ? krd->response_compressed : krd->response_uncompressed); } diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h index 8d2aae9d5..6c6853660 100644 --- a/src/exchange/taler-exchange-httpd_keys.h +++ b/src/exchange/taler-exchange-httpd_keys.h @@ -324,14 +324,12 @@ TEH_keys_exchange_revoke (const struct TALER_ExchangePublicKeyP *exchange_pub); * Function to call to handle requests to "/keys" by sending * back our current key material. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param args array of additional options (must be empty for this function) * @return MHD result code */ MHD_RESULT -TEH_keys_get_handler (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_keys_get_handler (struct TEH_RequestContext *rc, const char *const args[]); diff --git a/src/exchange/taler-exchange-httpd_link.c b/src/exchange/taler-exchange-httpd_link.c index a39e58641..bbb027522 100644 --- a/src/exchange/taler-exchange-httpd_link.c +++ b/src/exchange/taler-exchange-httpd_link.c @@ -169,23 +169,13 @@ link_transaction (void *cls, } -/** - * Handle a "/coins/$COIN_PUB/link" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 2, first is the coin_pub, second must be "link") - * @return MHD result code - */ MHD_RESULT -TEH_handler_link (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_link (struct TEH_RequestContext *rc, const char *const args[2]) { struct HTD_Context ctx; MHD_RESULT mhd_ret; - (void) rh; memset (&ctx, 0, sizeof (ctx)); @@ -196,22 +186,15 @@ TEH_handler_link (const struct TEH_RequestHandler *rh, sizeof (ctx.coin_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_GENERIC_COINS_INVALID_COIN_PUB, args[0]); } ctx.mlist = json_array (); - if (NULL == ctx.mlist) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_JSON_ALLOCATION_FAILURE, - "json_array() call failed"); - } + GNUNET_assert (NULL != ctx.mlist); if (GNUNET_OK != - TEH_DB_run_transaction (connection, + TEH_DB_run_transaction (rc->connection, "run link", &mhd_ret, &link_transaction, @@ -221,7 +204,7 @@ TEH_handler_link (const struct TEH_RequestHandler *rh, json_decref (ctx.mlist); return mhd_ret; } - mhd_ret = TALER_MHD_reply_json (connection, + mhd_ret = TALER_MHD_reply_json (rc->connection, ctx.mlist, MHD_HTTP_OK); json_decref (ctx.mlist); diff --git a/src/exchange/taler-exchange-httpd_link.h b/src/exchange/taler-exchange-httpd_link.h index 4c9651a9e..01679e877 100644 --- a/src/exchange/taler-exchange-httpd_link.h +++ b/src/exchange/taler-exchange-httpd_link.h @@ -31,14 +31,12 @@ /** * Handle a "/coins/$COIN_PUB/link" request. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param args array of additional options (length: 2, first is the coin_pub, second must be "link") * @return MHD result code */ MHD_RESULT -TEH_handler_link (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_link (struct TEH_RequestContext *rc, const char *const args[2]); diff --git a/src/exchange/taler-exchange-httpd_mhd.c b/src/exchange/taler-exchange-httpd_mhd.c index c9c6303b8..8d07c3cfc 100644 --- a/src/exchange/taler-exchange-httpd_mhd.c +++ b/src/exchange/taler-exchange-httpd_mhd.c @@ -34,27 +34,18 @@ #include "taler-exchange-httpd_mhd.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 args array of additional options (must be empty for this function) - * @return MHD result code - */ MHD_RESULT -TEH_handler_static_response (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_static_response (struct TEH_RequestContext *rc, const char *const args[]) { + const struct TEH_RequestHandler *rh = rc->rh; size_t dlen; (void) args; dlen = (0 == rh->data_size) ? strlen ((const char *) rh->data) : rh->data_size; - return TALER_MHD_reply_static (connection, + return TALER_MHD_reply_static (rc->connection, rh->response_code, rh->mime_type, rh->data, @@ -62,24 +53,13 @@ TEH_handler_static_response (const struct TEH_RequestHandler *rh, } -/** - * 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 args array of additional options (must be empty for this function) - * @return MHD result code - */ MHD_RESULT -TEH_handler_agpl_redirect (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_agpl_redirect (struct TEH_RequestContext *rc, const char *const args[]) { - (void) rh; (void) args; - return TALER_MHD_reply_agpl (connection, - "http://www.git.taler.net/?p=exchange.git"); + return TALER_MHD_reply_agpl (rc->connection, + "https://git.taler.net/?p=exchange.git"); } diff --git a/src/exchange/taler-exchange-httpd_mhd.h b/src/exchange/taler-exchange-httpd_mhd.h index 7547780df..270b0539a 100644 --- a/src/exchange/taler-exchange-httpd_mhd.h +++ b/src/exchange/taler-exchange-httpd_mhd.h @@ -30,16 +30,14 @@ /** * Function to call to handle the request by sending - * back static data from the @a rh. + * back static data from the request handler. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param args array of additional options (must be empty for this function) * @return MHD result code */ MHD_RESULT -TEH_handler_static_response (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_static_response (struct TEH_RequestContext *rc, const char *const args[]); @@ -47,14 +45,12 @@ TEH_handler_static_response (const struct TEH_RequestHandler *rh, * 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 rc request context * @param args array of additional options (must be empty for this function) * @return MHD result code */ MHD_RESULT -TEH_handler_agpl_redirect (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_agpl_redirect (struct TEH_RequestContext *rc, const char *const args[]); diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index 2a5c3aca7..dc4bdf0e6 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2019 Taler Systems SA + Copyright (C) 2014-2019, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -805,7 +805,7 @@ cleanup: * @param coin_evs envelopes of gamma-selected coins to be signed * @return MHD result code */ -static int +static MHD_RESULT handle_refreshes_reveal_json (struct MHD_Connection *connection, struct RevealContext *rctx, const json_t *tp_json, @@ -853,7 +853,7 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection, GNUNET_JSON_spec_fixed_auto (NULL, &rctx->transfer_privs[i]), GNUNET_JSON_spec_end () }; - int res; + enum GNUNET_GenericReturnValue res; res = TALER_MHD_parse_json_array (connection, tp_json, @@ -872,24 +872,8 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection, } -/** - * Handle a "/refreshes/$RCH/reveal" request. This time, the client reveals the - * private transfer keys except for the cut-and-choose value returned from - * "/coins/$COIN_PUB/melt". This function parses the revealed keys and secrets and - * ultimately passes everything to resolve_refreshes_reveal_denominations() - * which will verify that the revealed information is valid then runs the - * transaction in refreshes_reveal_transaction() and finally returns the signed - * refreshed coins. - * - * @param rh context of the handler - * @param connection MHD request handle - * @param root uploaded JSON data - * @param args array of additional options (length: 2, session hash and the string "reveal") - * @return MHD result code - */ MHD_RESULT -TEH_handler_reveal (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_reveal (struct TEH_RequestContext *rc, const json_t *root, const char *const args[2]) { @@ -907,7 +891,6 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh, GNUNET_JSON_spec_end () }; - (void) rh; memset (&rctx, 0, sizeof (rctx)); @@ -918,7 +901,7 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh, sizeof (rctx.rc))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_REFRESHES_REVEAL_INVALID_RCH, args[0]); @@ -927,16 +910,16 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh, "reveal")) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_REFRESHES_REVEAL_OPERATION_INVALID, args[1]); } { - int res; + enum GNUNET_GenericReturnValue res; - res = TALER_MHD_parse_json_data (connection, + res = TALER_MHD_parse_json_data (rc->connection, root, spec); if (GNUNET_OK != res) @@ -952,16 +935,16 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh, { GNUNET_JSON_parse_free (spec); GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_REFRESHES_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID, NULL); } { - int res; + MHD_RESULT res; - res = handle_refreshes_reveal_json (connection, + res = handle_refreshes_reveal_json (rc->connection, &rctx, transfer_privs, link_sigs, diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.h b/src/exchange/taler-exchange-httpd_refreshes_reveal.h index b9806dbd3..30716995a 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.h +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2017 Taler Systems SA + Copyright (C) 2014-2017, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -37,15 +37,13 @@ * transaction in refresh_reveal_transaction() and finally returns the signed * refreshed coins. * - * @param rh context of the handler - * @param connection MHD request handle + * @param rc request context * @param root uploaded JSON data * @param args array of additional options (length: 2, session hash and the string "reveal") * @return MHD result code */ MHD_RESULT -TEH_handler_reveal (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_reveal (struct TEH_RequestContext *rc, const json_t *root, const char *const args[2]); diff --git a/src/exchange/taler-exchange-httpd_reserves_get.c b/src/exchange/taler-exchange-httpd_reserves_get.c index 6ad393a28..d08543a4e 100644 --- a/src/exchange/taler-exchange-httpd_reserves_get.c +++ b/src/exchange/taler-exchange-httpd_reserves_get.c @@ -29,6 +29,45 @@ #include "taler-exchange-httpd_responses.h" +/** + * Reserve GET request that is long-polling. + */ +struct ReservePoller +{ + /** + * Kept in a DLL. + */ + struct ReservePoller *next; + + /** + * Kept in a DLL. + */ + struct ReservePoller *prev; + + /** + * Connection we are handling. + */ + struct MHD_Connection *connection; + + /** + * Entry in the timeout heap. + */ + struct GNUNET_CONTAINER_HeapNode *hn; + + /** + * Subscription for the database event we are + * waiting for. + */ + struct GNUNET_DB_EventHandler *eh; + + /** + * When will this request time out? + */ + struct GNUNET_TIME_Absolute timeout; + +}; + + /** * Send reserve history to client. * @@ -112,26 +151,13 @@ reserve_history_transaction (void *cls, } -/** - * Handle a GET "/reserves/" request. Parses the - * given "reserve_pub" in @a args (which should contain the - * EdDSA public key of a reserve) and then respond with the - * history of the reserve. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 1, just the reserve_pub) - * @return MHD result code - */ MHD_RESULT -TEH_handler_reserves_get (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_reserves_get (struct TEH_RequestContext *rc, const char *const args[1]) { struct ReserveHistoryContext rsc; MHD_RESULT mhd_ret; - (void) rh; if (GNUNET_OK != GNUNET_STRINGS_string_to_data (args[0], strlen (args[0]), @@ -139,14 +165,14 @@ TEH_handler_reserves_get (const struct TEH_RequestHandler *rh, sizeof (rsc.reserve_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_MERCHANT_GENERIC_RESERVE_PUB_MALFORMED, args[0]); } rsc.rh = NULL; if (GNUNET_OK != - TEH_DB_run_transaction (connection, + TEH_DB_run_transaction (rc->connection, "get reserve history", &mhd_ret, &reserve_history_transaction, @@ -155,11 +181,11 @@ TEH_handler_reserves_get (const struct TEH_RequestHandler *rh, /* generate proper response */ if (NULL == rsc.rh) - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_NOT_FOUND, TALER_EC_EXCHANGE_RESERVES_GET_STATUS_UNKNOWN, args[0]); - mhd_ret = reply_reserve_history_success (connection, + mhd_ret = reply_reserve_history_success (rc->connection, rsc.rh); TEH_plugin->free_reserve_history (TEH_plugin->cls, rsc.rh); diff --git a/src/exchange/taler-exchange-httpd_reserves_get.h b/src/exchange/taler-exchange-httpd_reserves_get.h index b46a6a448..1eb9ab60e 100644 --- a/src/exchange/taler-exchange-httpd_reserves_get.h +++ b/src/exchange/taler-exchange-httpd_reserves_get.h @@ -33,14 +33,12 @@ * EdDSA public key of a reserve) and then respond with the * status of the reserve. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param args array of additional options (length: 1, just the reserve_pub) * @return MHD result code */ MHD_RESULT -TEH_handler_reserves_get (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_reserves_get (struct TEH_RequestContext *rc, const char *const args[1]); #endif diff --git a/src/exchange/taler-exchange-httpd_terms.c b/src/exchange/taler-exchange-httpd_terms.c index 1c703021f..10114f157 100644 --- a/src/exchange/taler-exchange-httpd_terms.c +++ b/src/exchange/taler-exchange-httpd_terms.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2019 Taler Systems SA + Copyright (C) 2019, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -38,51 +38,26 @@ static struct TALER_MHD_Legal *tos; static struct TALER_MHD_Legal *pp; -/** - * Handle a "/terms" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (must be empty for this function) - * @return MHD result code - */ MHD_RESULT -TEH_handler_terms (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_terms (struct TEH_RequestContext *rc, const char *const args[]) { - (void) rh; (void) args; - return TALER_MHD_reply_legal (connection, + return TALER_MHD_reply_legal (rc->connection, tos); } -/** - * Handle a "/privacy" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (must be empty for this function) - * @return MHD result code - */ MHD_RESULT -TEH_handler_privacy (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_privacy (struct TEH_RequestContext *rc, const char *const args[]) { - (void) rh; (void) args; - return TALER_MHD_reply_legal (connection, + return TALER_MHD_reply_legal (rc->connection, pp); } -/** - * Load our terms of service as per configuration. - * - * @param cfg configuration to process - */ void TEH_load_terms (const struct GNUNET_CONFIGURATION_Handle *cfg) { diff --git a/src/exchange/taler-exchange-httpd_terms.h b/src/exchange/taler-exchange-httpd_terms.h index 3cbd36884..9815080fe 100644 --- a/src/exchange/taler-exchange-httpd_terms.h +++ b/src/exchange/taler-exchange-httpd_terms.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2019 Taler Systems SA + Copyright (C) 2019, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -32,28 +32,24 @@ /** * Handle a "/terms" request. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param args array of additional options (must be empty for this function) * @return MHD result code */ MHD_RESULT -TEH_handler_terms (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_terms (struct TEH_RequestContext *rc, const char *const args[]); /** * Handle a "/privacy" request. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param args array of additional options (must be empty for this function) * @return MHD result code */ MHD_RESULT -TEH_handler_privacy (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_privacy (struct TEH_RequestContext *rc, const char *const args[]); diff --git a/src/exchange/taler-exchange-httpd_transfers_get.c b/src/exchange/taler-exchange-httpd_transfers_get.c index c4e276cc3..9fd343a53 100644 --- a/src/exchange/taler-exchange-httpd_transfers_get.c +++ b/src/exchange/taler-exchange-httpd_transfers_get.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018 Taler Systems SA + Copyright (C) 2014-2018, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -499,23 +499,13 @@ get_transfer_deposits (void *cls, } -/** - * Handle a GET "/transfers/$WTID" request. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param args array of additional options (length: 1, just the wtid) - * @return MHD result code - */ MHD_RESULT -TEH_handler_transfers_get (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_transfers_get (struct TEH_RequestContext *rc, const char *const args[1]) { struct WtidTransactionContext ctx; MHD_RESULT mhd_ret; - (void) rh; memset (&ctx, 0, sizeof (ctx)); @@ -526,13 +516,13 @@ TEH_handler_transfers_get (const struct TEH_RequestHandler *rh, sizeof (ctx.wtid))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_TRANSFERS_GET_WTID_MALFORMED, args[0]); } if (GNUNET_OK != - TEH_DB_run_transaction (connection, + TEH_DB_run_transaction (rc->connection, "run transfers GET", &mhd_ret, &get_transfer_deposits, @@ -541,7 +531,7 @@ TEH_handler_transfers_get (const struct TEH_RequestHandler *rh, free_ctx (&ctx); return mhd_ret; } - mhd_ret = reply_transfer_details (connection, + mhd_ret = reply_transfer_details (rc->connection, &ctx.total, &ctx.merchant_pub, &ctx.h_wire, diff --git a/src/exchange/taler-exchange-httpd_transfers_get.h b/src/exchange/taler-exchange-httpd_transfers_get.h index 83c173347..8a92a5ff2 100644 --- a/src/exchange/taler-exchange-httpd_transfers_get.h +++ b/src/exchange/taler-exchange-httpd_transfers_get.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2017 Taler Systems SA + Copyright (C) 2014-2017, 2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -29,14 +29,12 @@ /** * Handle a GET "/transfers/$WTID" request. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context of the handler * @param args array of additional options (length: 1, just the wtid) * @return MHD result code */ MHD_RESULT -TEH_handler_transfers_get (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_transfers_get (struct TEH_RequestContext *rc, const char *const args[1]); diff --git a/src/exchange/taler-exchange-httpd_wire.c b/src/exchange/taler-exchange-httpd_wire.c index 2617b574f..7246939d5 100644 --- a/src/exchange/taler-exchange-httpd_wire.c +++ b/src/exchange/taler-exchange-httpd_wire.c @@ -95,7 +95,7 @@ destroy_wire_state_cb (void *cls) } -int +enum GNUNET_GenericReturnValue TEH_WIRE_init () { if (0 != @@ -369,21 +369,19 @@ get_wire_state (void) MHD_RESULT -TEH_handler_wire (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_wire (struct TEH_RequestContext *rc, const char *const args[]) { struct WireStateHandle *wsh; - (void) rh; (void) args; wsh = get_wire_state (); if (NULL == wsh) - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION, NULL); - return TALER_MHD_reply_json (connection, + return TALER_MHD_reply_json (rc->connection, wsh->wire_reply, wsh->http_status); } diff --git a/src/exchange/taler-exchange-httpd_wire.h b/src/exchange/taler-exchange-httpd_wire.h index ba556477c..18bec7883 100644 --- a/src/exchange/taler-exchange-httpd_wire.h +++ b/src/exchange/taler-exchange-httpd_wire.h @@ -31,7 +31,7 @@ * * @return #GNUNET_OK on success, #GNUNET_SYSERR on error. */ -int +enum GNUNET_GenericReturnValue TEH_WIRE_init (void); @@ -58,14 +58,12 @@ TEH_wire_update_state (void); /** * Handle a "/wire" request. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param args array of additional options (must be empty for this function) * @return MHD result code */ MHD_RESULT -TEH_handler_wire (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_wire (struct TEH_RequestContext *rc, const char *const args[]); diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c index 7be560847..7d10bb8e7 100644 --- a/src/exchange/taler-exchange-httpd_withdraw.c +++ b/src/exchange/taler-exchange-httpd_withdraw.c @@ -316,24 +316,8 @@ withdraw_transaction (void *cls, } -/** - * Handle a "/reserves/$RESERVE_PUB/withdraw" request. Parses the - * "reserve_pub" EdDSA key of the reserve and the requested "denom_pub" which - * specifies the key/value of the coin to be withdrawn, and checks that the - * signature "reserve_sig" makes this a valid withdrawal request from the - * specified reserve. If so, the envelope with the blinded coin "coin_ev" is - * passed down to execute the withdrawal operation. - * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param root uploaded JSON data - * @param args array of additional options (first must be the - * reserve public key, the second one should be "withdraw") - * @return MHD result code - */ MHD_RESULT -TEH_handler_withdraw (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_withdraw (struct TEH_RequestContext *rc, const json_t *root, const char *const args[2]) { @@ -351,7 +335,6 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, enum TALER_ErrorCode ec; struct TEH_DenominationKey *dk; - (void) rh; if (GNUNET_OK != GNUNET_STRINGS_string_to_data (args[0], strlen (args[0]), @@ -359,7 +342,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, sizeof (wc.wsrd.reserve_pub))) { GNUNET_break_op (0); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, TALER_EC_MERCHANT_GENERIC_RESERVE_PUB_MALFORMED, args[0]); @@ -368,7 +351,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, { enum GNUNET_GenericReturnValue res; - res = TALER_MHD_parse_json_data (connection, + res = TALER_MHD_parse_json_data (rc->connection, root, spec); if (GNUNET_OK != res) @@ -379,7 +362,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, struct GNUNET_TIME_Absolute now; dk = TEH_keys_denomination_by_hash (&wc.denom_pub_hash, - connection, + rc->connection, &mret); if (NULL == dk) { @@ -397,7 +380,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, /* This denomination is past the expiration time for withdraws */ GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_expired_denom_pub_hash ( - connection, + rc->connection, &wc.denom_pub_hash, now, TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED, @@ -412,7 +395,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, /* This denomination is not yet valid */ GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_expired_denom_pub_hash ( - connection, + rc->connection, &wc.denom_pub_hash, now, TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE, @@ -427,7 +410,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, /* This denomination has been revoked */ GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_expired_denom_pub_hash ( - connection, + rc->connection, &wc.denom_pub_hash, now, TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, @@ -442,7 +425,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, &dk->meta.fee_withdraw)) { GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW, NULL); @@ -470,7 +453,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, TALER_LOG_WARNING ( "Client supplied invalid signature for withdraw request\n"); GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, + return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_FORBIDDEN, TALER_EC_EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID, NULL); @@ -487,7 +470,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, { GNUNET_break (0); GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_ec (connection, + return TALER_MHD_reply_with_ec (rc->connection, ec, NULL); } @@ -498,7 +481,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, MHD_RESULT mhd_ret; if (GNUNET_OK != - TEH_DB_run_transaction (connection, + TEH_DB_run_transaction (rc->connection, "run withdraw", &mhd_ret, &withdraw_transaction, @@ -520,7 +503,7 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh, MHD_RESULT ret; ret = TALER_MHD_REPLY_JSON_PACK ( - connection, + rc->connection, MHD_HTTP_OK, GNUNET_JSON_pack_rsa_signature ("ev_sig", wc.collectable.sig.rsa_signature)); diff --git a/src/exchange/taler-exchange-httpd_withdraw.h b/src/exchange/taler-exchange-httpd_withdraw.h index 8b248597b..8d2d8c182 100644 --- a/src/exchange/taler-exchange-httpd_withdraw.h +++ b/src/exchange/taler-exchange-httpd_withdraw.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2020 Taler Systems SA + Copyright (C) 2014-2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -35,16 +35,14 @@ * specified reserve. If so, the envelope with the blinded coin "coin_ev" is * passed down to execute the withdrawal operation. * - * @param rh context of the handler - * @param connection the MHD connection to handle + * @param rc request context * @param root uploaded JSON data * @param args array of additional options (first must be the * reserve public key, the second one should be "withdraw") * @return MHD result code */ MHD_RESULT -TEH_handler_withdraw (const struct TEH_RequestHandler *rh, - struct MHD_Connection *connection, +TEH_handler_withdraw (struct TEH_RequestContext *rc, const json_t *root, const char *const args[2]);