Fix PHP-FPM compatibility and add server diagnostics
Changes to .htaccess: - Removed php_flag and php_value directives (don't work with php-fpm) - Simplified DirectoryMatch to FilesMatch for .json files - Added note about configuring PHP settings in php.ini/pool config - More compatible with user directories Added diagnostic.php: - Tests PHP version, extensions, and configuration - Checks storage directory permissions - Tests Server-Sent Events (SSE) connection - Shows server API type (php-fpm vs mod_php) - Provides troubleshooting hints for common issues - Live SSE connection test with detailed logging Added data/index.php: - Blocks direct access to data directory - Returns 403 Forbidden Fixes: - php-fpm environments not respecting .htaccess PHP settings - DirectoryMatch issues in user directories - Hard to diagnose connection problems Usage: Navigate to diagnostic.php to troubleshoot server issues
This commit is contained in:
@@ -1,22 +1,15 @@
|
||||
# Security settings for Multi-User Transcription Server
|
||||
|
||||
# Deny access to data directory
|
||||
<DirectoryMatch "^.*/data/.*$">
|
||||
Require all denied
|
||||
</DirectoryMatch>
|
||||
# Compatible with both mod_php and php-fpm
|
||||
|
||||
# Deny access to config file directly (if accessed via URL)
|
||||
<Files "config.php">
|
||||
Require all denied
|
||||
</Files>
|
||||
|
||||
# Enable PHP error logging (disable display for production)
|
||||
php_flag display_errors Off
|
||||
php_flag log_errors On
|
||||
|
||||
# Set upload limits
|
||||
php_value upload_max_filesize 1M
|
||||
php_value post_max_size 1M
|
||||
# Deny access to .json data files
|
||||
<FilesMatch "\.json$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
|
||||
# Disable directory listing
|
||||
Options -Indexes
|
||||
@@ -29,3 +22,7 @@ Options -Indexes
|
||||
# Set MIME types
|
||||
AddType application/json .json
|
||||
AddType text/event-stream .php
|
||||
|
||||
# NOTE: PHP settings (display_errors, upload limits) must be configured in:
|
||||
# - For php-fpm: /etc/php/X.X/fpm/pool.d/www.conf or php.ini
|
||||
# - For mod_php: Can use php_flag/php_value directives here
|
||||
|
||||
5
server/php/data/index.php
Normal file
5
server/php/data/index.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
// Block direct access to data directory
|
||||
http_response_code(403);
|
||||
header('Content-Type: text/plain');
|
||||
die('Access Denied');
|
||||
205
server/php/diagnostic.php
Normal file
205
server/php/diagnostic.php
Normal file
@@ -0,0 +1,205 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Server Diagnostic - Multi-User Transcription</title>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 900px;
|
||||
margin: 40px auto;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.test {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
margin: 15px 0;
|
||||
border-radius: 5px;
|
||||
border-left: 4px 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: 10px;
|
||||
border-radius: 3px;
|
||||
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;
|
||||
}
|
||||
|
||||
// Create test room
|
||||
const testRoom = 'diagnostic-test-' + Date.now();
|
||||
const url = `server.php?action=stream&room=${encodeURIComponent(testRoom)}`;
|
||||
|
||||
log(`Attempting to connect to: ${url}`);
|
||||
|
||||
try {
|
||||
const eventSource = new EventSource(url);
|
||||
|
||||
eventSource.onopen = () => {
|
||||
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(() => {
|
||||
eventSource.close();
|
||||
log('Connection test complete - closing');
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
eventSource.onmessage = (event) => {
|
||||
log('Received message: ' + event.data);
|
||||
};
|
||||
|
||||
eventSource.onerror = (error) => {
|
||||
sseStatus.innerHTML = '<span style="color: #f44336; font-weight: bold;">✗ SSE Failed</span>';
|
||||
log('✗ Connection error occurred');
|
||||
log('Error: ' + JSON.stringify(error));
|
||||
log('Check browser console for more details');
|
||||
eventSource.close();
|
||||
};
|
||||
} catch (error) {
|
||||
sseStatus.innerHTML = '<span style="color: #f44336; font-weight: bold;">✗ SSE Error</span>';
|
||||
log('✗ Exception: ' + error.message);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user