somratpro commited on
Commit
d43f799
Β·
1 Parent(s): 8360c0f

refactor: optimize rate limiting, harden WebSocket parsing, update webhook payload formatting, and cleanup Docker assets

Browse files
Files changed (4) hide show
  1. Dockerfile +0 -1
  2. health-server.js +9 -1
  3. start.sh +4 -1
  4. wa-guardian.js +13 -6
Dockerfile CHANGED
@@ -65,7 +65,6 @@ RUN ln -s /home/node/.openclaw/openclaw-app/openclaw.mjs /usr/local/bin/openclaw
65
  # Copy HuggingClaw files
66
  COPY --chown=1000:1000 cloudflare-proxy.js /opt/cloudflare-proxy.js
67
  COPY --chown=1000:1000 cloudflare-proxy-setup.py /home/node/app/cloudflare-proxy-setup.py
68
- COPY --chown=1000:1000 cloudflare-worker.js /home/node/app/cloudflare-worker.js
69
  COPY --chown=1000:1000 health-server.js /home/node/app/health-server.js
70
  COPY --chown=1000:1000 iframe-fix.cjs /home/node/app/iframe-fix.cjs
71
  COPY --chown=1000:1000 start.sh /home/node/app/start.sh
 
65
  # Copy HuggingClaw files
66
  COPY --chown=1000:1000 cloudflare-proxy.js /opt/cloudflare-proxy.js
67
  COPY --chown=1000:1000 cloudflare-proxy-setup.py /home/node/app/cloudflare-proxy-setup.py
 
68
  COPY --chown=1000:1000 health-server.js /home/node/app/health-server.js
69
  COPY --chown=1000:1000 iframe-fix.cjs /home/node/app/iframe-fix.cjs
70
  COPY --chown=1000:1000 start.sh /home/node/app/start.sh
health-server.js CHANGED
@@ -13,7 +13,7 @@ const TELEGRAM_ENABLED = !!process.env.TELEGRAM_BOT_TOKEN;
13
  const WHATSAPP_ENABLED = /^true$/i.test(process.env.WHATSAPP_ENABLED || "");
14
  const WHATSAPP_STATUS_FILE = "/tmp/huggingclaw-wa-status.json";
15
  const HF_BACKUP_ENABLED = !!process.env.HF_TOKEN;
16
- const SYNC_INTERVAL = process.env.SYNC_INTERVAL || "600";
17
  const DASHBOARD_BASE = "/dashboard";
18
  const DASHBOARD_STATUS_PATH = `${DASHBOARD_BASE}/status`;
19
  const DASHBOARD_HEALTH_PATH = `${DASHBOARD_BASE}/health`;
@@ -135,6 +135,14 @@ function isRateLimited(req) {
135
  return recent.length > UPTIMEROBOT_RATE_MAX;
136
  }
137
 
 
 
 
 
 
 
 
 
138
  function isAllowedUptimeSetupOrigin(req) {
139
  const host = String(req.headers.host || "").toLowerCase();
140
  const origin = String(req.headers.origin || "").toLowerCase();
 
13
  const WHATSAPP_ENABLED = /^true$/i.test(process.env.WHATSAPP_ENABLED || "");
14
  const WHATSAPP_STATUS_FILE = "/tmp/huggingclaw-wa-status.json";
15
  const HF_BACKUP_ENABLED = !!process.env.HF_TOKEN;
16
+ const SYNC_INTERVAL = process.env.SYNC_INTERVAL || "180";
17
  const DASHBOARD_BASE = "/dashboard";
18
  const DASHBOARD_STATUS_PATH = `${DASHBOARD_BASE}/status`;
19
  const DASHBOARD_HEALTH_PATH = `${DASHBOARD_BASE}/health`;
 
135
  return recent.length > UPTIMEROBOT_RATE_MAX;
136
  }
137
 
