Hinnerk: mode_rewrite

Hi!

Ich leite per mode_rewrite mit folgendem Code Anfragen um:
RewriteRule ^([^/]+).html$ data/site.php?id=$1 [L]

Das funktioniert wunderbar.
Nur wenn die id index heißt, ist die Seite zwar über examle.org/index.html erreichbar, über example.org direkt kommt allerdings ein Error 403.

Kann mir jemand helfen?

  1. Hallo!

    Ich leite per mode_rewrite mit folgendem Code Anfragen um:
    RewriteRule ^([^/]+).html$ data/site.php?id=$1 [L]

    Das funktioniert wunderbar.
    Nur wenn die id index heißt, ist die Seite zwar über examle.org/index.html erreichbar, über example.org direkt kommt allerdings ein Error 403.

    Kann mir jemand helfen?

    Das Problem ist, dass DirectoryIndex (d.h. das automatische 'Zugriff auf Verzeichnis = Zugriff auf index.html') nur funktioniert, wenn die Datei tatsächlich existiert. Tut sie bei Dir jedoch nicht.

    Am einfachsten umgehst Du das, indem Du den Fall, dass das Verzeichnis direkt aufgerufen wird, gesondert behandelst:

    RewriteRule ^$ data/site.php?id=index [L]

    Viele Grüße,
    Christian

    1. Aha, wieder etwas gelernt.
      Jetzt funktioniert es.
      Vielen Dank!

    2. Hi,

      Das Problem ist, dass DirectoryIndex (d.h. das automatische 'Zugriff auf Verzeichnis = Zugriff auf index.html') nur funktioniert, wenn die Datei tatsächlich existiert. Tut sie bei Dir jedoch nicht.

      Am einfachsten umgehst Du das, indem Du den Fall, dass das Verzeichnis direkt aufgerufen wird, gesondert behandelst:

      RewriteRule ^$ data/site.php?id=index [L]

      Ich haett' ja jetzt gesagt, definiere einfach die Datei data/site.php als DirectoryIndex ...

      Wenn diese keinen Parameter bekommt, kann man ja index als Defaultwert annehmen.

      Und den DirectoryIndex als data/site.php?id=index zu definieren, funktioniert IIRC sogar auch.

      MfG ChrisB

      1. Hallo,

        Ich haett' ja jetzt gesagt, [...]

        Es gibt noch weitere Möglichkeiten, z.B. eine leere index.html anzulegen und dann nichts an der bestehenden .htaccess ändern, dann greift die Default-DirectoryIndex-Einstellung, durch das mod_rewrite wird aber nicht die Datei ausgeliefert, sondern die umgeschriebene PHP-Seite.

        Wie heißt es so schön? Viele Wege führen nach Rom.

        Btw. streiche das IIRC in Deinem letzten Absatz, das funktioniert auch tatsächlich. ;-)

        Viele Grüße,
        Christian

        1. gudn tach!

          Es gibt noch weitere Möglichkeiten, z.B. eine leere index.html anzulegen und dann nichts an der bestehenden .htaccess ändern, dann greift die Default-DirectoryIndex-Einstellung, durch das mod_rewrite wird aber nicht die Datei ausgeliefert, sondern die umgeschriebene PHP-Seite.

          kannst du evtl. auch gerade noch zu </archiv/2008/3/t168072/#m1096583> was sagen? ich war mir da naemlich nicht ganz sicher.

          gegeben sind also die zwei zeilen
           RewriteCond %{HTTP_HOST}    ^(www.)?(.*).de
           RewriteRule (.*)          http://www.example.com?a=%2&b=$1   [L]

          wenn man nun verschiedene urls aufruft, bekommt man in der zweiten zeile (scheinbar) inkonsistente ergebnisse:
          http://html-ag.wvs-berlin.de/rewrite/        $1=='/'
          http://html-ag.wvs-berlin.de/rewrite/abc/def $1=='abc/def'
          http://html-ag.wvs-berlin.de/rewrite         $1=='/var/www/vhosts/html-ag.wvs-berlin.de/httpdocs/rewrite'

          wie genau kommt sowas zustande?

          prost
          seth

          1. Hallo seth,

            kannst du evtl. auch gerade noch zu </archiv/2008/3/t168072/#m1096583> was sagen? ich war mir da naemlich nicht ganz sicher.

            Du hast soeben einen Bug im mod_rewrite-Code für Apache 2.0 gefunden! Gratulation! :-)

            http://html-ag.wvs-berlin.de/rewrite/        $1=='/'

            Nein, $1 == '' bei mir, sowohl Apache 2.0 als auch 2.2 und auch der Testserver, den Du angegeben hast:

            christian@cobalt ~ $ curl -I http://html-ag.wvs-berlin.de/rewrite/ 2>/dev/null | grep Location
            Location: http://www.example.com?a=html-ag.wvs-berlin&b=

            Das ist aber auch vollkommen in Ordnung und Konsistent mit dem zweiten:

            http://html-ag.wvs-berlin.de/rewrite/abc/def $1=='abc/def'

            Die dritte Zeile allerdings, die Dein Problem darstellt:

            http://html-ag.wvs-berlin.de/rewrite         $1=='/var/www/vhosts/html-ag.wvs-berlin.de/httpdocs/rewrite'

            Das ist tatsächlich ein Bug!

            wie genau kommt sowas zustande?

            Vorneweg: mod_rewrite SOLL in der Situation (3) gar nicht aktiv werden. Dort soll erst mod_dir aktiv werden, das nach $VERZEICHNIS + / weiterleitet (hier also nach 'http://html-ag.wvs-berlin.de/rewrite/' weitergeleitet werden) und DORT würde erst mod_rewrite aktiv werden. Kommentar dazu im Sourcecode von mod_rewrite:

                /*  
                 *  .htaccess file is called before really entering the directory, i.e.:  
                 *  URL: http://localhost/foo  and .htaccess is located in foo directory  
                 *  Ignore such attempts, since they may lead to undefined behaviour.  
                 */
            

            Nun, was ist passiert?

            Am 29. März 2004 (zu der Zeit war Apache 2.0 schon released, Apache 2.2 aber noch nicht, d.h. trunk/ war aktuell der 2.1/2.2-Entwicklungsstand, branches/APACHE_2_0_BRANCH/ der 2.0er-Entwicklungsstand) wurde in den Apache Trunk ein Patch eingespielt, der bei mod_rewrite irgendwas an der Proxy-Geschichte macht, Revision 103199 (ich müsste mich einlesen, um zu sehen, was genau da eigentlich passiert). Dazu wurde folgende if-Bedingung in den trunk/ eingefügt:

            if (!is_proxyreq) {

            Im Prinzip: Wenn der Request nichts mit Proxy-Requests zu tun hat, dann mach die Überprüfung ob http://localhost/foo aufgerufen wurde (die dann evtl. zum vorzeitigen Abbruch der Verarbeitung führt), ansonsten ist es Dir egal.

            Am 26. August 2004 wurde der Patch auf den 2.0er-Branch backportet, siehe Revision 104840. Dort hat sich dann allerdings ein Fehler eingeschlichen, denn die If-Bedingung lautete nun:

            if (is_proxyreq) {

            Das heißt: Die Überprüfung, die eigentlich für Nicht-Proxy-Requests ausgeführt wird, wird nun nur noch für Proxy-Requests ausgeführt.

            Ist natürlich irgendwie extrem doof. ;-)

            Da der Patch im trunk/ korrekt war, tritt der Bug in Apache 2.2 natürlich nicht mehr auf.

            Workaround

            Du kannst mod_rewrite manuell sagen, dass er Requests an das Verzeichnis ohne / am Ende ignorieren soll. Dazu musst Du eine RewriteCond auf das REQUEST_URI einfügen, z.B. so:

            RewriteCond %{REQUEST_URI} !^/rewrite(\?|$)

            Achja, Du könntest den Bug auch mal melden. Ich bezweifle zwar, dass die Apache-Leute den im Apache 2.0 noch fixen werden (zumal er in 2.2 schon gefixed ist), aber versuchen kann man's mal. Der Testserver liefert allerdings Apache 2.0.53, der ja schon etwas älter ist (2.0.63 ist in der 2.0er-Reihe aktuell), d.h. ob so ein Patch überhaupt etwas bringen würde, ist natürlich die zweite Frage. Bug melden geht hier.

            Viele Grüße,
            Christian

            1. gudn tach!

              http://html-ag.wvs-berlin.de/rewrite/        $1=='/'

              Nein, $1 == '' bei mir, sowohl Apache 2.0 als auch 2.2 und auch der Testserver, den Du angegeben hast

              oops, ja, sorry, hatte ich falsch in erinnerung.

              Die dritte Zeile allerdings, die Dein Problem darstellt:

              http://html-ag.wvs-berlin.de/rewrite         $1=='/var/www/vhosts/html-ag.wvs-berlin.de/httpdocs/rewrite'

              genau.

              Vorneweg: mod_rewrite SOLL in der Situation (3) gar nicht aktiv werden. Dort soll erst mod_dir aktiv werden, das nach $VERZEICHNIS + / weiterleitet (hier also nach 'http://html-ag.wvs-berlin.de/rewrite/' weitergeleitet werden) und DORT würde erst mod_rewrite aktiv werden.

              ok, dass da etwas davorgeschaltet wird, dachte ich. meine vage und wohl falsche vermutung war allerdings, dass _durch_ diese weiterleitung (mittels mod_dir) sich auch der pfad (url->abs.path) aendert.

              danke fuer die ausfuehrliche analyse.

              Achja, Du könntest den Bug auch mal melden. [...] geht hier.

              och, ehm, die ehre gebuehrt eigentlich doch eher dir oder frankx. ich hab doch gar nix gemacht. ;-)

              prost
              seth

              1. Hallo seth,

                Achja, Du könntest den Bug auch mal melden. [...] geht hier.

                och, ehm, die ehre gebuehrt eigentlich doch eher dir oder frankx.

                Da war sowieso schon jemand schneller als ich (siehe letzten Kommentar in dem Bugreport). Und wie ich vermutete wird's in 2.0 nicht mehr gefixed werden. Da wird wohl nur der Workaround nützen.

                Viele Grüße,
                Christian