Rewrite rule that works for different domains and subdomains - asp.net

I am wondering if it is possible to set up a rewrite rule where you do not specify the domain, only the page accessed and the page to redirect to. My goal for this is to not have to have different versions of the same rule for different sites (i.e. dev.mysite.com, qa.mysite.com, etc), so one rule works for multiple subdomains. For example, I need to redirect someone going to dev.mysite.com/mexico to mx.dev.mysite.com/es/mexico, but that also has to work for QA. Additionally, production has a slightly different domain which would make this even more difficult. This is what I came up with - it definitely needs work:
<rule name="Test Mexico Redirect">
<match url="^mexico"/>
<action type="Redirect" url="http://mx.{R:2}/es/mexico" redirectType="Permanent"/>
</rule>
Unfortunately it just does not work; I get a blank page. Probably because {R:2} is looking for the domain in the rule and one isn't specified. I can't think of a way to do this, because not even the domain is the same across all environments.
It would be cool if you could use regex in the <action> element, then I would do something like this: ^(mx\.).*com/es/mexico.

It's possible using {HTTP_HOST} and back references like {C:#}. The IIS Rewrite module is extremely useful for setting this up. Here is a screenshot with some notes that explains how it's done:
By using {HTTP_HOST} and conditions I was able to make a rewrite rule that can apply to all environments. The actual XML result:
<rule name="Mexico Redirect" stopProcessing="true">
<match url="mexico" />
<conditions>
<add input="{HTTP_HOST}" pattern="^((?!mx))" />
<add input="{CACHE_URL}" pattern="^(.+)://" />
</conditions>
<action type="Redirect" url="{C:1}://mx.{HTTP_HOST}/es/search" redirectType="Temporary" />
</rule>
Also I may have been incorrect saying you won't need to recycle the app pool with a Temporary (307) redirect. I still needed to recycle it but only in production... no verdict on this yet.

Related

Website deployed on IIS Server displays a blank page

The main problem is specified in the title; however, it is a little more nuanced than that.
I cannot give away the exact address, but the URL has the syntax: https://name.mywebsite.com.
If I go to that exact address, the page will load as intended. If I try to be more specific about where exactly I want to go on the page - let's say to: https://name.mywebsite.com/home - I get a blank page.
Curiously enough, after I go to https://name.mywebsite.com, all the other addresses work as well and either redirect me to that address or display the site that they are supposed to show. I figured out that some necessary Cache-Data and data for the local storage are not set if I don't call the site over the mentioned address.
All of that wouldn't be much of a problem, since only the first call of the website is affected. However, most users of the site will first call it with a QR-Code (which leads to a specific sub-page of the site), and it wouldn't be very nice if they are greeted with a blank page.
Also, it is a .NET Core App with Angular Frontend.
I can reproduce the error by clearing my cache and cookies. The necessary data is no longer set and all domains will display a white page - except https://name.mywebsite.com - again.
I think I understood the problem, but I cannot seem to come up with a solution. I tried some changes in the IIS Manager on the server, but to no avail. My main bet was to apply an inbound rule with the URL Rewrite function, but that did not work.
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect from first shop open" enabled="false" stopProcessing="true">
<match url=".*" />
<action type="Redirect" url="https://name.mywebsite.com/" appendQueryString="true" logRewrittenUrl="true" redirectType="Found" />
</rule>
</rules>
</rewrite>
</system.webServer>
I also tried that rule with all possible Redirect types. Those rules do alter the page, but not in the way I want it. Instead of the blank white page I get an error that the redirect failed (with the hint that it is probably due to a lack of cookies). That error applies to all pages, even https://name.mywebsite.com. So I have no way of accessing the website now.
I also tried to find any other configuration that might prevent other URLs from loading the data, but I did not find anything like that either (or I simply looked at the wrong places).
Edit: /home would be a route in Angular. Also, the only rewrite rule that exists and that I tried is the one shown in the picture (which I updated so that it fits better with the question). I made some changes to the question in general.
As it turns out, I simply had to make some changes to the rule I posted in the question. Changing the Redirect to a Rewrite that targets /index.html and adding some conditions (which should be adapted to your personal needs) did the trick and the website no longer shows a blank page.
The link from Lex Li in the comments from the questions angular.io/guide/deployment#fallback-configuration-examples and the link https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/url-rewrite-module-configuration-reference#accessing-url-parts-from-a-rewrite-rule helped me building the correct rule.
<rewrite>
<rules>
<rule name="Angular Routes" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern=".*/(home|item.*)" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" logRewrittenUrl="false" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name=".*" />
</rewriteMaps>
</rewrite>

Web Config Rewrite/redirect

I am working on an existing project that I did not create.
In the web.config file, there are a number of redirects, setup in the following way:
<rewriteMaps>
<rewriteMap name="Redirects">
<add key="/findyourlocalbranch/" value="/find-your-local-branch/" />
</rewriteMap>
</rewriteMaps>
It seems to me that a rewrite rule is being used to do these redirects, but as I said, I did not write this and am not in a position to change this. I am not sure if this is right or wrong.
My problem is that I need to implement the following redirect:
<add key="/need-a-loan/.htm" value="/need-a-loan/" />
but this brings the whole site down - I suspect due to a syntax error in this line.
I suspect the error is the '.' after the '/'
My question is, what can I do about it - there is nothing on the internet that I can find about this.
Basically, I want to redirect this one, specific URL to the given URL???
I can't say whats going on with the map, as without the corresponding rule I'm blind.
But, this rewrite rule will redirect from /need-a-loan/.htm to /need-a-loan/.
<rewrite>
<rules>
<rule name="Need-A-Loan" stopProcessing="true">
<match url="need-a-loan/.htm" />
<action type="Redirect" url="need-a-loan/" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
Note: doesn't use the map, so you'd remove that entry.
That will give you a 301. If you want a different type, you can adjust the rediectType. E.g. Temporary will give you a 307.

