URL Rewrite to https on certain URLs - http

I need to redirect http requests, to https. But only when my site is accessed via the normal URL. i.e. www.accufinance.com
When I access it in debug, locally, I connect using localhost - and don't want the rewrite to happen (As I don't have SSL locally).
I am trying this:
<rewrite>
<rules>
<clear />
<rule name="Redirect to https" stopProcessing="true">
<match url="^accufinance.com$" ignoreCase="true"/>
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
</rule>
</rules>
</rewrite>
But the rewrite rule doesn't happen. If I use (.*) as the match URL, it works fine, but catches ALL connections. How can I make the rule only fire when there is 'accufinance.com' in the URL?

You need to check HTTP_HOST with a condition to match your domain name.
The directive match for url param only contains what's after your domain name.
Example: http://www.domain.tld/some/url/here.ext
HTTP_HOST = www.domain.tld
REQUEST_URI = /some/url/here.ext
You can use this rule to do what you want
<rule name="Redirect to https" stopProcessing="true">
<match url=".*" ignoreCase="true" />
<conditions>
<add input="{HTTP_HOST}" pattern="^(www\.)?accufinance\.com$" ignoreCase="true" />
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
</rule>
Please note you'll need to clear your browser's cache before trying again (your old rule is still in cache because of your permanent redirect)

The regular expression ^accufinance.com$ is extremely restrictive. The ^ indicates that it must match all the way to the beginning (i.e. nothing else precedes it), and the $ requires that nothing follow it all the way to the end. As such, the match will only succeed when the request URL is exactly accufinance.com.
Try removing the ^ and $. Or, you can explicitly allow parts of the URL before and after the desired filter, as in .*accufinance\.com.*.

Related

Combine several 301 redirects into one for ASP.NET URL Rewrite module

I am trying to move a complex redirect logic implemented in Global.asax into a set of rules for the IIS URL Rewrite module in a classic ASP.NET website. Shortly, the logic must redirect requests like
{http|https}://[www.]ourdomain.com/[Home/]Products/old-product-name/page.aspx
to
https://ourdomain.com/new-product-name/
(optional and variable parts are in square and curly brackets).
The first 3 main things I implemented with URL Rewrite rules are the followings:
<rule name="Redirect to HTTPS">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
</rule>
<rule name="Canonical Host Name">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^ourdomain\.com$" />
</conditions>
<action type="Redirect" url="https://ourdomain.com/{R:1}" redirectType="Permanent" />
</rule>
<rule name="Default Page">
<match url="(.*)default.aspx" />
<conditions>
<add input="{REQUEST_URI}" negate="true" pattern="-default.aspx$" />
</conditions>
<action type="Redirect" url="{R:1}" redirectType="Permanent" />
</rule>
These rules allow to redirect requests like http://www.ourdomain.com/product-name/default.aspx to https://ourdomain.com/product-name.
However, the browser developer tools report that this conversion causes 301 redirects. I tried to find a solution of this redirect chain problem in the Internet and found this post. After reading it, I managed to recode my rules to have just one final 301 redirect with URL rewriting:
<rule name="Redirect to HTTPS">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Rewrite" url="_{REQUEST_URI}" redirectType="Permanent" />
</rule>
<rule name="Canonical Host Name">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^ourdomain\.com$" />
</conditions>
<action type="Rewrite" url="_{R:1}" redirectType="Permanent" />
</rule>
<rule name="Default Page">
<match url="(.*)default.aspx" />
<conditions>
<add input="{REQUEST_URI}" negate="true" pattern="-default.aspx$" />
</conditions>
<action type="Rewrite" url="_{R:1}" redirectType="Permanent" />
</rule>
<rule name="FINAL REDIRECT" stopProcessing="true">
<match url="^(_+)(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_METHOD}" pattern="GET" />
</conditions>
<action type="Redirect" url="https://ourdomain.com{R:2}" />
</rule>
However, this approach looks non-natural. It makes hard adding new rules because of these workarounds with the underscore character. And maybe, such several rewrite operations for one request may impact on the website performance.
Is there another, more elegant solution, of the 301 redirect chain problem for the URL Rewrite module?
This is not a limitation of IIS Url Rewrite, but the way the web works. A redirection sends a header to the browser telling it that it should navigate to another place. If you have 3 rules that apply to the same original request, and the 3 apply a redirection, then you'll always get 3 redirections no matter how you do it: IIS Url Rewrite, Apache .htaccess or your own custom code.
The solution you've implemented is a "patch" to change several redirections into internal rewrites in the server and a final "catch" of those special rewrites to transform them into a unique redirection at the end (BTW, if you have any real page that strats with _ you won't be able to access it with this extra rule). That's not bad and won't affect your performance, but it's ugly.
I'm not a SEO expert but I think the 301 chaining thing to reach a final similar URL won't hurt your SEO at all in recent times, if that's what worries you (read the final part specially). And being 301 redirects they will affect only the first visit of your users, so probably won't hurt your loading times or conversions either anyway.
However, if you want to avoid that, try to make a single rule for your purpose, doing all the transformations at once. In your case, you want to transform this:
{http|https}://[www.]ourdomain.com/[Home/]Products/old-product-name/page.aspx
(I guess /Home/ can be present sometimes or not)
into this:
https://ourdomain.com/new-product-name/
Then you can use this single rule:
<rule name="New URLs!!" stopProcessing="true">
<match url="^(Home/){0,1}Products/(.+?/).+.aspx" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
<add input="{HTTP_HOST}" negate="true" pattern="^ourdomain\.com$" />
</conditions>
<action type="Redirect" url="https://ourdomain.com/{R:2}" redirectType="Permanent" />
</rule>
and you will transform everything with a single rule (so, just one redirect). The regular expression in the match URL part will identify this specific kind of URL (old product URLs) and the conditions (matching any of them) will take care of the HTTPs and domain change. The stopProcessing="true" will keep other rules to act, and you'll have this specific kind of URLs under control.
Please note that I've not tested this rule and maybe it has minor problems. But you get the idea...
You'll need extra rules after this one to take care of other less-specific URLs, such as your general HTTP to HTTPS or canonical domain rules. But in the case you want to resolve, this will achieve what you want in a single step.

