Kürzlich wurde mein Team gebeten, ein HttpModule für eine ASP.NET MVC-Anwendung zu implementieren, die doppelt codierte URLs auf IIS 7 und .NET 3.5 behandelte. Hier ist der Kern des Problems:
Manchmal erhalten wir URLs mit doppelt codierten Schrägstrichen, die wie folgt aussehen:
%Vor%Es gibt noch andere Formate, die wir behandeln müssen, aber alle haben etwas gemeinsam, sie haben einen doppelt kodierten Schrägstrich.
Um das zu beheben, haben wir ein HttpModule geschrieben, das nur funktioniert, wenn eine URL einen doppelt kodierten Forward-Schrägstrich hat, und wir leiten es an eine vernünftige URL weiter. Die Details sind nicht wichtig, aber es gibt zwei Bits, die sind:
Hier ist das Problem:
Die erste Anfrage nach dem Start von IIS zeigt eine andere URL als die zweite Anfrage.
Wenn wir die URL aus dem obigen Beispiel verwendet hätten, würde die erste Anfrage an IIS wie folgt aussehen:
http://www.example.com/bar/baz/foo
und die zweite Anfrage würde wie folgt aussehen:
http://www.example.com/%252fbar%5cbaz/foo
Dies wurde getan, indem die Eigenschaft Application.Request.Url.AbsolutePath
beim Debugging untersucht wurde.
Hier ist das kleinste Codebeispiel, das das Problem reproduzieren sollte (erstellen Sie eine neue MVC-Anwendung und registrieren Sie das folgende HttpModule):
%Vor%Rufen Sie dann dieselbe URL auf localhost auf:
%Vor%Hinweis: Stellen Sie sicher, dass Sie vor der Zeile in
sehen könnenDebugger.Launch()
einencontext_BeginRequest
-Aufruf einfügen, damit Sie ihn beim ersten Start von IIS
Wenn Sie die erste Anfrage ausführen, sollten Sie folgendes sehen:
http://example.com/bar/foo
Bei nachfolgenden Anfragen sollten Sie sehen:
http://example.com//bar/foo
.
Meine Frage ist: Ist das ein Fehler in IIS? Warum bietet es verschiedene URLs beim ersten Aufruf von Application.Request.Url.AbsolutePath
, aber nicht für eine nachfolgende Anfrage?
Auch: Es spielt keine Rolle, ob die erste Anfrage eine doppelt codierte URL ist oder nicht, die zweite Anfrage wird immer von IIS entsprechend gehandhabt (oder zumindest so gut wie die Handhabung doppelt codierter Forward Slashes sein kann) . Es ist diese erste Anfrage, die das Problem ist.
Ich habe ein paar verschiedene Eigenschaften ausprobiert, um zu sehen, ob man bei der ersten Anfrage andere Werte hat:
Erste Anfrage %Vor% Die einzige interessante Sache ist, dass Application.Request.RawUrl
einen single-codierten Forward-Schrägstrich ( %2f
) ausgibt und den kodierten umgekehrten Schrägstrich ( %5c
) in einen forwardslash umsetzt (obwohl alles andere auch das tut).
Das RawUrl
ist bei der ersten Anfrage noch teilweise verschlüsselt.
Interessante Punkte aus der zweiten Anfrage:
IsWellFormedOriginalString()
ist false
. Auf die erste Anfrage war true
. AbsoluteUri
ist anders. Auf der zweiten Anfrage hat es zwei Schrägstriche. Offene Fragen
iisreset
gemacht wird.
Beachten Sie, dass die physikalischen Auswirkungen dieses Problems gering sind: Damit es sich um ein tatsächliches Problem handelt, müsste die erste Anfrage an den Webserver von einem Client für die oben angegebene URL und die damit verbundenen Chancen erfolgen sind relativ niedrig.
Request.Url kann bereits dekodiert werden - ich würde es nicht für das, was Sie tun, vertrauen.
Siehe die internen Details unter: Querystring mit url-codierten Ampersand vorzeitig in Request.Url decodiert
Die Lösung besteht darin, direkt über Request.RawUrl auf die Werte zuzugreifen.
Ich erkenne, dass dein Problem mit dem Pfad ist, aber es scheint, dass das Gleiche passiert. Probieren Sie die RawUrl - sehen Sie, ob es stattdessen für Sie arbeitet.
Das ist wirklich keine Antwort, aber möglicherweise ein Schritt in die richtige Richtung. Ich hatte keine Zeit, ein Testkabel zu erstellen, um irgendetwas zu beweisen.
Ich habe this.PrivateAbsolutePath
über Reflector verfolgt und es geht weiter und weiter. Es gibt eine Menge von String-Manipulation, wenn auf sie zugegriffen wird.
Tags und Links asp.net-mvc .net c# iis httpmodule