-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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 doesn't expose the original, user-provided port value #89768
Comments
Tagging subscribers to this area: @dotnet/ncl Issue DetailsWhen a port isn't specified, Uri automatically infers the default port based on the scheme: Console.WriteLine(new Uri("http://example.com").Port); // 80
Console.WriteLine(new Uri("https://example.com").Port); // 443 However, Uri doesn't provide any way to know whether that port was explicitly user-specified, or whether Uri inferred it. This presents a problem when using Uri to accept endpoint information from users for services which by default run on the non-standard port. For example, if my custom service by default runs over HTTP on port 12345, and the user omits the port, Uri will return 80 as the HTTP default. If I assume that 80 means the user hasn't provided a port and default to 12345, it becomes impossible for the user to run on port 80 if they so wish. Of course, it's possible to do various string matching to see whether /cc @stephentoub
|
cc: @MihaZupan |
I don't think there's a built-in way to distinguish whether the port was set vs. it had a default value for A workaround that makes use of that fact without manually parsing stuff: internal static class UriHelper
{
// "http://foo/test" => -1
// "http://foo:80/test" => 80
public static int GetOriginalPort(this Uri uri)
{
Debug.Assert(uri.Scheme is "http" or "https");
return new Uri($"custom-{uri.OriginalString.TrimStart(' ', '\n', '\r', '\t')}", UriKind.Absolute).Port;
}
} |
I think an API along the lines of |
I somewhat does not understand the argumentation. Uri has |
The service in question is a database server using gRPC over HTTP, with some arbitrary non-80 port as its default. On the client side, the .NET gRPC client has GrpcChannel.ForAddress, which accepts a Uri, and AFAIK the http scheme is expected there; it really does speak HTTP over the wire, it just does it on a different default port. So for one thing, I'm not sure I can invent a new scheme and pass it to GrpcChannel: it may very well care about the scheme (e.g. http vs. https to know about encryption?). It's also a bit odd to require users to use the specific new scheme where in fact it's just HTTP on the wire. Does that make sense? |
I am running into the same problem. I have a URI I want to accept and for my application my default port is 38281 so I would like to know if the user did or didn't provide one and set it to 38281 if they didn't. However If my user decides to run on port http port 80 or https port 443 (which they are allowed to do) I can't determine if I should use the default 38281 or not because 80 may be what they explicitly provided or the default. |
Chiming in that we had the same problem in dotnet/sdk#44050 - for our scenario (falling back to default ports for http if https doesn't work) we needed to know if the user-provided domain had a port or not, but we didn't want the port-defaulting behavior of |
When a port isn't specified, Uri automatically infers the default port based on the scheme:
However, Uri doesn't provide any way to know whether that port was explicitly user-specified, or whether Uri inferred it. This presents a problem when using Uri to accept endpoint information from users for services which by default run on the non-standard port.
For example, if my custom service by default runs over HTTP on port 12345, and the user omits the port, Uri will return 80 as the HTTP default. If I assume that 80 means the user hasn't provided a port and default to 12345, it becomes impossible for the user to run on port 80 if they so wish.
Of course, it's possible to do various string matching to see whether
:80
was present, but it seems like Uri should provide some way to access the user-provided port, or to know whether the port was inferred or not./cc @stephentoub
The text was updated successfully, but these errors were encountered: