summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-01-21 20:15:44 +0100
committerChristian Grothoff <christian@grothoff.org>2023-01-21 20:15:44 +0100
commit97a5ce5c22572c30e44b076ed51df6666fde25cc (patch)
tree26e3eaaeee15940c95fc35b40235a34371d8f7f0 /src/backend
parent70afc87a13174ddd3de9e424920460d4d0767fd9 (diff)
downloadmerchant-97a5ce5c22572c30e44b076ed51df6666fde25cc.tar.gz
merchant-97a5ce5c22572c30e44b076ed51df6666fde25cc.tar.bz2
merchant-97a5ce5c22572c30e44b076ed51df6666fde25cc.zip
implement new spa loader logic
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/taler-merchant-httpd.c59
-rw-r--r--src/backend/taler-merchant-httpd_spa.c245
-rw-r--r--src/backend/taler-merchant-httpd_spa.h10
-rw-r--r--src/backend/taler-merchant-httpd_statics.c10
-rw-r--r--src/backend/taler-merchant-httpd_statics.h4
5 files changed, 272 insertions, 56 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 9366c1bf..8e1a0fc0 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -459,6 +459,49 @@ handle_server_options (const struct TMH_RequestHandler *rh,
}
+static MHD_RESULT
+spa_redirect (const struct TMH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ struct TMH_HandlerContext *hc)
+{
+ const char *text = "Redirecting to /webui/";
+ struct MHD_Response *response;
+
+ response = MHD_create_response_from_buffer (strlen (text),
+ (void *) text,
+ MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ TALER_MHD_add_global_headers (response);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/plain"));
+ if (MHD_NO ==
+ MHD_add_response_header (response,
+ MHD_HTTP_HEADER_LOCATION,
+ "/webui/"))
+ {
+ GNUNET_break (0);
+ MHD_destroy_response (response);
+ return MHD_NO;
+ }
+
+ {
+ MHD_RESULT ret;
+
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_FOUND,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+ }
+}
+
+
/**
* Extract the token from authorization header value @a auth.
*
@@ -637,7 +680,7 @@ url_handler (void *cls,
{
.url_prefix = "/instances/",
.method = MHD_HTTP_METHOD_DELETE,
- .skip_instance = true,
+ .skip_instance = true,
.default_only = true,
.have_id_segment = true,
.handler = &TMH_private_delete_instances_default_ID
@@ -1034,6 +1077,15 @@ url_handler (void *cls,
.method = MHD_HTTP_METHOD_GET,
.mime_type = "text/html",
.skip_instance = true,
+ .handler = &spa_redirect,
+ .response_code = MHD_HTTP_FOUND
+ },
+ {
+ .url_prefix = "/webui/",
+ .method = MHD_HTTP_METHOD_GET,
+ .mime_type = "text/html",
+ .skip_instance = true,
+ .have_id_segment = true,
.handler = &TMH_return_spa,
.response_code = MHD_HTTP_OK
},
@@ -1381,7 +1433,7 @@ url_handler (void *cls,
{
prefix_strlen = slash - url + 1; /* includes both '/'-es if present! */
infix_url = slash + 1;
- slash = strchr (&infix_url[1], '/');
+ slash = strchr (infix_url, '/');
if (NULL == slash)
{
/* the infix was the rest */
@@ -1903,7 +1955,8 @@ run (void *cls,
GNUNET_SCHEDULER_shutdown ();
return;
}
- TMH_statics_init ();
+ /* /static/ is currently not used */
+ /* (void) TMH_statics_init (); */
elen = TMH_EXCHANGES_init (config);
if (GNUNET_SYSERR == elen)
{
diff --git a/src/backend/taler-merchant-httpd_spa.c b/src/backend/taler-merchant-httpd_spa.c
index 0258f883..92cc5bf3 100644
--- a/src/backend/taler-merchant-httpd_spa.c
+++ b/src/backend/taler-merchant-httpd_spa.c
@@ -27,14 +27,47 @@
/**
- * SPA, compressed.
+ * Resource from the WebUi.
*/
-static struct MHD_Response *zspa;
+struct WebuiFile
+{
+ /**
+ * Kept in a DLL.
+ */
+ struct WebuiFile *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct WebuiFile *prev;
+
+ /**
+ * Path this resource matches.
+ */
+ char *path;
+
+ /**
+ * SPA resource, compressed.
+ */
+ struct MHD_Response *zspa;
+
+ /**
+ * SPA resource, vanilla.
+ */
+ struct MHD_Response *spa;
+
+};
+
+
+/**
+ * Resources of the WebuUI, kept in a DLL.
+ */
+static struct WebuiFile *webui_head;
/**
- * SPA, vanilla.
+ * Resources of the WebuUI, kept in a DLL.
*/
-static struct MHD_Response *spa;
+static struct WebuiFile *webui_tail;
MHD_RESULT
@@ -42,40 +75,95 @@ TMH_return_spa (const struct TMH_RequestHandler *rh,
struct MHD_Connection *connection,
struct TMH_HandlerContext *hc)
{
+ struct WebuiFile *w = NULL;
+ const char *infix = hc->infix;
+
+ if ( (NULL == infix) ||
+ (0 == strcmp (infix,
+ "")) )
+ infix = "index.html";
+ for (struct WebuiFile *pos = webui_head;
+ NULL != pos;
+ pos = pos->next)
+ if (0 == strcmp (infix,
+ pos->path))
+ {
+ w = pos;
+ break;
+ }
+ if (NULL == w)
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_GENERIC_ENDPOINT_UNKNOWN,
+ hc->url);
if ( (MHD_YES ==
TALER_MHD_can_compress (connection)) &&
- (NULL != zspa) )
+ (NULL != w->zspa) )
return MHD_queue_response (connection,
MHD_HTTP_OK,
- zspa);
+ w->zspa);
return MHD_queue_response (connection,
MHD_HTTP_OK,
- spa);
+ w->spa);
}
-int
-TMH_spa_init ()
+/**
+ * Function called on each file to load for the WebUI.
+ *
+ * @param cls NULL
+ * @param dn name of the file to load
+ */
+static enum GNUNET_GenericReturnValue
+build_webui (void *cls,
+ const char *dn)
{
- char *dn;
int fd;
struct stat sb;
-
+ struct MHD_Response *zspa;
+ struct MHD_Response *spa;
+ const char *ext;
+ const char *mime;
+ struct
{
- char *path;
-
- path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
- if (NULL == path)
+ const char *ext;
+ const char *mime;
+ } mime_map[] = {
{
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- GNUNET_asprintf (&dn,
- "%s/merchant/spa/spa.html",
- path);
- GNUNET_free (path);
- }
+ .ext = "css",
+ .mime = "text/css"
+ },
+ {
+ .ext = "html",
+ .mime = "text/html"
+ },
+ {
+ .ext = "js",
+ .mime = "text/javascript"
+ },
+ {
+ .ext = "jpg",
+ .mime = "image/jpeg"
+ },
+ {
+ .ext = "jpeg",
+ .mime = "image/jpeg"
+ },
+ {
+ .ext = "png",
+ .mime = "image/png"
+ },
+ {
+ .ext = "svg",
+ .mime = "image/svg+xml"
+ },
+ {
+ .ext = NULL,
+ .mime = NULL
+ },
+ };
+ (void) cls;
/* finally open template */
fd = open (dn,
O_RDONLY);
@@ -84,7 +172,6 @@ TMH_spa_init ()
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"open",
dn);
- GNUNET_free (dn);
return GNUNET_SYSERR;
}
if (0 !=
@@ -95,10 +182,21 @@ TMH_spa_init ()
"open",
dn);
GNUNET_break (0 == close (fd));
- GNUNET_free (dn);
return GNUNET_SYSERR;
}
+ mime = NULL;
+ ext = strrchr (dn, '.');
+ GNUNET_assert (NULL != ext);
+ ext++;
+ for (unsigned int i = 0; NULL != mime_map[i].ext; i++)
+ if (0 == strcasecmp (ext,
+ mime_map[i].ext))
+ {
+ mime = mime_map[i].mime;
+ break;
+ }
+
{
void *in;
ssize_t r;
@@ -110,7 +208,6 @@ TMH_spa_init ()
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
"malloc");
GNUNET_break (0 == close (fd));
- GNUNET_free (dn);
return GNUNET_SYSERR;
}
r = read (fd,
@@ -124,7 +221,6 @@ TMH_spa_init ()
dn);
GNUNET_free (in);
GNUNET_break (0 == close (fd));
- GNUNET_free (dn);
return GNUNET_SYSERR;
}
csize = (size_t) r;
@@ -146,10 +242,11 @@ TMH_spa_init ()
MHD_destroy_response (zspa);
zspa = NULL;
}
- GNUNET_break (MHD_YES ==
- MHD_add_response_header (zspa,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "text/html"));
+ if (NULL != mime)
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (zspa,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ mime));
}
}
else
@@ -166,7 +263,6 @@ TMH_spa_init ()
"open",
dn);
GNUNET_break (0 == close (fd));
- GNUNET_free (dn);
if (NULL != zspa)
{
MHD_destroy_response (zspa);
@@ -174,11 +270,62 @@ TMH_spa_init ()
}
return GNUNET_SYSERR;
}
+ if (NULL != mime)
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (spa,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ mime));
+
+ {
+ struct WebuiFile *w;
+ const char *fn;
+
+ fn = strrchr (dn, '/');
+ GNUNET_assert (NULL != fn);
+ w = GNUNET_new (struct WebuiFile);
+ w->path = GNUNET_strdup (fn + 1);
+ w->spa = spa;
+ w->zspa = zspa;
+ GNUNET_CONTAINER_DLL_insert (webui_head,
+ webui_tail,
+ w);
+ }
+ return GNUNET_OK;
+}
+
+
+enum GNUNET_GenericReturnValue
+TMH_spa_init ()
+{
+ char *dn;
+
+ {
+ char *path;
+
+ path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
+ if (NULL == path)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_asprintf (&dn,
+ "%s/merchant-backoffice/",
+ path);
+ GNUNET_free (path);
+ }
+
+ if (-1 ==
+ GNUNET_DISK_directory_scan (dn,
+ &build_webui,
+ NULL))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to load WebUI from `%s'\n",
+ dn);
+ GNUNET_free (dn);
+ return GNUNET_SYSERR;
+ }
GNUNET_free (dn);
- GNUNET_break (MHD_YES ==
- MHD_add_response_header (spa,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- "text/html"));
return GNUNET_OK;
}
@@ -189,14 +336,24 @@ TMH_spa_init ()
void __attribute__ ((destructor))
get_spa_fini ()
{
- if (NULL != spa)
- {
- MHD_destroy_response (spa);
- spa = NULL;
- }
- if (NULL != zspa)
+ struct WebuiFile *w;
+
+ while (NULL != (w = webui_head))
{
- MHD_destroy_response (zspa);
- zspa = NULL;
+ GNUNET_CONTAINER_DLL_remove (webui_head,
+ webui_tail,
+ w);
+ if (NULL != w->spa)
+ {
+ MHD_destroy_response (w->spa);
+ w->spa = NULL;
+ }
+ if (NULL != w->zspa)
+ {
+ MHD_destroy_response (w->zspa);
+ w->zspa = NULL;
+ }
+ GNUNET_free (w->path);
+ GNUNET_free (w);
}
}
diff --git a/src/backend/taler-merchant-httpd_spa.h b/src/backend/taler-merchant-httpd_spa.h
index 8a998c38..9450bdbd 100644
--- a/src/backend/taler-merchant-httpd_spa.h
+++ b/src/backend/taler-merchant-httpd_spa.h
@@ -24,8 +24,9 @@
#include <microhttpd.h>
#include "taler-merchant-httpd.h"
+
/**
- * Return our single-page-app user interface (see contrib/spa.html).
+ * Return our single-page-app user interface (see contrib/spa/).
*
* @param rh request handler
* @param connection the connection we act upon
@@ -37,10 +38,13 @@ TMH_return_spa (const struct TMH_RequestHandler *rh,
struct MHD_Connection *connection,
struct TMH_HandlerContext *hc);
+
/**
- * Preload and compress SPA file.
+ * Preload and compress SPA files.
+ *
+ * @return #GNUNET_OK on success
*/
-int
+enum GNUNET_GenericReturnValue
TMH_spa_init (void);
diff --git a/src/backend/taler-merchant-httpd_statics.c b/src/backend/taler-merchant-httpd_statics.c
index 6b4ff351..72f81d85 100644
--- a/src/backend/taler-merchant-httpd_statics.c
+++ b/src/backend/taler-merchant-httpd_statics.c
@@ -15,7 +15,7 @@
*/
/**
* @file taler-merchant-httpd_statics.c
- * @brief logic to load and complete HTML templates
+ * @brief logic to load and return static resource files by client language preference
* @author Christian Grothoff
*/
#include "platform.h"
@@ -144,7 +144,7 @@ TMH_return_static (const struct TMH_RequestHandler *rh,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
*/
-static int
+static enum GNUNET_GenericReturnValue
load_static_file (void *cls,
const char *filename)
{
@@ -275,7 +275,7 @@ load_static_file (void *cls,
/**
* Preload static files.
*/
-int
+enum GNUNET_GenericReturnValue
TMH_statics_init ()
{
char *dn;
@@ -291,7 +291,7 @@ TMH_statics_init ()
return GNUNET_SYSERR;
}
GNUNET_asprintf (&dn,
- "%s/merchant/static/",
+ "%smerchant/static/",
path);
GNUNET_free (path);
}
@@ -300,7 +300,7 @@ TMH_statics_init ()
NULL);
if (-1 == ret)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Could not load static resources from `%s': %s\n",
dn,
strerror (errno));
diff --git a/src/backend/taler-merchant-httpd_statics.h b/src/backend/taler-merchant-httpd_statics.h
index 977a488d..ac3e2ca1 100644
--- a/src/backend/taler-merchant-httpd_statics.h
+++ b/src/backend/taler-merchant-httpd_statics.h
@@ -40,8 +40,10 @@ TMH_return_static (const struct TMH_RequestHandler *rh,
/**
* Preload static files.
+ *
+ * @return #GNUNET_OK on success
*/
-int
+enum GNUNET_GenericReturnValue
TMH_statics_init (void);