3
votes

I want to redirect subdomains that come to iis to subdomains in localhost:port that my dotnet core application is running.


Simply i want to redirect like this:

xyz.example.com => xyz.localhost:4000

john.example.com => john.localhost:4000

test.example.com => test.localhost:4000

example.com => localhost:4000 (no subdomain address redirects to localhost:4000)


How can I do this with url rewrite rules is iis?


Edit:

there are some solutions for one subdomain (like this question) but my question is more general to redirect all subdomain from one domain to corresponding subdomain in another domain.

1
No, this is not duplicate, because that question that you mentioned is very simpler than my problem. I need dynamically rewrite all subdomains, not only samples I wrote.Hussein Jahanbakhsh

1 Answers

5
votes

Here is the rule that performs redirect you are asking for:

<rewrite>
    <rules>
        <rule name="Test Rule" stopProcessing="true">
            <match url=".*" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="^((.+.)?)example.com" />
            </conditions>
            <action type="Redirect" url="http://{C:1}localhost:4000{REQUEST_URI}" appendQueryString="false" />
        </rule>
    </rules>
</rewrite>

It's pretty straightforward:

  1. <match url=".*" /> matches any URL. Whether requested URL is in example.com domain is checked in later condition. match section is useless for our case because it operates with the URL part without a hostname (after first '/').

  2. Condition <add input="{HTTP_HOST}" pattern="^((.+.)?)example.com" /> matches domains like xyz.example.com or example.com. If condition is matched, capture group {C:1} will contain xyz. for xyz.example.com and empty string for example.com, which will be used further.

  3. <action type="Redirect" url="http://{C:1}localhost:4000{REQUEST_URI}" appendQueryString="false" />

    The result URL is built as http://{C:1}localhost:4000{REQUEST_URI}. {C:1} will hold subdomain name as said above and {REQUEST_URI} contains URL part after hostname. We also set appendQueryString to false because query is a part of {REQUEST_URI}.

You should add this <rewrite> section to site web.config under <system.webServer>. You could also configure it manually from IIS Configuration Manager. Here is a screenshot of such configuration:

enter image description here

Finally, here is a set of test that demonstrates how urls are changed:

[TestCase("http://xyz.example.com", "http://xyz.localhost:4000/")]
[TestCase("http://xyz.example.com/some/inner/path", "http://xyz.localhost:4000/some/inner/path")]
[TestCase("http://xyz.example.com/some/inner/path?param1=value1&param2=value2", "http://xyz.localhost:4000/some/inner/path?param1=value1&param2=value2")]
[TestCase("http://example.com", "http://localhost:4000/")]
[TestCase("http://example.com/some/inner/path", "http://localhost:4000/some/inner/path")]
[TestCase("http://example.com/some/inner/path?param1=value1&param2=value2", "http://localhost:4000/some/inner/path?param1=value1&param2=value2")]
public void CheckUrlRedirect(string originalUrl, string expectedRedirectUrl)
{
    using (var httpClient = new HttpClient(new HttpClientHandler {AllowAutoRedirect = false}))
    {
        var response = httpClient.GetAsync(originalUrl).Result;

        Assert.AreEqual(HttpStatusCode.MovedPermanently, response.StatusCode);
        var redirectUrl = response.Headers.Location.ToString();
        Assert.AreEqual(expectedRedirectUrl, redirectUrl);
    }
}