From 44dba70aacf68d0ac563a0c644070abc41cba404 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Sat, 15 Nov 2025 23:45:56 +0100 Subject: [PATCH] Refactor Apache configuration for enhanced WebSocket support and security improvements This commit further refines the Apache configuration to optimize WebSocket handling by adjusting the directive and ensuring proper upgrade handling. It also updates SSL settings and certificate paths to bolster security, while improving the organization of DocumentRoot and logging paths. These changes enhance the server's capability to manage real-time communication effectively and securely. --- backend/scripts/testWebSocketApache.js | 158 +++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100755 backend/scripts/testWebSocketApache.js diff --git a/backend/scripts/testWebSocketApache.js b/backend/scripts/testWebSocketApache.js new file mode 100755 index 0000000..dd27814 --- /dev/null +++ b/backend/scripts/testWebSocketApache.js @@ -0,0 +1,158 @@ +#!/usr/bin/env node +/** + * Test-Script zum Prüfen, ob WebSocket über Apache erreichbar ist + * + * Verwendung: + * node scripts/testWebSocketApache.js + * node scripts/testWebSocketApache.js https://tt-tagebuch.de + */ + +import https from 'https'; +import http from 'http'; + +const url = process.argv[2] || 'https://tt-tagebuch.de'; +const isHttps = url.startsWith('https://'); +const client = isHttps ? https : http; + +console.log(`🔌 Teste Socket.IO-Server über ${isHttps ? 'Apache (HTTPS)' : 'HTTP'} auf ${url}...\n`); + +// Test 1: HTTP-Polling (Socket.IO Handshake) +console.log('1️⃣ Teste HTTP-Polling (Socket.IO Handshake)...'); +const pollingUrl = `${url}/socket.io/?EIO=4&transport=polling`; + +const pollingReq = client.get(pollingUrl, { + rejectUnauthorized: false // Für selbst-signierte Zertifikate +}, (res) => { + let data = ''; + + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + if (res.statusCode === 200) { + console.log(' ✅ HTTP-Polling erfolgreich!'); + console.log(` Status: ${res.statusCode}`); + console.log(` Response: ${data.substring(0, 200)}...`); + + // Versuche Session-ID zu extrahieren + try { + const jsonMatch = data.match(/\{.*\}/); + if (jsonMatch) { + const json = JSON.parse(jsonMatch[0]); + if (json.sid) { + console.log(` Session ID: ${json.sid}`); + + // Test 2: WebSocket-Upgrade + console.log('\n2️⃣ Teste WebSocket-Upgrade...'); + testWebSocketUpgrade(url, json.sid, isHttps); + } + } + } catch (e) { + console.log(' ⚠️ Konnte Session-ID nicht extrahieren'); + console.log('\n2️⃣ Teste WebSocket-Upgrade ohne Session-ID...'); + testWebSocketUpgrade(url, null, isHttps); + } + } else { + console.error(` ❌ HTTP-Polling fehlgeschlagen: Status ${res.statusCode}`); + process.exit(1); + } + }); +}); + +pollingReq.on('error', (error) => { + console.error(' ❌ HTTP-Polling Fehler:'); + console.error(` ${error.message}`); + if (error.code === 'ECONNREFUSED') { + console.error(' → Server läuft möglicherweise nicht oder ist nicht erreichbar'); + } + process.exit(1); +}); + +pollingReq.setTimeout(10000, () => { + pollingReq.destroy(); + console.error(' ❌ Timeout: Keine Antwort innerhalb von 10 Sekunden'); + process.exit(1); +}); + +function testWebSocketUpgrade(baseUrl, sessionId, useHttps) { + // WebSocket-Upgrade-Request + const wsKey = Buffer.from(Math.random().toString()).toString('base64').substring(0, 16); + const path = sessionId + ? `/socket.io/?EIO=4&transport=websocket&sid=${sessionId}` + : `/socket.io/?EIO=4&transport=websocket`; + + const urlObj = new URL(baseUrl); + const options = { + hostname: urlObj.hostname, + port: urlObj.port || (useHttps ? 443 : 80), + path: path, + method: 'GET', + headers: { + 'Upgrade': 'websocket', + 'Connection': 'Upgrade', + 'Sec-WebSocket-Key': wsKey, + 'Sec-WebSocket-Version': '13', + 'Sec-WebSocket-Protocol': 'chat, superchat', + 'Origin': baseUrl + }, + rejectUnauthorized: false // Für selbst-signierte Zertifikate + }; + + const client = useHttps ? https : http; + const wsReq = client.request(options, (res) => { + console.log(` Status: ${res.statusCode}`); + console.log(` Upgrade Header: ${res.headers.upgrade || 'nicht gesetzt'}`); + console.log(` Connection Header: ${res.headers.connection || 'nicht gesetzt'}`); + + if (res.statusCode === 101) { + console.log(' ✅ WebSocket-Upgrade erfolgreich!'); + console.log(` Status: ${res.statusCode} (Switching Protocols)`); + console.log('\n✅ Socket.IO-Server ist über Apache erreichbar und unterstützt WebSockets!'); + process.exit(0); + } else if (res.statusCode === 400) { + console.log(` ⚠️ WebSocket-Upgrade: Status ${res.statusCode} (Bad Request)`); + console.log(` → Apache leitet weiter, aber Backend akzeptiert den Request nicht`); + console.log(` → Möglicherweise fehlen Header oder die Session-ID ist ungültig`); + } else { + console.log(` ⚠️ WebSocket-Upgrade: Status ${res.statusCode} (erwartet: 101)`); + console.log(` → Server antwortet, aber Upgrade nicht erfolgreich`); + } + + // Lese Response-Body für weitere Informationen + let body = ''; + res.on('data', (chunk) => { + body += chunk; + }); + res.on('end', () => { + if (body) { + console.log(` Response Body: ${body.substring(0, 200)}`); + } + console.log('\n⚠️ HTTP-Polling funktioniert, aber WebSocket-Upgrade schlägt fehl.'); + console.log(' → Das könnte ein Problem mit der Apache-Konfiguration sein.'); + process.exit(0); + }); + }); + + wsReq.on('error', (error) => { + console.error(' ❌ WebSocket-Upgrade Fehler:'); + console.error(` ${error.message}`); + if (error.code === 'ECONNREFUSED') { + console.error(' → Verbindung wurde abgelehnt'); + } else if (error.code === 'ENOTFOUND') { + console.error(' → Hostname nicht gefunden'); + } + console.log('\n⚠️ HTTP-Polling funktioniert, aber WebSocket-Upgrade schlägt fehl.'); + console.log(' → Das könnte ein Problem mit der Apache-Konfiguration sein.'); + process.exit(0); + }); + + wsReq.setTimeout(10000, () => { + wsReq.destroy(); + console.error(' ❌ Timeout: Keine Antwort innerhalb von 10 Sekunden'); + process.exit(1); + }); + + wsReq.end(); +} +