// Maintenance page worker - Cloudflare Tunnel specific async function handleRequest(request) { const url = new URL(request.url); // Try to fetch through the tunnel const tunnelResponse = await fetch(request, { cf: { cacheTtl: 0, cacheEverything: false, // Don't cache error responses cacheTags: ['no-cache'] } }).catch((error) => { console.error('Tunnel fetch error:', error); return null; }); // Check if tunnel is working (200 OK) - NOT 502 or other errors if (tunnelResponse && tunnelResponse.status === 200) { return tunnelResponse; // Tunnel is up, serve normal content } // Check for specific tunnel errors const isTunnelError = !tunnelResponse || tunnelResponse.status === 502 || // Bad Gateway - Tunnel down tunnelResponse.status === 503 || // Service Unavailable tunnelResponse.status === 504; // Gateway Timeout if (isTunnelError) { console.log('Tunnel is down or returning error:', tunnelResponse?.status); } // Show maintenance page return new Response(getMaintenanceHTML(), { status: 503, headers: { "Content-Type": "text/html", "Retry-After": "3600", // Tell browsers to retry after 1 hour "Cache-Control": "no-cache, no-store, must-revalidate" } }); } function getMaintenanceHTML() { return `
$ cloudflared tunnel list $ cloudflared tunnel route ip show $ cloudflared tunnel --config ~/.cloudflared/config.yml run
Reference ID: ' + Math.random().toString(36).substr(2, 9) + '
Need help? Contact Support