2025-12-26 12:45:23 -08:00
<! DOCTYPE html >
< html >
< head >
< title > Server Diagnostic - Multi - User Transcription </ title >
< meta charset = " UTF-8 " >
< style >
body {
font - family : Arial , sans - serif ;
max - width : 900 px ;
margin : 40 px auto ;
padding : 20 px ;
background : #f5f5f5;
}
. test {
background : white ;
padding : 20 px ;
margin : 15 px 0 ;
border - radius : 5 px ;
border - left : 4 px solid #ccc;
}
. test . pass { border - color : #4CAF50; }
. test . fail { border - color : #f44336; }
. test . warn { border - color : #ff9800; }
. test h3 {
margin - top : 0 ;
color : #333;
}
. test pre {
background : #f5f5f5;
padding : 10 px ;
border - radius : 3 px ;
overflow - x : auto ;
}
. status { font - weight : bold ; }
. pass . status { color : #4CAF50; }
. fail . status { color : #f44336; }
. warn . status { color : #ff9800; }
h1 { color : #333; }
. info { background : #e3f2fd; padding: 15px; border-radius: 5px; margin: 20px 0; }
</ style >
</ head >
< body >
< h1 > 🔧 Server Diagnostic </ h1 >
< ? php
require_once 'config.php' ;
// Test 1: PHP Version
$php_version = phpversion ();
$php_ok = version_compare ( $php_version , '7.4.0' , '>=' );
?>
<div class="test <?php echo $php_ok ? 'pass' : 'fail'; ?>">
<h3>PHP Version</h3>
<p class="status"><?php echo $php_ok ? '✓ PASS' : '✗ FAIL'; ?></p>
<p>Version: <strong><?php echo $php_version; ?></strong></p>
<?php if (!$php_ok): ?>
<p>Minimum required: PHP 7.4.0</p>
<?php endif; ?>
</div>
<?php
// Test 2: Server API
$server_api = php_sapi_name();
$is_fpm = strpos($server_api, 'fpm') !== false;
?>
<div class="test pass">
<h3>Server API</h3>
<p class="status">ℹ INFO</p>
<p>SAPI: <strong><?php echo $server_api; ?></strong></p>
<p>Type: <strong><?php echo $is_fpm ? 'PHP-FPM' : 'Other'; ?></strong></p>
<?php if ($is_fpm): ?>
<p class="info">✓ Running under PHP-FPM. Note: php_flag/php_value directives in .htaccess won't work. Configure PHP settings in php.ini or FPM pool config.</p>
<?php endif; ?>
</div>
<?php
// Test 3: Storage Directory
$storage_exists = file_exists(STORAGE_DIR);
$storage_writable = $storage_exists && is_writable(STORAGE_DIR);
$storage_ok = $storage_exists && $storage_writable;
?>
<div class="test <?php echo $storage_ok ? 'pass' : 'fail'; ?>">
<h3>Storage Directory</h3>
<p class="status"><?php echo $storage_ok ? '✓ PASS' : '✗ FAIL'; ?></p>
<p>Path: <code><?php echo STORAGE_DIR; ?></code></p>
<p>Exists: <?php echo $storage_exists ? 'Yes' : 'No'; ?></p>
<p>Writable: <?php echo $storage_writable ? 'Yes' : 'No'; ?></p>
<?php if (!$storage_ok): ?>
<p><strong>Fix:</strong> Run: <code>mkdir -p <?php echo STORAGE_DIR; ?> && chmod 755 <?php echo STORAGE_DIR; ?></code></p>
<?php endif; ?>
</div>
<?php
// Test 4: Required PHP Extensions
$required_extensions = ['json', 'mbstring'];
$missing_extensions = [];
foreach ($required_extensions as $ext) {
if (!extension_loaded($ext)) {
$missing_extensions[] = $ext;
}
}
$extensions_ok = empty($missing_extensions);
?>
<div class="test <?php echo $extensions_ok ? 'pass' : 'fail'; ?>">
<h3>PHP Extensions</h3>
<p class="status"><?php echo $extensions_ok ? '✓ PASS' : '✗ FAIL'; ?></p>
<?php if ($extensions_ok): ?>
<p>All required extensions loaded</p>
<?php else: ?>
<p>Missing extensions: <strong><?php echo implode(', ', $missing_extensions); ?></strong></p>
<?php endif; ?>
</div>
<?php
// Test 5: Server Info
?>
<div class="test pass">
<h3>Server Information</h3>
<p class="status">ℹ INFO</p>
<p>Server: <strong><?php echo $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown'; ?></strong></p>
<p>Document Root: <code><?php echo $_SERVER['DOCUMENT_ROOT'] ?? 'Unknown'; ?></code></p>
<p>Script Path: <code><?php echo __DIR__; ?></code></p>
</div>
<?php
// Test 6: API Endpoint Test
?>
<div class="test pass">
<h3>API Endpoint Test</h3>
<p class="status">ℹ INFO</p>
<p>Info endpoint: <a href="server.php?action=info" target="_blank">server.php?action=info</a></p>
<p>Test this endpoint to verify the API is accessible</p>
</div>
<?php
// Test 7: Server-Sent Events Test
?>
<div class="test pass">
<h3>Server-Sent Events (SSE) Test</h3>
<p class="status">Testing...</p>
<div id="sse-status">Connecting to SSE endpoint...</div>
<div id="sse-log" style="background: #f5f5f5; padding: 10px; margin-top: 10px; border-radius: 3px; max-height: 200px; overflow-y: auto;"></div>
</div>
<div class="info">
<h3>Common Issues & Solutions</h3>
<ul>
<li><strong>Disconnected Status:</strong> Check that server.php is accessible and SSE test above succeeds</li>
<li><strong>403 Forbidden:</strong> Check file permissions (644 for files, 755 for directories)</li>
<li><strong>500 Internal Server Error:</strong> Check PHP error logs for details</li>
<li><strong>CORS Errors:</strong> Ensure ENABLE_CORS is true in config.php</li>
<li><strong>PHP-FPM Issues:</strong> Check that PHP-FPM is running and configured correctly</li>
</ul>
</div>
<script>
// Test SSE connection
const sseLog = document.getElementById('sse-log');
const sseStatus = document.getElementById('sse-status');
function log(message) {
const time = new Date().toLocaleTimeString();
sseLog.innerHTML += `[${time}] ${message}<br>`;
sseLog.scrollTop = sseLog.scrollHeight;
2025-12-26 13:57:28 -08:00
console.log(`[SSE Test] ${message}`);
2025-12-26 12:45:23 -08:00
}
// Create test room
const testRoom = 'diagnostic-test-' + Date.now();
const url = `server.php?action=stream&room=${encodeURIComponent(testRoom)}`;
2025-12-26 13:57:28 -08:00
console.group('SSE Connection Test');
console.log('Test Room:', testRoom);
console.log('Full URL:', url);
console.log('Current Location:', window.location.href);
console.log('Base URL:', window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '/'));
2025-12-26 12:45:23 -08:00
log(`Attempting to connect to: ${url}`);
try {
const eventSource = new EventSource(url);
2025-12-26 13:57:28 -08:00
console.log('EventSource object created:', eventSource);
console.log('EventSource readyState:', eventSource.readyState, '(0=CONNECTING, 1=OPEN, 2=CLOSED)');
console.log('EventSource url:', eventSource.url);
eventSource.onopen = (event) => {
console.log('EventSource.onopen fired:', event);
console.log('ReadyState after open:', eventSource.readyState);
2025-12-26 12:45:23 -08:00
sseStatus.innerHTML = '<span style="color: #4CAF50; font-weight: bold;">✓ SSE Connected</span>';
log('✓ Connection established');
log('✓ Server-Sent Events are working');
// Close after successful connection
setTimeout(() => {
2025-12-26 13:57:28 -08:00
console.log('Closing EventSource after successful test');
2025-12-26 12:45:23 -08:00
eventSource.close();
log('Connection test complete - closing');
2025-12-26 13:57:28 -08:00
console.groupEnd();
2025-12-26 12:45:23 -08:00
}, 2000);
};
eventSource.onmessage = (event) => {
2025-12-26 13:57:28 -08:00
console.log('EventSource.onmessage:', event);
console.log('Message data:', event.data);
console.log('Event ID:', event.lastEventId);
2025-12-26 12:45:23 -08:00
log('Received message: ' + event.data);
};
eventSource.onerror = (error) => {
2025-12-26 13:57:28 -08:00
console.error('EventSource.onerror fired:', error);
console.error('ReadyState on error:', eventSource.readyState);
console.error('EventSource URL:', eventSource.url);
// Try to get more info from the error
console.error('Error type:', error.type);
console.error('Error target:', error.target);
console.error('Error currentTarget:', error.currentTarget);
// Check if it's a network error
if (eventSource.readyState === EventSource.CLOSED) {
console.error('Connection is CLOSED - this usually indicates a network error or server rejection');
} else if (eventSource.readyState === EventSource.CONNECTING) {
console.warn('Still CONNECTING - may be retrying');
}
2025-12-26 12:45:23 -08:00
sseStatus.innerHTML = '<span style="color: #f44336; font-weight: bold;">✗ SSE Failed</span>';
log('✗ Connection error occurred');
2025-12-26 13:57:28 -08:00
log('ReadyState: ' + eventSource.readyState + ' (0=CONNECTING, 1=OPEN, 2=CLOSED)');
log('Check browser console for detailed error information');
2025-12-26 12:45:23 -08:00
eventSource.close();
2025-12-26 13:57:28 -08:00
console.groupEnd();
2025-12-26 12:45:23 -08:00
};
2025-12-26 13:57:28 -08:00
// Monitor readyState changes
let lastReadyState = eventSource.readyState;
const stateMonitor = setInterval(() => {
if (eventSource.readyState !== lastReadyState) {
console.log('ReadyState changed:', lastReadyState, '→', eventSource.readyState);
lastReadyState = eventSource.readyState;
}
if (eventSource.readyState === EventSource.CLOSED) {
clearInterval(stateMonitor);
}
}, 100);
2025-12-26 12:45:23 -08:00
} catch (error) {
2025-12-26 13:57:28 -08:00
console.error('Exception creating EventSource:', error);
console.error('Error stack:', error.stack);
2025-12-26 12:45:23 -08:00
sseStatus.innerHTML = '<span style="color: #f44336; font-weight: bold;">✗ SSE Error</span>';
log('✗ Exception: ' + error.message);
2025-12-26 13:57:28 -08:00
console.groupEnd();
2025-12-26 12:45:23 -08:00
}
</script>
</body>
</html>