Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Uri] Uri does no accept mailto protcoll with multiple recipients #30300

Closed
LokiMidgard opened this issue Jul 18, 2019 · 10 comments
Closed

[Uri] Uri does no accept mailto protcoll with multiple recipients #30300

LokiMidgard opened this issue Jul 18, 2019 · 10 comments
Labels
area-System.Net enhancement Product code improvement that does NOT require public API changes/additions
Milestone

Comments

@LokiMidgard
Copy link
Contributor

Trying to create following Uri new Uri("mailto:[email protected],[email protected]") will result in an Exception System.UriFormatException: 'Invalid URI: The hostname could not be parsed.'.

If I understand RFC 6068 correctly, You should be able to splitt multiple addresses with a ,

      mailtoURI    = "mailto:" [ to ] [ hfields ]
      to           = addr-spec *("," addr-spec )
      hfields      = "?" hfield *( "&" hfield )
      hfield       = hfname "=" hfvalue
      hfname       = *qchar
      hfvalue      = *qchar
      addr-spec    = local-part "@" domain
      local-part   = dot-atom-text / quoted-string
      domain       = dot-atom-text / "[" *dtext-no-obs "]"
      dtext-no-obs = %d33-90 / ; Printable US-ASCII
                     %d94-126  ; characters not including
                               ; "[", "]", or "\"
      qchar        = unreserved / pct-encoded / some-delims
      some-delims  = "!" / "$" / "'" / "(" / ")" / "*"
                   / "+" / "," / ";" / ":" / "@"
@davidsh
Copy link
Contributor

davidsh commented Jul 18, 2019

This is a known limitation with System.Uri.

@karelz
Copy link
Member

karelz commented Sep 12, 2019

Triage: Uri is already complex and messy. We need to redo and clean it, before we can add new parsing code path into it ...

@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the Future milestone Feb 1, 2020
@MihaZupan
Copy link
Member

@LokiMidgard
Is the ask here just to have Uri consider such input as valid? Or to also make use of the parsed value?
We could make new Uri not throw and TryCreate return true for Uris with multiple addresses, but an actual instance of Uri is not useful for such input.

Uri has the assumption of a single Host and UserInfo. Would these properties only return information about the first address? I don't think we would want to add mailto-specific properties to Uri.

Another thing to consider is Uri equality. It is documented that we ignore the UserInfo part, but that might not be obvious when dealing with MailTo uris - personally I find it nonsensical.

Currently:

Uri foo = new Uri("mailto:foo@domain");
Uri bar = new Uri("mailto:bar@domain");

Console.WriteLine(foo == bar); // true

What would we return in the case of multiple addresses (multiple hosts)?

@karelz
Copy link
Member

karelz commented Feb 26, 2020

Agreed, looks like Uri might not be the best fit for full mailto support ...

@LokiMidgard
Copy link
Contributor Author

I tried to used some WinRT API that only accepted URI's. It's some time ago, I need to look what I actually tried to call.

@LokiMidgard
Copy link
Contributor Author

I have tried to work with Windows.System.Launcher.LaunchUriAsync

I now use Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }).

I'm writing a Win32 app that is packaged. I'm not sure if this workaround would work for UWP apps.

I also have looked at the documentation and was not able to find any part that said some valid uri's are not supported. Either it is not there or I did not recognize it. I would expect a note box at the beginning of remarks that says "not every valid uri is supported" or better listing what uri's do not work.

Up to now I normaly used Uri to tell the caller that he needs to use an url as parameter. I wasn't aware that some valid url's might not be usable with my method because I did not use string.

Maybe that was also the case with the WinRT API.

@LokiMidgard
Copy link
Contributor Author

LokiMidgard commented Feb 26, 2020

@MihaZupan to answer your question. What I wan't is to give a method that accepts only 'Uri' objects an "valid" input for that method. But it seems to be more complicated ¬_¬

If Uri would parse it according to RFC 3986 [email protected],[email protected] would be the path. I'm not sure if that matches the AbsolutePath property of Uri.

mailto:[email protected],[email protected]
\ 1  / \           2             /
[1]: scheme
[2]: path-rootless

The Uri parserses mailto:[email protected] to {Scheme: mailto UserInfo: user Host: test.de} but should not. To get UserInfo and Host the uri must look like 'mailto://[email protected]'.

To have host, port and userinfo which is defined in authority a // is needed after scheme ":"

   URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
   hier-part     = "//" authority path-abempty
                 / path-absolute
                 / path-rootless
                 / path-empty
   authority     = [ userinfo "@" ] host [ ":" port ]
   path-rootless = segment-nz *( "/" segment )
   segment-nz    = 1*pchar
   pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
   pct-encoded   = "%" HEXDIG HEXDIG
   unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
   reserved      = gen-delims / sub-delims
   sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
                 / "*" / "+" / "," / ";" / "="

Of course changing the current behavior would probably break everyone that is currently using Uri to get host and user from a mailtto uri.


Still the problem I head persists. From my perspective there seems to be two approaches that do not break everyone and helps everyone who uses LaunchUriAsync.

  • Parsing Uri the same as always, but if it fails check if it isn't actually conform to the ABNF of uri
  • Overload Windows.System.Launcher.LaunchUriAsync() with string.

The later will probably not break anyone because Uri does not change. The former still could break some code, since I now can call methods with parameters that were not possible before.

But the first approach could also fix the same problem with other methods that require Uri.

@karelz
Copy link
Member

karelz commented Feb 26, 2020

Overload Windows.System.Launcher.LaunchUriAsync() with string.

@LokiMidgard please note that WinRT APIs are part of Windows OS and have nothing to do with .NET. The closest thing we do is that we map the native Uri type to our managed .NET Uri type for interop purposes. Which methods WinRT exposes or how it behaves is defined by its OS implementation though.
As such, this part is out of scope of this repo.

Parsing Uri the same as always, but if it fails check if it isn't actually conform to the ABNF of uri

I am not convinced the effort is worth the benefit. It would create second implementation for very rare scenario of multiple user addresses.
I would suggest to just mention it in documentation that mailto part of the spec is not fully honored by Uri.

@LokiMidgard
Copy link
Contributor Author

I though about editing the docs. But I'm not sure how to phrase it correctly. So I create an issue in the documentation reposetory.

I also would like to open an issue for LaunchUriAsync. Where would I do this?
My first guess would be the report a porblem button Visual Studio.

@karelz
Copy link
Member

karelz commented Feb 28, 2020

Visual Studio is not the right avenue either. I don't know if there is any way to report issues for WinRT APIs or their docs.

Closing as there is nothing left to work on here. Thanks!

@karelz karelz closed this as completed Feb 28, 2020
@karelz karelz modified the milestones: Future, 5.0.0 Aug 18, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net enhancement Product code improvement that does NOT require public API changes/additions
Projects
None yet
Development

No branches or pull requests

5 participants