heinetz: mod_rewrite macht mich fertig ...

Hallo Forum,

ich stand gestern vor folgender Aufgabe:

Ich will die Verzeichnisstruktur in einem DocumentRoot dahngehend ändern, dass index.php 'eine Ebene tiefer rutscht'. Das Dokument 'index.php' liegt nicht mehr unter '/' sondern unter '/public/' und ist insofern zukünftig  über a) http://www.example.org/ sondern unter b) http://www.example.org public/ erreichbar.

Damit der Aufruf a) nach wie vor funktioniert, gibt es die einfache Möglichkeit, mt mod_rewrite folgende Regel zu definieren:

RewriteCond %{REQUEST_URI} !^/public/  
RewriteRule ^(.*)$ /public/$1

... und damit funktionieren sowohl a) als auch b). Nun wollte ich aber zusätzlich erreichen, dass bei Eingabe von b) per redirect nach a) umgeleitet wird, damit in jedem Fall a) in der Adresszeile des Browsers steht. Total naheleigend war der Gedanke, meine .htaccess wie folgt zu erweitern:

RewriteRule ^public/(.*)$ /$1 [R]  
  
RewriteCond %{REQUEST_URI} !^/public/  
RewriteRule ^(.*)$ /public/$1

... was dazu führte, dass "die aufgerufene Website leitet die Anfrage so um, dass sie nie beendet werden kann.", was ich nicht verstanden habe. Danach habe ich dann noch die Umkehrung versucht, was (meinem Verständnis nach) auch hääte fnktionieren müssen:

RewriteCond %{REQUEST_URI} !^/public/  
RewriteRule ^(.*)$ /public/$1 [L]  
  
RewriteRule ^public/(.*)$ /$1 [R]

... aber zum gleichen Ergebnis führte. Nach langer Recherche und ewigem Trial&Error, habe ich das ganze dann wie folgt hinbekommen:

RewriteCond %{THE_REQUEST} /public/  
RewriteRule ^public/(.*)$ /$1 [R]  
  			  
RewriteCond %{REQUEST_URI} !^/public/  
RewriteRule ^(.*)$ /public/$1

... aber leider nicht verstanden, warum die Versuche vorher nicht funktioniert haben. Kann mir das jemand erklären?

danke für Tipps und

