|
|
@@ -0,0 +1,272 @@
|
|
|
+<?php
|
|
|
+/**
|
|
|
+ * Upload Diagnostic Script
|
|
|
+ * Helps identify what's limiting file uploads
|
|
|
+ */
|
|
|
+
|
|
|
+// 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();
|
|
|
+
|
|
|
+?>
|
|
|
+<!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
|
|
|
+// Handle test upload
|
|
|
+if (isset($_GET['action']) && $_GET['action'] === 'test' && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
|
+ 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;
|
|
|
+}
|
|
|
+
|
|
|
+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';
|
|
|
+ }
|
|
|
+}
|
|
|
+?>
|