dotnet-websharper / core

WebSharper - Full-stack, functional, reactive web apps and microservices in F# and C#
https://websharper.com
Apache License 2.0
599 stars 50 forks source link

Encoded slashes (%2F) treated same as regular slash when using Sitelet.Infer #960

Open nbevans opened 6 years ago

nbevans commented 6 years ago

When Sitelet.Infer encounters a request that contains a %2F encoded slash, it should treat this as part of the path segment. But it does not; it treats it as an unencoded regular slash (/).

If the union case is such:

type EndPoint = [<EndPoint "GET /test"] Test of string * string .. and a GET request is issued to:

http://localhost/test/path%2Fseg1/pathseg2 The expectation is that this infers to a: EndPoint.Test ("path/seg1", "pathseg2")

But actually it doesn't and routes to the default root page.

W3C spec document here https://www.w3.org/Addressing/URL/4_URI_Recommentations.html suggests this is incorrect behaviour:

Example 2 The URIs http://www.w3.org/albert/bertram/marie-claude

and http://www.w3.org/albert/bertram%2Fmarie-claude

are NOT identical, as in the second case the encoded slash does not have hierarchical significance.

We are using W# 4.1.7.232 via OWIN middleware with Microsoft.Owin.Host.HttpListener (HTTP.SYS) as the HTTP server.

Jand42 commented 6 years ago

Thanks for the detailed report! I will test this with latest version, there has been some fixes to Infer since.

nbevans commented 6 years ago

My colleague found this which appears to be related: https://github.com/aspnet/AspNetKatana/issues/208

nbevans commented 6 years ago

Possible related: https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/network/add-element-for-schemesettings-uri-settings

Jand42 commented 6 years ago

@nbevans Thanks, I checked these out, seems like an ASP.NET non-compliance for which I could see no workaround yet...

WebSharper is actually encoding strings in routers with a its own custom logic using the ~ character so it is safely environment-independent. See this at https://github.com/dotnet-websharper/core/blob/master/src/sitelets/WebSharper.Sitelets/Router.fs#L67

So a string "xxx/yyy" becomes a segment xxx~2fyyy

ghost commented 6 years ago

@nbevans Possible related: https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/network/add-element-for-schemesettings-uri-settings

This setting does not affect how OWIN processes the URIs, since there is a bug in OWIN itself. You can verify that by playing around with that setting by just instantiating an Uri object that contains forward slashes encoded. There is a workaround to get "raw" URI that OWIN received from Http.Sys; it is provided in the "Workaround" section in the OWIN issue you've referenced (aspnet/AspNetKatana#208).