Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uri ToString() method decoding the Uri Query

In my WebAPI project I have some problems with redirects. This is because the Uri.ToString() method behaves in a "defensive" way, in oter words, once the mentione method is called he decodes the safe parts of the query string.

Consider this failing unit test:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UriTest
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            // Arrange
            const string expectedUrlRaw = 
                "http://localhost/abc?proxy=http%3A%2F%2Ftarget.nl%3Fparam1%3Dvalue1%26param2%3Dvalue2";
            const string expectedUrlInHttpsRaw =
                "https://localhost/abc?proxy=http%3A%2F%2Ftarget.nl%3Fparam1%3Dvalue1%26param2%3Dvalue2";

            Uri expectedUri = new Uri(expectedUrlRaw);
            Uri expectedUriInHttps = new Uri(expectedUrlInHttpsRaw);

            // Act
            string returnsUriInHttpsRaw = expectedUri.ToHttps().ToString();

            // Assert
            Assert.AreEqual(expectedUrlInHttpsRaw, returnsUriInHttpsRaw);
        }
    }
    public static class StringExtensions
    {
        public static Uri ToHttps(this Uri uri)
        {
            UriBuilder uriBuilder = new UriBuilder(uri);
            uriBuilder.Scheme = Uri.UriSchemeHttps;
            uriBuilder.Port = 443;
            return uriBuilder.Uri;
        }
    }
}

Now, I can't modify this behavior by constructing my own link from Uri properties as I have no control over it. In my controller I do respond in the following way to a get message in order to redirect the call:

HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Found);
            response.Headers.Location = // my Uri object

This works fine until a certain point. If my redirect Uri contains a query that contains an encoded link, it will return the wrong result. (and this is probably because the Headers.Location is read by calling a ToString on that property.

Does anyone have an idea on how to overcome this problem?

Thanks

like image 611
MaiOM Avatar asked Nov 10 '22 13:11

MaiOM


1 Answers

Uri.ToString() does decode URL encoded sequences. (like %20=> a white space). The behavior also changes between different versions of the .net framework.

In short, don't use Uri.ToString(), use Uri.AbsoluteUri or Uri.OriginalString.

See the following article for an in-depth investigation https://dhvik.blogspot.com/2019/12/uritostring-automatically-decodes-url.html

like image 115
Dan Avatar answered Nov 14 '22 21:11

Dan