mod_rewrite, unterordner und mehr

DeeJTwoK

Erfahrenes Mitglied
Hallo, ich habe ein nettes Problem:

Situation:
Ich mache ein File-Management-System. Alle Scripts/Grafiken/etc, die ich dazu benötige sind in einem Ordner "/var/www/ich/filelisting". Die Dateien/Ordner, die verwaltet werden, liegen NEBEN diesem Ordner auf dem Server.
Greift ein User nun auf eine Datei zu (zB "/var/www/ich/ordner/datei.txt") wird erstmal mittels mod_rewrite zu einem Script (/var/www/ich/filelisting/showfile.php) umgeleitet, das prüft, ob der User berechtigt ist diese Datei zu sehen.
Wenn JA, dann zeige ich diese Datei mit header("Location:...") an.

Problem:
Es scheint so, als wenn die Weiterleitung mittels header(...) die mod_rewrite-Regeln erneut durchlaufen würde, was dann ja zu einer Endlosschleife führt (Fehlermeldung im Firefox: "Fehler: Umleitungsfehler - Die aufgerufene Website leitet die Anfrage so um, dass sie nie beendet werden kann.")
Kann man das überhaupt so machen? Wo liegt da der Fehler?
Also: Warum wird header("Location:..."); durch die rewrite-Rules geschickt, bzw. wie kann man das umgehen?

Mein rewrite-Script (.htaccess) liegt im Ordner /war/www/ich
Code:
RewriteEngine on

# alles was im Verwaltunsordner liegt nicht umschreiben
RewriteRule ^filelisting/(.*)$ filelisting/$1 [L]

# Indexdatei darf natürlich so angezeigt werden
RewriteRule ^index.php$ index.php [L]

# leere Anfrage direkt auf den Ordner soll natürlich im Index enden
RewriteRule ^$ index.php [L]

# alles andere soll an das showfile-Script weitergegeben werden
RewriteRule ^(.*)$ filelisting/showfile.php?file=$1 [L]

Im showfile siehts dann so aus (stark gekürzt, aber hoffentlich nicht weg, was den Fehler ausmacht):
PHP:
<?php

$datei = $_GET["file"];

if (/*ungültige datei*/)
   {
   echo "ungültige datei"
   exit();
   }

if (/*user die rechte hat*/)
   {
   Header("Location:".basename($datei));
   }
else
   {
   //Meldung ausgeben
   }

?>

Kann mir da jemand helfen?
 
Gar nicht, da [phpf]header[/phpf] ja nur eine Weiterleitung auslöst. Diese bleibt aber trotzdem ein neuer HTTP Request und darauf wird wieder die mod_rewrite Rule ausgegeben.

Wie wäre es, wenn du die Datei per [phpf]readfile[/phpf] einliest und mit korrekten Content-Type Definitionen direkt an den User ausgibst?
 
Danke schonmal für die schnelle Antwort!

