dotnet / dotnet/aspnetcore

Allow Host matching based on wildcard suffix

Open
#19,369 13 comments 0 reactions 0 assignees View on GitHub
affected-very-few area-mvc enhancement feature-routing severity-nice-to-have
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is your feature request related to a problem? Please describe.
I am trying to build a service using the Endpoint Routing feature where some endpoint should only be accessible through a specific sub domain while others should be accessible through a different one.
For example, I have two DNS
- subdomain1.[environment].mydomain.com
- subdomain2.[environment].mydomain.com

[environment] could be dev, staging etc... depending where it is deployed. I'm not worry to much on security for this component since we already a component validating the hosts before the request is forwarded to this one. It is only used for routing purpose.

### Describe the solution you'd like
I tried to use the Host matching policy using the `RequireHost` extension method on the endpoint however it does not support wildcard as suffix, I would love to be able to use hosts patterns like
- subdomain1.*
- subdomain2.*

I tried to see if it would be complicate to support with the currently policy implemented and it seems to only be a few line of codes.

First modify the EdgeKey constructor in [HostMatcherPolicy.cs](https://github.com/dotnet/aspnetcore/blob/0a1d68b8f375eb979c5722b8bedd57496749b1f8/src/Http/Routing/src/Matching/HostMatcherPolicy.cs)

```
public EdgeKey(string host, int? port)
{
Host = host ?? WildcardHost;
Port = port;

if (Host.StartsWith(WildcardPrefix, StringComparison.Ordinal))
{
HasHostWildcard = true;
_wildcardEndsWith = Host.Substring(1);
_wildcardStartsWith = null;
}
else if (Host.EndsWith(WildcardSuffix, StringComparison.Ordinal))
{
HasHostWildcard = true;
_wildcardEndsWith = null;
_wildcardStartsWith = Host.Substring(0, Host.Length - 1);
}
else
{
HasHostWildcard = false;
_wildcardEndsWith = null;
_wildcardStartsWith = null;
}
}
```

Then modify the MatchHost method in the same file
```
public bool MatchHost(string host)
{
if (MatchesHost)
{
if (HasHostWildcard)
{
if (_wildcardEndsWith != null)
{
return host.EndsWith(_wildcardEndsWith, StringComparison.OrdinalIgnoreCase);
}
else
{
return host.StartsWith(_wildcardStartsWith, StringComparison.OrdinalIgnoreCase);
}
}
else
{
return string.Equals(host, Host, StringComparison.OrdinalIgnoreCase);
}
}

return true;
}
```
Or maybe this to avoid many nested if
```
public bool MatchHost(string host)
{
if (!MatchesHost)
{
return true;
}

if (!HasHostWildcard)
{
return string.Equals(host, Host, StringComparison.OrdinalIgnoreCase);
}

if (_wildcardStartsWith != null)
{
return host.StartsWith(_wildcardStartsWith, StringComparison.OrdinalIgnoreCase);
}

return host.EndsWith(_wildcardEndsWith, StringComparison.OrdinalIgnoreCase);
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.