lighttp, redirects und rewrites

Wenns mal wieder performant sein muss, ist oft der Griff zu lighty (http://www.lighttpd.net/) ein probates Mittel.

Seine Performance-Vorteile gegenüber dem Apache2 aus der Dose (http://httpd.apache.org/) erreicht der lighttpd unter anderem dadurch, dass er sich das aufwendige Parsen von .htaccess-Files spart. Der Pferdefuß dabei ist allerdings, dass serverseitige rewrites und redirects nichtmehr einfach in ein File im betroffenen Verzeichnis gekippt werden können sondern direkt in die Config von lighttpd geschrieben werden.

Gerade in Verbindung mit einer TYPO3-Umgebung kann der Einsatz von lighttpd als Webserver allerdings schnell zur Herausforderung werden. Seiten werden umbenannt, realurl generiert die Pfade neu und – hoppla, plötzlich gehen natürlich Links, die noch auf den alten Titel verweisen, auf eine 404-Seite oder im schlimmsten Fall komplett ins Leere. Natürlich muss eine Lösung her: die Redirects um dem Browser (und natürlich auch der Suchmaschine) gleich noch mitzuteilen, dass sich die URL geändert hat. Nehmen wir daher ein Beispiel:

Die bisherige Seite „diese-seite-ist-toll.html“ heißt nun „diese-seite-ist-spitze.html“. Links auf http://www.beispielseite.de/diese-seite-ist-toll.html“ führen also ab sofort ins Leere, genau so wie Links, die auf Unterseiten verweisen (z.B. „http://www.beispielseite.de/diese-seite-ist-toll/eine-unterseite.html“). Das Ziel ist also, alle URLs, die „diese-seite-ist-toll“ beinhalten, sollen umgeleitet werden auf „diese-seite-ist-spitze“ und gleichzeitig soll der HTTP-Status „301 – Moved permanently“ gesendet werden, um Browser und Suchmaschine zu sagen, dass die bisherige URL nichtmehr gültig ist. Dazu muss die lighttpd-Konfiguration angepasst werden:

Die Datei lighttpd.conf sieht für TYPO3-Umgebungen mit installierter realurl-Extension i.d.R. bereits einen rewrite-Block vor, der in etwa folgendermaßen aussieht:

url.rewrite-once = (
    "^/(typo3|phpmyadmin/|info/|typo3temp/|typo3conf/|uploads/|fileadmin/|t3lib/|robots\.txt|clear\.gif|favicon\.ico).*$" => "$0",
    "^/$" => "index.php",
    "^typo3$" => "typo3/index_re.php",
    ".html\?([^*]+)" => "index.php?$1",
    ".html$" => "index.php",
    "^([^*]+)\.([^*])+\.html\?([^*]+)$" => "index.php?id=$1&type=$2&$3",
    "^/.*\?([^*]+)" => "index.php?$1",
    "^/.*$" => "index.php"
)

Dazu fügen wir nun den Redirect-Block ein, der folgendermaßen aussieht:

url.redirect-code = 301
url.redirect = (
        "^/diese-seite-ist-toll(/.*|\.html.*)" => "http://www.beispielseite.de/diese-seite-ist-spitze$1",
)

Testet man nun die Funktion, wird man feststellen: es funktioniert nicht. Eine unangenehme Eigenschaft des lighty ist, dass die Reihenfolge, in der Redirects und Rewrites abgearbeitet werden, fest vorgegeben ist, d.h. es ist irrelevant, an welcher Stelle in der Config eine Rewrite- oder Redirect-Direktive eingefügt wird, es werden stets und immer zuerst die Rewrites und dann die Redirects abgearbeitet. Mit diesem Wissen ist es logisch, dass nichts passiert denn der lighty kommt garnicht dazu, die URL zu redirecten.

Abhilfe hierfür schafft man dadurch, dass man die URLs, die umgeleitet werden sollen, von sämtlichen Rewrite-Regeln ausnimmt. In userem Beispiel wäre das die Erweiterung der Direktive „url.rewrite-once durch das Statement

"^/diese-seite-ist-toll(/.*|\.html.*)" => "$0",

Danach lighttpd neu starten und siehe da, der Lighty leitet die fragliche URL um und sendet wie gewünscht vorher den 301-Header.

Schreibe einen Kommentar