diff --git a/hifi/.htaccess b/hifi/.htaccess index 52d6f9c..f7802f0 100644 --- a/hifi/.htaccess +++ b/hifi/.htaccess @@ -22,6 +22,34 @@ RewriteBase / # Upload mit "Methode nicht erlaubt" fehlschlägt. DirectorySlash Off +# Groessere Upload-/POST-Limits fuer den Daten-Export/-Import im Admin-Bereich +# (der Export bettet die Bildergalerie als Base64 direkt in die JSON-Datei ein, +# das kann schnell 40+ MB werden - PHPs Standard-Limits liegen oft niedriger). +# Nur relevant, wenn PHP als Apache-Modul laeuft (mod_php) - die IfModule-Pruefung +# sorgt dafuer, dass dieser Block auf FastCGI/PHP-FPM-Hosting (dort greift +# stattdessen api/public/.user.ini) folgenlos uebersprungen wird, statt einen +# "Invalid command"-Fehler fuer die ganze Seite auszuloesen. + + php_value upload_max_filesize 200M + php_value post_max_size 200M + php_value memory_limit 512M + + + php_value upload_max_filesize 200M + php_value post_max_size 200M + php_value memory_limit 512M + + + php_value upload_max_filesize 200M + php_value post_max_size 200M + php_value memory_limit 512M + + + php_value upload_max_filesize 200M + php_value post_max_size 200M + php_value memory_limit 512M + + # API-Requests an den PHP-Front-Controller weiterleiten RewriteCond %{REQUEST_URI} ^/api/ RewriteCond %{REQUEST_FILENAME} !-f diff --git a/hifi/api/public/.user.ini b/hifi/api/public/.user.ini new file mode 100644 index 0000000..167ddca --- /dev/null +++ b/hifi/api/public/.user.ini @@ -0,0 +1,8 @@ +; Groessere Upload-/POST-Limits fuer den Daten-Export/-Import im Admin-Bereich +; (der Export bettet die Bildergalerie als Base64 direkt in die JSON-Datei ein, +; das kann schnell 40+ MB werden). Greift auf PHP-FPM/CGI-Hosting (z.B. viele +; Shared-Hosting-Umgebungen) - fuer klassisches Apache-Modul-PHP (mod_php) +; uebernimmt stattdessen der php_value-Block in hifi/.htaccess. +upload_max_filesize = 200M +post_max_size = 200M +memory_limit = 512M diff --git a/hifi/api/src/Controllers/SettingsController.php b/hifi/api/src/Controllers/SettingsController.php index 025baa7..d277fc3 100644 --- a/hifi/api/src/Controllers/SettingsController.php +++ b/hifi/api/src/Controllers/SettingsController.php @@ -70,11 +70,53 @@ class SettingsController exit; } + /** Wandelt eine php.ini-Groessenangabe ("200M", "1G", "512K") in Bytes um. */ + private static function iniBytes(string $value): int + { + $value = trim($value); + if ($value === '') { + return 0; + } + $num = (float) $value; + return match (strtolower(substr($value, -1))) { + 'g' => (int) ($num * 1024 * 1024 * 1024), + 'm' => (int) ($num * 1024 * 1024), + 'k' => (int) ($num * 1024), + default => (int) $value, + }; + } + public static function importData(): void { - if (!empty($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) { + if (!empty($_FILES['file'])) { + $uploadError = $_FILES['file']['error']; + if ($uploadError === UPLOAD_ERR_INI_SIZE || $uploadError === UPLOAD_ERR_FORM_SIZE) { + Http::error( + 'Die Datei überschreitet das Upload-Limit dieses Servers (aktuell ' . ini_get('upload_max_filesize') . + '). Bitte den Hosting-Anbieter um ein höheres PHP-Upload-Limit bitten.', + 422 + ); + } + if ($uploadError !== UPLOAD_ERR_OK) { + Http::error('Datei-Upload fehlgeschlagen (Fehlercode ' . $uploadError . ').', 422); + } $raw = file_get_contents($_FILES['file']['tmp_name']); } else { + // Ein Upload, der post_max_size ueberschreitet, wird von PHP nicht in $_FILES + // aufgenommen - der rohe Body ist ueber php://input aber trotzdem da (nur eben + // noch als unverarbeitetes Multipart-Gemisch, kein gueltiges JSON). Deshalb direkt + // Content-Length gegen das konfigurierte Limit pruefen, statt block auf einen + // (nicht garantiert leeren) Body zu vertrauen - sonst landet eine zu grosse, aber + // eigentlich intakte Export-Datei im irrefuehrenden generischen "ungueltige Datei"-Fehler. + $contentLength = (int) ($_SERVER['CONTENT_LENGTH'] ?? 0); + $maxPost = self::iniBytes((string) ini_get('post_max_size')); + if ($maxPost > 0 && $contentLength > $maxPost) { + Http::error( + 'Die Datei überschreitet das Größen-Limit dieses Servers (aktuell ' . ini_get('post_max_size') . + '). Bitte den Hosting-Anbieter um ein höheres PHP-Upload-Limit (post_max_size) bitten.', + 422 + ); + } $raw = file_get_contents('php://input'); }