beste gruesse,
heinetz

  1. Hi,

    ... aber leider nicht verstanden, warum die Versuche vorher nicht funktioniert haben. Kann mir das jemand erklären?

    Das RewriteLog kann, in unterschiedlich einstellbarer Ausführlichkeit.

    Das ist nicht das erste Rewriting-Problem mit dem du hier fragst - also lerne bitte langsam mal, solche Hilfsmittel wie das RewriteLog auch zu nutzen.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. hi,

      Das RewriteLog kann, in unterschiedlich einstellbarer Ausführlichkeit.

      ist mir bewusst und ich versuche die mit loglevel 9 geschriebenen 10.000 Zeilen zu verstehen.

      also lerne bitte langsam mal, solche Hilfsmittel wie das RewriteLog auch zu nutzen.

      fällt mir echt schwer ohne Dokumentation der Syntax.

      gruss,
      heinetz

      1. Hi!

        Das RewriteLog kann, in unterschiedlich einstellbarer Ausführlichkeit.
        ist mir bewusst und ich versuche die mit loglevel 9 geschriebenen 10.000 Zeilen zu verstehen.

        Ja, das kann schon mal sehr gesprächig sein.

        also lerne bitte langsam mal, solche Hilfsmittel wie das RewriteLog auch zu nutzen.
        fällt mir echt schwer ohne Dokumentation der Syntax.

        Der Anfang der Zeile kann üblicherweise ignoriert werden. Lediglich die IDs sind beachtenswert, weil sie den Zusammenhang zwischen den möglicherweise parallelen Requests herstellt. Der Rest ist kein Code, der eine Syntax hätte, sondern einigermaßen Klartext.

        Bei der ID ist noch zu beachten, dass ein umgeschriebener Reqest erneut den Apache-Prozess durchläuft und, wenn die umgeschriebene URL wieder auf ein Verzeichnis mit RewiteRules trifft, auch diese abgearbeitet werden. Wenn der Request also im selben Verzeichnis bleibt, durchläuft er die selben Rules erneut.

        Lo!

      2. Hi,

        Das RewriteLog kann, in unterschiedlich einstellbarer Ausführlichkeit.

        ist mir bewusst und ich versuche die mit loglevel 9 geschriebenen 10.000 Zeilen zu verstehen.

        Leere es, mache *einen* Request, schau dir das Ergebnis an - ganz von oben.
        Bei einer Endlos-Umleitung sollte das Schema klar werden, ohne dass man 10.000 Zeilen durchsehen muss.

        also lerne bitte langsam mal, solche Hilfsmittel wie das RewriteLog auch zu nutzen.

        fällt mir echt schwer ohne Dokumentation der Syntax.

        Dokumentation welcher Syntax?
        Des Logfiles selber? Abgesehen von ein paar statistischen Daten spricht das eigentlich ziemlich Klartext, was in welchem Schritt gemacht wurde.

        MfG ChrisB

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
        1. hi,

          Leere es, mache *einen* Request, schau dir das Ergebnis an - ganz von oben.
          Bei einer Endlos-Umleitung sollte das Schema klar werden, ohne dass man 10.000 Zeilen durchsehen muss.

          Du hast natürlich vollkommen Recht. Aber stelle Dir einmal vor, dass ich bisher davon ausgegangen bin, zu verstehen, wie mod_rewrite funktioniert, so hinbekommen habe, dass es das macht, was ich will und mich von daher bestätigt sehe. Dann komme ich irgendwo an einen Punkt, wo etwas für mich unvorhergesehenes passiert. Ich gehe dann natürlich davon aus, dass ich einfach ein Brett vor dem Kopf habe und irgendeinen Denkfehler mache, der sich nicht durch googeln klären lässt. Dann lasse ich ein Logfile schreiben und gucke da rein. Was ich sehe sind 10.000 Zeilen Informationen. Weil mein Ruleset nur aus ganz wenigen Regeln besteht, die diese 10.000 Zeilen erzeugen sollen, kann ich das natürlich nicht in Zusammenhang bringen. Das ist der Moment, wo ich hier nachfrage. Ich habe zu dem Zeitpunkt schon eine Ahnung davon, was passiert und wünsche mir den entscheidenden Hinweis einfach ausgedückt. Aber, wie gesagt, gebe ich Dir vollkommen Recht und gehe noch einen Schritt weiter:

          Mit *einem* Request war es nicht getan, weil der immernoch zu viele Informationen erzeugte. Ich habe mein Ruleset vollständig zurückgebaut um zu sehen, was bei einer Regel ohne irgendwelche Bedingungen passiert und das sind schon 13 Zeilen!

          beste gruesse,
          heinetz

          1. Leere es, mache *einen* Request, schau dir das Ergebnis an - ganz von oben.
            Bei einer Endlos-Umleitung sollte das Schema klar werden, ohne dass man 10.000 Zeilen durchsehen muss.

            Du hast natürlich vollkommen Recht. Aber stelle Dir einmal vor, dass ich bisher davon ausgegangen bin, zu verstehen, wie mod_rewrite funktioniert, so hinbekommen habe, dass es das macht, was ich will und mich von daher bestätigt sehe. Dann komme ich irgendwo an einen Punkt, wo etwas für mich unvorhergesehenes passiert. Ich gehe dann natürlich davon aus, dass ich einfach ein Brett vor dem Kopf habe und irgendeinen Denkfehler mache, der sich nicht durch googeln klären lässt. Dann lasse ich ein Logfile schreiben und gucke da rein. Was ich sehe sind 10.000 Zeilen Informationen. Weil mein Ruleset nur aus ganz wenigen Regeln besteht, die diese 10.000 Zeilen erzeugen sollen,

            Das ist doch Quark, ein Fehler erzeugt zwar häufig mehrere Einträge, aber sicher nicht 10.000. Da die Einträge immer eine Zeitangabe haben, sollte es einfach sein, die auf dein konkretes Problem zurück zu führen. Ausserdem lassen sich beim rewrite Log auch andere Level einstellen bei dem nicht soviele (normalerweise uninteressante) Informationen eingetragen werden.

            Struppi.

            1. Klar snd die 10.000 Einträge nicht nach einem Request entstanden und das da eine Uhrzeit dabei steht, habe ich dann natürlich auch gesehen. Was ich damit sagen wollte, war auch viel mehr, dass mich die Menge an Informationen erstmal erschlagen und zu dem Schluss kommen lassen hat, dass ich diese Information nicht auswerten kann ...

          2. Hi!

            Aber stelle Dir einmal vor, dass ich bisher davon ausgegangen bin, zu verstehen, wie mod_rewrite funktioniert, so hinbekommen habe, dass es das macht, was ich will und mich von daher bestätigt sehe.

            Wenn du dieses Verständnis noch weiter vertiefen willst, ist gerade der Blick in das RewriteLog empfehlenswert.

            Dann komme ich irgendwo an einen Punkt, wo etwas für mich unvorhergesehenes passiert. Ich gehe dann natürlich davon aus, dass ich einfach ein Brett vor dem Kopf habe und irgendeinen Denkfehler mache, der sich nicht durch googeln klären lässt. Dann lasse ich ein Logfile schreiben und gucke da rein. Was ich sehe sind 10.000 Zeilen Informationen.

            Übung macht den Meister. Das kann einem leider niemand abnehmen. Du wirst dann auch Erfahrung gesammelt haben, und dich mit dem Lesen des Logfiles bestimmt etwas einfacher tun.

            Weil mein Ruleset nur aus ganz wenigen Regeln besteht, die diese 10.000 Zeilen erzeugen sollen, kann ich das natürlich nicht in Zusammenhang bringen.

            Auch Kleinvieh macht Mist. Eine Endlosschleife kann auch als Einzeiler notiert werden.

            Das ist der Moment, wo ich hier nachfrage. Ich habe zu dem Zeitpunkt schon eine Ahnung davon, was passiert und wünsche mir den entscheidenden Hinweis einfach ausgedückt.

            Verständlich. Doch nicht immer kann der Erfahrene sein Wissen aus dem Ärmel schütteln. Entscheidend ich nicht immer, Detailwissen zu allen möglichen Situationen aufzubauen, sondern die Werkzeuge benutzen zu können, um die Ursache ermitteln zu können. Wenn du mit dem RewriteLog-Lesen nicht zurecht kommst, kannst du ja auch mal ein paar Zeilen posten, die wir dir dann zu interpretieren versuchen können.

            Ich habe mein Ruleset vollständig zurückgebaut um zu sehen, was bei einer Regel ohne irgendwelche Bedingungen passiert und das sind schon 13 Zeilen!

            Da kannst du mal sehen, wie aufwendig so ein Rewrite-Prozess ist.

            Lo!

            1. Hi,

              nachdem ich mir nun allabendlich das rewrite_log antuhe, bin ich tatsächlich einen gewaltigen Schritt weiter. Nicht dass mir nun klar wäre, wie ich meine Rulsesets einfach aufbaue aber das eine wird eines immer klarer ;)

              The Apache module mod_rewrite is a killer one

              Frage zum rewrite_log:

              add path info postfix: /Users/heinetz/Sites/example/_content -> /Users/heinetz/Sites/example/_content/content.php

              Was ist verantwortlich für so einen Eintrag?

              danke und

              beste gruesse,
              heinetz

              1. Hi!

                add path info postfix: /Users/heinetz/Sites/example/_content -> /Users/heinetz/Sites/example/_content/content.php
                Was ist verantwortlich für so einen Eintrag?

                Eine Rule erzeugt gleich mehrere Einträge, denn zu ihrer Abarbeitung sind - wie du sicher bemerkt hast - eine ganze Reihe von Schritten notwendig. Das "add path info postfix" ist eins der ersten Schritte, kann aber auch mehrfach vorkommen. Ich interpretiere das so, dass der Apache sich gerade in /Users/heinetz/Sites/example/ befindet und den Teil _content aufzulösen versucht. Dabei kommt er an deiner Rule vorbei. mod_rewrite kann aber mit diesem Fragment allein diese Regel nicht auswerten. Also hängt es den Rest des Requests an und begibt sich dann auf den nächsten Schritt zur Rule-Auswertung, dem Abschneiden des nicht benötigten Anfangs /Users/heinetz/Sites/example/, so dass noch _content/content.php übrigbleibt. Darauf kann es nun die Regel anwenden, die relativ zum aktuellen Verzeichnis notiert ist.

                Lo!

                1. Hi,

                  Eine Rule erzeugt gleich mehrere Einträge, denn zu ihrer Abarbeitung sind - wie du sicher bemerkt hast - eine ganze Reihe von Schritten notwendig. Das "add path info postfix" ist eins der ersten Schritte, kann aber auch mehrfach vorkommen.

                  ich bin darüber gefallen, als ich herausfinden wollte, wie es sich wohl auswirken würde, wenn ich statt alle RewirteRules unter:

                  /Users/heinetz/Sites/example/.htaccess

                  ... zu definieren, den letzten Teil davon in eine:

                  /Users/heinetz/Sites/example/public/.htaccess

                  zu schieben. Beim Vergleich beider rewrite_logs wird mir nicht klar, nach welcher Logik bzw. Reihenfolge die Regeln dann abgearbeitet werden.

                  beste gruesse,
                  heinetz

                  1. Hi!

                    Eine Rule erzeugt gleich mehrere Einträge, denn zu ihrer Abarbeitung sind - wie du sicher bemerkt hast - eine ganze Reihe von Schritten notwendig. Das "add path info postfix" ist eins der ersten Schritte, kann aber auch mehrfach vorkommen.

                    ich bin darüber gefallen, als ich herausfinden wollte, wie es sich wohl auswirken würde, wenn ich statt alle RewirteRules unter:
                    /Users/heinetz/Sites/example/.htaccess
                    ... zu definieren, den letzten Teil davon in eine:
                    /Users/heinetz/Sites/example/public/.htaccess
                    zu schieben. Beim Vergleich beider rewrite_logs wird mir nicht klar, nach welcher Logik bzw. Reihenfolge die Regeln dann abgearbeitet werden.

                    Die Pfadangabe bei "add path info postfix" ist vielleicht etwas verwirrend. Bei

                    add path info postfix: /Users/heinetz/Sites/example/_content -> /Users/heinetz/Sites/example/_content/content.php

                    befindet sich der Apache im Verzeichnis "example" und möchte gern den nächsten Pfad-Teil "_content" auflösen. Deshalb geht der Teil links vom "->" nur bis "_content". Die RewriteRule hingegen möchte gern alles betrachten, weswegen als erstes der für den normalen Apache-Prozess uninteressante Teil "/content.php" angefügt wird, bevor die weitere Auswertung der Regel beginnt.

                    Aus den letzten beiden Angaben dieses linken Teils kann man nun erkennen, was der normale Apache-Prozess tun wollte.

                    Wenn ich in meinen Versuchen eben keinen Fehler gemacht habe, dann ignoriert mod_rewrite beim Vorhandensein einer RewriteRule in einem Verzeichnis alle Regeln von übergeordneten Verzeichnissen. Also dürftest du keine Vermischung der Regeln sehen, sondern lediglich die Verzeichnissituation aus den letzten beiden Pfadbestandteilen der Angabe links vom "->" wiederfinden.

                    Lo!

                    1. hi,

                      Wenn ich in meinen Versuchen eben keinen Fehler gemacht habe, dann ignoriert mod_rewrite beim Vorhandensein einer RewriteRule in einem Verzeichnis alle Regeln von übergeordneten Verzeichnissen.

                      ... verstanden ... und nachdem der Groschen gefallen ist auch eingesehen;)

                      Was ich aktuell nicht hinbekomme, ist folgendes:

                      ------------------------------------------------
                      #ergänzt den im REQUEST fehlenden Slash am Ende.
                      RewriteCond %{REQUEST_FILENAME} !-f
                      RewriteRule ^(.*[^/])$ /$1/ [L,R=301]

                      #ergänzt ein im REQUEST fehlendes www.
                      RewriteCond %{HTTP_HOST} !www..*
                      RewriteRule ^(.*)$ http://www.daimler-bkk29.leo.dev/$1 [L,R=301]
                      ------------------------------------------------

                      Zwei Rules/Conditions, die jeweils unter Umständen einen Request zur Folge haben und damit unter Umständen eben zwei Requests. Das funktioniert zwar so aber durch die ganze Auseinandersetzung mit dem rewrite_log und dadurch enstandenen Bewusstsein, was sollche Rules für Auswirkungen haben, frage ich mich natürlich, ob sich so etwas nicht auf einen neuen Requst beschränkenk lässt. In einem prozedural programmierten PHP-Skript wüste ich z.B., wie ich mit Kontrollstrukturen und Variablen dafür sorge, dass die Ausführung nur einmal stattfindet. Bei dieser Logik fällt es schwer, mir vorzustellen, wie sich soetwas machen lässt.

                      beste gruesse,
                      heinetz

                      1. Hi!


                        #ergänzt den im REQUEST fehlenden Slash am Ende.
                        RewriteCond %{REQUEST_FILENAME} !-f
                        RewriteRule ^(.*[^/])$ /$1/ [L,R=301]

                        #ergänzt ein im REQUEST fehlendes www.
                        RewriteCond %{HTTP_HOST} !www..*
                        RewriteRule ^(.*)$ http://www.daimler-bkk29.leo.dev/$1 [L,R=301]

                        Zwei Rules/Conditions, die jeweils unter Umständen einen Request zur Folge haben und damit unter Umständen eben zwei Requests. [...] frage ich mich natürlich, ob sich so etwas nicht auf einen neuen Requst beschränkenk lässt.

                        Hast du dich auch gefragt, ob man das gleich ganz weglassen kann? Hast du dich überzeugende Antworten auf die Fragen, wem ein / und www nützt gefunden?

                        RewriteRules wirken auch nacheinander. Voraussetzung ist natürlich, dass das L-Flag nicht die Ausführug der nachfolgenden verhindert. RewriteLog und in dem Fall vor allem ein Requestmonitor (wie die livehttpheaders-Extension für den Firefox und ähnliche) sind Werkzeuge, zum Überprüfen der Auswirkungen der Ergebnsse von Änderungen. In meinem kleinen Test mit zwei anderen Rules - beide aber mit dem R=301-Flag versehen - gab es nur einen Redirect, wohl aber wurden beide Regeln berücksichtigt.

                        Lo!

                        1. hi,

                          Hast du dich auch gefragt, ob man das gleich ganz weglassen kann? Hast du dich überzeugende Antworten auf die Fragen, wem ein / und www nützt gefunden?

                          Es geht mir hier eher um die Theorie. Der Slash und das www sind lediglich Beispiele.

                          RewriteRules wirken auch nacheinander. Voraussetzung ist natürlich, dass das L-Flag nicht die Ausführug der nachfolgenden verhindert.

                          Ich hatte den Eindruck, das R-Flag hat einen sofortigen Redirect zur Folge. Scheint aber tatsächlich nicht so zu sein.

                          beste gruesse,
                          heinetz