IIS Redirect HTTP to HTTPS and WWW to non-WWW

On IIS 10 with URL Rewrite Module 2.0 I need 2 rules
1) HTTP to HTTPS
2) WWW to non-WWW
First one created by Blank rule template.
For second one I use Canonical domain name template.
In my web.config rules likes like this:
<rewrite>
<rules>
<rule name="ForceHttps" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
<rule name="CanonicalHostNameRule1" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^cooltechunder\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://cooltechunder.com/{R:1}" />
</rule>
</rules>
</rewrite>
All cases works fine expect one starting with: http://www.
See this image for results I have:
https://i.imgur.com/h2l3Yw6.png
You wrote stopProcessing="true".
This means that, if the rule matches, subsequent rules will be skipped.
From the documentation:
A rule may have the StopProcessing flag turned on. When the rule action is performed (i.e. the rule matched) and this flag is turned on, it means that no more subsequent rules will be processed and the request will be passed to the IIS request pipeline. By default, this flag is turned off.
It seems to me that this is the situation you are describing that you did not want.
So, remove it.
Ok, My problem was different and related to bindings.
I have to specify 'Host Name' in bindings, as specific ports used by other websites also
And I forgot to add 'www' versions of bindings also.
Now my bindings looks like this: https://i.imgur.com/Lhdv4nS.jpg
Also I have changed rewrite code to more compact one:
<rewrite>
<rules>
<rule name="Https and non-www">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{HTTP_HOST}" pattern="^cooltechunder\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://cooltechunder.com/{R:1}" />
</rule>
</rules>
</rewrite>

Translating apache rewrite rules to IIS web.config

