/* This file is part of TALER Copyright (C) 2020 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 Foundation; either version 3, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, see */ /** * @file taler-merchant-httpd_spa.c * @brief logic to load the single page app (/) * @author Christian Grothoff */ #include "platform.h" #include #include #include #include "taler-merchant-httpd_statics.h" #include /** * SPA, compressed. */ static struct MHD_Response *zspa; /** * SPA, vanilla. */ static struct MHD_Response *spa; MHD_RESULT TMH_return_spa (const struct TMH_RequestHandler *rh, struct MHD_Connection *connection, struct TMH_HandlerContext *hc) { if ( (MHD_YES == TALER_MHD_can_compress (connection)) && (NULL != zspa) ) return MHD_queue_response (connection, MHD_HTTP_OK, zspa); return MHD_queue_response (connection, MHD_HTTP_OK, spa); } int TMH_spa_init () { char *dn; int fd; struct stat sb; { 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/spa/spa.html", path); GNUNET_free (path); } /* finally open template */ fd = open (dn, O_RDONLY); if (-1 == fd) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", dn); GNUNET_free (dn); return GNUNET_SYSERR; } if (0 != fstat (fd, &sb)) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", dn); GNUNET_break (0 == close (fd)); GNUNET_free (dn); return GNUNET_SYSERR; } { 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)); GNUNET_free (dn); 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)); GNUNET_free (dn); 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; } GNUNET_break (MHD_YES == MHD_add_response_header (zspa, MHD_HTTP_HEADER_CONTENT_TYPE, "text/html")); } } 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)); GNUNET_free (dn); if (NULL != zspa) { MHD_destroy_response (zspa); zspa = NULL; } 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; } /** * Nicely shut down. */ void __attribute__ ((destructor)) get_spa_fini () { if (NULL != spa) { MHD_destroy_response (spa); spa = NULL; } if (NULL != zspa) { MHD_destroy_response (zspa); zspa = NULL; } }