Seite 1 von 1

mod_rewrite RewriteCond: nachgefragt

Verfasst: 26.08.2005, 00:59
von whobee
Hallo,

seit einiger Zeit schlage ich mich mit mod_rewrite herum und habe da so meine Sorgen....

Konkret:
Ich überschreibe Urls in der Form
www.mydomain.de/name1/name2/param1.param2...param9/
in
www.mydomain.de/script.php?p1=param1&p2 ... .p9=param9

Meine Regeln sehen vereinfacht etwa so aus:
RewriteRule ^/name1/name2/(.*)\.(.*)..../$ /script.php?p1=$1&p2=$2....

Ich will aber nicht alle URLs überschreiben und möchte aus Perfomance-und Esthetik-Gründen :-) Requests auf nicht überschriebene php-Scripte gar nicht erst gegen meine Regeln laufen lassen:

RewriteEngine On
RewriteLogLevel 9
RewriteLog "MyLog"

RewriteCond %{SCRIPT_FILENAME} !^/.*\.php\?.*$
RewriteRule ^/name1/.+/(.*)\.(.*)..../$ /script.php?p1=$1&p2=$2.... [L]
RewriteRule ^/name2/.+/(.*)\.(.*)..../$ /script.php?p1=$1&p2=$2....[L]
...

(Die Regeln tippse ich gerade so zusammen, man möge Syntax-Fehler nachsehen ... )

Wenn ich mir MyLog ansehe,entdecke ich: (Request: /newscript.php?foo=bar)