I am trying to translate this apache rewrite rule into web.config rules but I can't get it to work.
Basically it checks the user agent and redirect the agent to the url provided
# allow social media crawlers to work by redirecting them to a server-rendered static version on the page
RewriteCond %{HTTP_USER_AGENT (facebookexternalhit/[09]|Twitterbot|Pinterest|Google.*snippet)
RewriteRule qs/(\d*)$ http://sitetocrawl.com/doc?id=$1 [P]
This is what I have so far. However, I can't figure out how to catch the url querystring parameter. Basically the text string after http://example.com/qs/parameter
<rule name="Social Rewrite" patternSyntax="ECMAScript" stopProcessing="true">
<match url="urltomatchpattern" ignoreCase="true" negate="false" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="false">
<add input="{HTTP_USER_AGENT}" pattern="facebookexternalhit/[0-9]|Twitterbot|Pinterest|Google.*snippet" />
</conditions>
<action type="Redirect" url="http://sitetocrawl.com/doc?parameter" appendQueryString="true" redirectType="Found" />
</rule>
EDIT:
I tried with many variants of simpler rules, like redirect/rewrite when a specific user agent requests the site(in my case, the facebook crawler). But I can't even get those rules to work. I am debugging using the Facebook OG debugger
<rule name="Rule1" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_USER_AGENT}" pattern="facebookexternalhit/1.1|Facebot" />
</conditions>
<action type="Redirect" url="new url here" />
</rule>
Not an answer but a starting point. The IIS Manager (IIS 8 on Windows 8.1) translates your apache mod_rewrite rules into this slightly different configuration:
<rewrite>
<rules>
<rule name="Imported Rule 1" stopProcessing="true">
<match url="qs/(\d*)$" ignoreCase="false" />
<conditions>
<add input="%{HTTP_USER_AGENT}" pattern="(facebookexternalhit/[09]|Twitterbot|Pinterest|Google.*snippet)" ignoreCase="false" />
</conditions>
<action type="Rewrite" url="http://sitetocrawl.com/doc?id={R:1}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
I see that it is rewrite instead of redirect, but please check if this would work for your scenario. And if it works, you may begin changing it until reaching desired result.
And now I see that Your main URL Matching pattern is simply urlmatchpattern which of course is not a pattern and is the root cause for your rules to not work.

How can I create a URL rewrite rule for a domain-only request?

I am trying to create a URL rewrite for a site that has multiple domains. For example one of the domains is mydomain.com and if a user puts www.mydomain.com in their browser and does not specify a page I want to rewrite the URL to call www.mydomain.com/landingpage.aspx?cat=1&sol=4.
If the user calls anything else such as www.mydomain.com/somepage.aspx this rule should be ignored.
I have installed URL Rewrite 2.0 on the server 2008 R2 machine we have and I have added this rule to the web.config.
<rewrite>
<rules>
<rule name="mydomain.com" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="^(www.)?mydomain.com" />
<add input="{PATH_INFO}" pattern="^$" negate="true" />
</conditions>
<action type="Rewrite" url="\landingpage.aspx?cat=1&sol=4" />
</rule>
</rules>
</rewrite>
I am using the {PATH_INFO} of ^$ so that if anything other than just a call for the domain occurs this should ignore it I think. However it does not work.
I am using .NET 4.0 on the site.
Can someone tell me what I am doing wrong please?
You are looking for following rule:
This will check if URL is empty i.e. no page is specified using match url=^$ - empty string and redirect to specific page.
<rule name="Redirect to specific page" enabled="true" stopProcessing="true">
<match url="^$" />
<conditions>
<add input="{HTTP_HOST}" pattern="^(www.)?mydomain.com$" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/landingpage.aspx?cat=1&sol=4" />
</rule>

IIS Url-Rewrite

I'm trying to use IIS7 Url Rewrite module rewrite
services.mydomain.com/some-file-here to mydomain.webhost.com/folder/some-file-here
The rule is as follows:
Pattern = ^services.mydomain.com/(.*)$
Action = Rewrite
Rewrite URL = http://mydomain.webhost.com/folder/{R:1}
The problem is IIS keeps giving me 404 not found errors. I've been stuck at this for days now. Any ideas?
You have your pattern wrong. It should not include domain name or query string there -- only path without leading slash. See the working rule below:
<rule name="MyRewriteRule" stopProcessing="true">
<match url="^(some-file-here)$" />
<conditions>
<add input="{HTTP_HOST}" pattern="^services\.mydomain\.com$" />
</conditions>
<action type="Redirect" url="http://mydomain.webhost.com/folder/{R:1}" />
</rule>
The above rule will only trigger if host name is services.mydomain.com. If you do not require such additional condition (which is optional) then just remove these 3 lines: <conditions>...</conditions>
Also, the above rule will only do one specific redirect from services.mydomain.com/some-file-here to mydomain.webhost.com/folder/some-file-here. If you need to redirect ANY file like that, then use this one instead:
<rule name="MyRewriteRule" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^services\.mydomain\.com$" />
</conditions>
<action type="Redirect" url="http://mydomain.webhost.com/folder/{R:1}" />
</rule>

Resources