wahsaga: Apache & mod_rewrite: unnötiger Subrequest?

Beitrag lesen

hi,

ich möchte in einem Verzeichnis per RewriteRule Anfragen an ein Script umleiten - aber nur, wenn keine physische Datei existiert, auf die der Request passen würde.

Beispiel:
Datei abc.txt ist vorhanden,
rw.php ist das Script, auf welches umgeleitet werden soll.

Options +MultiViews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-z0-9.-]+)$ rw.php?param=$1 [NS]

Zur Kontrolle des Ablaufs habe ich auch das Rewrite Logging eingeschaltet, auf Level 9.

MultiViews ist aktiviert, weil ich abc.txt auch über /abc erreichen möchte - "funzt" auch.

Wenn ich also /abc anfrage, erhalte ich im Log folgende Einträge:

[rid#13c8bc8/initial] (3) [per-dir j:/web/htdocs/test/rwlog/] strip per-dir prefix: j:/web/htdocs/test/rwlog/abc.txt -> abc.txt
[rid#13c8bc8/initial] (3) [per-dir j:/web/htdocs/test/rwlog/] applying pattern '^([a-z0-9.-]+)$' to uri 'abc.txt'
[rid#13c8bc8/initial] (4) RewriteCond: input='j:/web/htdocs/test/rwlog/abc.txt' pattern='!-f' => not-matched
[rid#13c8bc8/initial] (1) [per-dir j:/web/htdocs/test/rwlog/] pass through j:/web/htdocs/test/rwlog/abc.txt

Die Bedingung, dass dem REQUEST_FILENAME _keine_ physische Datei entsprechen soll, ist ja wenn ich das richtig sehe, _nicht_ erfüllt - bedeutet also, es wurde erkannt, dass zum Request eine Datei existiert, Request wird also durchgereicht - "pass through".

Was mich hierbei aber wundert - wieso kommt "applying pattern" vor der Prüfung der RewriteCond?

Verstehe ich irgendwas fürchterlich falsch, wenn ich annehme, dass die RewriteCond zuerst geprüft werden, und die nachfolgende RewriteRule nur noch ausgewertet werden sollte, wenn die Cond gematched wurde?

So, jetzt zum Testfall, dass keine physische Datei existiert: Ich fordere /xyz an, wird auch korrekt an das Script rw.php durchgereicht - das zeigt mir in der Kontrollausgabe von $_GET an, dass [param] => xyz übergeben wurde.

Das Rewrite Log spuckt dazu folgendes aus:

[rid#13c8bc8/initial] (3) [per-dir j:/web/htdocs/test/rwlog/] strip per-dir prefix: j:/web/htdocs/test/rwlog/xyz -> xyz
[rid#13c8bc8/initial] (3) [per-dir j:/web/htdocs/test/rwlog/] applying pattern '^([a-z0-9.-]+)$' to uri 'xyz'
[rid#13c8bc8/initial] (4) RewriteCond: input='j:/web/htdocs/test/rwlog/xyz' pattern='!-f' => matched
[rid#13c8bc8/initial] (2) [per-dir j:/web/htdocs/test/rwlog/] rewrite xyz -> rw.php?param=xyz

[rid#13c8bc8/initial] (3) split uri=rw.php?param=xyz -> uri=rw.php, args=param=xyz
[rid#13c8bc8/initial] (3) [per-dir j:/web/htdocs/test/rwlog/] add per-dir prefix: rw.php -> j:/web/htdocs/test/rwlog/rw.php
[rid#13c8bc8/initial] (2) [per-dir j:/web/htdocs/test/rwlog/] strip document_root prefix: j:/web/htdocs/test/rwlog/rw.php -> /rw.php
[rid#13c8bc8/initial] (1) [per-dir j:/web/htdocs/test/rwlog/] internal redirect with /rw.php [INTERNAL REDIRECT]

[rid#13cdde0/initial/redir#1] (3) [per-dir j:/web/htdocs/test/rwlog/] strip per-dir prefix: j:/web/htdocs/test/rwlog/rw.php -> rw.php
[rid#13cdde0/initial/redir#1] (3) [per-dir j:/web/htdocs/test/rwlog/] applying pattern '^([a-z0-9.-]+)$' to uri 'rw.php'
[rid#13cdde0/initial/redir#1] (4) RewriteCond: input='j:/web/htdocs/test/rwlog/rw.php' pattern='!-f' => not-matched
[rid#13cdde0/initial/redir#1] (1) [per-dir j:/web/htdocs/test/rwlog/] pass through j:/web/htdocs/test/rwlog/rw.php

OK, bei den ersten vier Zeilen komme ich noch mit - auch wenn ich mich erneut wundere, dass "applying pattern" vor der RewriteCond kommt - das Pattern passt, und die Bedingung, dass zu xyz keine physische Datei existieren soll, ist erfüllt - es erfolgt das Umschreiben auf rw.php?param=xyz.

So, jetzt sollte hier aber m.E. "Feierabend" sein - schließlich habe ich das Flag NS angegeben, "used only if no internal sub-request".
Das wird wohl in den nächsten 4 Zeilen auch korrekt erkannt:
internal redirect with /rw.php [INTERNAL REDIRECT]

Aber warum tauchen jetzt die letzten 4 Zeilen dort auch noch auf?
[rid#13cdde0/initial/redir#1] will mir wohl sagen, dass jetzt für die intern erfolgte Umschreibung die Rewrite-Maschine noch mal angeworfen wird.
Generell ja OK - aber warum verhindert hier das Flag NS das nicht?

gruß,
wahsaga

--
/voodoo.css:
#GeorgeWBush { position:absolute; bottom:-6ft; }