[inital] init Rewrite engine with requested uri /newscript.php
[inital] applying pattern <patten1> to uri /newscript.php
[inital] applying pattern <patten2> to uri /newscript.php
....
(alle Regeln werden durchgenudelt!)
passthru /newscript.php
(und das ganze nocheinmal (redir#1)
[inital/redir#1] init Rewrite engine with requested uri /newscript.php
[inital/redir#1] applying pattern <patten1> to uri /newscript.php
[inital/redir#1] applying pattern <patten2> to uri /newscript.php
....

Was ist mit meiner RewriteCond???????

Der Dokumentation entnehme ich:
Precede a RewriteRule directive with one or more RewriteCond directives. The following rewriting rule is only used if its pattern matches the current state of the URI and if these additional conditions apply too.

Heisst das, es geht nur *eine* Regel nach einer RewriteCond?
Kann ich durch (m)eine RewriteCond gar nicht verhindern, daß die Regeln angewandt werden?
Wie kann ich es schaffen, das mod_rewrite bei uri newscript.php?... schon vorher quasi abbiegt?

Wann wird den die Bedingung geprüft? Habe jetzt schon einige Zeit rumgeforscht und es sieht so aus, als würden meinen Bedingungen überhaupt nicht ziehen %-( und langsam geht mir die Zeit aus....

Was mache ich falsch?
Wo ist mein Denk- oder Konzeptionsfehler?
kann mir hier jemand weiterhelfen?

Bin für jeden Rat dankbar...
Viele Gruhuß
whobee

p.s. Kennt jemand eine verständliche Docu zu mod_rewrite???? ;-)

Verfasst:
von

Hochwertiger Linkaufbau bei ABAKUS:
  • Google-konformer Linkaufbau
  • nachhaltiges Ranking
  • Linkbuilding Angebote zu fairen Preisen
  • internationale Backlinks
Wir bieten Beratung und Umsetzung.
Jetzt anfragen: 0511 / 300325-0

mod_rewrite RewriteCond: nachgefragt

Verfasst: 26.08.2005, 08:50
von Caterham
-> Die Condition bezieht sich immer nur auf die aktuelle Rule, du musst also

Code: Alles auswählen

RWCond %&#123;HTTP_HOST&#125; ^aa
RWRule ^ab /cd &#91;L&#93;
RWCond %&#123;HTTP_HOST&#125; ^aa
RWRule ^de /fg &#91;L&#93;
notieren
-> Das Processing ist Pattern der RewriteRule -> Condition(s) -> Substitution; also nicht Condition -> Pattern Rule -> Substitution - auch wenn das Zeilenmäßig gesehen in der .htaccess anders aussieht. Darum kann die Cond. auch nur ausgeführt werden, wenn der Pattern der Rule matched.
(und das ganze nocheinmal (redir#1)
Dann nutzt du das in .htaccess-Dateien.
SCRIPT_FILENAME
Besser immer hier REQUEST_URI
RewriteRule ^.+\.(php|gif|jpg|css)$ - [L]

RewriteRule ^name1/.+/(.*)\.(.*)..../$ /script.php?p1=$1&p2=$2.... [L]
RewriteRule ^name2/.+/(.*)\.(.*)..../$ /script.php?p1=$1&p2=$2....[L]
Kennt jemand eine verständliche Docu zu mod_rewrite
Die umfassendste Quelle ist immer noch die Apache manual.

-> www.modrewrite.de

Grüße
Robert

mod_rewrite RewriteCond: nachgefragt

Verfasst: 26.08.2005, 10:59
von whobee
Die Condition bezieht sich immer nur auf die aktuelle Rule....

Das Processing ist Pattern der RewriteRule -> Condition(s) -> Substitution; also nicht Condition -> Pattern Rule -> Substitution - auch wenn das Zeilenmäßig gesehen in der .htaccess anders aussieht. Darum kann die Cond. auch nur ausgeführt werden, wenn der Pattern der Rule matched.
Das erklärt einiges! Eigentlich alles!!!!
(und das ganze nocheinmal (redir#1)
Dann nutzt du das in .htaccess-Dateien.
Hm... ich habe meine Regeln alle direkt in die httpd.conf geschrieben.....
Mir ist das interne Proccessing von mod_rewrite einfach noch nicht klar: Was/Warum passiert redir1#?
Besser immer hier REQUEST_URI
Erfahrungswert?
Mit REQUEST_URI klappt es tatsächlich gleich deutlich besser....

Vielen Vielen Dank, Robert, deine hints haben mich ein gutes Stück weitergebracht.
Vor allem
RewriteRule ^.+\.(php|gif|jpg|css)$ - [L]
tut genau das, was ich wollte und jetzt (bis jetzt) kann ich eigentlich auf meine RewriteConds verzichten. :D

Viele Grüße
whobee

Verfasst:
von
SEO Consulting bei ABAKUS Internet Marketing
Erfahrung seit 2002
  • persönliche Betreuung
  • individuelle Beratung
  • kompetente Umsetzung

Jetzt anfragen: 0511 / 300325-0.


mod_rewrite RewriteCond: nachgefragt

Verfasst: 26.08.2005, 13:04
von Caterham
Hm... ich habe meine Regeln alle direkt in die httpd.conf geschrieben.....
Innerhalb oder außerhalb von <Directory>-Containern? Es müsste innerhalb eines solchen <Directory>...</Directory>-Abschnitts stehen. Das ist der sog. per-dir-Context. Das rewriting findet also erst auf der Verzeichnisebene statt.
Was/Warum passiert redir1#?
Das liegt an dem Zeitpunkt. In diesem Verarbeitungsschritt auf der Verzeichnisebene ist es bereits zu spät noch auf andere Sachen zu reagieren, bspw. kann deine neue URL (in deinem Beispiel /script.php) ja zu einem 404 führen. Dass kann nach dem ersten Durchlauf (wg. des fortgeschrittenen Stadiums im processing) aber nicht mehr erkannt werden. Darum wird alles noch einmal durchlaufen. Dabei wird nicht nur mod_rewrite ein zweites mal durchlaufen, sondern das betrifft alle Module (sonst könnte ein z.B. 404 ja nicht festgestellt werden).

Anders sieht die Sache im sog. per-server context aus, also innerhalb von <Virtualhost>...</Virtualhost> und in der Main Server Config-Section in der httpd.conf (aber wie gesagt außerhalb von <Directory>, <Location> und sonstigen per-directory Abschnitten). Dort (<Virtualhost> und main server config section) ist das Processing noch nicht auf der Verzeichnisebene angekommen, sodass ein zweiter Durchlauf nicht nötig ist. Daher ist u.a. der per-server Conntext vorzuziehen (wenn man die Möglichkeit hat).

Ein kleiner Unterschied in der Syntag des RewriteRule Patterns:
im per-server conntext beginnt dieser immer mit einem führenden Slash - also
RWRule ^/abc/def /index.php [L]
im per-dir-Context (normal) ohne Slash (1und1 ist da eine Ausnahme)
RWRule ^abc/def /index.php [L]
Erfahrungswert?
Mit REQUEST_URI klappt es tatsächlich gleich deutlich besser....
Es vermeidet Fehler bei der RegEx, man kann sie auch "spezieller" notieren, also ^/abc/.+\.php$ statt /abc/.+\.php (oder gar ^/var/ww/htdocs/abc/.+\.php$), wo (bei der 2. regEx) nach vorhe hin alles "offen" ist. Das läuft langsamer.
REQUEST_FILENAME (das ist identisch SCRIPT_FILENAME) enthält ja den physischen lokalen Pfad der Datei, REQUEST_URI nur die URL (ohne fqdn, also https://www.xy.de).

Mit dem Konstrukt
RewriteRule ^.+\.(php|gif|jpg|css)$ - [L]
über allen anderen Regeln kannst du ja auch bestimmte Dateien ausschließen (wichtig eben dabei ist, dass es über den Regeln steht, die dann nicht mehr durchlaufen werden sollen. Natürlich kann man das auch wieder über Conditions machen, die dann prüfen, ob die Datei wirklich existiert (hier wird -das ist die einzige Stelle- zwangsweise REQUEST_FILENAME als Variable benötigt

Code: Alles auswählen

# ...der physische Pfad ist eine existierende Datei...
RewriteCond %&#123;REQUEST_FILENAME&#125; -f &#91;OR&#93;
# ... oder ein existierendes Verzeichnis
RewriteCond %&#123;REQUEST_FILENAME&#125; -d
# "do nothing &#40;no substitution&#41;" und Last rule
RewriteRule ^.* - &#91;L&#93;
Das läuft natürlich wesentlich langsamer. Zuerst springt jeder Request auf ^.* an, dann wird die 1. Cond. geprüft, dann die zweite und erst dann (wenn beide wahr sind) wird abgebrochen)

mod_rewrite RewriteCond: nachgefragt

Verfasst: 26.08.2005, 21:27
von whobee
Innerhalb oder außerhalb von <Directory>-Containern? Es müsste innerhalb eines solchen <Directory>...</Directory>-Abschnitts stehen. Das ist der sog. per-dir-Context. Das rewriting findet also erst auf der Verzeichnisebene statt.
Definitv außerhalb eines Directory-Containers.. ? zumindest außerhalb einer Directory-Directive, innerhalb einer Virt-Hosts.

Ich habe allerdings eine Directory-Direktive in meinem Vhost in der Art

<Directory "mydocumentroot">
Options all
Order allow,deny
allow from all
AllowOverride None
</Directory>

wohl wegen der httpd.conf Dir-Directive
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>

(default , "first we configure the default to be very restrictiv"...)

meine Regeln stehen aber nicht innerhalb dieser Directive.
im per-server conntext beginnt dieser immer mit einem führenden Slash - also
RWRule ^/abc/def /index.php [L]
im per-dir-Context (normal) ohne Slash (1und1 ist da eine Ausnahme)
RWRule ^abc/def /index.php [L]
Das hängt offensichtlich vom Provider ab? Meine Regeln beginnen alle mit
^/.. (mal von der neuen
^.+\.(php|gif|jpg|css)$ - [L]
abgesehen... :D

Ich habe alle Rechte auf den Servern und kann mir den Kontext auch aussuchen. Sofort habe ich ein wenig rumgeforscht und meinen vhosts und die Main-Server-Konfig durchgegraben: So wie ich es verstehe, befinde ich mich außerhalb eines Directory-Kontextes (und davon bin ich eigentlich auch immer ausgegangen), trotzdem redir#1 ... :-?

Ein bisschen unsicher bin ich schon wegen meiner Main-Server-Konfig und habe bei apache.org noch einmal nachgelesen: Die VHost Directiven überschreiben die Dir-Direktiven der Main-Server-Konfig aber ich habe nichts gefunden, ob ich im VHost die MS-Konfig <Directory> irgendwie erbe...

.. Habe es auch gerade ausprobiert und die Main-Server-Direktive entfernt: Hilft auch nicht gegen redir#1 :( :(
Das liegt an dem Zeitpunkt. In diesem Verarbeitungsschritt auf der Verzeichnisebene ist es bereits zu spät noch auf andere Sachen zu reagieren, bspw. kann deine neue URL (in deinem Beispiel /script.php) ja zu einem 404 führen. Dass kann nach dem ersten Durchlauf (wg. des fortgeschrittenen Stadiums im processing) aber nicht mehr erkannt werden. Darum wird alles noch einmal durchlaufen. Dabei wird nicht nur mod_rewrite ein zweites mal durchlaufen, sondern das betrifft alle Module (sonst könnte ein z.B. 404 ja nicht festgestellt werden).

So gut kenne ich die apache/mod_rewrite-Implementierung nicht :D , aber offensichtlich müssen im Directory-Context nochmal alle Module durchlaufen werden, um die 404-Kurve zu noch kriegen...? Man lernt ja nie aus...
Es vermeidet Fehler bei der RegEx, man kann sie auch "spezieller" notieren, also ^/abc/.+\.php$ statt /abc/.+\.php (oder gar ^/var/ww/htdocs/abc/.+\.php$), wo (bei der 2. regEx) nach vorhe hin alles "offen" ist. Das läuft langsamer.

/var/ww/htdocs/abc/ doch als relativer Pfad (zu DocumentRoot), oder? Ich denke ja, sicher ...
Natürlich kann man das auch wieder über Conditions machen, die dann prüfen, ob die Datei wirklich existiert (hier wird -das ist die einzige Stelle- zwangsweise REQUEST_FILENAME als Variable benötigt
Ich bin beindruckt! Du beschäftigst dich ganz offenbar schon länger mit der Materie!
Die erste Variante finde ich aber deutlich eleganter, die "-" Notation für "no substitution" war mir allerdings nicht geläufig (habe gerade nochmal gekuckt: Ist natürlich dokumentiert! Wie muß ich denn die Doku noch lesen?? )

Noch einmal herzlichen Dank für deine Mühen und deine sehr kompetenten Infos, mir gehen wirklich Welten auf !!!!

Viele Grüße
whobee