Schrift
[thread]3108[/thread]

mod_rewrite und logische Fallunterscheidung



<< |< 1 2 >| >> 16 Einträge, 2 Seiten
cbxk1xg
 2004-04-16 16:31
#30685 #30685
User since
2003-10-20
496 Artikel
BenutzerIn
[default_avatar]
Hallo an alle!

Es geht um folgendes: Ich habe ein CMS (in Perl) welches Template- und Contentdateien zusammensetzt und diese dann als HTML-Dateien in einem Cache-Verzeichniss ablegt. Das soll aber nur passieren wenn die Datei nicht bereits im Cache liegt. Meine "geniale" Idee war nun, dass ich "mal eben schnell" ein mod_rewrite ruleset schreibe.

Nachdem ich die Doku von Apache gelesen und diverse Foren durchstöbert habe, bin ich nicht wirklich schlauer. Auch die Links im PerlCommunity-Forum führten mich leider nicht zum Ziel.

Die richtige URL zu einem typischen Cachefile ist: http://mydomain.xy/-/Cache/myfile.htm
Die umgeschriebene URL zu einem typischen Cachefile ist: http://mydomain.xy/Cache/myfile.htm - Diese URL wird dann auch öffentlich verlinkt und vom Browser aufgerufen.

Die richtige URL zu einem File, welches nicht im Cache liegt ist: http://mydomain.xy/-/index.pl?PID=myfile - Die Dateien haben KEINE Dateiendung!

Mein großes Problem ist, dass RULE 1 und RULE 2 einzeln funktionieren, aber nicht zusammen. Wenn ich also z.B. RULE 2 lösche, dann wird die Datei aus dem Cache gelesen und wenn ich RULE 1 lösche, dann bekomme ich die Verbindung zum Script. Beides zusammen funktioniert jedoch nicht. Ich habe versucht so etwas wie ein Fallunterscheidung zu programmieren, scheiterte aber kläglich daran. Ich dachte an etwas im Sinne von:

Code: (dl )
1
2
if (datei vorhanden) { Datei aus Cache holen }
else { CMS aufrufen }



Auzug aus meiner .htaccess
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
RewriteEngine on
RewriteBase /-/

# RULE 1: Datei aus Cache holen, wenn diese existiert.
#
RewriteCond %{REQUEST_URI} (.*)\.htm$
RewriteRule (.*)\.htm$ /-/Cache/$1 [L]
#

# RULE 2: Datei über Script holen, wenn diese NICHT exisitiert.
#
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^(.*)\.htm$ /-/?PID=$1 [T=application/x-httpd-cgi,L]
#


Ich könnte das natürlich auch alles irgendwie mit Perl lösen, aber ich denke, dass die Performance doch um ein vielfaches höher sein wird wenn man mod_rewrite benutzt. Außerdem will ich unbedingt eine statische URL vorgaukeln (RULE 2) um die Suchmaschinen nicht zu ärgen.
jan
 2004-04-16 19:42
#30686 #30686
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
bei der ersten prüfst du ja nur, ob der request-uri auf htm endet, nicht jedoch, ob die datei, die da angefragt wurde, auch so existiert. setz doch da noch entsprechend den check dazu, ob existiert (ist das -s? habe lange keine rewriterules mehr geschrieben) und. und beim zweiten setz noch dazu, ob die datei auf htm endet. mehrere Conditions sind per default mit AND verknüpft, meine ich.
dann ist eindeutig entscheidbar, ob die erste oder die zweite ausgeführt werden soll. so ist ein fall denkbar, bei dem zwar htm angefragt wurde, die datei aber nicht existiert, d.h. im grunde werden beide rules aktiviert / sollten aktiviert werden. die erste aber würde wohl zu einem problem werden. umleitung erfolgt, datei /-/irgendwas wird angefragt, die gibs aber nicht. sollte in einem fehler enden. oder habe ich nun alles vollkommen falsch verstanden?
cbxk1xg
 2004-04-16 19:53
#30687 #30687
User since
2003-10-20
496 Artikel
BenutzerIn
[default_avatar]
[quote=jan,16.04.2004, 17:42](...) sollte in einem fehler enden. oder habe ich nun alles vollkommen falsch verstanden?[/quote]
Nein, Du hast es schon richtig kapiert. Die erste Regel soll prüfen ob die htm Datei im Cache existiert und sie ausliefern wenn sie existiert. Und die zweite Regel soll im Falle dessen, dass die erste Regel nicht wirkte da die Datei nicht vorhanden ist, die Datei über das Script ausliefern bzw. das Script aufrufen. Also z.B. Script?PID=gesuchteDatei.

Einzeln funktionieren die Regeln auch, aber halt nur nicht zusammen? Ich probiere noch mal -s in die erste Regel zu integrieren. Mal sehen...

Wie genau verknüpft man denn mehrere Conditions? Ich habe schon nach der korrekten Syntax gesucht, aber nichts passendes gefunden.\n\n

<!--EDIT|cbxk1xg|1082130957-->
jan
 2004-04-16 20:07
#30688 #30688
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
an sich einfach
RewriteCond %{REQUEST_URI} (.*)\.htm$
RewriteCond %{REQUEST_URI} (.*)dateiname
RewriteRule (.*)\.htm$ /-/Cache/$1 [L]

und schon hast du ne verknüpfung. solltest du ein OR wünschen, setzt du das in [] dazwischen.
cbxk1xg
 2004-04-16 20:41
#30689 #30689
User since
2003-10-20
496 Artikel
BenutzerIn
[default_avatar]
Gelten dann die vorgnannten Conditions ausschließlich für die darauf folgende Rule, oder könnten die sich ins gehe kommen mit einer anderen Rule? Z.B. eine bei der keine Conditions existieren, bzw. angegeben wurden?
jan
 2004-04-16 20:52
