it-swarm.com.de

URL-Pfad mit codiertem Fragezeichen führt beim Kopieren in die Ziel-URL zu einer falschen Umleitung

Ich habe eine einfache RewriteRule, die eine Zeichenfolge an einige URLs anfügt:

RewriteRule  ^labels/([^/]+)/?$ /labels/$1/releases/ [R=301,L,NC]

Die Links sind datenbankgesteuert und dies funktioniert sehr gut. Nun, abgesehen von einem von ihnen. Der Name enthält ?! am Ende, sagen wir label?!.

Die generierten Links sind korrekt, dh:

/labels/label%3F%21

Die Umleitung wird jedoch zweimal angewendet und berücksichtigt das verschlüsselte Fragezeichen offensichtlich nicht als Teil der URL. Der resultierende Link sollte sein:

/labels/label%3F%21/releases/

Aber wir bekommen stattdessen:

/labels/label/releases/?!/releases/

Ich kann sehen, dass die Regel tatsächlich zweimal angewendet wird, aber ich bin mir sicher, dass dies leicht gelöst werden kann, wenn ich mein erstes Problem überwinde: Warum sehen Umschreiber den codierten %2F als tatsächlichen Begrenzer für Abfragezeichenfolgen? Wie kann ich diesen Fall entschärfen?

Vielen Dank für jeden Hinweis!

3
DJules

Sie benötigen das B -Flag, um die Rückreferenz zu umgehen nd das NE (noescape), um die resultierende Substitution (dh das Rückverweis) doppelt codiert. Zum Beispiel:

RewriteRule ^labels/([^/]+)/?$ /labels/$1/releases/ [B,NE,R=301,L,NC]

Sie müssen Ihren Browser-Cache leeren, da der vorherige (fehlerhafte) 301 zwischengespeichert wurde.


Warum wird der codierte %2F in Umformulierungen als tatsächlicher Begrenzer für Abfragezeichenfolgen angezeigt?

Leichter Tippfehler da, denke ich ... du meinst %3F. Ja, am Ende erhalten Sie zwei Weiterleitungen, weil ...

  • wenn Sie /labels/label%3F%21 anfordern, stimmt das RewriteRuleMuster mit dem% -decodierten URL-Pfad überein, d. h. /labels/label?!. Entsprechend Ihrer Regel wird dann label?! in die Ersetzung kopiert, was zu einer Umleitung zu /labels/label?!/releases/ führt (der ?! wird nicht automatisch neu codiert). Welches ist ein URL-Pfad von /labels/label und eine Abfragezeichenfolge von !/releases/. Daher kommt die Abfragezeichenfolge.

  • In der umgeleiteten Anforderung entspricht /labels/label Ihrem RewriteRuleMuster (die Abfragezeichenfolge wird zu diesem Zeitpunkt ignoriert). Dieses Mal wird nur label in Substitution kopiert, um /labels/label/releases/ zu werden. Anschließend wird die Abfragezeichenfolge aus der Anforderung an die Ersetzung übergeben, um eine zweite Umleitung zu /labels/label/releases/?!/releases/ auszuführen.

Das Flag B verlässt das erfasste Muster. z.B. label?! wird ausgeblendet, um label%3F%21 zu werden.

Und das NE -Flag verhindert, dass der % als %25 codiert wird (dh effektiv die Rückreferenz doppelt codiert). z.B. label%3F%21 würde ansonsten als label%253F%2521 codiert.

Aside: mod_rewrite codiert nicht automatisch first? in substitution, da davon ausgegangen wird, dass dies die Abfragezeichenfolge startet. Nachfolgende ? werden jedoch automatisch codiert. z.B. Bei RewriteRule ^foo$ /bar??? [R,L] führt eine Anfrage nach /foo zu einer Weiterleitung zu /bar?%3f%3f (beachten Sie, dass die zweiten beiden ? URL-codiert sind, die erste jedoch nicht).

2
MrWhite