commit 6595744558bb4cad664df9aa80f49209dc8bc0fc
parent a6c13ab1924cf8ef318a434754453f8998621e93
Author: Christian Grothoff <christian@grothoff.org>
Date: Sun, 22 Jun 2025 14:06:26 +0200
use SPA logic of libtalermhd instead of re-inventing the wheel
Diffstat:
1 file changed, 13 insertions(+), 300 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_spa.c b/src/backend/taler-merchant-httpd_spa.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2020, 2023 Taler Systems SA
+ Copyright (C) 2020, 2023, 2025 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -29,47 +29,9 @@
/**
- * Resource from the WebUi.
+ * Resources of the Merchant SPA.
*/
-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;
-
-/**
- * Resources of the WebuUI, kept in a DLL.
- */
-static struct WebuiFile *webui_tail;
+static struct TALER_MHD_Spa *spa;
MHD_RESULT
@@ -77,262 +39,28 @@ 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 != w->zspa) )
- return MHD_queue_response (connection,
- MHD_HTTP_OK,
- w->zspa);
- return MHD_queue_response (connection,
- MHD_HTTP_OK,
- w->spa);
-}
-
-
-/**
- * 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)
-{
- static struct
- {
- const char *ext;
- const char *mime;
- } mime_map[] = {
- {
- .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
- },
- };
- int fd;
- struct stat sb;
- struct MHD_Response *zspa = NULL;
- struct MHD_Response *spa;
- const char *ext;
- const char *mime;
-
- (void) cls;
- /* finally open template */
- fd = open (dn,
- O_RDONLY);
- if (-1 == fd)
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "open",
- dn);
- return GNUNET_SYSERR;
- }
- if (0 !=
- fstat (fd,
- &sb))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "open",
- dn);
- GNUNET_break (0 == close (fd));
- return GNUNET_SYSERR;
- }
-
- mime = NULL;
- ext = strrchr (dn, '.');
- if (NULL == ext)
- {
- GNUNET_break (0 == close (fd));
- return GNUNET_OK;
- }
- 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;
- size_t csize;
-
- in = GNUNET_malloc_large (sb.st_size);
- if (NULL == in)
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "malloc");
- GNUNET_break (0 == close (fd));
- return GNUNET_SYSERR;
- }
- r = read (fd,
- in,
- sb.st_size);
- if ( (-1 == r) ||
- (sb.st_size != (size_t) r) )
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "read",
- dn);
- GNUNET_free (in);
- GNUNET_break (0 == close (fd));
- return GNUNET_SYSERR;
- }
- csize = (size_t) r;
- if (MHD_YES ==
- TALER_MHD_body_compress (&in,
- &csize))
- {
- zspa = MHD_create_response_from_buffer (csize,
- in,
- MHD_RESPMEM_MUST_FREE);
- if (NULL != zspa)
- {
- if (MHD_NO ==
- MHD_add_response_header (zspa,
- MHD_HTTP_HEADER_CONTENT_ENCODING,
- "deflate"))
- {
- GNUNET_break (0);
- MHD_destroy_response (zspa);
- zspa = NULL;
- }
- if (NULL != mime)
- GNUNET_break (MHD_YES ==
- MHD_add_response_header (zspa,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- mime));
- }
- }
- else
- {
- GNUNET_free (in);
- }
- }
-
- spa = MHD_create_response_from_fd (sb.st_size,
- fd);
- if (NULL == spa)
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "open",
- dn);
- GNUNET_break (0 == close (fd));
- if (NULL != zspa)
- {
- MHD_destroy_response (zspa);
- zspa = NULL;
- }
- 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;
+ return TALER_MHD_spa_handler (spa,
+ connection,
+ infix);
}
enum GNUNET_GenericReturnValue
TMH_spa_init ()
{
- char *dn;
-
- {
- char *path;
-
- path = GNUNET_OS_installation_get_path (TALER_MERCHANT_project_data (),
- GNUNET_OS_IPK_DATADIR);
- if (NULL == path)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- GNUNET_asprintf (&dn,
- "%s/spa/",
- path);
- GNUNET_free (path);
- }
-
- if (-1 ==
- GNUNET_DISK_directory_scan (dn,
- &build_webui,
- NULL))
+ spa = TALER_MHD_spa_load (TALER_MERCHANT_project_data (),
+ "spa/");
+ if (NULL == spa)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to load WebUI from `%s'\n",
- dn);
- GNUNET_free (dn);
+ GNUNET_break (0);
return GNUNET_SYSERR;
}
- GNUNET_free (dn);
return GNUNET_OK;
}
@@ -347,24 +75,9 @@ get_spa_fini (void);
void __attribute__ ((destructor))
get_spa_fini ()
{
- struct WebuiFile *w;
-
- while (NULL != (w = webui_head))
+ if (NULL != spa)
{
- 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);
+ TALER_MHD_spa_free (spa);
+ spa = NULL;
}
}