Gunther: Apache mod_rewrite / '\..* und /$' entfernen

Hallo Selfgemeinde!

Obwohl ich mich jetzt schon seit geraumer Zeit immer wieder mit mod_rewrite beschäftigt habe, ist und bleibt es "Vodoo" für mich.

Ich hoffe, dass mir hier trotzdem jemand netterweise hilft. ;-)

Und zwar möchte ich (schlicht) erreichen, dass alle Eingaben in der Adresszeile wiefolgt behandelt werden:

  • wenn ein Punkt vorhanden ist, soll dieser und alles was danach folgt abgeschnitten werden => sichtbare Weiterleitung
  • trailing slash(es) sollen ebenfalls entfernt werden => sichtbare Weiterleitung

Die so "gesäuberten" Request_Uris sollen anschließend unsichtbar auf eine redirect.php weitergeleitet werden. Also in etwa so:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /redirect.php?$1 [L]

BTW: Die Geschichte mit mod_dir und "DirectorySlash Off" ist mir bekannt.

Gruß Gunther

    • wenn ein Punkt vorhanden ist, soll dieser und alles was danach folgt abgeschnitten werden => sichtbare Weiterleitung

    ^(.*).(.*)$

    ^    Anfang des Strings
    .    beliebiges Zeichen
    *    voranstehender Ausdruck/Zeichen 0 oder mehrmals
    .   ein Punkt
    $    Ende des Strings

    Die gefundenen Bestandteile des Ausdrucks lassen sich mit $1, $2 usw verwenden

    • trailing slash(es) sollen ebenfalls entfernt werden => sichtbare Weiterleitung

    ^(.*)/$

    Matcht auf alles, was mit einem Slash endet.

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    ggf. solltest du noch !-l hinzufügen, damit du nicht nur Dateien (f) und Verzeichnisse (d) sondern auch Symbolische Links (l) ausschließt.

    Obenstehendes nicht getestet und natürlich keine Garantie auf Richtigkeit - sollte aber einen Baukasten darstellen.

    1. Die gefundenen Bestandteile des Ausdrucks lassen sich mit $1, $2 usw verwenden

      Nachtrag - aus RewriteCond kannst du sie mit %1, %2 usw übernehmen.

    2. Moin!

      • wenn ein Punkt vorhanden ist, soll dieser und alles was danach folgt abgeschnitten werden => sichtbare Weiterleitung

      ^(.*).(.*)$

      Was, wenn in der URL zwei Punkte drin sind?

      - Sven Rautenberg

      1. Was, wenn in der URL zwei Punkte drin sind?

        Gutes Argument :) PCRE sollte per default gierig sein, hier wird wohl der letzte Punkt entscheidend sein

        Bei foo.de.html wird wohl folgendes gematcht:
        0 = foo.de.html
        1 = foo.de
        2 = html

        Gibts hier eine Möglichkeit, die Sache non-greedy zu matchen - hierzu wäre mir nämlich nichts bekannt.

        1. Hi,

          Was, wenn in der URL zwei Punkte drin sind?

          Gutes Argument :) PCRE sollte per default gierig sein, hier wird wohl der letzte Punkt entscheidend sein

          (.*?).

          oder

          ([^.]*).

          cu,
          Andreas

          --
          Warum nennt sich Andreas hier MudGuard?
          O o ostern ...
          Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
    3. Hallo!

      Vielen Dank für eure nette Hilfe! ;-)

      • wenn ein Punkt vorhanden ist, soll dieser und alles was danach folgt abgeschnitten werden => sichtbare Weiterleitung

      ^(.*).(.*)$

      ^    Anfang des Strings
      .    beliebiges Zeichen
      *    voranstehender Ausdruck/Zeichen 0 oder mehrmals
      .   ein Punkt
      $    Ende des Strings

      Die gefundenen Bestandteile des Ausdrucks lassen sich mit $1, $2 usw verwenden

      • trailing slash(es) sollen ebenfalls entfernt werden => sichtbare Weiterleitung

      ^(.*)/$

      Matcht auf alles, was mit einem Slash endet.

      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d

      ggf. solltest du noch !-l hinzufügen, damit du nicht nur Dateien (f) und Verzeichnisse (d) sondern auch Symbolische Links (l) ausschließt.

      Also dank eurer Hilfe habe ich jetzt folgendes:
      <IfModule mod_rewrite.c>
      RewriteEngine On

      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_URI} ^([^.]*). [OR]
      RewriteCond %{REQUEST_URI} ^(.*)/$
      RewriteRule ^(.*)$ %1 [R=301,L]

      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_FILENAME} !-l
      RewriteRule ^(.*)$ /test.php?$1 [L]
      </IfModule>

      Das funktioniert soweit auch wie gewünscht. Bei mehreren Punkten wird alles ab dem ersten Punkt abgeschnitten.

      Das Ganze ist ja auch nur für den Fall, dass ein User selber etwas in die Adresszeile eintippt. Suit kennt den Zusammenhang.

      Ein Problem habe ich aber trotzdem noch. Denn wenn ein User jetzt auch noch auf die tolle Idee kommt, einen Query String anzuhängen, greifen die obigen Regeln nicht mehr.

      Wie kann ich dieses Problem denn jetzt zusätzlich noch beseitigen?
      Und da ich (noch) nicht 100%ig weiß, ob ich nicht evt. später doch auch noch (quasi) "reguläre" Links mit einem Query String habe, darf dieser also nicht einfach pauschal "abgeschnitten & verworfen" werden.

      Gruß Gunther

      1. Hallo nochmal!

        Ein Problem habe ich aber trotzdem noch. Denn wenn ein User jetzt auch noch auf die tolle Idee kommt, einen Query String anzuhängen, greifen die obigen Regeln nicht mehr.

        Wie kann ich dieses Problem denn jetzt zusätzlich noch beseitigen?
        Und da ich (noch) nicht 100%ig weiß, ob ich nicht evt. später doch auch noch (quasi) "reguläre" Links mit einem Query String habe, darf dieser also nicht einfach pauschal "abgeschnitten & verworfen" werden.

        Hat sich erledigt! Sorry!
        Keine Ahnung, warum er es eben partou nicht machen wollte - jetzt funktioniert es jedenfalls. Der Query String bleibt unverändert an der redirecteten URI hinten dran (so sollte das AFAIK ja auch sein, solange man nicht mit dem QSA Flag rumhantiert).

        Gruß Gunther

      2. Hi,

        Das Ganze ist ja auch nur für den Fall, dass ein User selber etwas in die Adresszeile eintippt. Suit kennt den Zusammenhang.

        Warum willst du dann überhaupt irgendwohin umleiten?

        Vom Nutzer "ausgedachte" Ressourcen, zu denen keine passende Antwort gefunden wird, werden mit einem 404 Not Found beantwortet, und Basta.

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.
        1. Hi!

          Das Ganze ist ja auch nur für den Fall, dass ein User selber etwas in die Adresszeile eintippt. Suit kennt den Zusammenhang.

          Warum willst du dann überhaupt irgendwohin umleiten?

          Vom Nutzer "ausgedachte" Ressourcen, zu denen keine passende Antwort gefunden wird, werden mit einem 404 Not Found beantwortet, und Basta.

          Ja, sehe ich prinzipiell auch so, aber ...
          Nur weil jemand (aus Gewohnheit oder weil sie meinen, dass müsste immer so sein?) eine Dateiendung, oder einen trailing slash an eine ansonsten korrekte URL anhängt, ihm deshalb einen 404er zu servieren, halte ich dann doch nicht für so benutzerfreundlich.

          Nur sollte die URL dann halt auch entsprechend korrigiert werden, schon für den Fall, dass derjenige sie anschließend (was ja wünschenswert wäre) bookmarked. Denn wenn er sie dann auch noch weiterverlinkt, ist das Kind ansonsten "in den Brunnen gefallen".

          Oder sehe ich da etwas falsch?
          Ich lasse mich diesbezüglich auch gerne vom Gegenteil überzeugen, weil ich mir in der Sache alles andere als sicher bin.

          Gruß Gunther