penguin/tinyproxy

An L4 proxy designed to act as a tiny transparent shim

commit fda28b7eae1ce0d035b9182825571f427b19472c

author斟酌 鵬兄 <tgckpg@gmail.com>
date2026-05-29T14:05:45Z
subjectAdded builtin for http-ok
commit fda28b7eae1ce0d035b9182825571f427b19472c
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2026-05-29T14:05:45Z

    Added builtin for http-ok
---
 src/x_builtins.c | 35 +++++++++++++++++++++++++++++++----
 src/x_builtins.h |  1 +
 tinyproxy.conf   |  7 +++++++
 3 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/src/x_builtins.c b/src/x_builtins.c
index bbde45f..ef0d233 100644
--- a/src/x_builtins.c
+++ b/src/x_builtins.c
@@ -10,22 +10,32 @@ int x_builtin_parse(const char *s, enum x_builtin_upstream *out)
 		return -EINVAL;
 	}
 
-	if (strcmp(s, "client_addr") == 0 || strcmp(s, "X_CLIENT_ADDR") == 0) {
+	if (strcmp(s, "client_addr") == 0) {
 		*out = X_BUILTIN_CLIENT_ADDR;
 		return 0;
 	}
 
-	if (strcmp(s, "discard") == 0 || strcmp(s, "X_DISCARD") == 0) {
+	if (strcmp(s, "discard") == 0) {
 		*out = X_BUILTIN_DISCARD;
 		return 0;
 	}
 
-	if (strcmp(s, "hang") == 0 || strcmp(s, "X_HANG") == 0) {
+	if (strcmp(s, "hang") == 0) {
 		*out = X_BUILTIN_HANG;
 		return 0;
 	}
 
-	if (strcmp(s, "close") == 0 || strcmp(s, "X_CLOSE") == 0) {
+	if (strcmp(s, "http-ok") == 0) {
+		*out = X_BUILTIN_HTTP_OK;
+		return 0;
+	}
+
+	if (strcmp(s, "close") == 0) {
+		*out = X_BUILTIN_CLOSE;
+		return 0;
+	}
+
+	if (strcmp(s, "close") == 0) {
 		*out = X_BUILTIN_CLOSE;
 		return 0;
 	}
@@ -42,6 +52,8 @@ const char *x_builtin_name(enum x_builtin_upstream builtin)
 		return "discard";
 	case X_BUILTIN_HANG:
 		return "hang";
+	case X_BUILTIN_HTTP_OK:
+		return "http-ok";
 	case X_BUILTIN_CLOSE:
 		return "close";
 	case X_BUILTIN_NONE:
@@ -77,6 +89,21 @@ int x_builtin_handle(
 		res->action = X_BUILTIN_ACTION_CLOSE;
 		return 0;
 
+	case X_BUILTIN_HTTP_OK: {
+		static const char http_ok[] =
+			"HTTP/1.1 200 OK\r\n"
+			"Content-Length: 2\r\n"
+			"Connection: close\r\n"
+			"\r\n"
+			"OK";
+
+		memcpy(res->data, http_ok, sizeof(http_ok) - 1);
+		res->data_len = sizeof(http_ok) - 1;
+
+		res->action = X_BUILTIN_ACTION_CLOSE;
+		return 0;
+	}
+
 	case X_BUILTIN_DISCARD:
 		res->action = X_BUILTIN_ACTION_DISCARD;
 		return 0;
diff --git a/src/x_builtins.h b/src/x_builtins.h
index aca0151..e152874 100644
--- a/src/x_builtins.h
+++ b/src/x_builtins.h
@@ -9,6 +9,7 @@ enum x_builtin_upstream {
 	X_BUILTIN_CLIENT_ADDR,
 	X_BUILTIN_DISCARD,
 	X_BUILTIN_HANG,
+	X_BUILTIN_HTTP_OK,
 	X_BUILTIN_CLOSE,
 };
 
diff --git a/tinyproxy.conf b/tinyproxy.conf
index 701b49c..d922ab8 100644
--- a/tinyproxy.conf
+++ b/tinyproxy.conf
@@ -33,6 +33,11 @@
 # builtin close
 #   Accepts the connection and immediately closes it without reading or writing.
 #   For UDP, this is equivalent to discard/drop because UDP has no connection to close.
+#
+# builtin http-ok
+#   Respond "HTTP/1.1 200 OK\r\nContent-Length: 2\r\nConnection: close\r\n\r\nOK" then close.
+#   Useful for probing
+#
 
 
 # TCP stream forwarding.
@@ -54,12 +59,14 @@ listen tcp :12995  builtin client_addr
 listen tcp :12996  builtin hang         idle_timeout=3,connect_timeout=1
 listen tcp :12997  builtin discard
 listen tcp :12998  builtin close
+listen tcp :8080   builtin http-ok
 
 # Builtin UDP test backends.
 listen udp :12995  builtin client_addr
 listen udp :12996  builtin hang
 listen udp :12997  builtin discard
 listen udp :12998  builtin close
+listen udp :8080   builtin http-ok
 
 # Static file TCP backends.
 listen tcp :14000  file examples/http-response.txt