| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- <?php
- /**
- * Upload Diagnostic Script
- * Helps identify what's limiting file uploads
- */
- // Handle test upload first - before any HTML output
- if (isset($_GET['action']) && $_GET['action'] === 'test' && $_SERVER['REQUEST_METHOD'] === 'POST') {
- // Start session
- if (session_status() === PHP_SESSION_NONE) {
- session_start();
- }
-
- require_once '../includes/config.php';
- require_once '../includes/database.php';
- require_once '../includes/auth.php';
-
- // Require authentication
- $auth = new Auth();
- $auth->requireAuth();
-
- header('Content-Type: application/json');
-
- $result = [
- 'success' => false,
- 'size' => 0,
- 'error' => 'No file uploaded',
- 'php_info' => [
- 'upload_max_filesize' => ini_get('upload_max_filesize'),
- 'post_max_size' => ini_get('post_max_size'),
- 'memory_limit' => ini_get('memory_limit')
- ],
- 'server_info' => [
- 'content_length' => $_SERVER['CONTENT_LENGTH'] ?? 0,
- 'content_type' => $_SERVER['CONTENT_TYPE'] ?? 'unknown'
- ]
- ];
-
- if (isset($_FILES['test_file'])) {
- $file = $_FILES['test_file'];
- $result['size'] = $file['size'];
- $result['original_name'] = $file['name'];
- $result['type'] = $file['type'];
- $result['error_code'] = $file['error'];
-
- if ($file['error'] === UPLOAD_ERR_OK) {
- $result['success'] = true;
- $result['message'] = 'Upload successful';
- } else {
- $result['error'] = getUploadErrorMessage($file['error']);
- }
- }
-
- echo json_encode($result);
- exit;
- }
- // Start session for main page
- if (session_status() === PHP_SESSION_NONE) {
- session_start();
- }
- require_once '../includes/config.php';
- require_once '../includes/database.php';
- require_once '../includes/auth.php';
- // Require authentication
- $auth = new Auth();
- $auth->requireAuth();
- ?>
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Upload Diagnostics</title>
- <style>
- body { font-family: Arial, sans-serif; margin: 20px; }
- .section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; }
- .warning { background-color: #fff3cd; border-color: #ffeaa7; }
- .error { background-color: #f8d7da; border-color: #f5c6cb; }
- .success { background-color: #d4edda; border-color: #c3e6cb; }
- .info { background-color: #d1ecf1; border-color: #bee5eb; }
- table { width: 100%; border-collapse: collapse; }
- th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
- th { background-color: #f2f2f2; }
- .test-btn { padding: 10px 20px; margin: 5px; cursor: pointer; }
- #results { margin-top: 20px; }
- </style>
- </head>
- <body>
- <h1>Upload Diagnostics Tool</h1>
-
- <div class="section info">
- <h2>PHP Upload Configuration</h2>
- <table>
- <tr><th>Setting</th><th>Current Value</th><th>Recommended</th><th>Status</th></tr>
- <?php
- $settings = [
- 'upload_max_filesize' => ['current' => ini_get('upload_max_filesize'), 'recommended' => '20M', 'description' => 'Maximum file upload size'],
- 'post_max_size' => ['current' => ini_get('post_max_size'), 'recommended' => '25M', 'description' => 'Maximum POST request size'],
- 'memory_limit' => ['current' => ini_get('memory_limit'), 'recommended' => '256M', 'description' => 'Memory limit for PHP'],
- 'max_execution_time' => ['current' => ini_get('max_execution_time'), 'recommended' => '300', 'description' => 'Maximum execution time (seconds)'],
- 'max_input_time' => ['current' => ini_get('max_input_time'), 'recommended' => '300', 'description' => 'Maximum input time (seconds)'],
- 'file_uploads' => ['current' => ini_get('file_uploads'), 'recommended' => 'On', 'description' => 'File uploads enabled'],
- 'max_file_uploads' => ['current' => ini_get('max_file_uploads'), 'recommended' => '20', 'description' => 'Maximum simultaneous file uploads']
- ];
-
- foreach ($settings as $key => $setting) {
- $current = $setting['current'];
- $recommended = $setting['recommended'];
- $status = 'success';
- $statusClass = 'success';
-
- if ($key === 'file_uploads') {
- if ($current !== '1' && strtolower($current) !== 'on') {
- $status = 'ERROR - File uploads disabled!';
- $statusClass = 'error';
- }
- } elseif ($key === 'upload_max_filesize') {
- $currentBytes = return_bytes($current);
- $recommendedBytes = return_bytes($recommended);
- if ($currentBytes < $recommendedBytes) {
- $status = 'WARNING - Too small';
- $statusClass = 'warning';
- }
- } elseif ($key === 'post_max_size') {
- $currentBytes = return_bytes($current);
- $recommendedBytes = return_bytes($recommended);
- if ($currentBytes < $recommendedBytes) {
- $status = 'WARNING - Should be larger than upload_max_filesize';
- $statusClass = 'warning';
- }
- }
-
- echo "<tr>
- <td>{$key}</td>
- <td>{$current}</td>
- <td>{$recommended}</td>
- <td class='{$statusClass}'>{$status}</td>
- </tr>";
- }
- ?>
- </table>
- </div>
-
- <div class="section info">
- <h2>Server Information</h2>
- <table>
- <tr><th>Item</th><th>Value</th></tr>
- <tr><td>PHP Version</td><td><?php echo PHP_VERSION; ?></td></tr>
- <tr><td>Web Server</td><td><?php echo $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown'; ?></td></tr>
- <tr><td>Server API</td><td><?php echo PHP_SAPI; ?></td></tr>
- <tr><td>Document Root</td><td><?php echo $_SERVER['DOCUMENT_ROOT'] ?? 'Unknown'; ?></td></tr>
- <tr><td>Max Request Size (calculated)</td><td><?php echo min(return_bytes(ini_get('post_max_size')), return_bytes(ini_get('upload_max_filesize'))); ?> bytes</td></tr>
- </table>
- </div>
-
- <div class="section info">
- <h2>Upload Test</h2>
- <p>Test different file sizes to identify the exact limit:</p>
-
- <button class="test-btn" onclick="testUpload(100)">Test 100KB</button>
- <button class="test-btn" onclick="testUpload(500)">Test 500KB</button>
- <button class="test-btn" onclick="testUpload(1024)">Test 1MB</button>
- <button class="test-btn" onclick="testUpload(2048)">Test 2MB</button>
- <button class="test-btn" onclick="testUpload(5120)">Test 5MB</button>
- <button class="test-btn" onclick="testUpload(10240)">Test 10MB</button>
- <button class="test-btn" onclick="testUpload(20480)">Test 20MB</button>
-
- <div id="results"></div>
- </div>
-
- <div class="section info">
- <h2>Nginx Configuration Check</h2>
- <p><strong>Important:</strong> The error "client intended to send too large body" indicates an nginx limit.</p>
- <p>Check these nginx settings in your server configuration:</p>
- <ul>
- <li><code>client_max_body_size</code> - Default is 1MB, should be higher</li>
- <li><code>client_body_buffer_size</code> - Buffer size for request body</li>
- <li><code>client_header_timeout</code> - Timeout for client headers</li>
- <li><code>client_body_timeout</code> - Timeout for client body</li>
- </ul>
-
- <h3>Typical nginx configuration needed:</h3>
- <pre style="background: #f4f4f4; padding: 10px; border: 1px solid #ddd;">
- server {
- listen 80;
- server_name samuli.valavuo.net;
- root /path/to/website;
- index index.php;
-
- # Increase upload limits
- client_max_body_size 25M;
- client_body_buffer_size 128k;
- client_body_timeout 60s;
-
- location ~ \.php$ {
- fastcgi_pass unix:/var/run/php/php-fpm.sock;
- fastcgi_index index.php;
- include fastcgi_params;
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
- }
- }</pre>
- </div>
-
- <div class="section warning">
- <h2>Next Steps</h2>
- <ol>
- <li><strong>If nginx is the issue:</strong> Update your nginx configuration with <code>client_max_body_size 25M;</code> and restart nginx</li>
- <li><strong>If PHP is the issue:</strong> The .htaccess file should help, but you may need to update php.ini directly</li>
- <li><strong>Test again:</strong> After making changes, test with the buttons above</li>
- </ol>
- </div>
- <script>
- function testUpload(sizeKB) {
- const results = document.getElementById('results');
- results.innerHTML = '<p>Testing upload with ' + sizeKB + 'KB file...</p>';
-
- // Create test data
- const size = sizeKB * 1024;
- const data = new Uint8Array(size);
- for (let i = 0; i < size; i++) {
- data[i] = Math.floor(Math.random() * 256);
- }
-
- const blob = new Blob([data], { type: 'application/octet-stream' });
- const formData = new FormData();
- formData.append('test_file', blob, 'test_' + sizeKB + 'kb.dat');
-
- fetch('upload_diagnostic.php?action=test', {
- method: 'POST',
- body: formData
- })
- .then(response => response.json())
- .then(data => {
- const status = data.success ? 'success' : 'error';
- results.innerHTML = '<div class="section ' + status + '"><h3>Test Result: ' + sizeKB + 'KB</h3><pre>' + JSON.stringify(data, null, 2) + '</pre></div>';
- })
- .catch(error => {
- results.innerHTML = '<div class="section error"><h3>Test Failed: ' + sizeKB + 'KB</h3><p>' + error.message + '</p></div>';
- });
- }
- </script>
- </body>
- </html>
- <?php
- function return_bytes($val) {
- $val = trim($val);
- $last = strtolower($val[strlen($val)-1]);
- $val = (int)$val;
- switch($last) {
- case 'g':
- $val *= 1024;
- case 'm':
- $val *= 1024;
- case 'k':
- $val *= 1024;
- }
- return $val;
- }
- function getUploadErrorMessage($errorCode) {
- switch ($errorCode) {
- case UPLOAD_ERR_INI_SIZE:
- return 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
- case UPLOAD_ERR_FORM_SIZE:
- return 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
- case UPLOAD_ERR_PARTIAL:
- return 'The uploaded file was only partially uploaded';
- case UPLOAD_ERR_NO_FILE:
- return 'No file was uploaded';
- case UPLOAD_ERR_NO_TMP_DIR:
- return 'Missing a temporary folder';
- case UPLOAD_ERR_CANT_WRITE:
- return 'Failed to write file to disk';
- case UPLOAD_ERR_EXTENSION:
- return 'A PHP extension stopped the file upload';
- default:
- return 'Unknown upload error';
- }
- }
- ?>
|