commit 7d45401feda856622a440a5bb1b4404488a1b771
parent b97d08202347cbf5e3ac33e24d6f00f8ecf8c2ad
Author: Christian Grothoff <christian@grothoff.org>
Date: Wed, 26 Nov 2025 23:40:51 +0100
complete trivial reverse proxy
Diffstat:
6 files changed, 314 insertions(+), 41 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -14,3 +14,8 @@ ltmain.sh
m4/
missing
paivana_config.h.in
+config.log
+config.status
+libtool
+paivana_config.h
+stamp-h1
diff --git a/src/backend/.gitignore b/src/backend/.gitignore
@@ -0,0 +1,3 @@
+paivana-httpd
+*.o
+.deps/
diff --git a/src/backend/paivana-httpd.c b/src/backend/paivana-httpd.c
@@ -329,9 +329,7 @@ curl_check_hdr (void *buffer,
buffer,
bytes);
ndup[bytes] = '\0';
-
hdr_type = strtok (ndup, ":");
-
if (NULL == hdr_type)
{
GNUNET_free (ndup);
@@ -354,11 +352,9 @@ curl_check_hdr (void *buffer,
*tok = '\0';
if (NULL != (tok = strchr (hdr_val, '\t')))
*tok = '\0';
-
PAIVANA_LOG_DEBUG ("Parsed line: '%s: %s'\n",
hdr_type,
hdr_val);
-
/* Skip "Content-length:" header as it will be wrong, given
that we are man-in-the-middling the connection */
if (0 == strcasecmp (hdr_type,
@@ -586,7 +582,6 @@ curl_upload_cb (void *buf,
* Extract the hostname from a complete URL.
*
* @param url full fledged URL
- *
* @return pointer to the 0-terminated hostname, to be freed
* by the caller.
*/
@@ -600,16 +595,14 @@ build_host_header (const char *url)
char *hostname;
char *dup = GNUNET_strdup (url);
- hostname = strstr (dup, MARKER);
+ hostname = strstr (dup,
+ MARKER);
hostname += 3;
-
end = strchrnul (hostname, '/');
*end = '\0';
-
GNUNET_asprintf (&header,
"Host: %s",
hostname);
-
GNUNET_free (dup);
return header;
}
@@ -842,7 +835,6 @@ curl_task_download (void *cls)
break;
}
}
- ;
} while (mret == CURLM_CALL_MULTI_PERFORM);
if (CURLM_OK != mret)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -996,10 +988,10 @@ create_response (void *cls,
0);
curl_easy_setopt (hr->curl,
CURLOPT_CONNECTTIMEOUT,
- 600L);
+ 60L);
curl_easy_setopt (hr->curl,
CURLOPT_TIMEOUT,
- 600L);
+ 60L);
curl_easy_setopt (hr->curl,
CURLOPT_NOSIGNAL,
1L);
@@ -1013,7 +1005,6 @@ create_response (void *cls,
curl_easy_setopt (hr->curl,
CURLOPT_READFUNCTION,
&curl_upload_cb);
-
curl_easy_setopt (hr->curl,
CURLOPT_READDATA,
hr);
@@ -1021,7 +1012,6 @@ create_response (void *cls,
curl_easy_setopt (hr->curl,
CURLOPT_WRITEFUNCTION,
&curl_download_cb);
-
curl_easy_setopt (hr->curl,
CURLOPT_WRITEDATA,
hr);
@@ -1049,6 +1039,7 @@ create_response (void *cls,
GNUNET_free (host_hdr);
}
+ // FIXME: support PATCH, etc.
if (0 == strcasecmp (meth,
MHD_HTTP_METHOD_PUT))
{
@@ -1059,7 +1050,6 @@ create_response (void *cls,
CURLOPT_UPLOAD,
1L);
hr->state = REQUEST_STATE_PROXY_UPLOAD_STARTED;
-
}
else if (0 == strcasecmp (meth,
MHD_HTTP_METHOD_POST))
@@ -1073,7 +1063,6 @@ create_response (void *cls,
CURLOPT_VERBOSE,
1L);
hr->state = REQUEST_STATE_PROXY_UPLOAD_STARTED;
-
}
else if (0 == strcasecmp (meth,
MHD_HTTP_METHOD_HEAD))
@@ -1109,29 +1098,9 @@ create_response (void *cls,
return MHD_NO;
}
- if (0 == strcasecmp (ver,
- MHD_HTTP_VERSION_1_0))
- {
- curl_easy_setopt (hr->curl,
- CURLOPT_HTTP_VERSION,
- CURL_HTTP_VERSION_1_0);
- }
- else if (0 == strcasecmp (ver,
- MHD_HTTP_VERSION_1_1))
- {
- curl_easy_setopt (hr->curl,
- CURLOPT_HTTP_VERSION,
- CURL_HTTP_VERSION_1_1);
- }
- else
- {
- curl_easy_setopt (hr->curl,
- CURLOPT_HTTP_VERSION,
- CURL_HTTP_VERSION_NONE);
- }
-
- if (CURLM_OK != curl_multi_add_handle (curl_multi,
- hr->curl))
+ if (CURLM_OK !=
+ curl_multi_add_handle (curl_multi,
+ hr->curl))
{
GNUNET_break (0);
curl_easy_cleanup (hr->curl);
@@ -1162,6 +1131,9 @@ create_response (void *cls,
GNUNET_assert (REQUEST_STATE_PROXY_DOWNLOAD_DONE == hr->state);
+ hr->response
+ = MHD_create_response_from_buffer_copy (hr->io_len,
+ hr->io_buf);
for (struct HttpResponseHeader *header = hr->header_head;
NULL != header;
header = header->next)
@@ -1577,7 +1549,8 @@ open_unix_path (const char *path,
* @param mode[out] mode string for @a path.
* @return #GNUNET_SYSERR if the parsing didn't succeed.
*/
-static int
+// FIXME: replace by helper function of Taler?
+static enum GNUNET_GenericReturnValue
parse_serving_mean (const struct GNUNET_CONFIGURATION_Handle *ccfg,
uint16_t *port,
char **path,
@@ -1589,7 +1562,6 @@ parse_serving_mean (const struct GNUNET_CONFIGURATION_Handle *ccfg,
char *modestring;
unsigned long long port_ull;
-
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_choice (ccfg,
"paivana",
diff --git a/src/backend/test.conf b/src/backend/test.conf
@@ -0,0 +1,4 @@
+[paivana]
+DESTINATION_BASE_URL = https://grothoff.org/
+SERVE = tcp
+HTTP_PORT = 8888
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
@@ -0,0 +1,7 @@
+# This Makefile.am is in the public domain
+SUBDIRS = .
+
+paivanaincludedir = $(includedir)/paivana
+
+paivanainclude_HEADERS = \
+ platform.h
diff --git a/src/include/platform.h b/src/include/platform.h
@@ -0,0 +1,282 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2012 GNUnet e.V.
+ Copyright (C) 2025 Taler Systems SA
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet 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
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @author Nils Durner
+ * @author Christian Grothoff
+ *
+ * @file gnunet/src/include/platform.h
+ * Platform specific includes and defines.
+ *
+ * This file should never be included by installed
+ * header files (those starting with "gnunet_").
+ */
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+#ifndef HAVE_USED_CONFIG_H
+#define HAVE_USED_CONFIG_H
+#if HAVE_CONFIG_H
+#include "paivana_config.h"
+#endif
+#endif
+
+#define BREAKPOINT
+#define GNUNET_SIGCHLD SIGCHLD
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <inttypes.h>
+
+#ifdef __clang__
+#undef HAVE_STATIC_ASSERT
+#endif
+
+/**
+ * These may be expensive, but good for debugging...
+ */
+#define ALLOW_EXTRA_CHECKS GNUNET_YES
+
+/**
+ * For strptime (glibc2 needs this).
+ */
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 499
+#endif
+
+#ifndef _REENTRANT
+#define _REENTRANT
+#endif
+
+/* configuration options */
+
+#define VERBOSE_STATS 0
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#if HAVE_NETINET_IP_H
+#include <netinet/ip.h> /* superset of previous */
+#endif
+#include <arpa/inet.h>
+#include <netinet/tcp.h>
+#include <pwd.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <grp.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <signal.h>
+#include <libgen.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h> /* for mallinfo on GNU */
+#endif
+#include <unistd.h> /* KLB_FIX */
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h> /* KLB_FIX */
+#include <fcntl.h>
+#include <math.h>
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#include <time.h>
+#ifdef BSD
+#include <net/if.h>
+#endif
+#if defined(BSD) && defined(__FreeBSD__) && defined(__FreeBSD_kernel__)
+#include <semaphore.h>
+#endif
+#ifdef DARWIN
+#include <dlfcn.h>
+#include <semaphore.h>
+#include <net/if.h>
+#include <xlocale.h>
+#endif
+#if defined(__linux__) || defined(GNU)
+#include <net/if.h>
+#endif
+#ifdef SOLARIS
+#include <sys/sockio.h>
+#include <sys/filio.h>
+#include <sys/loadavg.h>
+#include <semaphore.h>
+#endif
+#if HAVE_UCRED_H
+#include <ucred.h>
+#endif
+#if HAVE_SYS_UCRED_H
+#include <sys/ucred.h>
+#endif
+#if HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+#include <errno.h>
+#include <limits.h>
+
+#if HAVE_VFORK_H
+#include <vfork.h>
+#endif
+
+#include <ctype.h>
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#if HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+#if HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif
+
+#define DIR_SEPARATOR '/'
+#define DIR_SEPARATOR_STR "/"
+#define PATH_SEPARATOR ':'
+#define PATH_SEPARATOR_STR ":"
+#define NEWLINE "\n"
+
+#include <locale.h>
+#include <sys/mman.h>
+
+/* FreeBSD_kernel is not defined on the now discontinued kFreeBSD */
+#if defined(BSD) && defined(__FreeBSD__) && defined(__FreeBSD_kernel__)
+#define __BYTE_ORDER BYTE_ORDER
+#define __BIG_ENDIAN BIG_ENDIAN
+#endif
+
+#ifdef DARWIN
+#define __BYTE_ORDER BYTE_ORDER
+#define __BIG_ENDIAN BIG_ENDIAN
+/* not available on darwin, override configure */
+#undef HAVE_STAT64
+#undef HAVE_MREMAP
+#endif
+
+#if ! HAVE_ATOLL
+long long
+atoll (const char *nptr);
+
+#endif
+
+#if ENABLE_NLS
+#include "langinfo.h"
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) (-1))
+#endif
+
+#ifndef O_LARGEFILE
+#define O_LARGEFILE 0
+#endif
+
+/**
+ * AI_NUMERICSERV not defined in windows. Then we just do without.
+ */
+#ifndef AI_NUMERICSERV
+#define AI_NUMERICSERV 0
+#endif
+
+
+#if defined(__sparc__)
+#define MAKE_UNALIGNED(val) ({ __typeof__((val)) __tmp; memmove (&__tmp, &(val), \
+ sizeof((val))); \
+ __tmp; })
+#else
+#define MAKE_UNALIGNED(val) val
+#endif
+
+/**
+ * The termination signal
+ */
+#define GNUNET_TERM_SIG SIGTERM
+
+
+#ifndef PATH_MAX
+/**
+ * Assumed maximum path length.
+ */
+#define PATH_MAX 4096
+#endif
+
+#if HAVE_THREAD_LOCAL_GCC
+#define GNUNET_THREAD_LOCAL __thread
+#else
+#define GNUNET_THREAD_LOCAL
+#endif
+
+
+/* LSB-style exit status codes */
+#ifndef EXIT_INVALIDARGUMENT
+#define EXIT_INVALIDARGUMENT 2
+#endif
+
+#ifndef EXIT_NOTIMPLEMENTED
+#define EXIT_NOTIMPLEMENTED 3
+#endif
+
+#ifndef EXIT_NOPERMISSION
+#define EXIT_NOPERMISSION 4
+#endif
+
+#ifndef EXIT_NOTINSTALLED
+#define EXIT_NOTINSTALLED 5
+#endif
+
+#ifndef EXIT_NOTCONFIGURED
+#define EXIT_NOTCONFIGURED 6
+#endif
+
+#ifndef EXIT_NOTRUNNING
+#define EXIT_NOTRUNNING 7
+#endif
+
+#ifndef EXIT_NO_RESTART
+#define EXIT_NO_RESTART 9
+#endif
+
+/**
+ * clang et al do not have such an attribute
+ */
+#if __has_attribute (__nonstring__)
+# define __nonstring __attribute__((__nonstring__))
+#else
+# define __nonstring
+#endif
+
+#endif