commit 54306aeb704d7078f93f4987511dc6f5f64399ed
parent 7c29dd278d79fe3b3819ab0fe0172624cb675cf1
Author: Christian Grothoff <christian@grothoff.org>
Date: Mon, 20 Apr 2026 15:21:07 +0200
WiP
Diffstat:
6 files changed, 377 insertions(+), 65 deletions(-)
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
@@ -15,6 +15,7 @@ paivana_httpd_SOURCES = \
paivana-httpd_helper.c paivana-httpd_helper.h \
paivana-httpd_reverse.c paivana-httpd_reverse.h \
paivana-httpd_pay.c paivana-httpd_pay.h \
+ paivana-httpd_templates.c paivana-httpd_templates.h \
paivana_pd.c paivana_pd.h
paivana_httpd_LDADD = \
$(LIBGCRYPT_LIBS) \
diff --git a/src/backend/paivana-httpd.c b/src/backend/paivana-httpd.c
@@ -36,6 +36,7 @@
#include "paivana-httpd_helper.h"
#include "paivana-httpd_pay.h"
#include "paivana-httpd_reverse.h"
+#include "paivana-httpd_templates.h"
#include "paivana_pd.h"
@@ -308,6 +309,78 @@ mhd_log_callback (void *cls,
}
+/**
+ * Callback invoked on every listen socket to start the
+ * respective MHD HTTP daemon.
+ *
+ * @param cls unused
+ * @param lsock the listen socket
+ */
+static void
+start_daemon (void *cls,
+ int lsock)
+{
+ struct MHD_Daemon *mhd;
+
+ (void) cls;
+ GNUNET_assert (-1 != lsock);
+ mhd = MHD_start_daemon (
+ MHD_USE_DEBUG
+ | MHD_ALLOW_SUSPEND_RESUME
+ | MHD_USE_DUAL_STACK,
+ 0,
+ NULL, NULL,
+ &create_response, NULL,
+ MHD_OPTION_LISTEN_SOCKET,
+ lsock,
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
+ MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL,
+ MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL,
+ MHD_OPTION_END);
+
+ if (NULL == mhd)
+ {
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ have_daemons = true;
+ TALER_MHD_daemon_start (mhd);
+}
+
+
+static void
+serve_requests (void *cls)
+{
+ enum GNUNET_GenericReturnValue ret;
+
+ ret = TALER_MHD_listen_bind (cfg,
+ "paivana",
+ &start_daemon,
+ NULL);
+ switch (ret)
+ {
+ case GNUNET_SYSERR:
+ global_ret = EXIT_NOTCONFIGURED;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ case GNUNET_NO:
+ if (! have_daemons)
+ {
+ global_ret = EXIT_NOTCONFIGURED;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Could not open all configured listen sockets\n");
+ break;
+ case GNUNET_OK:
+ break;
+ }
+
+}
+
+
/* *************** General / main code *************** */
@@ -326,6 +399,7 @@ do_shutdown (void *cls)
PAIVANA_HTTPD_payment_shutdown ();
PAIVANA_HTTPD_reverse_shutdown ();
TALER_MHD_daemons_destroy ();
+ PAIVANA_HTTPD_unload_templates ();
GNUNET_free (PH_target_server_base_url);
GNUNET_free (PH_merchant_base_url);
GNUNET_free (PH_base_url);
@@ -394,46 +468,6 @@ load_paywall (void)
/**
- * Callback invoked on every listen socket to start the
- * respective MHD HTTP daemon.
- *
- * @param cls unused
- * @param lsock the listen socket
- */
-static void
-start_daemon (void *cls,
- int lsock)
-{
- struct MHD_Daemon *mhd;
-
- (void) cls;
- GNUNET_assert (-1 != lsock);
- mhd = MHD_start_daemon (
- MHD_USE_DEBUG
- | MHD_ALLOW_SUSPEND_RESUME
- | MHD_USE_DUAL_STACK,
- 0,
- NULL, NULL,
- &create_response, NULL,
- MHD_OPTION_LISTEN_SOCKET,
- lsock,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
- MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL,
- MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL,
- MHD_OPTION_END);
-
- if (NULL == mhd)
- {
- GNUNET_break (0);
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- have_daemons = true;
- TALER_MHD_daemon_start (mhd);
-}
-
-
-/**
* Main function that will be run. Main tasks are (1) init. the
* curl infrastructure (curl_global_init() / curl_multi_init()),
* then fetch the HTTP port where its Web service should listen at,
@@ -450,7 +484,6 @@ run (void *cls,
const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *c)
{
- enum GNUNET_GenericReturnValue ret;
char *secret;
(void) cls;
@@ -594,30 +627,8 @@ run (void *cls,
GNUNET_free (auth_header);
}
ctx_rc = GNUNET_CURL_gnunet_rc_create (PH_ctx);
-
- ret = TALER_MHD_listen_bind (c,
- "paivana",
- &start_daemon,
- NULL);
- switch (ret)
- {
- case GNUNET_SYSERR:
- global_ret = EXIT_NOTCONFIGURED;
- GNUNET_SCHEDULER_shutdown ();
- return;
- case GNUNET_NO:
- if (! have_daemons)
- {
- global_ret = EXIT_NOTCONFIGURED;
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Could not open all configured listen sockets\n");
- break;
- case GNUNET_OK:
- break;
- }
+ PAIVANA_HTTPD_load_templates (&serve_requests,
+ NULL);
}
diff --git a/src/backend/paivana-httpd_helper.c b/src/backend/paivana-httpd_helper.c
@@ -0,0 +1,120 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2026 Taler Systems SA
+
+ Paivana 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.
+
+ Paivana 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 Paivana; see the file COPYING. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin
+ Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @author Christian Grothoff
+ * @file paivana-httpd_helper.c
+ * @brief helper functions
+ */
+#include "paivana-httpd.h"
+#include "paivana-httpd_helper.h"
+#include <taler/taler_mhd_lib.h>
+
+bool
+PAIVANA_HTTPD_get_client_address (struct MHD_Connection *connection,
+ void **ca,
+ size_t *ca_len)
+{
+ const union MHD_ConnectionInfo *ci;
+ const struct sockaddr *sa;
+ socklen_t sa_len;
+
+ // FIXME: also support getting client address from HTTP
+ // headers instead (in case of reverse proxy).
+ ci = MHD_get_connection_info (connection,
+ MHD_CONNECTION_INFO_CLIENT_ADDRESS);
+ GNUNET_assert (NULL != ci);
+ sa = ci->client_addr;
+ switch (sa->sa_family)
+ {
+ case AF_INET:
+ sa_len = sizeof (struct sockaddr_in);
+ break;
+ case AF_INET6:
+ sa_len = sizeof (struct sockaddr_in6);
+ break;
+ default:
+ GNUNET_break (0);
+ *ca = NULL;
+ *ca_len = 0;
+ return false;
+ }
+ ca = GNUNET_memdup (sa,
+ sa_len);
+ *ca_len = sa_len;
+ return true;
+}
+
+
+bool
+PAIVANA_HTTPD_get_base_url (struct MHD_Connection *connection,
+ struct GNUNET_Buffer *buf)
+{
+ const char *host;
+ const char *forwarded_host;
+ const char *forwarded_port;
+
+ GNUNET_buffer_clear (buf);
+ if (NULL != PH_base_url)
+ {
+ GNUNET_buffer_write_str (buf,
+ PH_base_url);
+ return true;
+ }
+ if (GNUNET_YES ==
+ TALER_mhd_is_https (connection))
+ GNUNET_buffer_write_str (buf,
+ "https://");
+ else
+ GNUNET_buffer_write_str (buf,
+ "http://");
+ host = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_HOST);
+ forwarded_host = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ "X-Forwarded-Host");
+ if (NULL != forwarded_host)
+ {
+ GNUNET_buffer_write_str (buf,
+ forwarded_host);
+ }
+ else
+ {
+ if (NULL == host)
+ {
+ GNUNET_break (0);
+ return false;
+ }
+ GNUNET_buffer_write_str (buf,
+ host);
+ }
+ forwarded_port = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ "X-Forwarded-Port");
+ if (NULL != forwarded_port)
+ {
+ GNUNET_buffer_write_str (buf,
+ ":");
+ GNUNET_buffer_write_str (buf,
+ forwarded_port);
+ }
+ return true;
+}
diff --git a/src/backend/paivana-httpd_helper.h b/src/backend/paivana-httpd_helper.h
@@ -0,0 +1,62 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2026 Taler Systems SA
+
+ Paivana 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.
+
+ Paivana 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 Paivana; see the file COPYING. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin
+ Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @author Christian Grothoff
+ * @file paivana-httpd_helper.h
+ * @brief helper functions
+ */
+#ifndef PAIVANA_HTTPD_HELPER_H
+#define PAIVANA_HTTPD_HELPER_H
+
+#include <stdbool.h>
+#include <microhttpd.h>
+#include <gnunet/gnunet_util_lib.h>
+
+
+/**
+ * Obtain the client address of @a connection
+ *
+ * @param connection HTTP client connection
+ * @param[out] ca where to write the client address
+ * @param[out] ca_len number of bytes in @a ca
+ * @return true on success
+ */
+bool
+PAIVANA_HTTPD_get_client_address (struct MHD_Connection *connection,
+ void **ca,
+ size_t *ca_len);
+
+/**
+ * Determine the Base URL that the client made the HTTP request to.
+ * The URL returned will be without the trailing '/'.
+ *
+ * @param connection client connection used
+ * @param[out] buf where to write the base URL; buffer will be cleared
+ * and must be reaped by caller.
+ * @return false on error (no suitable HTTP headers found and nothing
+ * configured)
+ */
+bool
+PAIVANA_HTTPD_get_base_url (struct MHD_Connection *connection,
+ struct GNUNET_Buffer *buf);
+
+
+#endif
diff --git a/src/backend/paivana-httpd_templates.c b/src/backend/paivana-httpd_templates.c
@@ -0,0 +1,55 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2026 Taler Systems SA
+
+ Paivana 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.
+
+ Paivana 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 Paivana; see the file COPYING. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin
+ Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @author Christian Grothoff
+ * @file paivana-httpd_templates.c
+ * @brief template functions
+ */
+#include "paivana-httpd.h"
+#include "paivana-httpd_templates.h"
+#include <taler/taler_mhd_lib.h>
+
+
+void
+PAIVANA_HTTPD_load_templates (GNUNET_SCHEDULER_TaskCallback cb,
+ void *cb_cls)
+{
+ // FIXME: not implemented!
+ GNUNET_SCHEDULER_add_now (cb,
+ cb_cls);
+}
+
+
+struct MHD_Response *
+PAIVANA_HTTPD_search_templates (const char *website)
+{
+ // FIXME: not implemented
+ return NULL;
+}
+
+
+/**
+ * Unload all of the template state.
+ */
+void
+PAIVANA_HTTPD_unload_templates ()
+{
+}
diff --git a/src/backend/paivana-httpd_templates.h b/src/backend/paivana-httpd_templates.h
@@ -0,0 +1,63 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2026 Taler Systems SA
+
+ Paivana 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.
+
+ Paivana 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 Paivana; see the file COPYING. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin
+ Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @author Christian Grothoff
+ * @file paivana-httpd_templates.h
+ * @brief functions to work with merchant backend templates
+ */
+#ifndef PAIVANA_HTTPD_TEMPLATES_H
+#define PAIVANA_HTTPD_TEMPLATES_H
+
+#include <microhttpd.h>
+#include <gnunet/gnunet_util_lib.h>
+
+
+/**
+ * Load the templates from the merchant backend.
+ * Calls @a cb upon completion if successful, otherwise
+ * may initiate shutdown.
+ *
+ * @param cb continuation to call when done
+ * @param cb_cls closure for @a cb
+ */
+void
+PAIVANA_HTTPD_load_templates (GNUNET_SCHEDULER_TaskCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Return the paywall page for the given @a website.
+ *
+ * @param website site to look for paywall templates for
+ * @return NULL if the @a url is not protected by the paywall,
+ * otherwise paywall response to return (do NOT free!)
+ */
+struct MHD_Response *
+PAIVANA_HTTPD_search_templates (const char *website);
+
+
+/**
+ * Unload all of the template state.
+ */
+void
+PAIVANA_HTTPD_unload_templates (void);
+
+#endif