gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: implement new spa loader logic


From: gnunet
Subject: [taler-merchant] branch master updated: implement new spa loader logic
Date: Sat, 21 Jan 2023 20:15:47 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 97a5ce5c implement new spa loader logic
97a5ce5c is described below

commit 97a5ce5c22572c30e44b076ed51df6666fde25cc
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Jan 21 20:15:44 2023 +0100

    implement new spa loader logic
---
 src/backend/taler-merchant-httpd.c         |  59 ++++++-
 src/backend/taler-merchant-httpd_spa.c     | 245 +++++++++++++++++++++++------
 src/backend/taler-merchant-httpd_spa.h     |  10 +-
 src/backend/taler-merchant-httpd_statics.c |  10 +-
 src/backend/taler-merchant-httpd_statics.h |   4 +-
 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);
 
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]