svalavuo 1 місяць тому
батько
коміт
75fe96236e
1 змінених файлів з 272 додано та 0 видалено
  1. 272 0
      admin/upload_diagnostic.php

+ 272 - 0
admin/upload_diagnostic.php

@@ -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';
+    }
+}
+?>