HifiPlanet-Website/hifi/.htaccess
Maaxxs a9aea99028 Fix data export/import: PHP's default upload limits rejected real exports
Root cause: the export embeds the whole gallery as base64 directly in the
JSON (that's how it stays a single self-contained file), which pushes a
realistic export well past 40MB. PHP's post_max_size/upload_max_filesize
default to values well under that on most hosting, so the browser's
upload got silently discarded before the app ever saw it - PHP clears
$_FILES and $_POST once post_max_size is exceeded, and the leftover raw
body in php://input is unparsed multipart data, not JSON, so it fell
into a generic "invalid file" 422 with no indication of what actually
went wrong. Reproduced locally with a real ~43MB export against the
previous 40M limit.

Raises the limits to 200M via two paths, since we don't know which PHP
SAPI the various hosting targets (All-Inkl, the Plesk test server) use:
hifi/.htaccess sets php_value overrides for classic Apache module PHP,
guarded by <IfModule> checks for several common module names so hosts
running PHP-FPM/CGI (which ignore php_value and would otherwise choke on
an unrecognized directive) skip the block instead of 500ing the entire
site; hifi/api/public/.user.ini covers exactly that FPM/CGI case, which
mod_php hosts in turn simply don't read.

Also makes SettingsController::importData() detect an oversized upload
by comparing Content-Length against the configured post_max_size, and
report the actual limit instead of the generic corrupt-file message -
so if some host's real limit is still too low, the admin sees why
instead of a dead end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 00:54:34 +02:00

64 lines
2.6 KiB
ApacheConf

RewriteEngine On
RewriteBase /
# Lang-lebiger Cache fuer gehashte Build-Assets (Vite haengt bei jeder Aenderung einen
# neuen Hash an den Dateinamen) und hochgeladene Bilder (bekommen beim Upload einen
# zufaelligen Dateinamen) - beide aendern sich unter derselben URL nie, "immutable" ist
# hier also sicher. Ueber mod_headers statt mod_expires, da Letzteres nicht ueberall
# aktiviert ist.
<IfModule mod_headers.c>
<FilesMatch "\.(js|css|woff2?|ttf|eot)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
<FilesMatch "\.(jpg|jpeg|png|webp|avif|gif|svg|ico|mp4|webm)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
</IfModule>
# Ohne dies leitet Apache (mod_dir) Anfragen an /api/uploads mit einem 301 auf
# /api/uploads/ um, bevor mod_rewrite greifen kann - weil api/uploads/ als
# echtes Verzeichnis existiert. Bei einem POST mit Datei-Upload geht dabei der
# Body verloren (der Browser sendet den redirect als GET nach), wodurch der
# 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.
<IfModule mod_php.c>
php_value upload_max_filesize 200M
php_value post_max_size 200M
php_value memory_limit 512M
</IfModule>
<IfModule php_module>
php_value upload_max_filesize 200M
php_value post_max_size 200M
php_value memory_limit 512M
</IfModule>
<IfModule php7_module>
php_value upload_max_filesize 200M
php_value post_max_size 200M
php_value memory_limit 512M
</IfModule>
<IfModule php8_module>
php_value upload_max_filesize 200M
php_value post_max_size 200M
php_value memory_limit 512M
</IfModule>
# API-Requests an den PHP-Front-Controller weiterleiten
RewriteCond %{REQUEST_URI} ^/api/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^api/(.*)$ api/public/index.php [QSA,L]
# Dynamische sitemap.xml (DB-generiert)
RewriteRule ^sitemap\.xml$ api/public/sitemap.php [L]
# Alles andere: SPA-Fallback auf index.html (React Router übernimmt das Routing)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [QSA,L]