#30690 #30690
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
nein, sollten nur für die darauf folgende rule gelten.
cbxk1xg
 2004-04-16 21:03
#30691 #30691
User since
2003-10-20
496 Artikel
BenutzerIn
[default_avatar]
Aaah! Ich glaube ich nähere mich langsam der Lösung!

Jetzt hab ich nur noch ein Problemchen... Die URL die ich aufrufe heisst: http://domain.xy/datei0001.htm. Die Datei liegt aber eigentlich hier: http://domain.xy/-/Cache/datei0001.htm.

Wie kann ich jetzt mit -s prüfen ob die Datei existiert? Ich habe es versucht mit:

Code: (dl )
1
2
3
RewriteCond %{REQUEST_URI} (.*)\.htm$
RewriteCond /-/Cache/%{REQUEST_FILENAME} -s
RewriteRule (.*)\.htm$ /-/Cache/$1 [L]


Da findet er aber nix und geht dann weiter zur zweiten Regel. Der Pfad stimmt allerdings.\n\n

<!--EDIT|cbxk1xg|1082137309-->
jan
 2004-04-16 22:12
#30692 #30692
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
ahh, ok, fehler gefunden.
%{REQUEST_FILENAME} enthält den vollen pfad zur datei.
Quote
The full local filesystem path to the file or script matching the request.

das verstehe ich als /home/web/html/hallo.htm als beispiel. wenn du da einfach was davorhängst, geht das natürlich nicht. du müsstest also alles ab dem letzten / auslesen (wäre das
Code: (dl )
.*/([^/]*)$
?) und es dann an /-/Cache/ anhängen...
siehe auch:
http://httpd.apache.org/docs/mod/mod_rewrite.html
http://httpd.apache.org/docs/misc/rewriteguide.html
cbxk1xg
 2004-04-16 22:46
#30693 #30693
User since
2003-10-20
496 Artikel
BenutzerIn
[default_avatar]
[quote=jan,16.04.2004, 20:12]du müsstest also alles ab dem letzten / auslesen (wäre das
Code: (dl )
.*/([^/]*)$
?) und es dann an /-/Cache/ anhängen...[/quote]
Misst, ich hatte mir schon sowas gedacht. Mal wieder RegEx. Meine Lieblingsdisziplin.

etwa so?
Code: (dl )
RewriteCond /-/Cache/.*/([^/]*)$ -s


Ich weiss einfach nicht wo man die RegEx jetzt rein schreibt? In die Cond oder in die Rule?!? Und vor allem mit welcher Syntax. Vielleicht in Klammern? In der Doku finde ich da auch nix passendes. Btw. die Doku ist ja nun wirklich schlimm strukturiert.

Also ich habe jetzt insgesammt folgendes:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Datei aus Cache holen, wenn diese existiert.
#
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{REQUEST_URI} (.*)\.htm
RewriteCond /-/Cache/.*/([^/]*)$ -s
RewriteRule (.*)\.htm$ /-/Cache/$1 [L]
#

# Datei über Script holen, wenn diese NICHT exisitiert.
#
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{REQUEST_URI} (.*)\.htm
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^(.*)\.htm$ /-/?PID=static/$1 [T=application/x-httpd-cgi,L]
#


Ich glaube Du hast Recht. Es wird eindeutig unter einem falschen Pfad nach der Datei gesucht. - Ich glaub ich bin zu doof dazu...\n\n

<!--EDIT|cbxk1xg|1082141580-->
jan
 2004-04-16 23:25
#30694 #30694
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
uhm, jetzt wird mir schlagartig wieder klar, warum ich immer heilfroh war, wenn ich meine rewrite-conditions und -rules fertig habe, alles funktioniert und ich wieder die finger davon lassen kann...
also, mit doku und ein bisschen hoffnung habe ich mir folgendes zusammengereimt:
Code: (dl )
1
2
3
4
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{REQUEST_URI} .*/([^/]+\.htm)$
RewriteCond /-/Cache/%1 -s
RewriteRule .* /-/Cache/%1 [L]

für das prüfen, ob datei im cache. zweite zeile: haben wir ein match auf eventuell-irgendwas (.*), dann einen /, ab jetzt bitte backreferencing an (klammer auf), mindestens ein zeichen aus der gruppe aller zeichen außer / (versuch, den dateinamen zu bekommen), dann einen punkt und htm, jetzt backreferencing ende und das ganze am ende des REQUEST_URI. sollte nun eigentlich in den backreferencing den dateinamen inklusive .htm haben, wenn ich mich nicht irre. also testen wir in der nächsten zeile (3), ob /-/Cache/%1 (%N ist eine backref auf den letzten match in einer RewriteCond, $N ist für das RUle-Matching) existiert - wenn beides zutrifft (d.h. ein dateinamen mit .htm extrahiert werden kann und selber im verzeichnis /-/Cache/ existiert und größer als 0 byte ist (-s)), dann mach einen rewrite von allem .* nach /-/Cache/%1 (nochmal bezug auf oben gematchten dateinamen) und lassen das ganze damit gut sein [L].

bei der zweiten müsste das nun, wenn ich nicht irre, nur
Code: (dl )
1
2
3
4
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{REQUEST_URI} .*/([^/]+\.htm)$
RewriteCond /-/Cache/%1 !-s
RewriteRule .* /-/?PID=static/%1 [T=application/x-httpd-cgi,L]

sein. teste das am besten mal, vielleicht geht's ja in die richtige richtung und ein bisschen ausprobieren sorgt dafür, dass sich das ganze zurechtruckelt ;)\n\n

<!--EDIT|jan|1082143572-->
<< |< 1 2 >| >> 16 Einträge, 2 Seiten



View all threads created 2004-04-16 16:31.