Hallo miteinander,
hier geht es darum, dass man mit der .htaccess aus Contao 2.11 nicht mehr auf Verzeichnisse zugreifen kann – und wie man das Problem löst.
In der alten .htaccess(.default) steht noch folgendes:
Code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Das bedeutet so viel wie: Die folgenden Regeln nur ausführen, falls die angefragte Ressource weder eine im Dateisystem vorhandene Datei noch ein vorhandenes Verzeichnis ist.
Anders ausgedrückt: Rufe ich domain.tld/foo.jpg auf und existiert die datei foo.jpg wird diese ausgegeben und keine weiteren Regeln ausgeführt. Selbiges gilt für das Verzeichnis domain.tld/bar, falls /bar existiert.
In der .htaccess(.default) von Contao 2.11 steht nun aber
Code:
<FilesMatch "\.(png|gif|jpe?g|js|css|ico|php|xml|csv|txt|gz|swf|flv|eot|woff|svg|ttf|htm)$">
RewriteEngine Off
</FilesMatch>
Dazu steht in der Changelog
[...]In this context, the default .htaccess file has been improved and should now
execute faster and produce less overhead.
Ein bisschen was steht auch hier https://github.com/contao/core/issues/3930
So weit so gut, macht Sinn. Der Parser schaut nur, ob eine Datei mit entsprechender Dateiendung angefordert wird und schaltet bei einem Match die RewriteEngine aus, damit keine Regeln mehr ausgeführt werden. Das geht (vermutlich) scheller, weil nicht im Dateisytem nachgeschaut werden muss, ob die Datei existiert.
ABER:
Was ist mit Verzeichnissen? Diese werden immer an Contao weitergereicht und von diesem dann natürlich nicht als Ressource innerhalb Contaos gefunden.
Ich konnte nicht mal domain.tld/contao aufrufen sondern musste domain.tld/contao/index.php öffnen, da Letzteres nach oberer Regel nicht weitergereicht wird - finde ich etwas unschön. Außerdem habe ich noch Piwik mit in das Verzeichnis installiert, was natürlich auch nicht mehr aufgerufen werden konnte. (Contao liegt direkt im Document-Root, also zwangsläufig alle anderen Verzeichnisse auch dort, gab bisher keinerlei Probleme).
Für's erste habe ich die .htaccess für mich folgendermaßen gefixt:
Code:
##
# Do not rewrite requests for static files or folders such as style sheets,
# images, movies or text documents. Do not add the URL suffix here!
##
<FilesMatch "\.(png|gif|jpe?g|js|css|ico|php|xml|csv|txt|gz|swf|flv|eot|woff|svg|ttf|htm)$">
RewriteEngine Off
</FilesMatch>
RewriteCond %{REQUEST_FILENAME} !-d
##
# By default, Contao adds ".html" to the generated URLs to simulate static
# HTML documents. If you change the URL suffix in the back end settings, make
# sure to change it here accordingly!
#
# RewriteRule .*\.html$ index.php [L] # URL suffix .html
RewriteRule .* index.php [L] # No URL suffix
# RewriteRule .*\.txt$ index.php [L] # URL suffix .txt
Jetzt muss der Server zwar bei jeder Anfrage (bei der die RewriteEngine nicht mit der Regel darüber abgeschaltet wird) wieder ins Dateisystem schauen, ob das Verzeichnis existiert und ist daher unmerklich (aber bestimmt messbar) langsamer, dafür kann ich aber wieder auf meine Verzeichnisse zugfreifen und auch domain.tld/contao ohne die angabe der index.php öffnen. Neu angelegte Verzeichnisse werden automatisch erkannt. Vorsicht ist geboten, wenn man Verzeichnisse so nennt, wie die virtuellen Verzeichnisse in Contao heißen, denn dann haben auch die echten Verzeichnisse Vorrang.
Alternative
Damit der Server nicht im Dateisystem nachschauen muss, kann man die Pfade auch manuell in die .htaccess eintragen. Da DirectoryMatch leider nur in der Server- und VirtualHost-Config geht, habe ich es mit einer normalen RewriteCond und REQUEST_URI gelöst:
Code:
# Do not rewrite requests for static files or folders such as style sheets,
# images, movies or text documents. Do not add the URL suffix here!
##
<FilesMatch "\.(png|gif|jpe?g|js|css|ico|php|xml|csv|txt|gz|swf|flv|eot|woff|svg|ttf|htm)$">
RewriteEngine Off
</FilesMatch>
RewriteCond %{REQUEST_URI} !^(/((contao)|(piwik))/)$
##
# By default, Contao adds ".html" to the generated URLs to simulate static
# HTML documents. If you change the URL suffix in the back end settings, make
# sure to change it here accordingly!
#
# RewriteRule .*\.html$ index.php [L] # URL suffix .html
RewriteRule .* index.php [L] # No URL suffix
# RewriteRule .*\.txt$ index.php [L] # URL suffix .txt
Das hat nach ersten Tests funktioniert, ich bin mir aber nicht sicher, ob es 100%ig richtig ist. Weiß da jemand mehr dazu?
Idee dahinter: in %{REQUEST_URI} steht die Browseranfrage ohne Host und ohne Parameterstring, also nur der gesuchte Pfad zur Datei bzw. zum Verzeichnis. Dieser wird mit dem Regulären Ausdruck ^(/((contao)|(piwik))/)$ mit meinen Verzeichnisnamen verglichen. ^ und $ beschränken den Ausdruck, dass %{REQUEST_URI} mit dem Verzeichnisnamen anfängt und auch aufhört, also genau diesem entspricht und nicht auch z.B. /foo/bar/contao gefunden wird. Das Ausrufezeichen negiert die Bedingung. Wir wollen die folgenden RewriteRules ja nur ausführen, wenn es sich NICHT um eines unserer Verzeichnisse handelt.
Wer nur das Verzeichnis /contao will, ersetzt die Zeile dadurch:
Code:
RewriteCond %{REQUEST_URI} !^/contao/$
Wer mehrere Verzeichnisse hat, kann das obige Beispiel einfach erweitern:
Code:
RewriteCond %{REQUEST_URI} !^(/((contao)|(piwik)|(foo)|(bar)|(bla)|(blubb))/)$
Ich hoffe, ich konnte dem ein oder anderen damit helfen. Sollten jemandem Lücken / Fehler in meinen Ausführungen auffallen, bitte ich um Korrektur. Fragen werde ich natürlich nach bestem Wissen und Gewissen beantworten.
Grüße, Elch
Lesezeichen