summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-08-03 11:02:26 +0200
committerChristian Grothoff <christian@grothoff.org>2020-08-03 11:02:26 +0200
commitadf0f4fd36290becd33292d56d819aeaf260d5f6 (patch)
tree9f93802a22d7c06dadf2ac0e784e8d8e1fb7a4f6 /src
parentb90d7d27871ca09772a5ff4a5af15928bf3e68cb (diff)
downloadmerchant-adf0f4fd36290becd33292d56d819aeaf260d5f6.tar.gz
merchant-adf0f4fd36290becd33292d56d819aeaf260d5f6.tar.bz2
merchant-adf0f4fd36290becd33292d56d819aeaf260d5f6.zip
support i18n with HTML templates
Diffstat (limited to 'src')
-rw-r--r--src/backend/Makefile.am4
-rw-r--r--src/backend/taler-merchant-httpd.c2
-rw-r--r--src/backend/taler-merchant-httpd_get-orders-ID.c417
3 files changed, 48 insertions, 375 deletions
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index ac2eaafd..925746b3 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -90,7 +90,9 @@ taler_merchant_httpd_SOURCES = \
taler-merchant-httpd_post-tips-ID-pickup.c \
taler-merchant-httpd_post-tips-ID-pickup.h \
taler-merchant-httpd_reserves.c \
- taler-merchant-httpd_reserves.h
+ taler-merchant-httpd_reserves.h \
+ taler-merchant-httpd_templating.c \
+ taler-merchant-httpd_templating.h
taler_merchant_httpd_LDADD = \
$(top_builddir)/src/backenddb/libtalermerchantdb.la \
-ltalerexchange \
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 75a4cf4d..92986ab7 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -62,6 +62,7 @@
#include "taler-merchant-httpd_post-orders-ID-pay.h"
#include "taler-merchant-httpd_post-tips-ID-pickup.h"
#include "taler-merchant-httpd_reserves.h"
+#include "taler-merchant-httpd_templating.h"
/**
* Backlog for listen operation on unix-domain sockets.
@@ -1515,6 +1516,7 @@ run (void *cls,
"merchant",
"FORCE_AUDIT"))
TMH_force_audit = GNUNET_YES;
+ TMH_templating_init ();
if (GNUNET_SYSERR ==
TMH_EXCHANGES_init (config))
{
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c b/src/backend/taler-merchant-httpd_get-orders-ID.c
index efe7c2a3..f34b7ec7 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -27,7 +27,8 @@
#include <taler/taler_exchange_service.h>
#include "taler-merchant-httpd_exchanges.h"
#include "taler-merchant-httpd_get-orders-ID.h"
-#include "../mustach/mustach.h"
+#include "taler-merchant-httpd_templating.h"
+
/**
* How often do we retry DB transactions on serialization failures?
@@ -246,41 +247,6 @@ struct GetOrderData
/**
- * Entry in a key-value array we use as the mustach closure.
- */
-struct KVC
-{
- /**
- * A name, used as the key. NULL for the last entry.
- */
- const char *name;
-
- /**
- * 0-terminated string value to return for @e name.
- */
- char *value;
-};
-
-
-/**
- * Entry in a key-value array we use to cache templates.
- */
-struct TVE
-{
- /**
- * A name, used as the key. NULL for the last entry.
- */
- const char *name;
-
- /**
- * 0-terminated (!) file data to return for @e name.
- */
- char *value;
-
-};
-
-
-/**
* Head of DLL of (suspended) requests.
*/
static struct GetOrderData *god_head;
@@ -290,218 +256,6 @@ static struct GetOrderData *god_head;
*/
static struct GetOrderData *god_tail;
-/**
- * Templated loaded into RAM.
- */
-static struct TVE *loaded;
-
-/**
- * Length of the #loaded array.
- */
-static unsigned int loaded_length;
-
-
-/**
- * Function called by Mustach to enter the section @a name.
- * As we do not support sections, we always return 0.
- *
- * @param cls a `struct KVC[]` array
- * @param name section to enter
- * @return 0 (do not enter)
- */
-static int
-m_enter (void *cls, const char *name)
-{
- (void) cls;
- (void) name;
- return 0;
-}
-
-
-/**
- * Function called by mustach to activate the next item in the
- * section. Does nothing, as we do not support sections.
- *
- * @param cls a `struct KVC[]` array
- * @return 0 (no next item to activate)
- */
-static int
-m_next (void *cls)
-{
- (void) cls;
- return 0;
-}
-
-
-/**
- * Function called by Mustach to leave the current section.
- * As we do not support sections, we should never be called.
- *
- * @param cls a `struct KVC[]` array
- * @return 0 (not documented by mustach)
- */
-static int
-m_leave (void *cls)
-{
- GNUNET_assert (0);
- return 0;
-}
-
-
-/**
- * Return the value of @a name in @a sbuf.
- *
- * @param cls a `struct KVC[]` array
- * @param name the value to lookup
- * @param[out] sbuf where to return the data
- * @return mustach-defined status code
- */
-static int
-m_get (void *cls,
- const char *name,
- struct mustach_sbuf *sbuf)
-{
- struct KVC *kvc = cls;
-
- for (unsigned int i = 0; NULL != kvc[i].name; i++)
- {
- if (0 == strcmp (name,
- kvc[i].name))
- {
- sbuf->value = kvc[i].value;
- sbuf->releasecb = NULL;
- sbuf->closure = &kvc[i];
- return MUSTACH_OK;
- }
- }
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Template requires value for unexpected name `%s'\n",
- name);
- return MUSTACH_ERROR_ITEM_NOT_FOUND;
-}
-
-
-/**
- * Mustach callback at the end. Cleans up the @a cls.
- *
- * @param cls a `struct KVC[]` array
- * @param status status of mustach (ignored)
- */
-static void
-m_stop (void *cls,
- int status)
-{
- struct KVC *kvc = cls;
-
- (void) status;
- for (unsigned int i = 0; NULL != kvc[i].name; i++)
- GNUNET_free (kvc[i].value);
-}
-
-
-/**
- * Our 'universal' callbacks for mustach.
- */
-static struct mustach_itf itf = {
- .enter = &m_enter,
- .next = &m_next,
- .leave = &m_leave,
- .get = &m_get,
- .stop = &m_stop
-};
-
-
-/**
- * Load Mustach template into memory. Note that we intentionally cache
- * failures, that is if we ever failed to load a template, we will never try
- * again.
- *
- * FIXME: support i18n: evaluate Language: header from the browser!
- *
- * @param name name of the template file to load
- * (MUST be a 'static' string in memory!)
- * @return NULL on error, otherwise the template
- */
-static const char *
-load_template (const char *name)
-{
- char *fn;
- char *map;
- int fd;
- struct stat sb;
-
- for (unsigned int i = 0; i<loaded_length; i++)
- {
- if (0 == strcmp (loaded[i].name,
- name))
- return loaded[i].value;
- }
- GNUNET_array_grow (loaded,
- loaded_length,
- loaded_length + 1);
- loaded[loaded_length - 1].name = name;
- {
- char *path;
-
- path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
- if (NULL == path)
- {
- GNUNET_break (0);
- return NULL;
- }
- GNUNET_asprintf (&fn,
- "%s/merchant/%s.must",
- path,
- name);
- GNUNET_free (path);
- }
- fd = open (fn, O_RDONLY);
- if (-1 == fd)
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "open",
- fn);
- GNUNET_free (fn);
- return NULL;
- }
- if (0 !=
- fstat (fd,
- &sb))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "open",
- fn);
- GNUNET_free (fn);
- GNUNET_break (0 == close (fd));
- return NULL;
- }
- map = GNUNET_malloc_large (sb.st_size + 1);
- if (NULL == map)
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "malloc");
- GNUNET_free (fn);
- GNUNET_break (0 == close (fd));
- return NULL;
- }
- if (sb.st_size !=
- read (fd,
- map,
- sb.st_size))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "read",
- fn);
- GNUNET_free (fn);
- GNUNET_break (0 == close (fd));
- return NULL;
- }
- GNUNET_break (0 == close (fd));
- GNUNET_free (fn);
- loaded[loaded_length - 1].value = map;
- return loaded[loaded_length - 1].value;
-}
-
/**
* Create the QR code image for a URI.
@@ -739,10 +493,7 @@ send_pay_request (struct GetOrderData *god,
&god->claim_token);
if (god->generate_html)
{
- struct MHD_Response *reply;
char *qr;
- char *body;
- size_t body_size;
qr = create_qrcode (taler_pay_uri);
if (NULL == qr)
@@ -753,58 +504,28 @@ send_pay_request (struct GetOrderData *god,
{
struct KVC kvc[] = {
{ "taler_pay_uri",
- GNUNET_strdup (taler_pay_uri) },
+ taler_pay_uri },
{ "taler_pay_qrcode_svg",
qr },
{ "order_summary",
- GNUNET_strdup ("FIXME") },
+ "FIXME" },
{ NULL, NULL }
};
- const char *tmpl;
- int eno;
-
- tmpl = load_template ("request_payment");
- if (NULL == tmpl)
+ enum GNUNET_GenericReturnValue res;
+
+ res = TMH_return_from_template (god->sc.con,
+ MHD_HTTP_PAYMENT_REQUIRED,
+ "request_payment",
+ taler_pay_uri,
+ kvc);
+ if (GNUNET_SYSERR == res)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to load template `%s'\n",
- "request_payment");
- return MHD_NO; // FIXME: add nicer error reply...
- }
- if (0 !=
- (eno = mustach (tmpl,
- &itf,
- &kvc,
- &body,
- &body_size)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "mustach failed with error %d\n",
- eno);
- return MHD_NO; // FIXME: add nicer error reply...
+ GNUNET_break (0);
+ ret = MHD_NO;
}
+ ret = MHD_YES;
}
-
- reply = MHD_create_response_from_buffer (body_size,
- body,
- MHD_RESPMEM_MUST_FREE);
- if (NULL == reply)
- {
- GNUNET_break (0);
- return MHD_NO;
- }
- GNUNET_break (MHD_NO !=
- MHD_add_response_header (reply,
- "Taler",
- taler_pay_uri));
- GNUNET_break (MHD_NO !=
- MHD_add_response_header (reply,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "text/html"));
- ret = MHD_queue_response (god->sc.con,
- MHD_HTTP_PAYMENT_REQUIRED,
- reply);
- MHD_destroy_response (reply);
+ GNUNET_free (qr);
}
else
{
@@ -1590,94 +1311,53 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
if (god->generate_html)
{
- int ret;
- struct MHD_Response *reply;
- char *body;
- size_t body_size;
- char *qr;
-
- qr = create_qrcode ("taler://refund/FIXME");
- if (NULL == qr)
- {
- GNUNET_break (0);
- return MHD_NO; // FIXME: add nicer error reply...
- }
+ enum GNUNET_GenericReturnValue res;
- if (god->refunded)
+ if (god->refunded) // FIXME: don't check for refunded, but for PENDING refund!
{
- struct KVC kvc[] = {
- { "refund_amount",
- GNUNET_strdup (TALER_amount2s (&god->refund_amount)) },
- { "refund_uri",
- qr },
- { NULL, NULL }
- };
- const char *tmpl;
+ char *qr;
- tmpl = load_template ("offer_refund");
- if (NULL == tmpl)
+ qr = create_qrcode ("taler://refund/FIXME");
+ if (NULL == qr)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to load template `%s'\n",
- "offer_refund");
+ GNUNET_break (0);
return MHD_NO; // FIXME: add nicer error reply...
}
- if (0 !=
- mustach (tmpl,
- &itf,
- &kvc,
- &body,
- &body_size))
{
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "mustach");
- return MHD_NO; // FIXME: add nicer error reply...
+ struct KVC kvc[] = {
+ { "refund_amount",
+ TALER_amount2s (&god->refund_amount) },
+ { "refund_uri",
+ qr },
+ { NULL, NULL }
+ };
+
+ res = TMH_return_from_template (god->sc.con,
+ MHD_HTTP_OK,
+ "offer_refund",
+ "FIXME: refund-URI here",
+ kvc);
}
+ GNUNET_free (qr);
}
else
{
struct KVC kvc[] = {
{ NULL, NULL }
};
- const char *tmpl;
- tmpl = load_template ("show_order_details");
- if (NULL == tmpl)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to load template `%s'\n",
- "show_order_details");
- return MHD_NO; // FIXME: add nicer error reply...
- }
- if (0 !=
- mustach (tmpl,
- &itf,
- &kvc,
- &body,
- &body_size))
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "mustach");
- return MHD_NO; // FIXME: add nicer error reply...
- }
+ res = TMH_return_from_template (god->sc.con,
+ MHD_HTTP_OK,
+ "show_order_details",
+ NULL,
+ kvc);
}
- reply = MHD_create_response_from_buffer (body_size,
- body,
- MHD_RESPMEM_MUST_FREE);
- if (NULL == reply)
+ if (GNUNET_SYSERR == res)
{
GNUNET_break (0);
return MHD_NO;
}
- GNUNET_break (MHD_NO !=
- MHD_add_response_header (reply,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "text/html"));
- ret = MHD_queue_response (god->sc.con,
- MHD_HTTP_OK,
- reply);
- MHD_destroy_response (reply);
- return ret;
+ return MHD_YES;
}
else
{
@@ -1697,15 +1377,4 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
}
-/**
- * Nicely shut down.
- */
-void __attribute__ ((destructor))
-get_orders_fini ()
-{
- for (unsigned int i = 0; i<loaded_length; i++)
- GNUNET_free (loaded[i].value);
-}
-
-
/* end of taler-merchant-httpd_get-orders-ID.c */