Een URL verkrijgen met een url-gecodeerde schuine streep

Een URL verkrijgen met een url-gecodeerde schuine streep

Dit is een vreselijke hack, die ongetwijfeld onverenigbaar is met toekomstige versies van het raamwerk, enzovoort.

Maar het werkt!

(op mijn computer...)

Uri uri = new Uri("http://example.com/%2F");
ForceCanonicalPathAndQuery(uri);
using (WebClient webClient = new WebClient())
{
  webClient.DownloadData(uri);
}

void ForceCanonicalPathAndQuery(Uri uri){
  string paq = uri.PathAndQuery; // need to access PathAndQuery
  FieldInfo flagsFieldInfo = typeof(Uri).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic);
  ulong flags = (ulong) flagsFieldInfo.GetValue(uri);
  flags &= ~((ulong) 0x30); // Flags.PathNotCanonical|Flags.QueryNotCanonical
  flagsFieldInfo.SetValue(uri, flags);
}

Standaard is de Uri class staat geen escaped / toe teken (%2f ) in een URI (ook al lijkt dit legaal te zijn in mijn lezing van RFC 3986).

Uri uri = new Uri("http://example.com/%2F");
Console.WriteLine(uri.AbsoluteUri); // prints: http://example.com//

(Opmerking:gebruik Uri.ToString niet om URI's af te drukken.)

Volgens het bugrapport voor dit probleem op Microsoft Connect is dit gedrag inherent aan het ontwerp, maar u kunt dit omzeilen door het volgende toe te voegen aan uw app.config- of web.config-bestand:

<uri>
  <schemeSettings>
    <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
  </schemeSettings>
</uri>

(Opnieuw gepost van https://stackoverflow.com/a/10415482 omdat dit de "officiële" manier is om deze bug te vermijden zonder reflectie te gebruiken om privévelden aan te passen.)

Bewerken: Het Connect-bugrapport is niet meer zichtbaar, maar de documentatie voor <schemeSettings> raadt deze aanpak aan om escaped / . toe te staan tekens in URI's. Houd er rekening mee (volgens dat artikel) dat er beveiligingsimplicaties kunnen zijn voor componenten die escaped slashes niet correct verwerken.


Update hierover:het lijkt erop dat het standaardgedrag van de Uri-klasse daadwerkelijk is gewijzigd in .NET 4.5, en u kunt nu slashes met escapetekens gebruiken die niet worden gewijzigd.

Ik heb de volgende code uitgevoerd in .NET 3.5, .NET 4.0, .NET 4.5/4.5.1

static void Main(string[] args)
{
    var uri = new Uri("http://www.yahooo.com/%2F");
    var client = new WebClient();
    client.DownloadString(uri);
}

In .NET 3.5/4.0 laat de trace zien dat de %2F inderdaad niet ontsnapt was zoals verwacht.

In .NET 4.5/4.5.1 kunt u echter zien dat de %2F niet ontsnapt was (let op de GET /%2F)

Je kunt nu zelfs ToString() gebruiken op de Uri en je krijgt hetzelfde resultaat.

Dus tot slot, het lijkt erop dat als je .NET>=.NET 4.5 gebruikt, de dingen zich zullen gedragen zoals ze zouden moeten zijn in overeenstemming met de RFC.

Ik heb net een verkenning gedaan om dezelfde aanpak voor Mono te laten werken. Ik heb mijn vraag over de aanpak hier gepost:Een Uri krijgen met escaped slashes op mono