diff options
author | Florian Dold <florian.dold@gmail.com> | 2019-10-04 22:33:33 +0530 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2019-10-04 22:33:33 +0530 |
commit | 549761d6b362ee29d6b2569a147788c77065be76 (patch) | |
tree | d6c9dcd39e87f75e93f768277e10e63a45951cda | |
parent | a8a5115d2c526b33b8f92e5cca94802c34e19298 (diff) |
properly separate external/internal APIs
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 177 | ||||
-rw-r--r-- | src/lib/merchant_api_pay.c | 2 | ||||
-rw-r--r-- | src/lib/merchant_api_proposal.c | 2 | ||||
-rw-r--r-- | src/lib/merchant_api_refund.c | 2 | ||||
-rw-r--r-- | src/lib/merchant_api_tip_pickup.c | 2 | ||||
-rw-r--r-- | src/lib/test_merchant_api.c | 114 | ||||
-rw-r--r-- | src/lib/testing_api_helpers.c | 1 |
7 files changed, 182 insertions, 118 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 2864ef66..47c3e34d 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -1066,12 +1066,6 @@ url_handler (void *cls, { "/agpl", MHD_HTTP_METHOD_GET, "text/plain", NULL, 0, &TMH_MHD_handler_agpl_redirect, MHD_HTTP_FOUND }, - { "/public/pay", MHD_HTTP_METHOD_POST, "application/json", - NULL, 0, - &MH_handler_pay, MHD_HTTP_OK }, - { "/public/pay", NULL, "text/plain", - "Only POST is allowed", 0, - &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, { "/track/transfer", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, &MH_handler_track_transfer, MHD_HTTP_OK}, @@ -1090,36 +1084,12 @@ url_handler (void *cls, { "/order", MHD_HTTP_METHOD_POST, "application/json", NULL, 0, &MH_handler_proposal_put, MHD_HTTP_OK }, - { "/public/proposal", MHD_HTTP_METHOD_GET, "text/plain", - NULL, 0, - &MH_handler_proposal_lookup, MHD_HTTP_OK}, - { "/proposal", NULL, "text/plain", - "Only GET/POST are allowed", 0, - &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, { "/refund", MHD_HTTP_METHOD_POST, "application/json", NULL, 0, &MH_handler_refund_increase, MHD_HTTP_OK}, - { "/public/refund", MHD_HTTP_METHOD_GET, "text/plain", - NULL, 0, - &MH_handler_refund_lookup, MHD_HTTP_OK}, - { "/refund", NULL, "application/json", - "Only POST/GET are allowed", 0, - &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED}, { "/tip-authorize", MHD_HTTP_METHOD_POST, "text/plain", NULL, 0, &MH_handler_tip_authorize, MHD_HTTP_OK}, - { "/tip-authorize", NULL, "application/json", - "Only POST is allowed", 0, - &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED}, - { "/public/tip-pickup", MHD_HTTP_METHOD_POST, "text/plain", - NULL, 0, - &MH_handler_tip_pickup, MHD_HTTP_OK}, - { "/public/tip-pickup", MHD_HTTP_METHOD_GET, "text/plain", - NULL, 0, - &MH_handler_tip_pickup_get, MHD_HTTP_OK}, - { "/public/tip-pickup", NULL, "application/json", - "Only POST/GET are allowed", 0, - &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED}, { "/tip-query", MHD_HTTP_METHOD_GET, "text/plain", NULL, 0, &MH_handler_tip_query, MHD_HTTP_OK}, @@ -1131,9 +1101,27 @@ url_handler (void *cls, &MH_handler_config, MHD_HTTP_OK}, {NULL, NULL, NULL, NULL, 0, 0 } }; + static struct TMH_RequestHandler public_handlers[] = { + { "/pay", MHD_HTTP_METHOD_POST, "application/json", + NULL, 0, + &MH_handler_pay, MHD_HTTP_OK }, + { "/proposal", MHD_HTTP_METHOD_GET, "text/plain", + NULL, 0, + &MH_handler_proposal_lookup, MHD_HTTP_OK }, + { "/tip-pickup", MHD_HTTP_METHOD_POST, "text/plain", + NULL, 0, + &MH_handler_tip_pickup, MHD_HTTP_OK }, + { "/refund", MHD_HTTP_METHOD_GET, "text/plain", + NULL, 0, + &MH_handler_refund_lookup, MHD_HTTP_OK }, + { "/tip-pickup", MHD_HTTP_METHOD_GET, "text/plain", + NULL, 0, + &MH_handler_tip_pickup_get, MHD_HTTP_OK }, + {NULL, NULL, NULL, NULL, 0, 0 } + }; static struct TMH_RequestHandler h404 = { "", NULL, "text/html", - "<html><title>404: not found</title></html>", 0, + "<html><title>404: not found</title><body>404: not found</body></html>", 0, &TMH_MHD_handler_static_response, MHD_HTTP_NOT_FOUND }; @@ -1142,7 +1130,12 @@ url_handler (void *cls, const char *correlation_id = NULL; struct MerchantInstance *instance; const char *effective_url; + /* Is a publicly facing endpoint being requested? */ + int is_public; + /* Matching URL found, but maybe method doesn't match */ + int url_found = GNUNET_NO; int ret; + struct TMH_RequestHandler *selected_handler = NULL; if (NULL == hc) { @@ -1178,18 +1171,36 @@ url_handler (void *cls, method, url); + effective_url = url; + + { + const char *public_prefix = "/public/"; + + if (0 == strncmp (effective_url, + public_prefix, + strlen (public_prefix))) + { + is_public = GNUNET_YES; + effective_url = effective_url + strlen (public_prefix) - 1; + } + else + { + is_public = GNUNET_NO; + } + } + /* Find out the merchant backend instance for the request. * If there is an instance, remove the instance specification * from the beginning of the request URL. */ { const char *instance_prefix = "/instances/"; - if (0 == strncmp (url, + if (0 == strncmp (effective_url, instance_prefix, strlen (instance_prefix))) { /* url starts with "/instances/" */ - const char *istart = url + strlen (instance_prefix); + const char *istart = effective_url + strlen (instance_prefix); const char *slash = strchr (istart, '/'); char *instance_id; @@ -1210,7 +1221,6 @@ url_handler (void *cls, } else { - effective_url = url; instance = lookup_instance (NULL); } } @@ -1223,39 +1233,78 @@ url_handler (void *cls, "error", "merchant instance unknown"); - for (unsigned int i = 0; NULL != handlers[i].url; i++) + if (GNUNET_NO == is_public) { - struct TMH_RequestHandler *rh = &handlers[i]; + for (unsigned int i = 0; NULL != handlers[i].url; i++) + { + struct TMH_RequestHandler *rh = &handlers[i]; + + if ( (0 != strcasecmp (effective_url, rh->url)) ) + continue; + url_found = GNUNET_YES; + if ( (rh->method != NULL) && (0 != strcasecmp (method, rh->method)) ) + continue; + selected_handler = rh; + break; + } + } - if ( (0 == strcasecmp (effective_url, - rh->url)) && - ( (NULL == rh->method) || - (0 == strcasecmp (method, - rh->method)) ) ) + if (NULL == selected_handler) + { + for (unsigned int i = 0; NULL != public_handlers[i].url; i++) { - ret = rh->handler (rh, - connection, - con_cls, - upload_data, - upload_data_size, - instance); - hc = *con_cls; - if (NULL != hc) - { - hc->rh = rh; - /* Store the async context ID, so we can restore it if - * we get another callack for this request. */ - hc->async_scope_id = aid; - } - return ret; + struct TMH_RequestHandler *rh = &public_handlers[i]; + + if ( (0 != strcasecmp (effective_url, rh->url)) ) + continue; + url_found = GNUNET_YES; + if ( (rh->method != NULL) && (0 != strcasecmp (method, rh->method)) ) + continue; + selected_handler = rh; + break; } } - return TMH_MHD_handler_static_response (&h404, - connection, - con_cls, - upload_data, - upload_data_size, - instance); + + if (NULL == selected_handler) + { + if (GNUNET_YES == url_found) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "invalid request: method '%s' for '%s' not allowed\n", + method, + url); + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_METHOD_NOT_ALLOWED, + "{s:s}", + "error", + "method not allowed"); + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "invalid request: URL '%s' not handled\n", + url); + return TMH_MHD_handler_static_response (&h404, + connection, + con_cls, + upload_data, + upload_data_size, + instance); + } + + ret = selected_handler->handler (selected_handler, + connection, + con_cls, + upload_data, + upload_data_size, + instance); + hc = *con_cls; + if (NULL != hc) + { + hc->rh = selected_handler; + /* Store the async context ID, so we can restore it if + * we get another callack for this request. */ + hc->async_scope_id = aid; + } + return ret; } @@ -1282,10 +1331,6 @@ run (void *cls, result = GNUNET_SYSERR; GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); - GNUNET_assert (GNUNET_OK == - GNUNET_log_setup ("taler-merchant-httpd", - "WARNING", - NULL)); if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (config, "taler", diff --git a/src/lib/merchant_api_pay.c b/src/lib/merchant_api_pay.c index c7919a04..174b0c6d 100644 --- a/src/lib/merchant_api_pay.c +++ b/src/lib/merchant_api_pay.c @@ -598,7 +598,7 @@ request_pay_generic ph->abort_cb_cls = abort_cb_cls; ph->pay_cb = pay_cb; ph->pay_cb_cls = pay_cb_cls; - ph->url = TALER_url_join (merchant_url, "public/pay", NULL); + ph->url = TALER_url_join (merchant_url, "pay", NULL); ph->num_coins = num_coins; ph->coins = GNUNET_new_array (num_coins, struct TALER_MERCHANT_PaidCoin); diff --git a/src/lib/merchant_api_proposal.c b/src/lib/merchant_api_proposal.c index 83371eda..88e68dac 100644 --- a/src/lib/merchant_api_proposal.c +++ b/src/lib/merchant_api_proposal.c @@ -387,7 +387,7 @@ TALER_MERCHANT_proposal_lookup (struct GNUNET_CURL_Context *ctx, nonce_str = GNUNET_STRINGS_data_to_string_alloc (nonce, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); } - plo->url = TALER_url_join (backend_url, "public/proposal", + plo->url = TALER_url_join (backend_url, "proposal", "order_id", order_id, "nonce", diff --git a/src/lib/merchant_api_refund.c b/src/lib/merchant_api_refund.c index 3f888099..21138184 100644 --- a/src/lib/merchant_api_refund.c +++ b/src/lib/merchant_api_refund.c @@ -341,7 +341,7 @@ TALER_MERCHANT_refund_lookup (struct GNUNET_CURL_Context *ctx, rlo->cb = cb; rlo->cb_cls = cb_cls; - rlo->url = TALER_url_join (backend_url, "public/refund", "order_id", order_id, NULL); + rlo->url = TALER_url_join (backend_url, "refund", "order_id", order_id, NULL); eh = curl_easy_init (); if (CURLE_OK != curl_easy_setopt (eh, CURLOPT_URL, diff --git a/src/lib/merchant_api_tip_pickup.c b/src/lib/merchant_api_tip_pickup.c index 116b994c..34b7d259 100644 --- a/src/lib/merchant_api_tip_pickup.c +++ b/src/lib/merchant_api_tip_pickup.c @@ -288,7 +288,7 @@ TALER_MERCHANT_tip_pickup (struct GNUNET_CURL_Context *ctx, tpo->cb_cls = pickup_cb_cls; tpo->url = TALER_url_join (backend_url, - "public/tip-pickup", + "tip-pickup", NULL); eh = curl_easy_init (); if (GNUNET_OK != TALER_curl_easy_post (&tpo->post_ctx, diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c index 7548aa58..573d06c4 100644 --- a/src/lib/test_merchant_api.c +++ b/src/lib/test_merchant_api.c @@ -62,26 +62,6 @@ static char *fakebank_url; static char *merchant_url; /** - * Merchant base URL for the tipping instance. - */ -static char *merchant_tip_instance_url; - -/** - * Merchant base URL for the tipping instance. - */ -static char *merchant_tip_instance_2_url; - -/** - * Merchant base URL for the tipping instance. - */ -static char *merchant_tip_instance_nulltip_url; - -/** - * Merchant base URL for a non-existent instance. - */ -static char *merchant_tip_unknown_instance_url; - -/** * Merchant process. */ static struct GNUNET_OS_Process *merchantd; @@ -167,6 +147,57 @@ static char *auditor_url; EXCHANGE_ACCOUNT_NO, USER_LOGIN_NAME, USER_LOGIN_PASS, \ subject) + +static struct GNUNET_CONTAINER_MultiHashMap *interned_strings; + +static const char * +intern (const char *str) +{ + struct GNUNET_HashCode hash; + const char *hs; + + if (NULL == interned_strings) + interned_strings = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); + GNUNET_assert (NULL != interned_strings); + GNUNET_CRYPTO_hash (str, strlen (str), &hash); + hs = GNUNET_CONTAINER_multihashmap_get (interned_strings, &hash); + if (NULL != hs) + return hs; + hs = GNUNET_strdup (str); + GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (interned_strings, + &hash, + (void *) hs, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + return hs; +} + + +#define BUF_SZ 512 + +static const char * +merchant_url_internal (const char *instance_id) +{ + char buf[BUF_SZ]; + if (NULL == instance_id) + GNUNET_assert (0 < snprintf (buf, BUF_SZ, "%s", merchant_url)); + else + GNUNET_assert (0 < snprintf (buf, BUF_SZ, "%sinstances/%s/", merchant_url, instance_id)); + return intern (buf); +} + + +static const char * +merchant_url_external (const char *instance_id) +{ + char buf[BUF_SZ]; + if (NULL == instance_id) + GNUNET_assert (0 < snprintf (buf, BUF_SZ, "%spublic/", merchant_url)); + else + GNUNET_assert (0 < snprintf (buf, BUF_SZ, "%spublic/instances/%s/", merchant_url, instance_id)); + return intern (buf); +} + + /** * Main function that will tell the interpreter what commands to * run. @@ -631,14 +662,14 @@ run (void *cls, "EUR:20.04", USER_ACCOUNT_NO, EXCHANGE_ACCOUNT_NO), TALER_TESTING_cmd_tip_authorize ("authorize-tip-1", - merchant_tip_instance_url, + merchant_url_internal ("tip"), exchange_url, MHD_HTTP_OK, "tip 1", "EUR:5.01"), TALER_TESTING_cmd_tip_authorize ("authorize-tip-2", - merchant_tip_instance_url, + merchant_url_internal ("tip"), exchange_url, MHD_HTTP_OK, "tip 2", @@ -651,7 +682,7 @@ run (void *cls, * actually create a reserve. */ TALER_TESTING_cmd_tip_authorize_with_ec ("authorize-tip-null", - merchant_tip_instance_nulltip_url, + merchant_url_internal ("nulltip"), exchange_url, MHD_HTTP_NOT_FOUND, "tip 2", @@ -659,37 +690,37 @@ run (void *cls, TALER_EC_RESERVE_STATUS_UNKNOWN), TALER_TESTING_cmd_tip_query ("query-tip-1", - merchant_tip_instance_url, + merchant_url_internal ("tip"), MHD_HTTP_OK), TALER_TESTING_cmd_tip_query_with_amounts ("query-tip-2", - merchant_tip_instance_url, + merchant_url_internal ("tip"), MHD_HTTP_OK, "EUR:0.0", // picked "EUR:10.02", // auth "EUR:20.04"),// ava TALER_TESTING_cmd_tip_pickup ("pickup-tip-1", - merchant_tip_instance_url, + merchant_url_external ("tip"), MHD_HTTP_OK, "authorize-tip-1", pickup_amounts_1), TALER_TESTING_cmd_tip_query_with_amounts ("query-tip-3", - merchant_tip_instance_url, + merchant_url_internal ("tip"), MHD_HTTP_OK, "EUR:5.01", // picked NULL, // auth "EUR:15.03"),// ava TALER_TESTING_cmd_tip_pickup ("pickup-tip-2", - merchant_tip_instance_url, + merchant_url_external ("tip"), MHD_HTTP_OK, "authorize-tip-2", pickup_amounts_1), TALER_TESTING_cmd_tip_query_with_amounts ("query-tip-4", - merchant_tip_instance_url, + merchant_url_internal ("tip"), MHD_HTTP_OK, "EUR:10.02", // pick "EUR:10.02", // auth @@ -719,7 +750,7 @@ run (void *cls, TALER_TESTING_cmd_tip_authorize_with_ec ("authorize-tip-3-insufficient-funds", - merchant_tip_instance_2_url, + merchant_url_internal ("dtip"), exchange_url, MHD_HTTP_PRECONDITION_FAILED, "tip 3", @@ -728,7 +759,7 @@ run (void *cls, TALER_TESTING_cmd_tip_authorize_with_ec ("authorize-tip-4-unknown-instance", - merchant_tip_unknown_instance_url, + merchant_url_internal ("unknown"), exchange_url, MHD_HTTP_NOT_FOUND, "tip 4", @@ -746,7 +777,7 @@ run (void *cls, TALER_TESTING_cmd_tip_pickup_with_ec ("pickup-tip-3-too-much", - merchant_tip_instance_url, + merchant_url_external ("tip"), MHD_HTTP_CONFLICT, "authorize-tip-1", pickup_amounts_1, @@ -757,7 +788,7 @@ run (void *cls, TALER_TESTING_cmd_tip_pickup_with_ec ("pickup-non-existent-id", - merchant_tip_instance_url, + merchant_url_external ("tip"), MHD_HTTP_NOT_FOUND, "fake-tip-authorization", pickup_amounts_1, @@ -765,7 +796,7 @@ run (void *cls, TALER_TESTING_cmd_proposal ("create-proposal-tip-1", - merchant_tip_instance_url, + merchant_url_internal ("tip"), MHD_HTTP_OK, "{\"max_fee\":\ {\"currency\":\"EUR\",\ @@ -784,7 +815,7 @@ run (void *cls, \"value\":\"{EUR:5}\"} ] }"), TALER_TESTING_cmd_pay ("deposit-tip-simple", - merchant_tip_instance_url, + merchant_url_external ("tip"), MHD_HTTP_OK, "create-proposal-tip-1", "pickup-tip-1", @@ -1048,19 +1079,6 @@ main (int argc, (merchant_url = TALER_TESTING_prepare_merchant (CONFIG_FILE))) return 77; - merchant_tip_instance_url = TALER_url_join (merchant_url, - "instances/tip/", - NULL); - merchant_tip_instance_2_url = TALER_url_join (merchant_url, - "instances/dtip/", - NULL); - merchant_tip_instance_nulltip_url = TALER_url_join (merchant_url, - "instances/nulltip/", - NULL); - merchant_tip_unknown_instance_url = TALER_url_join (merchant_url, - "instances/foo/", - NULL); - TALER_TESTING_cleanup_files (CONFIG_FILE); switch (TALER_TESTING_prepare_exchange (CONFIG_FILE, diff --git a/src/lib/testing_api_helpers.c b/src/lib/testing_api_helpers.c index 39cef121..2d1a9317 100644 --- a/src/lib/testing_api_helpers.c +++ b/src/lib/testing_api_helpers.c @@ -54,6 +54,7 @@ TALER_TESTING_run_merchant (const char *config_filename, NULL, NULL, NULL, "taler-merchant-httpd", "taler-merchant-httpd", + "--log=INFO", "-c", config_filename, NULL); if (NULL == merchant_proc) |