Rob
February 4, 2021, 8:04pm
1
I have a client that uses % in their URLs. This is possible and normally this implies a hex number in the url. However… it is possible To have a URL like ttis:
GET https://localhost:46780/puzzel/Legering van ijzer met 14% silicium
In this case, UrlEncoding gives:
Legering%20van%20%C4%B3zer%20met%2014%%20silicium
Which is fine. However, the decoder assumes two digits after the % sign.
Not sure if this is an OK fix, but this seems to do the trick:
public static string UrlDecode(string text)
{
if (String.IsNullOrEmpty(text)) return null;
var bytes = new List<byte>();
var textLength = text.Length;
for (var i = 0; i < textLength; i++)
{
var c = text[i];
if (c == '+')
{
bytes.Add(32);
}
else if (c == '%' && text[i + 1] != '%') // test for additional % sign
{
var hexNo = Convert.ToByte(text.Substring(i + 1, 2), 16);
bytes.Add(hexNo);
i += 2;
}
else
{
bytes.Add((byte)c);
}
}
byte[] byteArray = bytes.ToArray();
return Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
}
mythz
February 4, 2021, 8:24pm
2
If that’s the case they should also be encoding the %
so that it results in:
Legering%20van%20%C4%B3zer%20met%2014%25%20silicium
i.e. as encoded with:
encodeURIComponent('Legering van ijzer met 14% silicium')
instead of:
Legering%20van%20%C4%B3zer%20met%2014%%20silicium
They can’t just use special URL encoded chars without encoding them as well.
Rob
February 5, 2021, 8:44am
3
This is the exact url sent:
https://localhost:25810/puzzle/question/Legering%20van%20%C4%B3zer%20met%2014%25%20silicium
And it gives this:
FormatException: Could not find any recognizable digits.
System.ParseNumbers.StringToInt(ReadOnlySpan s, int radix, int flags, ref int currPos)
System.Convert.ToByte(string value, int fromBase)
ServiceStack.StringExtensions.UrlDecode(string text) in StringExtensions.cs
ServiceStack.AppHostBase.ProcessRequest(HttpContext context, Func next) in AppHostBase.NetCore.cs
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
System.FormatException: Could not find any recognizable digits.
at System.ParseNumbers.StringToInt(ReadOnlySpan1 s, Int32 radix, Int32 flags, Int32& currPos) at System.Convert.ToByte(String value, Int32 fromBase) at ServiceStack.StringExtensions.UrlDecode(String text) in C:\BuildAgent\work\912418dcce86a188\src\ServiceStack.Text\StringExtensions.cs:line 155 at ServiceStack.AppHostBase.ProcessRequest(HttpContext context, Func
1 next) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\AppHostBase.NetCore.cs:line 264
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
mythz
February 5, 2021, 8:50am
4
Can you provide the raw HTTP Request?
Rob
February 5, 2021, 9:20am
5
Better yet. Here’s a small test program that demonstrates the behaviour:
http://www.webfeud.com/wf/HttpRequestTest.zip
It seems that the URL gets mangled as soon as the reuqest is passed to ServiceStack.
1 Like
mythz
February 5, 2021, 10:10am
6
Cheers, issue was the path is already URL Decoded in .NET Core, resolved in this commit .
Will let you know when this change is on MyGet.
1 Like
mythz
February 5, 2021, 11:06am
8
FYI now available from the latest v5.10.5+ that’s now on MyGet.
Rob
February 5, 2021, 11:52am
9
Confirmed! Works like a charm.
1 Like