paivana

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

commit ae5a8145089e0e67179cfeae202685a6b15d351e
parent 030ce29b4b14db3f57439909a8be650304bd539d
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 31 May 2026 10:58:14 +0200

cleanup minor issues

Diffstat:
Msrc/backend/paivana-httpd_daemon.c | 4+++-
Msrc/backend/paivana-httpd_pay.c | 40++++++++++++++++++++++++++++------------
Msrc/backend/paivana-httpd_reverse.c | 27++++++++++++++++-----------
Msrc/backend/paivana-httpd_templates.c | 3++-
4 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/src/backend/paivana-httpd_daemon.c b/src/backend/paivana-httpd_daemon.c @@ -187,6 +187,8 @@ create_response (void *cls, void *ca = NULL; size_t ca_len = 0; + /* If we cannot get the client address, we just + use 0/NULL and log an error. */ GNUNET_break (PAIVANA_HTTPD_get_client_address (con, &ca, &ca_len)); @@ -207,9 +209,9 @@ create_response (void *cls, ret = PAIVANA_HTTPD_search_templates (con, website); - GNUNET_free (website); if (GNUNET_SYSERR != ret) { + GNUNET_free (website); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Payment required, sending paywall page %s\n", (GNUNET_OK == ret) ? "ok" : "failed"); diff --git a/src/backend/paivana-httpd_pay.c b/src/backend/paivana-httpd_pay.c @@ -58,7 +58,7 @@ struct PayRequest struct MHD_Connection *connection; /** - * Buffer for TALER_MHD_parse_post_json. + * Buffer for TALER_MHD_parse_post_json(). */ void *buffer; @@ -68,22 +68,25 @@ struct PayRequest json_t *body; /** - * Handle for our request to the merchant backend. + * Handle for our request to the merchant backend. This + * struct is in the #ph_head DLL as long as @e co is non-NULL. */ struct TALER_MERCHANT_GetPrivateOrderHandle *co; /** - * Response to return. + * Response to return, NULL if not yet determined. */ struct MHD_Response *response; /** - * ID of the order the client claims to have paid. + * ID of the order the client claims to have paid. Aliased + * from @e body. */ const char *order_id; /** - * Website the order is supposed to have paid for. + * Website the order is supposed to have paid for. Aliased + * from @e body. */ const char *website; @@ -132,6 +135,9 @@ PAIVANA_HTTPD_payment_shutdown () ph_tail, ph); MHD_resume_connection (ph->connection); + /* Note: PAIVANA_HTTPD_payment_destroy() + will be called by the owner of 'ph', + no need to do it here! */ } } @@ -230,6 +236,11 @@ order_status_cb (struct PayRequest *ph, const struct TALER_MERCHANT_GetPrivateOrderResponse *osr) { ph->co = NULL; + GNUNET_CONTAINER_DLL_remove (ph_head, + ph_tail, + ph); + MHD_resume_connection (ph->connection); + TALER_MHD_daemon_trigger (); switch (osr->hr.http_status) { case MHD_HTTP_OK: @@ -249,7 +260,9 @@ order_status_cb (struct PayRequest *ph, if (! check_contract (ph, osr->details.ok.details.paid.contract_terms)) - goto do_resume; + return; + /* If we cannot get the client address, we just + use 0/NULL and log an error. */ GNUNET_break (PAIVANA_HTTPD_get_client_address (ph->connection, &ca, &ca_len)); @@ -306,12 +319,6 @@ order_status_cb (struct PayRequest *ph, } break; } -do_resume: - GNUNET_CONTAINER_DLL_remove (ph_head, - ph_tail, - ph); - MHD_resume_connection (ph->connection); - TALER_MHD_daemon_trigger (); } @@ -404,9 +411,18 @@ PAIVANA_HTTPD_payment_destroy (struct PayRequest *ph) { TALER_MHD_parse_post_cleanup_callback (ph->buffer); if (NULL != ph->co) + { TALER_MERCHANT_get_private_order_cancel (ph->co); + GNUNET_CONTAINER_DLL_remove (ph_head, + ph_tail, + ph); + ph->co = NULL; + } if (NULL != ph->response) + { MHD_destroy_response (ph->response); + ph->response = NULL; + } json_decref (ph->body); GNUNET_free (ph); } diff --git a/src/backend/paivana-httpd_reverse.c b/src/backend/paivana-httpd_reverse.c @@ -600,7 +600,7 @@ curl_check_hdr (void *buffer, GNUNET_free (ndup); return bytes; } - hdr_val = strtok (NULL, ""); + hdr_val = strtok (NULL, "\n"); if (NULL == hdr_val) { GNUNET_free (ndup); @@ -1035,27 +1035,32 @@ buffer_upload_chunk (struct HttpRequest *hr, size_t upload_data_size, const char upload_data[static upload_data_size]) { + uint64_t min_size; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %u bytes UPLOAD\n", (unsigned int) upload_data_size); - if ( (hr->io_len + upload_data_size > PH_request_buffer_max) || - (hr->io_len + upload_data_size > UINT_MAX) ) + min_size = ((uint64_t) hr->io_len) + ((uint64_t) upload_data_size); + if ( (min_size < hr->io_len /* integer overflow */) || + (min_size > PH_request_buffer_max /* overflows config limit */) || + (min_size > UINT_MAX /* would overflow later */) ) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Upload exceeds %llu byte limit, rejecting\n", - PH_request_buffer_max); + "Upload exceeds limit, rejecting\n"); return false; } if (hr->io_size - hr->io_len < upload_data_size) { - GNUNET_assert (hr->io_size * 2 + 1024 > hr->io_size); - GNUNET_assert (upload_data_size + hr->io_len > hr->io_len); + unsigned int new_size; + + new_size = GNUNET_MAX ( + GNUNET_MIN (hr->io_size * 2 + 1024, + UINT_MAX), + min_size); + GNUNET_assert (new_size > hr->io_size); GNUNET_array_grow (hr->io_buf, hr->io_size, - GNUNET_MAX ( - GNUNET_MIN (hr->io_size * 2 + 1024, - UINT_MAX), - upload_data_size + hr->io_len)); + new_size); } GNUNET_memcpy (&hr->io_buf[hr->io_len], upload_data, diff --git a/src/backend/paivana-httpd_templates.c b/src/backend/paivana-httpd_templates.c @@ -601,11 +601,12 @@ PAIVANA_HTTPD_search_templates (struct MHD_Connection *connection, &buf)) { GNUNET_break (0); - return TALER_MHD_reply_with_error ( + ret = TALER_MHD_reply_with_error ( connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_HTTP_HEADERS_MALFORMED, "Host or X-Forwarded-Host required"); + return (MHD_YES == ret) ? GNUNET_OK : GNUNET_NO; } (void) GNUNET_STRINGS_base64url_encode (website, strlen (website),