Redirect non-www to www with IIS URL Rewrite generically without hardcoding domain or TLCD

I am building an ASP.NET CMS-driven web application which will serve multiple websites under different domain names. Some of these will use www sub-domain, others will use custom sub-domains. There will be a variety of top-level country domains.
I'm looking for a generic IIS URL Rewrite rule that will redirect any URL which doesn't specify a sub-domain to its www equivalent.
When I say generic it means the rule cannot hard-code either domain name or top-level country domain. So the rule must redirect
http://anything.anywhere/any-path to http://www.anything.anywhere/any-path but leave http://sub.anything.anywhere/any-path.
The closest I've found is this which still hard-codes TLCD. Without much knowledge of the syntax of URL Rewrite I'm not sure how to handle any TLCD.
Thanks in advance.
Update:
Inspired by comment, I've had a go with regex, but haven't yet found a method that doesn't require me to hard-code a list of all possible TLCDs. I suspect this is the best I'll get. Can anyone refine or confirm this as the answer?
^([a-z]+[.](com|co.uk|de|fr|etc)+)*
I just did the exact same thing using a rewrite rule with two conditions, one to get the Scheme and one to determine if the www is missing. The scheme is necessary as the redirect has to be absolute, but if your not catering for HTTPS that could be hard-coded. Just bear in mind I've not had time to test the HTTPS part yet, but pretty sure it will work ok.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Root Redirect" stopProcessing="true">
<match url=".*" negate="false" />
<action type="Redirect" url="{C:1}://www.{HTTP_HOST}/{R:0}" />
<conditions trackAllCaptures="true">
<add input="{CACHE_URL}" pattern="^(.*)://" />
<add input="{HTTP_HOST}" pattern="^(?!www\.).*" />
</conditions>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

Using Url Rewrite to change REMOTE_ADDR works for files but not folders

I have a number of websites that make use of the REMOTE_ADDR server variable to record client IPs for metrics. In moving the hosting of these sites into a load balanced environment we're now only ever getting the load balancer IP in REMOTE_ADDR. I'm fully aware of the use of HTTP_X_FORWARDED_FOR and how it works and we do have access to it and my preferred solution is to simply update the applications to use it.
However, the powers that be here want to avoid having to update all of the websites :( I'm looking into alternatives in the mean time.
Ultimately this means finding some way of replacing REMOTE_ADDR with HTTP_X_FORWARDED_FOR before the request hits the applications.
I'm trying to get the URL Rewrite 2.0 module working using advice from another acole76's question here:
IIS 7 Rewrite web.config serverVariables directive not working in sub folder
My web.config is practically the same as his:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="RemoteHostRewrite">
<match url="(.*)" ignoreCase="true" />
<serverVariables>
<set name="REMOTE_ADDR" value="4.3.2.1" />
</serverVariables>
<action type="Rewrite" url="{R:0}" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I'm using a hard-coded value 4.3.2.1 here for testing. I'll eventually replace that with the real value {HTTP_X_FORWARDED_FOR}.
Now, this works absolutely fine if a url contains a file name. It does not work if the url does not end with a file name.
For example:
mysite.local/default.aspx - works
mysite.local/ - does not work
mysite.local/folder/default.aspx - works
mysite.local/folder/ - does not work
I'm stumped! Can anyone offer any help?
you have to set another rule:
<match url="^$" />
<action type="Rewrite" url="/default.aspx" />
or whatever your default-page is
otherwise "url" will be empty --> no rule used

IIS url rewrite | How to remove directory and extension?

I have been struggling with the following for quite some time now:
Default url:
examplesite.com/folder/about.cshtml
Desired url:
examplesite.com/about
Basically I want to accomplish two things:
1 Remove the file extension with realtively compact code.
2 Remove the folder that houses the about page.
I have found some uncommon rules to achieve all the above, but they mostly contain a lot of redundant code that crashes my site when I test it with IIS 8.0.
So I was hoping someone could share a rule that is compact and fits my needs. Or seperate rules with the same outcome.
Every contribution is much appreciated :)
I'm not certain I entirely understand your needs, but here's something that's at least close. It strips out the first folder and file extension (so examplesite.com/folder/about.cshtml becomes examplesite.com/about and examplesite.com/folder/help/about.cshtml becomes examplesite.com/help/about). If you wanted to strip all folders then just remove the ?.
<rule name="Remove Directory and Extension">
<match url="^(.*?)/(.*)\.cshtml$" />
<action type="Rewrite" url="{R:2}" />
</rule>
Update:
Ok, I think what you want is a combination of two rules then:
<rules>
<rule name="Redirect requests to friendly URLs">
<match url="^(.*?)/(.*)\.cshtml$" />
<action type="Redirect" url="{R:2}" />
</rule>
<rule name="Rewrite friendly URLs to phsyical paths">
<match url="^(.*)$" />
<action type="Rewrite" url="folder/{R:0}.cshtml" />
</rule>
</rules>
The first rule makes sure that all requests are to friendly URLs. The second takes the friendly URL and rewrites it to your physical path, where the physical path is folder/[FRIENDLY_PATH].cshtml.

Resources