challenger

OAuth 2.0-based authentication service that validates user can receive messages at a certain address
Log | Files | Refs | Submodules | README | LICENSE

commit 240fbcdbe7f29bf98e5f09945b33ba80c33281ea
parent f7d861bed6851b42f42c8acbe7e49b93edaef7b7
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 22 Jun 2025 14:10:36 +0200

use SPA logic of libtalermhd instead of re-inventing the wheel

Diffstat:
Msrc/challenger/challenger-httpd_spa.c | 324+++++--------------------------------------------------------------------------
1 file changed, 18 insertions(+), 306 deletions(-)

diff --git a/src/challenger/challenger-httpd_spa.c b/src/challenger/challenger-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 Challenger 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 @@ -27,49 +27,10 @@ #include "challenger_util.h" #include "challenger-httpd_spa.h" - -/** - * Resource from the WebUi. - */ -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. + * Resources of the Challenger SPA. */ -static struct WebuiFile *webui_tail; +static struct TALER_MHD_Spa *spa; MHD_RESULT @@ -77,262 +38,28 @@ CH_handler_spa (struct CH_HandlerContext *hc, const char *upload_data, size_t *upload_data_size) { - struct WebuiFile *w = NULL; - const char *infix = hc->path; + const char *path = hc->path; - if ( (NULL == infix) || - (0 == strcmp (infix, + if ( (NULL == path) || + (0 == strcmp (path, "")) ) - 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 (hc->connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_GENERIC_ENDPOINT_UNKNOWN, - hc->path); - if ( (MHD_YES == - TALER_MHD_can_compress (hc->connection)) && - (NULL != w->zspa) ) - return MHD_queue_response (hc->connection, - MHD_HTTP_OK, - w->zspa); - return MHD_queue_response (hc->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; + path = "index.html"; + return TALER_MHD_spa_handler (spa, + hc->connection, + path); } enum GNUNET_GenericReturnValue CH_spa_init () { - char *dn; - - { - char *path; - - path = GNUNET_OS_installation_get_path (CHALLENGER_project_data (), - GNUNET_OS_IPK_DATADIR); - if (NULL == path) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - GNUNET_asprintf (&dn, - "%sspa/", - path); - GNUNET_free (path); - } - - if (-1 == - GNUNET_DISK_directory_scan (dn, - &build_webui, - NULL)) + spa = TALER_MHD_spa_load (CHALLENGER_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; } @@ -343,29 +70,14 @@ CH_spa_init () void __attribute__ ((destructor)) get_spa_fini (void); -/* Declaration to suppress compiler warning */ +/* Declaration to avoid compiler warning */ 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; } }