paivana

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

commit d822f2cb01ad0bba566cafe152b34be4cab39164
parent 93b195323d4bb3ce342fc716b654ef3f3cffeb9e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri,  8 May 2026 23:46:06 +0200

pass summary and choices to Paivana page generation

Diffstat:
Msrc/backend/paivana-httpd_templates.c | 173+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 103 insertions(+), 70 deletions(-)

diff --git a/src/backend/paivana-httpd_templates.c b/src/backend/paivana-httpd_templates.c @@ -105,11 +105,21 @@ struct Template char *template_id; /** + * Summary of the template, NULL if not given. + */ + char *summary; + + /** * Maximum pickup delay for the pages. */ struct GNUNET_TIME_Relative max_pickup_delay; /** + * Ways how to pay for the template. + */ + json_t *choices; + + /** * Regular expression of websites the template is for. */ char *regex; @@ -270,6 +280,13 @@ load_paywall (struct MHD_Connection *conn, GNUNET_JSON_pack_string ( "template_id", t->template_id), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ( + "summary", + t->summary)), + GNUNET_JSON_pack_object_incref ( + "choices", + t->choices), GNUNET_JSON_pack_uint64 ( "max_pickup_delay", t->max_pickup_delay.rel_value_us / 1000LLU / 1000LLU), @@ -355,12 +372,20 @@ parse_template (struct Template *t, const json_t *contract) { const char *regex = NULL; + const char *summary = NULL; + const json_t *choices; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("website_regex", &regex), NULL), GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("summary", + &summary), + NULL), + GNUNET_JSON_spec_object_const ("choices", + &choices), + GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_relative_time ("max_pickup_duration", &t->max_pickup_delay), NULL), @@ -380,18 +405,24 @@ parse_template (struct Template *t, en); return; } - if (0 != regcomp (&t->ex, - regex, - REG_NOSUB | REG_EXTENDED)) + if (NULL != regex) { - GNUNET_break_op (0); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Invalid regex in template %s: %s\n", - t->template_id, - regex); - return; + if (0 != regcomp (&t->ex, + regex, + REG_NOSUB | REG_EXTENDED)) + { + GNUNET_break_op (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Invalid regex in template %s: %s\n", + t->template_id, + regex); + return; + } + t->regex = GNUNET_strdup (regex); } - t->regex = GNUNET_strdup (regex); + if (NULL != summary) + t->summary = GNUNET_strdup (summary); + t->choices = json_incref ((json_t *) choices); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Using payment template %s for `%s'\n", t->template_id, @@ -518,73 +549,73 @@ enum GNUNET_GenericReturnValue PAIVANA_HTTPD_search_templates (struct MHD_Connection *connection, const char *website) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Searching templates for `%s'\n", website); for (struct Template *t = t_head; NULL != t; t = t->next) { - if (NULL == t->regex) - continue; - if (0 == regexec (&t->ex, - website, - 0, NULL, - 0)) + struct MHD_Response *redirect; + enum MHD_Result ret; + struct GNUNET_Buffer buf = { 0 }; + char *enc = NULL; + char *url; + + if ( (NULL != t->regex) && + (0 != regexec (&t->ex, + website, + 0, NULL, + 0)) ) { - struct MHD_Response *redirect; - enum MHD_Result ret; - struct GNUNET_Buffer buf = { 0 }; - char *enc = NULL; - char *url; - - redirect = MHD_create_response_from_buffer_static (0, - NULL); - if (! PAIVANA_HTTPD_get_base_url (connection, - &buf)) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_HTTP_HEADERS_MALFORMED, - "Host or X-Forwarded-Host required"); - } - GNUNET_STRINGS_base64url_encode (website, - strlen (website), - &enc); - GNUNET_buffer_write_str (&buf, - "/.well-known/paivana/templates/"); - GNUNET_buffer_write_str (&buf, - t->template_id); - GNUNET_buffer_write_str (&buf, - "#"); - GNUNET_buffer_write_str (&buf, - enc); - GNUNET_free (enc); - url = GNUNET_buffer_reap_str (&buf); - GNUNET_break (MHD_YES == - MHD_add_response_header (redirect, - MHD_HTTP_HEADER_LOCATION, - url)); - GNUNET_break (MHD_YES == - MHD_add_response_header (redirect, - MHD_HTTP_HEADER_VARY, - "Cookie")); - GNUNET_break (MHD_YES == - MHD_add_response_header (redirect, - MHD_HTTP_HEADER_CACHE_CONTROL, - "public, max-age=60")); - GNUNET_free (url); - ret = MHD_queue_response (connection, - MHD_HTTP_FOUND, - redirect); - MHD_destroy_response (redirect); - return (MHD_YES == ret) ? GNUNET_OK : GNUNET_NO; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Request for %s did not match template %s\n", + website, + t->template_id); + continue; + } + redirect = MHD_create_response_from_buffer_static (0, + NULL); + if (! PAIVANA_HTTPD_get_base_url (connection, + &buf)) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_HTTP_HEADERS_MALFORMED, + "Host or X-Forwarded-Host required"); } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Request for %s did not match template %s\n", - website, - t->template_id); + GNUNET_STRINGS_base64url_encode (website, + strlen (website), + &enc); + GNUNET_buffer_write_str (&buf, + "/.well-known/paivana/templates/"); + GNUNET_buffer_write_str (&buf, + t->template_id); + GNUNET_buffer_write_str (&buf, + "#"); + GNUNET_buffer_write_str (&buf, + enc); + GNUNET_free (enc); + url = GNUNET_buffer_reap_str (&buf); + GNUNET_break (MHD_YES == + MHD_add_response_header (redirect, + MHD_HTTP_HEADER_LOCATION, + url)); + GNUNET_break (MHD_YES == + MHD_add_response_header (redirect, + MHD_HTTP_HEADER_VARY, + "Cookie")); + GNUNET_break (MHD_YES == + MHD_add_response_header (redirect, + MHD_HTTP_HEADER_CACHE_CONTROL, + "public, max-age=60")); + GNUNET_free (url); + ret = MHD_queue_response (connection, + MHD_HTTP_FOUND, + redirect); + MHD_destroy_response (redirect); + return (MHD_YES == ret) ? GNUNET_OK : GNUNET_NO; } return GNUNET_SYSERR; } @@ -652,6 +683,8 @@ PAIVANA_HTTPD_unload_templates () GNUNET_free (t->regex); } GNUNET_free (t->template_id); + GNUNET_free (t->summary); + json_decref (t->choices); GNUNET_free (t); } if (NULL != gpt)