Wie WordPress Permalinks verarbeitet
Durch Permalinks bekommen Artikel und Seiten lesbare URLs und auch Struktur. Alle Artikel in der Kategorie ‚Wordpess‘ können mit schnurpsel.de/themen/wordpress/ aufgerufen werden, das Monatsarchiv für Juli 2010 mit schnurpsel.de/date/2010/07/.
Auf dem Webserver existiert aber kein Verzeichnis /themen/wordpress/ oder /date/2010/07/. Damit die Seiten trotzdem aufgerufen werden können, erstellt WordPress eine einfache Regel für das Rewrite-Modul des Apache-Webservers:
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L]
Diese drei Zeilen führen dazu, das alles, was nicht tatsächlich als Datei oder Verzeichnis auf dem Server existiert, einfach an die index.php von WordPress durchgereicht wird. WordPress kümmert sich nun darum, ob es z.B. eine Kategorie „WordPress“ gibt, stellt die Liste mit den passenden Artikeln zusammen und gibt sie aus.
Was es alles nicht gibt
Im Moment sind wohl mal wieder ein paar Bots oder Skriptkiddies unterwegs, die einfach versuchen, irgendwelche php-Skripte aufzurufen, um mögliche Sicherheitslücken ausnutzen zu können. Das sieht dann etwa so aus:
/scripts/setup.php /pma/scripts/setup.php /phpMyAdmin/scripts/setup.php /phpmyadmin/scripts/setup.php /myadmin/scripts/setup.php
Solche Dateien gibt es hier allerdings nicht. Auch andere Sachen können zu fehlerhaften Aufrufen führen, z.B. Standard-Icons wie favicon.ico oder apple-touch-icon.png, die manche Browser einfach aufrufen oder durch Nutzer aus der Bildersuche falsch kopierte BILd-URLs.
Durch die für die Permalinks notwendigen mod_rewrite-Regeln werden alle dies Aufrufe nun an WordPress weitergeleitet. WordPress wird geladen, stellt eine Datenbankverbingung her, klappert die internene Rewriteregeln ab um schließlich nur festzustellen, daß es mit dem Aufruf nichts anfangen kann. Dann gibt WordPress schließlich auch nur eine Fehlerseite aus, die möglicherweise auch noch aufwändig gestaltet ist und unnötig viel Daten als Antwort zurücküberträgt.
WordPress und den Webserver entlasten
Damit nun nicht WordPress wegen jeder Kleinigkeit behelligt werden, kann man eine spezielle Regel der WordPress-Regel vorschalten, die einfach gegebenfalls die Abarbeitung der Rewrite-Regeln beendet:
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule \.[^\.]+$ - [L] </IfModule>
Die Idee dabei ist, daß alle Permalink-URLs normalerweise keine Dateierweiterung wie .html, .jpg oder .php haben. Falls nun eine Datei nicht existiert (RewriteCond) und diese Datei mit einem Punkt und mindestens einem weiteren Zeichen endet, wird die Abarbeitung der Regeln an dieser Stelle beendet (RewriteRule). Diese Zeilen müssen vor den WordPress-Regeln stehen.
WordPress bekommt diese Aufrufe nicht mehr zu sehen, der Fehler wird einfach vom Webserver behandelt. Hier kommt dann auch eine konfigurierte und vorhanden benutzerdefinierte Fehlerseite zu Anwendung.
Ich weiß, es gibt auch Blogger, die aus welchen Gründen auch immer, die Permalinks mit einem abschließenden .html konfiguriert haben. Aber auch das ist kein Problem, es muß nur eine Zeile hinzugefügt werden, welche die Regel für die Endung .html (oder eine andere) ungültig macht:
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !\.html$ RewriteRule \.[^\.]+$ - [L] </IfModule>
Optimierte Version
Mann kann die zusätzlichen Bedingungen auch direkt in die WordPress-Rules einfügen. Nachteil hierbei ist aber, daß sie bei Änderungen an den Permalinkeinstellungen verloren gehen, weil WordPress den Block zwischen # BEGIN WordPress und # END WordPress neu schreibt:
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !\.[^\.]+$ RewriteRule . /index.php [L] </IfModule> # END WordPress
Die Version mit Endung .html:
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !\.[^\.]+$ [OR] RewriteCond %{REQUEST_URI} \.html$ RewriteRule . /index.php [L] </IfModule> # END WordPress
Plugin-Version
Angeregt durch die Kommentare von Ralf habe ich nun eine Plugin-Version fertig gestellt.
Download: 123 Rewrite Error 0.10
Das Plugin schreibt die Regeln beim Aktivieren, Deaktivieren und bei Änderungen an der Permalinkstruktur wie bei der Optimierten Version beschrieben automtisch mit den WordPress-RewriteRules in die .htaccess. Dabei wird auch gleich berücksichtigt, ob in der Permalinkstruktur eine Erweiterung wie .html angegeben wurde.
Fazit
Wieviel Serverlast oder Traffic durch diese Maßnahme eingespart wird, kann ich nicht sagen. Das hängt sicher auch vom Nutzungsprofil und der Konfiguration der Website ab. Aber warum sollte man solch eine einfache Möglichkeiten auslassen, um WordPress und dem Webserver das Leben ein bißchen leichter zu machen.