From 23750b7d0622c7080ff8acde2b623568b98a88f4 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 25 Apr 2020 21:55:45 +0200 Subject: misc. fixes --- src/backend/Makefile.am | 2 + src/backend/taler-merchant-httpd.c | 77 ++++++++++++---------- ...er-merchant-httpd_private-delete-instances-ID.c | 1 + ...ler-merchant-httpd_private-delete-products-ID.c | 6 +- ...taler-merchant-httpd_private-get-instances-ID.c | 2 +- ...ler-merchant-httpd_private-patch-instances-ID.c | 16 ++++- .../taler-merchant-httpd_private-post-instances.c | 2 + src/backenddb/drop0001.sql | 26 +++++--- src/backenddb/plugin_merchantdb_postgres.c | 46 ++++++++++++- src/include/taler_merchantdb_plugin.h | 48 +++++++++----- src/lib/merchant_api_get_instance.c | 1 + src/testing/Makefile.am | 2 +- src/testing/test_merchant_api.c | 76 +++++++++++++++++++-- src/testing/testing_api_cmd_patch_instance.c | 7 +- 14 files changed, 238 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index 58f11ed9..e367949c 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -25,6 +25,8 @@ taler_merchant_httpd_SOURCES = \ taler-merchant-httpd_mhd.c taler-merchant-httpd_mhd.h \ taler-merchant-httpd_private-delete-instances-ID.c \ taler-merchant-httpd_private-delete-instances-ID.h \ + taler-merchant-httpd_private-delete-products-ID.c \ + taler-merchant-httpd_private-delete-products-ID.h \ taler-merchant-httpd_private-get-instances.c \ taler-merchant-httpd_private-get-instances.h \ taler-merchant-httpd_private-get-instances-ID.c \ diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index d5bcec60..90d76811 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -37,6 +37,7 @@ #include "taler-merchant-httpd_private-patch-instances-ID.h" #include "taler-merchant-httpd_private-patch-products-ID.h" #include "taler-merchant-httpd_private-post-instances.h" +#include "taler-merchant-httpd_private-post-products.h" #include "taler-merchant-httpd_private-post-products-ID-lock.h" /** @@ -124,10 +125,18 @@ void TMH_instance_decref (struct TMH_MerchantInstance *mi) { struct TMH_WireMethod *wm; + struct GNUNET_HashCode h_instance; mi->rc--; if (0 != mi->rc) return; + GNUNET_CRYPTO_hash (mi->settings.id, + strlen (mi->settings.id), + &h_instance); + GNUNET_assert (GNUNET_OK == + GNUNET_CONTAINER_multihashmap_remove (TMH_by_id_map, + &h_instance, + mi)); while (NULL != (wm = (mi->wm_head))) { GNUNET_CONTAINER_DLL_remove (mi->wm_head, @@ -713,25 +722,6 @@ url_handler (void *cls, void **con_cls) { static struct TMH_RequestHandler private_handlers[] = { - /* GET /: */ - { - .url_prefix = "/", - .method = MHD_HTTP_METHOD_GET, - .mime_type = "text/plain", - .skip_instance = true, - .data = "This is a GNU Taler merchant backend. See https://taler.net/.\n", - .data_size = strlen ( - "This is a GNU Taler merchant backend. See https://taler.net/.\n"), - .handler = &TMH_MHD_handler_static_response, - .response_code = MHD_HTTP_OK - }, - /* GET /agpl: */ - { - .url_prefix = "/agpl", - .method = MHD_HTTP_METHOD_GET, - .skip_instance = true, - .handler = &TMH_MHD_handler_agpl_redirect - }, /* GET /instances: */ { .url_prefix = "/instances", @@ -770,30 +760,36 @@ url_handler (void *cls, .method = MHD_HTTP_METHOD_GET, .handler = &TMH_private_get_products }, - /* GET /products/$ID/: */ + /* POST /products: */ { .url_prefix = "/products", + .method = MHD_HTTP_METHOD_POST, + .handler = &TMH_private_post_products + }, + /* GET /products/$ID/: */ + { + .url_prefix = "/products/", .method = MHD_HTTP_METHOD_GET, .have_id_segment = true, - .handler = &TMH_private_get_instances_ID + .handler = &TMH_private_get_products_ID }, /* DELETE /products/$ID/: */ { - .url_prefix = "/products", + .url_prefix = "/products/", .method = MHD_HTTP_METHOD_DELETE, .have_id_segment = true, - .handler = &TMH_private_delete_instances_ID + .handler = &TMH_private_delete_products_ID }, /* PATCH /products/$ID/: */ { - .url_prefix = "/products", + .url_prefix = "/products/", .method = MHD_HTTP_METHOD_PATCH, .have_id_segment = true, .handler = &TMH_private_patch_products_ID }, /* POST /products/$ID/lock: */ { - .url_prefix = "/products", + .url_prefix = "/products/", .url_suffix = "lock", .method = MHD_HTTP_METHOD_POST, .have_id_segment = true, @@ -840,6 +836,7 @@ url_handler (void *cls, }; struct TMH_HandlerContext *hc = *con_cls; struct TMH_RequestHandler *handlers; + bool use_private = false; (void) cls; (void) version; @@ -904,6 +901,18 @@ url_handler (void *cls, MHD_HTTP_METHOD_HEAD)) method = MHD_HTTP_METHOD_GET; /* MHD will deal with the rest */ + { + const char *private_prefix = "/private/"; + + if (0 == strncmp (url, + private_prefix, + strlen (private_prefix))) + { + use_private = true; + url += strlen (private_prefix) - 1; + } + } + /* 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. */ @@ -920,16 +929,16 @@ url_handler (void *cls, char *instance_id; if (NULL == slash) - { - return TMH_MHD_handler_static_response (&h404, - connection, - hc); - } - instance_id = GNUNET_strndup (istart, - slash - istart); + instance_id = GNUNET_strdup (istart); + else + instance_id = GNUNET_strndup (istart, + slash - istart); hc->instance = TMH_lookup_instance (instance_id); GNUNET_free (instance_id); - url = slash; + if (NULL == slash) + url = ""; + else + url = slash; } else { @@ -950,7 +959,7 @@ url_handler (void *cls, } else { - handlers = public_handlers; + handlers = (use_private) ? private_handlers : public_handlers; } } if (0 == strcmp (url, diff --git a/src/backend/taler-merchant-httpd_private-delete-instances-ID.c b/src/backend/taler-merchant-httpd_private-delete-instances-ID.c index 2807318e..965de327 100644 --- a/src/backend/taler-merchant-httpd_private-delete-instances-ID.c +++ b/src/backend/taler-merchant-httpd_private-delete-instances-ID.c @@ -75,6 +75,7 @@ TMH_private_delete_instances_ID (const struct TMH_RequestHandler *rh, ? "Instance unknown" : "Private key unknown"); case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + TMH_instance_decref (mi); return TALER_MHD_reply_static (connection, MHD_HTTP_NO_CONTENT, NULL, diff --git a/src/backend/taler-merchant-httpd_private-delete-products-ID.c b/src/backend/taler-merchant-httpd_private-delete-products-ID.c index 995d4221..fe04d765 100644 --- a/src/backend/taler-merchant-httpd_private-delete-products-ID.c +++ b/src/backend/taler-merchant-httpd_private-delete-products-ID.c @@ -48,7 +48,7 @@ TMH_private_delete_products_ID (const struct TMH_RequestHandler *rh, case GNUNET_DB_STATUS_HARD_ERROR: return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_DELETE_PRODUCTS_ID_DB_HARD_FAILURE, + TALER_EC_PRODUCTS_DELETE_DB_HARD_FAILURE, "Transaction failed"); case GNUNET_DB_STATUS_SOFT_ERROR: GNUNET_break (0); @@ -64,11 +64,11 @@ TMH_private_delete_products_ID (const struct TMH_RequestHandler *rh, if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) return TALER_MHD_reply_with_error (connection, MHD_HTTP_NOT_FOUND, - TALER_EC_DELETE_PRODUCTS_NO_SUCH_PRODUCT, + TALER_EC_PRODUCTS_DELETE_NO_SUCH_PRODUCT, "Product unknown"); return TALER_MHD_reply_with_error (connection, MHD_HTTP_CONFLICT, - TALER_EC_DELETE_PRODUCTS_CONFLICTING_LOCK, + TALER_EC_PRODUCTS_DELETE_CONFLICTING_LOCK, "Product deletion impossible, product is locked"); case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: return TALER_MHD_reply_static (connection, diff --git a/src/backend/taler-merchant-httpd_private-get-instances-ID.c b/src/backend/taler-merchant-httpd_private-get-instances-ID.c index c379bfa3..b6993791 100644 --- a/src/backend/taler-merchant-httpd_private-get-instances-ID.c +++ b/src/backend/taler-merchant-httpd_private-get-instances-ID.c @@ -89,7 +89,7 @@ TMH_private_get_instances_ID (const struct TMH_RequestHandler *rh, &mi->settings.default_max_wire_fee), "default_wire_fee_amortization", (json_int_t) - &mi->settings.default_wire_fee_amortization, + mi->settings.default_wire_fee_amortization, "default_wire_transfer_delay", GNUNET_JSON_from_time_rel ( mi->settings.default_wire_transfer_delay), diff --git a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c index 9e151493..a4104b05 100644 --- a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c +++ b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c @@ -179,6 +179,9 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, bool matches[GNUNET_NZL (len)]; bool matched; + memset (matches, + 0, + sizeof (matches)); for (struct TMH_WireMethod *wm = mi->wm_head; NULL != wm; wm = wm->next) @@ -225,6 +228,9 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, if (! matched) { /* Account was REMOVED */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Existing account `%s' not found, inactivating it.\n", + uri); wm->deleting = true; qs = TMH_db->inactivate_account (TMH_db->cls, &wm->h_wire); @@ -249,11 +255,14 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, ad.payto_uri = json_string_value (json_array_get (payto_uris, i)); GNUNET_assert (NULL != ad.payto_uri); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Adding NEW account `%s'\n", + ad.payto_uri); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &ad.salt, sizeof (ad.salt)); wm = GNUNET_new (struct TMH_WireMethod); - wm->j_wire = json_pack ("{s:O, s:s}", + wm->j_wire = json_pack ("{s:s, s:o}", "payto_uri", ad.payto_uri, "salt", GNUNET_JSON_from_data_auto (&ad.salt)); GNUNET_assert (NULL != wm->j_wire); @@ -265,6 +274,7 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, TALER_JSON_merchant_wire_signature_hash (wm->j_wire, &wm->h_wire)) { + GNUNET_break_op (0); free_wm (wm); while (NULL != (wm = wm_head)) { @@ -338,8 +348,12 @@ giveup: /* Update our 'settings' */ GNUNET_free (mi->settings.name); + json_decref (mi->settings.address); + json_decref (mi->settings.jurisdiction); is.id = mi->settings.id; mi->settings = is; + mi->settings.address = json_incref (mi->settings.address); + mi->settings.jurisdiction = json_incref (mi->settings.jurisdiction); mi->settings.name = GNUNET_strdup (name); /* Add 'new' wire methods to our list */ diff --git a/src/backend/taler-merchant-httpd_private-post-instances.c b/src/backend/taler-merchant-httpd_private-post-instances.c index 609753f1..2bfce6ba 100644 --- a/src/backend/taler-merchant-httpd_private-post-instances.c +++ b/src/backend/taler-merchant-httpd_private-post-instances.c @@ -339,6 +339,8 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, mi->wm_head = wm_head; mi->wm_tail = wm_tail; mi->settings = is; + mi->settings.address = json_incref (mi->settings.address); + mi->settings.jurisdiction = json_incref (mi->settings.jurisdiction); mi->settings.id = GNUNET_strdup (is.id); mi->settings.name = GNUNET_strdup (is.name); GNUNET_CRYPTO_eddsa_key_create (&mi->merchant_priv.eddsa_priv); diff --git a/src/backenddb/drop0001.sql b/src/backenddb/drop0001.sql index 4a1b3ecc..b3ce6b42 100644 --- a/src/backenddb/drop0001.sql +++ b/src/backenddb/drop0001.sql @@ -25,19 +25,27 @@ BEGIN; -- Drops for 0001.sql -DROP TABLE IF EXISTS merchant_transfers CASCADE; -DROP TABLE IF EXISTS merchant_deposits CASCADE; -DROP TABLE IF EXISTS merchant_transactions CASCADE; -DROP TABLE IF EXISTS merchant_proofs CASCADE; +DROP TABLE IF EXISTS merchant_exchange_wire_fees CASCADE; +DROP TABLE IF EXISTS merchant_exchange_signing_keys CASCADE; +DROP TABLE IF EXISTS merchant_instances CASCADE; +DROP TABLE IF EXISTS merchant_keys CASCADE; +DROP TABLE IF EXISTS merchant_accounts CASCADE; +DROP TABLE IF EXISTS merchant_inventory CASCADE; +DROP TABLE IF EXISTS merchant_inventory_locks CASCADE; +DROP TABLE IF EXISTS merchant_accounts CASCADE; +DROP TABLE IF EXISTS merchant_orders CASCADE; +DROP TABLE IF EXISTS merchant_order_locks CASCADE; DROP TABLE IF EXISTS merchant_contract_terms CASCADE; +DROP TABLE IF EXISTS merchant_deposits CASCADE; DROP TABLE IF EXISTS merchant_refunds CASCADE; -DROP TABLE IF EXISTS exchange_wire_fees CASCADE; +DROP TABLE IF EXISTS merchant_credits CASCADE; +DROP TABLE IF EXISTS merchant_transfer_signatures CASCADE; +DROP TABLE IF EXISTS merchant_transfer_by_coin CASCADE; +DROP TABLE IF EXISTS merchant_tip_reserves CASCADE; +DROP TABLE IF EXISTS merchant_tip_reserve_keys CASCADE; DROP TABLE IF EXISTS merchant_tips CASCADE; DROP TABLE IF EXISTS merchant_tip_pickups CASCADE; -DROP TABLE IF EXISTS merchant_tip_reserve_credits CASCADE; -DROP TABLE IF EXISTS merchant_tip_reserves CASCADE; -DROP TABLE IF EXISTS merchant_orders CASCADE; -DROP TABLE IF EXISTS merchant_session_info CASCADE; +DROP TABLE IF EXISTS merchant_tip_pickup_signatures CASCADE; -- Drop versioning (0000.sql) DROP SCHEMA IF EXISTS _v CASCADE; diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index c12978ae..57da9811 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -845,7 +845,7 @@ postgres_lookup_product (void *cls, &pd->price), TALER_PQ_result_spec_json ("taxes", &pd->taxes), - GNUNET_PQ_result_spec_uint64 ("total_stocked", + GNUNET_PQ_result_spec_uint64 ("total_stock", &pd->total_stocked), GNUNET_PQ_result_spec_uint64 ("total_sold", &pd->total_sold), @@ -1029,6 +1029,37 @@ postgres_lock_product (void *cls, } +/** + * Delete information about an order. Note that the transaction must + * enforce that the order is not awaiting payment anymore. + * + * @param cls closure + * @param instance_id instance to delete order of + * @param order_id order to delete + * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS + * if pending payment prevents deletion OR order unknown + */ +static enum GNUNET_DB_QueryStatus +postgres_delete_order (void *cls, + const char *instance_id, + const char *order_id) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_string (order_id), + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_end + }; + + check_connection (pg); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "delete_order", + params); +} + + /* ********************* OLD API ************************** */ /** @@ -4128,7 +4159,17 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) " FROM merchant_order_locks" " WHERE product_serial=ps.product_serial)", 5), - + /* for postgres_delete_order() */ + GNUNET_PQ_make_prepare ("delete_order", + "DELETE" + " FROM merchant_orders" + " WHERE merchant_inventory.merchant_serial=" + " (SELECT merchant_serial " + " FROM merchant_instances" + " WHERE merchant_id=$1)" + " AND merchant_orders.order_id=$2" + " AND pay_deadline < $3", + 3), /* OLD API: */ #if 0 GNUNET_PQ_make_prepare ("insert_deposit", @@ -4638,6 +4679,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) plugin->insert_product = &postgres_insert_product; plugin->update_product = &postgres_update_product; plugin->lock_product = &postgres_lock_product; + plugin->delete_order = &postgres_delete_order; /* old API: */ plugin->store_deposit = &postgres_store_deposit; diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h index 2a452fb7..214baec9 100644 --- a/src/include/taler_merchantdb_plugin.h +++ b/src/include/taler_merchantdb_plugin.h @@ -613,6 +613,39 @@ struct TALER_MERCHANTDB_Plugin struct GNUNET_TIME_Absolute expiration_time); + /** + * Delete information about an order. Note that the transaction must + * enforce that the order is not awaiting payment anymore. + * + * @param cls closure + * @param instance_id instance to delete order of + * @param order_id order to delete + * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS + * if locks prevent deletion OR order unknown + */ + enum GNUNET_DB_QueryStatus + (*delete_order)(void *cls, + const char *instance_id, + const char *order_id); + + + /** + * Retrieve order given its order id and the instance's merchant public key. + * + * @param cls closure + * @param[out] contract_terms where to store the retrieved contract terms + * @param order id order id used to perform the lookup + * @param merchant_pub merchant public key that identifies the instance + * @return transaction status + */ + // FIXME: rename, change arguments! + enum GNUNET_DB_QueryStatus + (*find_order)(void *cls, + json_t **contract_terms, + const char *order_id, + const struct TALER_MerchantPublicKeyP *merchant_pub); + + /* ****************** OLD API ******************** */ /** @@ -723,21 +756,6 @@ struct TALER_MERCHANTDB_Plugin const char *order_id, const struct TALER_MerchantPublicKeyP *merchant_pub); - /** - * Retrieve order given its order id and the instance's merchant public key. - * - * @param cls closure - * @param[out] contract_terms where to store the retrieved contract terms - * @param order id order id used to perform the lookup - * @param merchant_pub merchant public key that identifies the instance - * @return transaction status - */ - enum GNUNET_DB_QueryStatus - (*find_order)(void *cls, - json_t **contract_terms, - const char *order_id, - const struct TALER_MerchantPublicKeyP *merchant_pub); - /** * Retrieve proposal data given its hashcode diff --git a/src/lib/merchant_api_get_instance.c b/src/lib/merchant_api_get_instance.c index 98e7f146..0007fb7f 100644 --- a/src/lib/merchant_api_get_instance.c +++ b/src/lib/merchant_api_get_instance.c @@ -189,6 +189,7 @@ handle_get_instance_finished (void *cls, return; } } + GNUNET_break_op (0); hr.http_status = 0; hr.ec = TALER_EC_INVALID_RESPONSE; GNUNET_JSON_parse_free (spec); diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index df922b0d..a0977e7a 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -68,7 +68,7 @@ check_PROGRAMS = \ test_merchant_api if HAVE_TWISTER -check_PROGRAMS += test_merchant_api_twisted +# check_PROGRAMS += test_merchant_api_twisted endif endif diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c index d4e25083..1e91d4eb 100644 --- a/src/testing/test_merchant_api.c +++ b/src/testing/test_merchant_api.c @@ -959,20 +959,82 @@ run (void *cls, merchant_url, "i2", MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_get_instance ("instances-get-i2", + TALER_TESTING_cmd_merchant_get_instance ("instances-get-i2-post-deletion", merchant_url, "i2", - MHD_HTTP_OK, + MHD_HTTP_NOT_FOUND, NULL), - TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i2", + TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i2-again", merchant_url, "i2", + MHD_HTTP_NOT_FOUND), + TALER_TESTING_cmd_merchant_post_instances ("instance-create-default", + merchant_url, + "default", + PAYTO_I1, + "EUR", MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_get_instance ("instances-get-i2", + TALER_TESTING_cmd_merchant_get_products ("get-products-empty", merchant_url, - "i2", - MHD_HTTP_NOT_FOUND, - NULL), + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_post_products ("post-products-p1", + merchant_url, + "product-1", + "a product", + "EUR:1", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_get_products ("get-products-p1", + merchant_url, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_get_product ("get-product-p1", + merchant_url, + "product-1", + MHD_HTTP_OK, + "post-products-p1"), + TALER_TESTING_cmd_merchant_post_products ("post-products-p2", + merchant_url, + "product-2", + "a product", + "EUR:1", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_patch_product ("patch-products-p2", + merchant_url, + "product-2", + "another product", + json_pack ("{s:s}", "en", "text"), + "kg", + "EUR:1", + json_object (), + json_object (), + 40, + 0, + json_pack ("{s:s}", + "street", + "pstreet"), + GNUNET_TIME_relative_to_absolute ( + GNUNET_TIME_UNIT_MINUTES), + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_patch_product ("patch-products-p3-nx", + merchant_url, + "product-3", + "nx updated product", + json_pack ("{s:s}", "en", "text"), + "kg", + "EUR:1", + json_object (), + json_object (), + 40, + 0, + json_pack ("{s:s}", + "street", + "pstreet"), + GNUNET_TIME_relative_to_absolute ( + GNUNET_TIME_UNIT_MINUTES), + MHD_HTTP_NOT_FOUND), + TALER_TESTING_cmd_merchant_delete_product ("get-products-empty", + merchant_url, + "p1", + MHD_HTTP_NO_CONTENT), #if 0 TALER_TESTING_cmd_batch ("pay", pay), diff --git a/src/testing/testing_api_cmd_patch_instance.c b/src/testing/testing_api_cmd_patch_instance.c index a198829a..81190769 100644 --- a/src/testing/testing_api_cmd_patch_instance.c +++ b/src/testing/testing_api_cmd_patch_instance.c @@ -203,6 +203,7 @@ patch_instance_cleanup (void *cls, } json_decref (pis->address); json_decref (pis->jurisdiction); + GNUNET_free (pis->payto_uris); GNUNET_free (pis); } @@ -251,7 +252,11 @@ TALER_TESTING_cmd_merchant_patch_instance ( pis->instance_id = instance_id; pis->http_status = http_status; pis->payto_uris_length = payto_uris_length; - pis->payto_uris = payto_uris; + pis->payto_uris = GNUNET_new_array (payto_uris_length, + const char *); + memcpy (pis->payto_uris, + payto_uris, + sizeof (const char *) * payto_uris_length); pis->name = name; pis->address = address; /* ownership transfer! */ pis->jurisdiction = jurisdiction; /* ownership transfer! */ -- cgit v1.2.3