runtime: [Uri] Does not allow $ in a hostname
Issue Title
System.Uri cannot parse trailing $ sign in paths
General
We want to store and load data from WSL2 rootfs projection, which is exposed into Windows as “\\wsl$”, we use this UNC path internally, to construct and manipulate the path. However, System.Uri cannot parse “\\wsl$” and throws a format exception:
System.UriFormatException: ‘Invalid URI: The hostname could not be parsed.’
Example code and repro
var uri = new System.Uri(@"\\wsl$");
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 35 (31 by maintainers)
Thanks @karelz. I have met with the WSL team, they are open to changing the share name to work with System.Uri, they have a candidate for a new name, and are working on telemetry to validate that the new name does not conflict with other names. I will provide more updates here once I have them.
Based on offline discussion, WSL team is considering change of the name (as it violates spec). Closing for now, we can reopen and reconsider if things change in future.
I am too 😄
Oh looks like as of Windows 10 20175 they added support for
\\wsl\instead of\\wsl$\with the dollar sign version being a legacy fallback. https://docs.microsoft.com/en-us/windows/wsl/release-notesThis build should be getting generally released soon enough. (Edited: I thought this was coming in 21H1, I was wrong. Probably 21H2?)
As noted offline, before going to far we probably want to understand whether this would help @itodirel anyway, given any change would almost surely only be in .NET Core. (He mentioned Visual Studio which still runs on .NET Framework.)
@itodirel do you have an update to share? I will unlock meantime.😀
Oops, sorry. Yes, I was totally mixed up.
We’ve discussed this in triage:
$is not a valid character for DNS hostnames, a path like\\wsl$technically violates the spec. We should seek guidance from the spec’s maintainers regarding this.reg-namesyntax definition, it isSystem.Urithat chooses to use a more-strict DNS validation for hostnames.\\wsl$and explicitfile:////wsl$form). We don’t see an upside to allowing it for other schemes (such as http).Yes, but relative is more of a Uri string wrapper that doesn’t provide much utility.
It’s not valid because of the $ being in the host -
System.Urisupports implicit file as input, so\\wsl\foowithout the explicit file scheme is fine.If you don’t think about it being in an implicit file form though, the format itself is not against the Uri spec - it’s just a question of what kind of hostname rules are used. See https://github.com/dotnet/runtime/issues/36595#issuecomment-630066238
I am against this.
UriKind.Relativeis kind-of this already - a string wrapper with no utility. If a string can’t be parsed and understood by Uri, it can’t provide info with properties either.If we decide this is something we would like to support, the question of allowing
$in the host opens up discussion for whether we should supportRegistry-based Naming Authorityin its entirety (that would include more characters and percent-encoding) or just make an exception for$.new Uri("\\wsl$")parses as an absolute URI, so it interprets thewsl$as a hostname.new Uri("\\wsl$", UriKind.Relative)parses as a relative, so it interprets thewsl$as part of the path/query.I’m not going to speak for @itodirel, but I’ve built systems in the past that used URIs to specify actions.
Relative URIs were also used to add/override parameters.
It won’t be becuase
.alone is not a valid host either.$itself in the path is not problematic - for example\\foo\C$works fine.This is an issue with that part of a UNC path being the host -
$in the host name will not be recognized.The validation fails in
IsValidDomainLabelCharacterfor http Uris orUncNameHelper.IsValidfor UNC paths.This stems from the fact that
System.Urivalidates hostnames as aServer-based Naming Authorityfor DNS resolution and not by the less-strict, genericRegistry-based Naming Authorityrules as defined in RFC 2396 and 3986.