Spaces:
Running
Running
feat: add query parameter support for proxy target/key and ensure unbuffered gateway logging
Browse files- cloudflare-proxy-setup.py +13 -6
- cloudflare-worker.js +15 -8
- start.sh +2 -1
cloudflare-proxy-setup.py
CHANGED
|
@@ -86,15 +86,16 @@ function isAllowedHost(hostname) {{
|
|
| 86 |
|
| 87 |
async function handleRequest(request) {{
|
| 88 |
const url = new URL(request.url);
|
| 89 |
-
const
|
|
|
|
| 90 |
|
| 91 |
if (PROXY_SHARED_SECRET) {{
|
| 92 |
-
const providedSecret = request.headers.get("x-proxy-key") || "";
|
| 93 |
if (providedSecret !== PROXY_SHARED_SECRET) {{
|
| 94 |
if (url.pathname.startsWith("/bot") && !targetHost) {{
|
| 95 |
// Allowed fallback
|
| 96 |
}} else {{
|
| 97 |
-
return new Response("Unauthorized", {{ status: 401 }});
|
| 98 |
}}
|
| 99 |
}}
|
| 100 |
}}
|
|
@@ -102,16 +103,21 @@ async function handleRequest(request) {{
|
|
| 102 |
let targetBase = "";
|
| 103 |
if (targetHost) {{
|
| 104 |
if (!isAllowedHost(targetHost)) {{
|
| 105 |
-
return new Response(
|
| 106 |
}}
|
| 107 |
targetBase = `https://${{targetHost}}`;
|
| 108 |
}} else if (url.pathname.startsWith("/bot")) {{
|
| 109 |
targetBase = "https://api.telegram.org";
|
| 110 |
}} else {{
|
| 111 |
-
return new Response("Invalid request.", {{ status: 400 }});
|
| 112 |
}}
|
| 113 |
|
| 114 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
const headers = new Headers(request.headers);
|
| 116 |
headers.delete("cf-connecting-ip");
|
| 117 |
headers.delete("cf-ray");
|
|
@@ -119,6 +125,7 @@ async function handleRequest(request) {{
|
|
| 119 |
headers.delete("host");
|
| 120 |
headers.delete("x-real-ip");
|
| 121 |
headers.delete("x-target-host");
|
|
|
|
| 122 |
|
| 123 |
const proxiedRequest = new Request(targetUrl, {{
|
| 124 |
method: request.method,
|
|
|
|
| 86 |
|
| 87 |
async function handleRequest(request) {{
|
| 88 |
const url = new URL(request.url);
|
| 89 |
+
const queryTarget = url.searchParams.get("proxy_target");
|
| 90 |
+
const targetHost = request.headers.get("x-target-host") || queryTarget;
|
| 91 |
|
| 92 |
if (PROXY_SHARED_SECRET) {{
|
| 93 |
+
const providedSecret = request.headers.get("x-proxy-key") || url.searchParams.get("proxy_key") || "";
|
| 94 |
if (providedSecret !== PROXY_SHARED_SECRET) {{
|
| 95 |
if (url.pathname.startsWith("/bot") && !targetHost) {{
|
| 96 |
// Allowed fallback
|
| 97 |
}} else {{
|
| 98 |
+
return new Response("Unauthorized: Invalid proxy key", {{ status: 401 }});
|
| 99 |
}}
|
| 100 |
}}
|
| 101 |
}}
|
|
|
|
| 103 |
let targetBase = "";
|
| 104 |
if (targetHost) {{
|
| 105 |
if (!isAllowedHost(targetHost)) {{
|
| 106 |
+
return new Response(`Forbidden: Host ${{targetHost}} is not allowed.`, {{ status: 403 }});
|
| 107 |
}}
|
| 108 |
targetBase = `https://${{targetHost}}`;
|
| 109 |
}} else if (url.pathname.startsWith("/bot")) {{
|
| 110 |
targetBase = "https://api.telegram.org";
|
| 111 |
}} else {{
|
| 112 |
+
return new Response("Invalid request: No target host provided.", {{ status: 400 }});
|
| 113 |
}}
|
| 114 |
|
| 115 |
+
const cleanSearch = new URLSearchParams(url.search);
|
| 116 |
+
cleanSearch.delete("proxy_target");
|
| 117 |
+
cleanSearch.delete("proxy_key");
|
| 118 |
+
const searchStr = cleanSearch.toString();
|
| 119 |
+
const targetUrl = targetBase + url.pathname + (searchStr ? `?${{searchStr}}` : "");
|
| 120 |
+
|
| 121 |
const headers = new Headers(request.headers);
|
| 122 |
headers.delete("cf-connecting-ip");
|
| 123 |
headers.delete("cf-ray");
|
|
|
|
| 125 |
headers.delete("host");
|
| 126 |
headers.delete("x-real-ip");
|
| 127 |
headers.delete("x-target-host");
|
| 128 |
+
headers.delete("x-proxy-key");
|
| 129 |
|
| 130 |
const proxiedRequest = new Request(targetUrl, {{
|
| 131 |
method: request.method,
|
cloudflare-worker.js
CHANGED
|
@@ -22,7 +22,8 @@ function normalizeList(raw) {
|
|
| 22 |
export default {
|
| 23 |
async fetch(request, env) {
|
| 24 |
const url = new URL(request.url);
|
| 25 |
-
const
|
|
|
|
| 26 |
const proxySecret = (
|
| 27 |
env.PROXY_SHARED_SECRET ||
|
| 28 |
env.CLOUDFLARE_PROXY_SECRET ||
|
|
@@ -30,14 +31,14 @@ export default {
|
|
| 30 |
).trim();
|
| 31 |
|
| 32 |
if (proxySecret) {
|
| 33 |
-
const providedSecret = request.headers.get("x-proxy-key") || "";
|
| 34 |
if (providedSecret !== proxySecret) {
|
| 35 |
-
// Fallback: allow Telegram requests via
|
| 36 |
-
//
|
| 37 |
if (url.pathname.startsWith("/bot") && !targetHost) {
|
| 38 |
// Allowed
|
| 39 |
} else {
|
| 40 |
-
return new Response("Unauthorized", { status: 401 });
|
| 41 |
}
|
| 42 |
}
|
| 43 |
}
|
|
@@ -62,16 +63,21 @@ export default {
|
|
| 62 |
let targetBase = "";
|
| 63 |
if (targetHost) {
|
| 64 |
if (!isAllowedHost(targetHost)) {
|
| 65 |
-
return new Response(
|
| 66 |
}
|
| 67 |
targetBase = `https://${targetHost}`;
|
| 68 |
} else if (url.pathname.startsWith("/bot")) {
|
| 69 |
targetBase = "https://api.telegram.org";
|
| 70 |
} else {
|
| 71 |
-
return new Response("Invalid request.", { status: 400 });
|
| 72 |
}
|
| 73 |
|
| 74 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
const headers = new Headers(request.headers);
|
| 76 |
headers.delete("cf-connecting-ip");
|
| 77 |
headers.delete("cf-ray");
|
|
@@ -79,6 +85,7 @@ export default {
|
|
| 79 |
headers.delete("host");
|
| 80 |
headers.delete("x-real-ip");
|
| 81 |
headers.delete("x-target-host");
|
|
|
|
| 82 |
|
| 83 |
const proxiedRequest = new Request(targetUrl, {
|
| 84 |
method: request.method,
|
|
|
|
| 22 |
export default {
|
| 23 |
async fetch(request, env) {
|
| 24 |
const url = new URL(request.url);
|
| 25 |
+
const queryTarget = url.searchParams.get("proxy_target");
|
| 26 |
+
const targetHost = request.headers.get("x-target-host") || queryTarget;
|
| 27 |
const proxySecret = (
|
| 28 |
env.PROXY_SHARED_SECRET ||
|
| 29 |
env.CLOUDFLARE_PROXY_SECRET ||
|
|
|
|
| 31 |
).trim();
|
| 32 |
|
| 33 |
if (proxySecret) {
|
| 34 |
+
const providedSecret = request.headers.get("x-proxy-key") || url.searchParams.get("proxy_key") || "";
|
| 35 |
if (providedSecret !== proxySecret) {
|
| 36 |
+
// Fallback: allow Telegram requests via path without secret if it looks like a bot API call.
|
| 37 |
+
// This is safe because it only proxies to api.telegram.org.
|
| 38 |
if (url.pathname.startsWith("/bot") && !targetHost) {
|
| 39 |
// Allowed
|
| 40 |
} else {
|
| 41 |
+
return new Response("Unauthorized: Invalid proxy key", { status: 401 });
|
| 42 |
}
|
| 43 |
}
|
| 44 |
}
|
|
|
|
| 63 |
let targetBase = "";
|
| 64 |
if (targetHost) {
|
| 65 |
if (!isAllowedHost(targetHost)) {
|
| 66 |
+
return new Response(`Forbidden: Host ${targetHost} is not allowed.`, { status: 403 });
|
| 67 |
}
|
| 68 |
targetBase = `https://${targetHost}`;
|
| 69 |
} else if (url.pathname.startsWith("/bot")) {
|
| 70 |
targetBase = "https://api.telegram.org";
|
| 71 |
} else {
|
| 72 |
+
return new Response("Invalid request: No target host provided.", { status: 400 });
|
| 73 |
}
|
| 74 |
|
| 75 |
+
const cleanSearch = new URLSearchParams(url.search);
|
| 76 |
+
cleanSearch.delete("proxy_target");
|
| 77 |
+
cleanSearch.delete("proxy_key");
|
| 78 |
+
const searchStr = cleanSearch.toString();
|
| 79 |
+
const targetUrl = targetBase + url.pathname + (searchStr ? `?${searchStr}` : "");
|
| 80 |
+
|
| 81 |
const headers = new Headers(request.headers);
|
| 82 |
headers.delete("cf-connecting-ip");
|
| 83 |
headers.delete("cf-ray");
|
|
|
|
| 85 |
headers.delete("host");
|
| 86 |
headers.delete("x-real-ip");
|
| 87 |
headers.delete("x-target-host");
|
| 88 |
+
headers.delete("x-proxy-key");
|
| 89 |
|
| 90 |
const proxiedRequest = new Request(targetUrl, {
|
| 91 |
method: request.method,
|
start.sh
CHANGED
|
@@ -515,7 +515,8 @@ if [ "${GATEWAY_VERBOSE:-0}" = "1" ]; then
|
|
| 515 |
echo "🔎 Gateway verbose logging enabled (GATEWAY_VERBOSE=1)"
|
| 516 |
fi
|
| 517 |
|
| 518 |
-
|
|
|
|
| 519 |
GATEWAY_PID=$!
|
| 520 |
|
| 521 |
# Wait a moment for startup errors
|
|
|
|
| 515 |
echo "🔎 Gateway verbose logging enabled (GATEWAY_VERBOSE=1)"
|
| 516 |
fi
|
| 517 |
|
| 518 |
+
# Use stdbuf -oL -eL to ensure logs are not buffered and appear immediately in the console
|
| 519 |
+
stdbuf -oL -eL openclaw "${GATEWAY_ARGS[@]}" 2>&1 | tee -a /home/node/.openclaw/gateway.log &
|
| 520 |
GATEWAY_PID=$!
|
| 521 |
|
| 522 |
# Wait a moment for startup errors
|