IIS URL Rewrite Module Canonical Link Only If No Subdomain - regex

I am using the IIS URL Rewrite module on a Windows 2012 server. I only want to add a canonical www rule if a subdomain is missing (or an exact match on 'example.com').
The problem is the ready-made Canonical rewrite rule IIS creates rewrites all traffic (*) for all subdomains to www.
<rule name="CanonicalHostNameRule1">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" />
</rule>
The problem is that I have multiple subdomains / applications under one site (and therefore one web.config).
I want
example.com
to go to
www.example.com
but to leave these and any other subdomain alone:
secure.example.com
profile.example.com
Do I need a more specific match regex or pattern?
More specifically, the secure subdomain uses https and a better encryption certificate.

You're looking for everything that is not www.example.com. And that includes all other sub-domains.
Let's have a look at your condition:
<add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" />
If www.example.com comes in --> match = true --> negate --> false --> nothing is changed (as you want)
If example.com comes in --> match = false --> negate --> true --> URL gets redirected (as you want)
If foo.example.com comes in --> match = false --> negate --> true --> URL get redirected (as you don't want)
To fix this, try this configuration:
<rule name="Redirect to www" stopProcessing="true">
<match url="(.*)" />
<conditions trackAllCaptures="true">
<add input="{CACHE_URL}" pattern="^(.+)://" />
<add input="{HTTP_HOST}" pattern="^example\.com$" />
</conditions>
<action type="Redirect" url="{C:1}://www.example.com/{R:1}" />
</rule>
The C:1 part is for the protocol (http and https).
Found here.

This regex is better:
^(w{3}\.)?\w+\.com/
This regex will give you the option to get url with and without the www. and the / at the end, but still wont math a subdomain.

Related

IIS Rewrite - redirect site to new domain capturing the language embedded in the URL

I am trying to write a regex to redirect the URL to a new domain. I wrote IIS Rewrite rule for this:
<rule name="Redirect to new domain" stopProcessing="true">
<match url="^(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^(www\.)?my-www-en\.sites\.company\.net(\/([a-zA-Z]{2,3}-[a-zA-Z]{2,3}|en)\/?)?(.*$)" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="https://my-new-domain.com/en-us/{C:4}" appendQueryString="true" />
</rule>
It works fine when the language is not added to the initial URL, however, some of the pages have the language added after the domain which results in double language appearance in the end URL.
So basically I would like to redirect things like:
my-www-en.sites.company.net/some-page/another/page/
www.my-www-en.sites.company.net/some-page/another/page/
my-www-en.sites.company.net/de-de/some-page/another/page/
www.my-www-en.sites.company.net/de-de/some-page/another/page/
my-www-en.sites.company.net/en/some-page/another/page/
to redirect to:
https://my-new-domain.com/en-us/some-page/another/page/
My current regex does not capture these groups correctly (even when it does while testing the regex in IIS rewrite) and I struggle to make it work. Right now everything gets redirected to the homepage instead to particular websites. Could you please help?
Please try this rule. The regular expressions can match all urls above.
<rule name="test">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="^(www\.)?my-www-en\.sites\.company\.net$" />
<add input="{REQUEST_URI}" pattern="(/.*)?(/some-page/another/page/)" />
</conditions>
<action type="Rewrite" url="https://my-new-domain.com/en-us{C:2}" />
You can change rewrite to redirect.

What is wrong with this regex in my rule redirect? (web.config)

This is a Azure WebApp web.config question.
I want to redirect all non-HTTPS requests to same url but with HTTPS, basically replacing the HTTP with HTTPS.
But not if the url containst following string: "/config/add_new_user?login=xxx&w=1".
This is my block in the section in web-config.
<rule name="Force HTTPS" stopProcessing="true">
<match url="(\/config\/add_new_user\?login=license_wizard\&w=1)" negate="true" />
<conditions>
<add input="{HTTPS}" pattern="OFF" />
</conditions>
<action type="Rewrite" url="public/redirect.html" />
</rule>
But i get error 500.19 - Configuration file is not well-formed XML
I used https://regex101.com/#javascript to work out the regex and tested with different urls. It seams to work out, the expression hits on the text.
So the negate="true" should reverse the statement, so only urls without the given string is matched and thus rewritten.
Oh by the way, the web.config xml seams to be ok, because when i change the regex back to the original then web-site works.
So this works:
<match url="(.*)" />
and this does not:
<match url="(\/config\/add_new_user\?login=license_wizard\&w=1)" negate="true" />
The & must be encoded as & in XML files.
<match url="(\/config\/add_new_user\?login=license_wizard\&w=1)" negate="true" />

IIS7.5 URL Rewrite Regex matching when it shouldn't

I have split some pages in between subdomains and want to do a URL rewrite to different pages on different subdomains in certain cases. Everything is a rewrite rule except for the final two rules in the file. Those last two rules determine which subdomain to route the path I fixed to.
The way I am doing it is if I prepend the path with an underscore (_) then it stays on subdomain A. If I prepend the path with a tilde (~) then it is redirected to subdomain B.
So I have this rule:
<rule name="Login rule" stopProcessing="false">
<match url="(.*?)/?old-path/Login\.aspx$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_METHOD}" pattern="GET" />
</conditions>
<action type="Rewrite" url="~new-path/login.aspx" />
</rule>
Please notice there is an aspx on the end of the URL. It continues processing, but I have a generic rewrite rule at the end of the list right before the redirect ones. This is to remove all ASPX extensions on subdomain A (www), but I want to leave the ASPX extension for subdomain B (Please don't suggest removing the suggested on the 2nd subdomain. Thanks :)
<rule name="Remove ASPX" stopProcessing="false">
<match url="^([^www\.]+)\.aspx$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="_{R:1}" />
</rule>
The problem is, is this won't work because all the URLs have www in the beginning. I am not that good with regex, but I am guessing I need to just apply this rule to all URL that has a tilde in it. I tried this, but it's not really working either:
<match url="^_+\.aspx$" />
Basically I want this rule to ignore URLs that I have rewritten to have a ~ in them, but remove the ASPX if I placed the _ at the start of the path.
Any suggestions?
If I'm understood your problem then you have URL: "~new-path/login.aspx" and you want do redirect to "~new-path/login", right?
Then your regex should be like this:
^(.*~.*)\.aspx$
Note: "www" is a part of domain name and not included into matching.
So if your full URL is "http://www.mysite.com/~new-path/login.aspx" then only "~new-path/login.aspx" piece will take part in regex matching.
And template {R:1} will contain value in first group (braces): "~new-path/login"

Regex URL match on anything but www

I'm using IIS7 and the URL Rewrite module.
I would like to use regex to match any subdomain apart from www.
So...
frog.domain.co.uk = Match
m.domain.co.uk = Match
anything.domain.co.uk = Match
www.domain.co.uk = No match
This way I can redirect any subdomain that someone types in back to www.
you can use 301 in .htaccess for this.
This will match what you want:
^(?!=www\.).*
Which is a negative lookahead for www.. Not sure if you need the trailing .*
Use this rule -- it will redirect to www.exmaple.com domain if domain is different:
<system.webServer>
<rewrite>
<rules>
<rule name="Force www" stopProcessing="true">
<match url="(.*)$" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.example\.com" negate="true" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
You can optimize it a bit if you do not want to type domain name twice (example.com) -- but that is very minor thing and depending on your circumstances/configuration it is can be undesired.

Multi part RegEx in IIS 7 URL Rewriter for outbound links

I have been trying to get the IIS URL Rewrite engine to work for a specific case of outbound URLs. I am trying to lowercase all URLs except for those that match these criteria:
An outbound link with a hash tag: page.aspx#q=MixedCaseParameter
An already rewritten outbound friendly URL with a mixed case product id and product description: /shopping/product/A12345/Mixed-Case-Product-Description
An outbound link with javascript: in the HREF instead of a URL: javascript:__doPostBack('control','action')
I can do parts of it, but not all of it in one expression, but I can't get all three. Here is what I have right now:
([A-Z]+)((?:(?!app\.aspx#q).)|(?:^(?!javascript:).))
And the settings in the web.config:
<rewrite>
<!-- other rules excluded for clarity -->
<outboundRules rewriteBeforeCache="true">
<rule name="Outbound lowercase" preCondition="IsHTML" enabled="true">
<match filterByTags="A" pattern="([A-Z]+)((?:(?!app\.aspx#q).)|(?:^(?!javascript:).))" ignoreCase="false" />
<action type="Rewrite" value="{ToLower:{R:0}}" />
</rule>
<!-- Example friendly outbound rewrite rule -->
<rule name="Rewrite Product Outbound" preCondition="IsHTML" enabled="true" stopProcessing="true">
<match filterByTags="A" pattern="product\.aspx\?cat=catalogname&amp;pid=([0-9a-zA-Z\-]+)&amp;pdisplayname=([0-9a-zA-Z\-]+)" ignoreCase="true" />
<action type="Rewrite" value="/shopping/product/{R:1}/{R:2}" />
</rule>
<preConditions>
<preCondition name="IsHTML" logicalGrouping="MatchAny">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
<!-- Shopping Outbound Rules End -->
</outboundRules>
</rewrite>
Thanks.
Here is a regex that will match the three types of outbound urls you don't want to lowercase :
.*?page\.aspx#q|.*?/shopping/product|^javascript:
Test :
page.aspx#q=MixedCaseParameter => Matched
/shopping/product/A12345/Mixed-Case-Product-Description => Matched
javascript:__doPostBack('control','action') => Matched
http://google.com => NOT Matched