paivana

HTTP paywall reverse proxy
Log | Files | Refs | Submodules | README | LICENSE

commit 1b754fe8da30ea906304931948adc7c8e1a16bae
parent 4d6092453dbce9b943019a3accf280b09fa2593d
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu,  6 Aug 2026 23:18:37 +0200

refuse to start without templates, unless in no-pay-mode

Diffstat:
MREADME | 5+++++
Msrc/backend/paivana-httpd_templates.c | 30++++++++++++++++++++++++------
2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/README b/README @@ -136,6 +136,11 @@ covers unpaywalled. Transient backend outages are the service manager's job to ride out -- the shipped `paivana-httpd.service` restarts with an increasing back-off, and does not restart on a configuration error. +An instance that offers no template at all is refused for the same +reason: with nothing to sell, no URL ever matches a paywall and the +entire site would be served for free without a word of warning. Serving +a site without a paywall is what `-n` is for, and it has to be asked for. + Deployment behind a reverse proxy ---------------------------------- diff --git a/src/backend/paivana-httpd_templates.c b/src/backend/paivana-httpd_templates.c @@ -233,12 +233,33 @@ load_timeout (void *cls) /** - * The templates are in (or there are none): stop the watchdog and - * open the listen sockets. + * The templates are in: stop the watchdog and open the listen sockets. + * + * Refuses to start if there is not a single one. Only reachable with + * the paywall enabled -- `-n' returns before + * #PAIVANA_HTTPD_load_templates() is ever called -- and a paywall with + * nothing to sell is not a paywall: PAIVANA_HTTPD_search_templates() + * would answer "no template matched" for every URL, which create_response() + * reads as "no paywall applies" and forwards. The whole site would be + * free, silently, which is exactly the outcome an operator running a + * paywall did not ask for. An operator who does want a plain reverse + * proxy says so with `-n'. */ static void templates_ready (void) { + if (NULL == t_head) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "The merchant backend at `%s' offers no payment template;" + " refusing to start, as every request would then be" + " forwarded for free. Pass -n if serving the site without" + " a paywall is what you want.\n", + PH_merchant_base_url); + PH_global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + } if (NULL != load_timeout_task) { GNUNET_SCHEDULER_cancel (load_timeout_task); @@ -692,8 +713,7 @@ check_templates ( case MHD_HTTP_OK: break; case MHD_HTTP_NO_CONTENT: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "No templates found, starting to serve requests\n"); + /* templates_ready() turns "none" into the diagnosis and the exit. */ templates_ready (); return; case MHD_HTTP_UNAUTHORIZED: @@ -714,8 +734,6 @@ check_templates ( } if (0 == tgr->details.ok.templates_length) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "No templates found, starting to serve requests\n"); templates_ready (); return; }