Spaces:
Running
fix(cloudflare-proxy): handle WebSocket upgrade in Worker without body/redirect
Browse filesWhatsApp (Baileys) connects to web.whatsapp.com via WebSocket. The https.request
patch correctly routes this through the Cloudflare Worker, but the Worker was
forwarding the upgrade request with body + redirect:follow, causing the Worker
to tear down the TCP connection before TLS completed:
ECONNRESET: Client network socket disconnected before
secure TLS connection was established
host: <worker>.workers.dev port: 443
Cloudflare Workers natively tunnel WebSocket connections when fetch() gets a
101 Switching Protocols upstream response — but only if the request is forwarded
cleanly without a body or redirect policy. Detect Upgrade: websocket and
forward with method+headers only; all other requests keep the existing path.
Fixes: WhatsApp status 428 retry loop after ECONNRESET in HF Spaces deployments
with CLOUDFLARE_WORKERS_TOKEN set.
- cloudflare-proxy-setup.py +11 -7
|
@@ -151,15 +151,19 @@ async function handleRequest(request) {{
|
|
| 151 |
headers.delete("x-target-host");
|
| 152 |
headers.delete("x-proxy-key");
|
| 153 |
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |
try {{
|
| 162 |
-
return await fetch(
|
| 163 |
}} catch (error) {{
|
| 164 |
return new Response(`Proxy Error: ${{error.message}}`, {{ status: 502 }});
|
| 165 |
}}
|
|
|
|
| 151 |
headers.delete("x-target-host");
|
| 152 |
headers.delete("x-proxy-key");
|
| 153 |
|
| 154 |
+
// WebSocket upgrade requests (e.g. WhatsApp via Baileys) must NOT have
|
| 155 |
+
// body or redirect set — passing them causes the Worker to drop the TCP
|
| 156 |
+
// connection before TLS completes, producing ECONNRESET on the client.
|
| 157 |
+
// Cloudflare Workers transparently tunnel WebSocket connections when fetch()
|
| 158 |
+
// receives a 101 Switching Protocols response from the upstream server.
|
| 159 |
+
const isWebSocketUpgrade = (request.headers.get("Upgrade") || "").toLowerCase() === "websocket";
|
| 160 |
+
|
| 161 |
+
const fetchInit = isWebSocketUpgrade
|
| 162 |
+
? {{ method: request.method, headers }}
|
| 163 |
+
: {{ method: request.method, headers, body: request.body, redirect: "follow" }};
|
| 164 |
|
| 165 |
try {{
|
| 166 |
+
return await fetch(new Request(targetUrl, fetchInit));
|
| 167 |
}} catch (error) {{
|
| 168 |
return new Response(`Proxy Error: ${{error.message}}`, {{ status: 502 }});
|
| 169 |
}}
|