Max Most: Apache; unerwarteter Redirect (o. ä.)

Hallo,

ich möchte alle Pfadteile unterhalb von http://host/skript/ an ein Skript weitergeben. Konkret heißt das, mod_rewrite soll aus Anfragen wie http://host/skript/foo/bar/ etwas machen wie: http://host/skript/skript.php?req=foo/bar/. Dazu habe ich in einer .htaccess das Folgende notiert:

RewriteEngine On  
RewriteRule ^skript.php$ - [L]  
RewriteRule ^(.*)$ skript.php?req=$1 [L]

Läuft auch wie erwartet, abgesehen von einer Kleinigkeit. Wenn ich den Schrägstrich am URL-Ende entferne, also http://host/skript/foo/bar aufrufe, scheint Apache eine interne Umleitung vorzunehmen, und ich lande auf http://host/skript/foo/bar/?req=foo/bar. Habe freilich einen Blick in die Dokumentation geworfen, stieß dort aber nicht auf mehr als die DirectorySlash-Direktive. Ein DirectorySlash Off brachte aber keinen Erfolg, daran wird's also nicht gelegen haben.

Ideen?

Grüße,
Max

  1. ich möchte alle Pfadteile unterhalb von http://host/skript/ an ein Skript weitergeben. Konkret heißt das, mod_rewrite soll aus Anfragen wie http://host/skript/foo/bar/ etwas machen wie: http://host/skript/skript.php?req=foo/bar/.

    Benenne dein Skript in skript um (ohne .php) und ersetze den ganzen Rewrite-Krams in der .htaccess durch diese Zeilen:

    <files skript>
    SetHandler application/x-httpd-php
    </files>

    Den angehängten Pfad findest du dann in der Variablen $_SERVER["PATH_INFO"].

    Beispiel: Beim Aufruf von http://host/skript/foo/bar/ ist $_SERVER["PATH_INFO"] == "/foo/bar/".

    1. Lieber Mattes,

      Benenne dein Skript in skript um (ohne .php) und ersetze den ganzen Rewrite-Krams in der .htaccess durch diese Zeilen:

      <files skript>
      SetHandler application/x-httpd-php
      </files>

      so elegant Dein Vorschlag auch ist, so ist er nicht für alle Hosting-Umgebungen geeignet. Das sollte man nicht verschweigen, denn die <files>-Direktive mag von manchem Hoster, der URL-Rewriting erlaubt, geblockt sein.

      Liebe Grüße,

      Felix Riesterer.

      --
      "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
    2. Hallo,

      Beispiel: Beim Aufruf von http://host/skript/foo/bar/ ist $_SERVER["PATH_INFO"] == "/foo/bar/".

      vielen Dank, eine Lösung ohne mod_rewrite ist mir im Zweifel sogar lieber. Meine Frage wäre da nur, ob das Ganze nur "versehentlich" funktioniert und irgendwann evtl. nicht mehr. Gefühlt wäre skript/foo/bar ja ein 404.

      Grüße,
      Max

      1. Aloha ;)

        Geht offenbar immer. PATH_INFO ist offenbar für genau diesen deinen Fall ausgelegt. Einfach auf php.net mal nachlesen; runterscrollen bis PATH_INFO.

        Offenbar ist es so - zumindest erkläre ich mir das laienhaft selbst so:

        Der Server geht die Addresse Schritt für Schritt von links nach rechts durch. Sobald er auf einen Identifier trifft, den er als Script identifiziert (also eine .php z.B. - oder wie hier, eine Datei namens "skript", denn du hast ihm ja per <file> gesagt, dass solche Dateien wie php zu behandeln sind), gibt er die Arbeit an PHP vollständig ab/weiter. Der Teil hinter dem Skriptaufruf wird also scheinbar gar nicht mehr durch den Server selbst ausgewertet (sondern nur noch durch das Skript). Und die Standard-404er schickt der Server ja "von allein" - aber eben erst wenn er ne Addresse auswertet, die er nirgendwohin weitergeben kann. In deinem Fall hat er ja mit skript immer jemanden zum weitergeben.

        Grüße,

        RIDER

        --
        Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
        ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
        1. Hi,

          Geht offenbar immer.

          Genauer: Es ist abhängig davon, ob AcceptPathInfo auf On oder Off steht, bzw. es mit Default dem Handler für die jeweils im Pfad gefundene Datei überlassen wird.

          Offenbar ist es so - zumindest erkläre ich mir das laienhaft selbst so:

          Der Server geht die Addresse Schritt für Schritt von links nach rechts durch. Sobald er auf einen Identifier trifft, den er als Script identifiziert (also eine .php z.B. - oder wie hier, eine Datei namens "skript", denn du hast ihm ja per <file> gesagt, dass solche Dateien wie php zu behandeln sind), gibt er die Arbeit an PHP vollständig ab/weiter. Der Teil hinter dem Skriptaufruf wird also scheinbar gar nicht mehr durch den Server selbst ausgewertet (sondern nur noch durch das Skript).

          Es ist egal, ob die Datei nun ein PHP-Script ist, oder von einem anderen Handler bedient wird, oder auch nur dem Default-Handler – sobald der Apache im Pfad auf eine Datei trifft, *kann* alles was dahinter kommt ja gar nicht mehr zu einem anderen Verzeichnis oder einer anderen Datei führen – denn eine Datei und ein Verzeichnis mit dem selben Namen kann es auf einer Ebene ja gar nicht geben.

          MfG ChrisB

          --
          Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
        2. Hi,

          Geht offenbar immer. PATH_INFO ist offenbar für genau diesen deinen Fall ausgelegt. Einfach auf php.net mal nachlesen; runterscrollen bis PATH_INFO.

          tatsächlich. Wirkt im Nachhinein wie etwas, das man hätte wissen müssen. :-) Danke nochmals auch an Mattes; wirklich eine sehr viel elegantere Lösung als das Rewriting zuvor.

          Grüße,
          Max

          1. Geht offenbar immer. PATH_INFO ist offenbar für genau diesen deinen Fall ausgelegt. Einfach auf php.net mal nachlesen; runterscrollen bis PATH_INFO.

            tatsächlich. Wirkt im Nachhinein wie etwas, das man hätte wissen müssen. :-)

            PATH_INFO gehört zur CGI-Spezifikation und gibt es dementsprechend schon seit Urzeiten, länger als den Apache-Webserver und PHP. CGI wurde IIRC mit dem NCSA httpd eingeführt, das muss irgendwann Anfang der Neunziger gewesen sein.

            Dummerweise ist a) PHP omnipräsent und b) schreibt jeder PHP-Anleitungsschreiber von irgendeiner anderen PHP-Anleitung ab – und der erste PHP-Anleitungsschreiber hatte wohl nicht wirklich den Überblick (PHP halt …) und dachte, die Datenübergabe an ein Skript ginge nur über URL-Parameter.

            Und seit diesem unseligen Tage gibt es die Unsitte, zur Seitenwahl in einer URL die Parameter zu vergewaltigen statt den Pfad zu benutzen. (Dass die Vergewaltigung nun auch schon seit etlichen Jahren vermehrt mit mod_rewrite vertuscht wird, macht die Geschichte nicht unbedingt weniger tragisch.)

    3. Aloha ;)

      ich möchte alle Pfadteile unterhalb von http://host/skript/ an ein Skript weitergeben. Konkret heißt das, mod_rewrite soll aus Anfragen wie http://host/skript/foo/bar/ etwas machen wie: http://host/skript/skript.php?req=foo/bar/.

      Benenne dein Skript in skript um (ohne .php) [...]

      Hm, und wenn ich die files-Direktive nicht benutzen will / kann (siehe Felix' Post)? Ich kann dann doch genauso rangehen, eben mit http://host/skript.php/foo/bar/, oder? Ist vom Aussehen her nicht ganz so elegant, aber möglich?

      Nur so aus Interesse ;) Würde manchmal die Arbeit erleichtern - also wenn man nicht mit mod_rewrite rumfummeln will.

      Grüße,

      RIDER

      --
      Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
      ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
      1. Aloha ;)

        Okay, selbst beantwortet. Laut phpInfo sollte das also gehen.

        Not bad ;)

        Grüße,

        RIDER

        --
        Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
        ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[