138
+ // Prune stale rate-limit buckets every 5 minutes to prevent unbounded growth.
139
+ setInterval(() => {
140
+ const cutoff = Date.now() - UPTIMEROBOT_RATE_WINDOW_MS;
141
+ for (const [ip, timestamps] of uptimerobotRateMap) {
142
+ if (timestamps.every((ts) => ts < cutoff)) uptimerobotRateMap.delete(ip);
143
+ }
144
+ }, 5 * 60 * 1000).unref();
145
+
146
  function isAllowedUptimeSetupOrigin(req) {
147
  const host = String(req.headers.host || "").toLowerCase();
148
  const origin = String(req.headers.origin || "").toLowerCase();
start.sh CHANGED
@@ -450,9 +450,12 @@ echo ""
450
 
451
  # ── Trigger Webhook on Restart ──
452
  if [ -n "${WEBHOOK_URL:-}" ]; then
 
 
 
453
  curl -s -X POST "$WEBHOOK_URL" \
454
  -H "Content-Type: application/json" \
455
- -d '{"event":"restart", "status":"success", "message":"HuggingClaw gateway has started/restarted.", "model": "'"$LLM_MODEL"'"}' >/dev/null 2>&1 &
456
  fi
457
 
458
  # ── Trap SIGTERM for graceful shutdown ──
 
450
 
451
  # ── Trigger Webhook on Restart ──
452
  if [ -n "${WEBHOOK_URL:-}" ]; then
453
+ WEBHOOK_BODY=$(jq -n \
454
+ --arg model "$LLM_MODEL" \
455
+ '{"event":"restart","status":"success","message":"HuggingClaw gateway has started/restarted.","model":$model}')
456
  curl -s -X POST "$WEBHOOK_URL" \
457
  -H "Content-Type: application/json" \
458
+ -d "$WEBHOOK_BODY" >/dev/null 2>&1 &
459
  fi
460
 
461
  # ── Trap SIGTERM for graceful shutdown ──
wa-guardian.js CHANGED
@@ -9,7 +9,12 @@
9
 
10
  const fs = require("fs");
11
  const path = require("path");
12
- const { WebSocket } = require('/home/node/.openclaw/openclaw-app/node_modules/ws');
 
 
 
 
 
13
  const { randomUUID } = require('node:crypto');
14
 
15
  const GATEWAY_URL = "ws://127.0.0.1:7860";
@@ -76,7 +81,8 @@ async function createConnection() {
76
  let resolved = false;
77
 
78
  ws.on("message", (data) => {
79
- const msg = JSON.parse(data.toString());
 
80
 
81
  if (msg.type === "event" && msg.event === "connect.challenge") {
82
  ws.send(JSON.stringify({
@@ -123,7 +129,8 @@ async function callRpc(ws, method, params) {
123
  return new Promise((resolve, reject) => {
124
  const id = randomUUID();
125
  const handler = (data) => {
126
- const msg = JSON.parse(data.toString());
 
127
  if (msg.id === id) {
128
  ws.removeListener("message", handler);
129
  if (msg.ok === false) {
@@ -170,7 +177,7 @@ async function checkStatus() {
170
  isWaiting = true;
171
  writeStatus({ configured: true, connected: false, pairing: true });
172
  if (!hasShownWaitMessage) {
173
- console.log("\n[guardian] πŸ“± WhatsApp pairing in progress. Please scan the QR code in the Control UI.");
174
  hasShownWaitMessage = true;
175
  }
176
 
@@ -192,7 +199,7 @@ async function checkStatus() {
192
  if (linkedAfter515) {
193
  console.log("[guardian] 515 after scan: credentials saved, reloading config to start WhatsApp...");
194
  } else {
195
- console.log("[guardian] βœ… Pairing completed! Reloading config...");
196
  }
197
 
198
  const getRes = await callRpc(ws, "config.get", {});
@@ -241,6 +248,6 @@ if (!WHATSAPP_ENABLED) {
241
  }
242
 
243
  writeStatus({ configured: true, connected: false, pairing: false });
244
- console.log("[guardian] βš”οΈ WhatsApp Guardian active. Monitoring pairing status...");
245
  setInterval(checkStatus, CHECK_INTERVAL);
246
  setTimeout(checkStatus, 15000);
 
9
 
10
  const fs = require("fs");
11
  const path = require("path");
12
+ let WebSocket;
13
+ try {
14
+ ({ WebSocket } = require('ws'));
15
+ } catch (_) {
16
+ ({ WebSocket } = require('/home/node/.openclaw/openclaw-app/node_modules/ws'));
17
+ }
18
  const { randomUUID } = require('node:crypto');
19
 
20
  const GATEWAY_URL = "ws://127.0.0.1:7860";
 
81
  let resolved = false;
82
 
83
  ws.on("message", (data) => {
84
+ let msg;
85
+ try { msg = JSON.parse(data.toString()); } catch { return; }
86
 
87
  if (msg.type === "event" && msg.event === "connect.challenge") {
88
  ws.send(JSON.stringify({
 
129
  return new Promise((resolve, reject) => {
130
  const id = randomUUID();
131
  const handler = (data) => {
132
+ let msg;
133
+ try { msg = JSON.parse(data.toString()); } catch { return; }
134
  if (msg.id === id) {
135
  ws.removeListener("message", handler);
136
  if (msg.ok === false) {
 
177
  isWaiting = true;
178
  writeStatus({ configured: true, connected: false, pairing: true });
179
  if (!hasShownWaitMessage) {
180
+ console.log("\n[guardian] WhatsApp pairing in progress. Please scan the QR code in the Control UI.");
181
  hasShownWaitMessage = true;
182
  }
183
 
 
199
  if (linkedAfter515) {
200
  console.log("[guardian] 515 after scan: credentials saved, reloading config to start WhatsApp...");
201
  } else {
202
+ console.log("[guardian] Pairing completed! Reloading config...");
203
  }
204
 
205
  const getRes = await callRpc(ws, "config.get", {});
 
248
  }
249
 
250
  writeStatus({ configured: true, connected: false, pairing: false });
251
+ console.log("[guardian] WhatsApp Guardian active. Monitoring pairing status...");
252
  setInterval(checkStatus, CHECK_INTERVAL);
253
  setTimeout(checkStatus, 15000);