OK, ich dachte mit halt, dass das ganze bei header() intern gemacht wird und das rewrite-Script nicht noch mal ins Spiel kommt. Pech gehabt. :(
Andere Idee:
Ich leite nicht nach der eigentlichen Datei um, sondern hänge an die datei noch etwas dran, zB "_showme":
PHP:
Header("Location:".basename($datei)."_showme");
Und in bei den Regeln füge ich vor die letzte eine Regel ein, die diese Anfrage abfängt und die Datei selbst anzeigt:
Code:
...
# alle Dateien mit _showme am Ende wirklich anzeigen
RewriteRule ^(.*)_showme$ $1 [L]

# alles andere soll an das showfile-Script weitergegeben werden
RewriteRule ^(.*)$ filelisting/showfile.php?file=$1 [L]
Das geht aber auch nicht. Wobei ich mir auch nicht erklären kann wieso... WIESO?

... und mit korrekten Content-Type ...
Das war auch meine ursprüngliche Idee. Nur wie bestimme ich den Conten-Type (zuverlässig). Und was passiert mit mit php Dateien? Wird dann da der Quellcode angezeigt oder werden die noch geparst!?
 
Nein, [phpf]readfile[/phpf] schreibt direkt in den Ausgabepuffer.

Und leider kenne ich mich mit mod_rewrite nicht wirklich gut aus, weshalb ich dir diese Frage nicht beantworten kann.

Ich vermute du lädst die Daten selber hoch?
Dann könntest du anhand der Dateiendung den Inhalt zu bestimmen. Bei unbekannten Typen immer als plain/text ausgeben, falls es sich um solche Dateien handeln könnte. Falls auch .exe oder .psd oder sonstige Dateien sein könnten, würde ich grundsätzlich als application/octet-stream einen Download erzwingen.
 
Danke, dann muss ich notfalls per Hand den Content-Type bestimmen und die php-Dateien könnte man dann ja direkt mit include() einbinden und sie nicht per readfile() ausgeben.

Schöner/einfacher wäre jedoch irgendwas mit mod_rewrite.
Nochmal für jemanden, der sich vielleicht mehr damit auskennt:
Wenn ich die Lösung mit _showme mache, dann werde ich wieder zu meiner showfile.php weitergeleitet. Wenn ich den Namen der Datei dort ausgebe erhalte ich den Namen ohne _showfile. In der Adresszeile steht natürlich noch der Name mit _showfile.
Sieht also so aus, als wenn erst die vorletzte Regel angewendet würde, danach aber noch die allerletzte, sodass sich eigentlich wieder ein Kreislauf ergibt. Kann es sein, dass das [L] keine Wirkung zeigt.
 
Also ich raffs nicht: Ich habe das Problem jetzt eigentlich minimiert:

Ein Ordner mit folgenden Inhalten:
.htaccess
avatar.jpg
showfile.php


Inhalt der .htaccess:
Code:
RewriteEngine on
RewriteRule ^(.*)_showme$ $1 [L]            #irgendetwas mit _showme am Ende soll ohne das _showme angezeigt werden
RewriteRule ^(.*)$ showfile.php?file=$1 [L] #alles andere soll der showfile.php als Parameter übergeben werden
Inhalt der showfile.php:
PHP:
<?php
header("Location:".$_GET["file"]."_showme");
?>

Tippe ich ...avatar.jpg in die Adresszeile, wird diese auf ...showfile.php_showme geändert und ich bekomme vom Browser eine Fehlermeldung:
Fehler: Umleitungsfehler - Die aufgerufene Website leitet die Anfrage so um, dass sie nie beendet werden kann.

Tippe ich ...showfile.php?file=avatar.jpg ein, lande ich (entsprechend dem anderen Fehler) auch bei ...showfile.php_showme mit gleicher Fehlermeldung.


Warum zeigt das [L] in der .htaccess keine Wirkung?
 
tut mir leid, aber das wird so nicht klappen. du wirst immer wieder in eine schleife fallen!
vollzieh es mal nach:
1. du rufst datei.jpg auf
2. htaccess leitet es auf die php-datei um
3. die php-datei ruft datei.jpg_showme auf
4. htaccess leitet das wieder auf datei.jpg um (wo wir wieder bei punkt1 wären)

mit der showfile.php-datei verfährt htaccess bei deinen regEx genauso, wie mit allen anderen Dateien.
 
tut mir leid, aber das wird so nicht klappen. du wirst immer wieder in eine schleife fallen!
vollzieh es mal nach:
1. du rufst datei.jpg auf
2. htaccess leitet es auf die php-datei um
3. die php-datei ruft datei.jpg_showme auf
4. htaccess leitet das wieder auf datei.jpg um (wo wir wieder bei punkt1 wären)

Bis punkt 3 stimme ich dir zu. dann sollte aber die erste regel greifen, da die datei ja auf _showme endet und danach KEINE WEITEREN REGELN mehr anwendet werden, weil durch das [L] ja gesagt wird das diese eben angewendete regel die Letzte sein sollte.

:( oder?
 
Die interne Verarbeitung sieht etwas anders aus. Aktiviere mal die Protokollierung (siehe RewriteLog- und RewriteLogLevel-Direktiven), um einen detaillierten Einblick zu bekommen, was sich im Hintergrund abspielt.
 
Nach Punkt drei passiert folgendes:
Es wird bei der ersten Umleitung gestoppt auf die Datei selbst umgeleitet -> Aber wenn das dann per htacces überprüft wird, greift wieder die zweite Umleitung.

Lass dir in der php-Datei mal einfach nur die GET-Variable ausgeben. Du wirst sehen, er wirft dich immer wieder zurück an den Anfang!

Ich habs eben selbst mal ausprobiert, ist wirklich knifflig.

EDIT: Sorry, ich habs verbessert! :)
 
Zuletzt bearbeitet:
Zurück