somratpro commited on
Commit
aea0c64
·
1 Parent(s): f4f91b0

feat: add query parameter support for proxy target/key and ensure unbuffered gateway logging

Browse files
Files changed (3) hide show
  1. cloudflare-proxy-setup.py +13 -6
  2. cloudflare-worker.js +15 -8
  3. 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 targetHost = request.headers.get("x-target-host");
 
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("Target host is not allowed.", {{ status: 403 }});
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 targetUrl = targetBase + url.pathname + url.search;
 
 
 
 
 
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 targetHost = request.headers.get("x-target-host");
 
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 apiRoot without secret if no x-target-host is provided
36
- // and the path matches Telegram bot API pattern.
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("Target host is not allowed.", { status: 403 });
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 targetUrl = targetBase + url.pathname + url.search;
 
 
 
 
 
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
- openclaw "${GATEWAY_ARGS[@]}" 2>&1 | tee -a /home/node/.openclaw/gateway.log &
 
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