I have implemented URL Rewriting at the server level as I wanted to redirect all HTTP and HTTPS requests that matches a certain rule to my actual site, and redirection should only take place if the users are hitting my actual site. The rules works fine initially. However, triggering CTRL+R repeatedly on my actual site seems to render my site unaccessible. The error "This page can't be displayed" is then returned to the user. This test was done on IE 11 browser on Windows x64, and my web server is IIS 8.5 on Windows Server 2012 R2. The HTTP response code returned for redirect is configured as 307.
When I turn on Failed Request Routing on my IIS server, I see a warning message on REWRITE_DISABLED_KERNEL_CACHE in the Failed Request Logs. This was the time when the page returns "This page can't be displayed".
Disabling my URL Rewrite rule would immediately render both my HTTP and HTTPS sites accessible once again, and I've verified that redirect no longer works. Enabling the same rule thereafter but on my HTTPS site only would work.
As follows is my redirection rule
<system.webServer>
...
<rewrite>
<globalRules>
<clear />
<rule name="HTTPS to HTTP" enabled="true" stopProcessing="true">
<match url="^(downloads?/?)?$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_URI}" pattern="http://.*?/downloads/" negate="true" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/downloads/" appendQueryString="false" redirectType="Temporary" />
</rule>
</globalRules>
<outboundRules>
</outboundRules>
</rewrite>
...
</system.webServer>
Basically, if the request hits any of the following example URLs, I will redirect them:
1) http://fqdn/download
2) http://fqdn/download/
3) https://fqdn/downloads
4) https://fqdn/downloads/
5) https://fqdn/download
6) https://fqdn/download/
I will not redirect, if the request hits my site directly:
http://fqdn/downloads/
When I hit my actual site, I realise that the redirection rule is still being applied. So I suspect there could be 2 different issues over here.
1) An infinite redirection rule being applied when requests are sent to http://fqdn/downloads/
2) Some unknown problem with REWRITE_DISABLED_KERNEL_CACHE
You're in trouble with infinite redirects because of your wrong assumptation about REQUEST_URI and the lack of HTTPS check.
{REQUEST_URI} contains URL's path, including the query string with a leading slash (never been welldocumented), never contains uri scheme or hostname. So, you have a false positive.
http(s)://<host>:<port>/<path>?<querystring>
Here's a self-explanatory rule.
<rule name="Force Http downloads page" stopProcessing="true">
<!-- If the url starts with download or downloads with an optional trailing slash -->
<match url="^downloads?/?$" />
<!-- Redirect -->
<action type="Redirect" url="http://{HTTP_HOST}/downloads/" appendQueryString="false" redirectType="Temporary" />
<!-- When -->
<conditions logicalGrouping="MatchAny">
<!-- REQUEST_URI does not start with "/downloads/" -->
<add input="{REQUEST_URI}" pattern="^/downloads/" negate="true" />
<!-- Or -->
<!-- HTTPS is not off -->
<add input="{HTTPS}" pattern="^off$" negate="true" />
</conditions>
</rule>
Hope it helps.
Related
I have subdomain with an A record to my IIS Server:
sub.domain.com
The IIS server has a binding for sub.domain.com and a cert for *.domain.com
What we need is when someone goes to sub.domain.com it takes them to another site but masks the URL and keeps the SSL. The destination page has in its SAN cert sub.domain.com.
Tried a forward on Godaddy which works but it doesn't keep the SSL and we get cert issues. So thought was to point to our server to pass SSL and then redirect it. I tried a URL Rewrite but it's giving a 404.
URL Rewrite:
<rewrite>
<rules>
<clear />
<rule name="Pay Redirect" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^(www\.)?sub\.domain\.com$" />
</conditions>
<action type="Redirect" url="https://www.domain2.com/cgsdesktop/PaymentLanding/UniversalPortal" appendQueryString="false" />
</rule>
</rules>
</rewrite>
I just need to know how to get this done.
How about this:
<rules>
<rule name="Pay Redirect" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^sub.domain.com$" ignoreCase="true"/>
<add input="{HTTP_HOST}" pattern="^www.sub.domain.com$" ignoreCase="true"/>
</conditions>
<action type="Redirect" url="https://www.domain2.com/cgsdesktop/PaymentLanding/UniversalPortal" appendQueryString="false" />
</rule>
</rules>
use sub.domain.com instead of sub\.domain\.com.
This article contains some useful recipes on IIS redirect/rewrite rules.
In order to mask the URL and keep the SSL in the browser bar, we need to create URL Rewrite action rules of URL Rewrite extension.
However, URL Rewrite action only supports to redirect the request to the same domain by default. We have to install the Application Request Routing extension when redirecting the request to another website.
https://www.iis.net/downloads/microsoft/application-request-routing
or we will get an Http 404 error.
See my preceding post for more details.
ASP.net URL Rewrite subdirectory to external URL
Feel free to let me know if there is anything I can help with.
I have a simple Umbraco 7.7.2 application and I'm hosting it on Azure (app-service). When I restart the server it takes 20-40 seconds for first time requesting a page which is really annoying specially when the load is high and you are Scaling out to reduce the response times.
I've tried this setting in my webconnfig, but it doesn't seem to work.
<system.webServer>
<applicationInitialization>
<add initializationPage="/page1/?warmup=1" hostName="mydomain.com" />
<add initializationPage="/page1/page2/?warmup=1" hostName="mydomain.com" />
</applicationInitialization>
</system.webServer>
I might be trying it in a wrong way, but what I did was to restart the server and I've left it for 2-3 minutes without requesting any page.
I've checked my Umbraco logs and the application wasn't even started.
Then I've requested the home page and it took 40 seconds to come up.
Then I've tried mydomain.com/page1 and it also took 20 seconds since it was the first request to access it.
*P.S: after the first request, the site is very fast and each page takes less than 100 ms to load
Update
I've implemented a rewrite to stop next redirects as Kevin has suggested.
As a result, my Umbraco will start up, but still the requests doesn't reach to the pages.
On my master page, I've added a line to write a line in the logs if it has the warmup in the querystring and it works it the page is hitted from the browser:
if (!string.IsNullOrWhiteSpace( Request.QueryString["warmup"]))
{
var pageC = Model.Content;
logger.Info(pageC.UrlAbsolute()+" "+ Request.QueryString);
}
However, there is nothing in my logs after
2018-02-08 15:16:51,245 [P7036/D2/T1] INFO Umbraco.Core.CoreBootManager - Umbraco application startup complete (took 12727ms)
2018-02-08 15:16:54,911 [P7036/D2/T1] INFO MyNamespace.Web.CustomStartup - base config done!
Here is the confing that I've added based on Kevin's answer:
<rule name="No redirect on warmup request (request from localhost with warmup user agent)" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{REMOTE_ADDR}" pattern="127.0.0.*" />
</conditions>
<action type="Rewrite" url="{URL}" />
</rule>
Also, I've found another similar config on Microsoft:
<rule name="No redirect on warmup request (request from localhost with warmup user agent)" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="localhost" />
<add input="{HTTP_USER_AGENT}" pattern="Initialization" />
</conditions>
<action type="Rewrite" url="{URL}" />
</rule>
Note that azure will warm up the URL on http, so if you are forcing https using rewrite rules, the full site will not warm up, only the redirect module will. Then it needs to finish warming up Umbraco after azure adds it into the load balancer and the first https gets through to the umbraco code. We found that out by checking the http logs when scaling out.
We couldn't figure out how to tell azure to warmup using https, so we allowed Azure to access the site on http by making a rule before our force https rewrite to stopProcessing when {REMOTE_ADDR} matches 127.0.0.*.
<rule name="Allow localhost to warmup" stopProcessing="true">
<match url="(.*)"/>
<conditions>
<add input="{REMOTE_ADDR}" pattern="127.0.0.*" />
</conditions>
</rule>
There was so many reasons for the requests not reaching my site and thanks to Kevin and Twamley whom opened my eyes to the probable cause I could trace and find all of them.
First, as Kevin said HTTPS was one of the issues which I've fixed as below:
<rule name="No redirect on warmup request (request from localhost with warmup user agent)" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="localhost" />
<add input="{HTTP_USER_AGENT}" pattern="Initialization" />
</conditions>
<action type="Rewrite" url="{URL}" />
</rule>
Then I could see that Umbraco starts up but the requests didn't get to my pages.
<rule name="Redirect rquests to www.example.com" stopProcessing="true" enabled="true">
<match url="(.*)" />
<conditions >
<add input="{HTTP_HOST}" pattern="^example\.com$" />
</conditions>
<action type="Redirect" url="https://www.example.com/{R:0}" />
</rule>
I didn't expect my requests to get to this redirect since it was at the end of my rewrite rules and therefore it should be stoped at No redirect on warmup request but it didn't so I've added another condition to it: <add input="{HTTP_USER_AGENT}" pattern="Initialization" negate="true" />
<rule name="Redirect rquests to www.example.com" stopProcessing="true" enabled="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^example\.com$" />
<add input="{HTTP_USER_AGENT}" pattern="Initialization" negate="true" />
</conditions>
<action type="Redirect" url="https://www.example.com/{R:0}" />
</rule>
Also, I have ipSecurity in my settings since it is my test environment and I didn't want it open to public. Turns out the Initialization cannot hit my site at all if I don't open up to 127.0.0.1.....
<security>
<ipSecurity allowUnlisted="false">
<add ipAddress="127.0.0.1" allowed="true" />
<add ipAddress="x.x.x.x" allowed="true" />
I like Kevin's idea of just stopping the processing as one of the first rewrite rules. I noticed his didn't have an action but you added one to yours. Maybe try his w/o an action? Is it the first rule in the file?
Another option we use is to add this condition to any problem rules (notice the negate).
<add input="{REMOTE_ADDR}" pattern="127\.0\.0\.1" negate="true"/>
Try temporarily clearing your rewrite rules until you're convinced your warmup is working, then add the rules back a few at a time to find and fix the problem redirect. Force SSL and Trailing Slash type rules will definitely cause problems.
Also, the hostName can get you in trouble easily. It should be a perfect match for your production environment. It doesn't use DNS to resolve it, it just talks to the local site and passes that in as the HOST header.
I don't have any querystrings in my warmup list. Maybe you should try dropping those. You don't really need them because you can change your logging code to:
if (Request.IsLocal && Request.UserAgent == "IIS Application Initialization Warmup") {
// log it
}
Logging them is a great idea because the warm up requests don't show up in the standard IIS logs. I have my servers mail me at the beginning and end of the warmup by hitting a special first and last entry that uses that if statement. Some useful details from Azure:
new {
WEBSITE_HOSTNAME = System.Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME"),
WEBSITE_INSTANCE_ID = System.Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID"),
WEBSITE_SITE_NAME = System.Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"),
COMPUTERNAME = System.Environment.GetEnvironmentVariable("COMPUTERNAME"),
USER_AGENT = Request.UserAgent,
URL = Request.Url,
WARM_UP_TIME = (DateTime.UtcNow - _start).ToString()
}
We have applications hosted on WebSphere 7.0 and Jboss EAP7 which is behind IIS 8.5 Web server, we enabled ssl for iis.
our requirement is whenever users access with http it has to be redirected to https, to achieve this we configured rewrite2 module in iis below inbound rule
<rules>
<rule name="http to https" enabled="false" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="SeeOther" />
</rule>
issue :- when i access http://www.example.com/login it redirects to https://www.example.com/sePlugins/iisWASPlugin_http.dll and gives 404 Status code. (only applications hosted websphere)
The problem is that we have a ISAPI Websphere plugin to handle the requests and for some reason URL is getting changed by IIS.
redirect rule works fine for Applications hosted on J BOSS.
Not sure what happened to my registration process but I posted the original answer so reposting again after registering.
I found that specifying {CACHE_URL} in the Redirect Url instead of https://{HTTP_HOST}{REQUEST_URI} worked. so url="{CACHE_URL}"
This is how my rule is defined and it seems to work well.
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_X_FORWARDED_PROTO}" pattern="^http$" />
</conditions>
<action type="Redirect" url="{CACHE_URL}" />
</rule>
I found that specifying {CACHE_URL} in the Redirect Url instead of https://{HTTP_HOST}{REQUEST_URI} worked. so url="{CACHE_URL}"
I'm new to the world of IIS in terms of redirects and have been tasked with setting up a redirect for a portion of our site.
The URL I need to redirect is brandview.auditedmedia.com and I need it
to go to https://auditedmedia.com/data/media-intelligence-center/brand-view
The trick is we can have a URL with a QueryString such as
brandview.auditedmedia.com/memberNumber=423524 and that URL should NOT
be redirected.
Also, the scheme of brandview.auditedmedia.com does not matter. Both
HTTP and HTTPS should redirect.
So I'm not sure should I be doing this in IIS or as a RouteMap in the app?
If I should be doing this in IIS can someone point me to either an article or give an example of what I need to do?
Thanks
Bob
You need to add URL rewrite rule on the server level. Use conditions to prevent redirection for requests with non-empty query string string.
For your case it is necessary to add the following rule:
<rule name="brandview redirect" stopProcessing="true">
<match url=".*" ignoreCase="true" negate="false" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^brandview\.auditedmedia\.com$" negate="false" />
<add input="{QUERY_STRING}" pattern=".+" negate="true" />
</conditions>
<action type="Redirect" url="https://auditedmedia.com/data/media-intelligence-center/brand-view" appendQueryString="false" redirectType="Permanent" />
</rule>
There is detailed instruction on your question. Note, the rule must be created in system.webServer/rewrite/globalRules section of %windir%\system32\inetsrv\config\ApplicationHost.config file.
I got the pattern fixed (see below) and though all the pattern matching works properly in URL Rewrite Module (using test button and putting in different URLs), it still isn't working properly when I attempt to go to the site. The server just continues with serving the page and not redirecting.
<rewrite>
<globalRules>
<rule name="brandview redirect" stopProcessing="true">
<match url=".*" ignoreCase="true" negate="false" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^(https?:\/\/)?brandviewdev\.auditedmedia\.com$" negate="false" />
<add input="{QUERY_STRING}" pattern=".+" negate="true" />
</conditions>
<action type="Redirect" url="https://auditedmedia.com/data/media-intelligence-center/brand-view" redirectType="Permanent" appendQueryString="false" />
</rule>
</globalRules>
</rewrite>
Also you can add URL rewrite rule using GUI. Before you start make sure that both of the direct HTTP-requests to brandview.auditedmedia.com and https://auditedmedia.com/data/media-intelligence-center/brand-view returns status 200 (OK).
Open IIS Manager by prompting inetmgr command.
Select brandview web site in the Connections pane and open URL Rewriting feature.
Create new empty rule using Add rule(s)... action.
Within the Edit Inbound Rule dialog, enter the following:
Name: Redirect to auditedmedia.com;
Requested URL: Matches the Pattern;
Using: Regular expressions;
Pattern: .*;
Action type: Redirect;
Redirect URL: https://auditedmedia.com/data/media-intelligence-center/brand-view.
Append query string: false;
Redirect type: See Other (303);
Save the rule by clicking Apply on the Actions pane.
Make sure that request to brandview.auditedmedia.com will be redirected to https://auditedmedia.com/data/media-intelligence-center/brand-view.
Repeat steps 1, 2 and select Redirect to auditedmedia.com rule.
Execute action Add condition(s)... with following:
Condition input: {QUERY_STRING};
Check if input string: Does Not Matches the Pattern;
Pattern: .+;
Ignore case: true.
Push OK button.
As result, all requests to brandview.auditedmedia.com with empty query string will be redirected to https://auditedmedia.com/data/media-intelligence-center/brand-view page. After testing you can change redirect type to 301.
After trying different combinations I finally got the redirect to work correctly and to be honest, I'm not sure how. Here is my config
<rewrite>
<rules>
<rule name="Brandview Redirect" enabled="true" stopProcessing="true">
<match url="^$" ignoreCase="true" negate="false" />
<action type="Redirect" url="https://auditedmedia.com/data/media-intelligence-center/brand-view" appendQueryString="false" redirectType="Temporary" />
<conditions>
<add input="{HTTP_HOST}" pattern="brandviewdev\.auditedmedia\.com" />
<add input="{QUERY_STRING}" pattern=".+" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>
I have used web.config to redirect the url to a different website but after i remmove the line of code that redirects, the changes do not reflect and when i access the website i still get an redirect.
I have tried to restart the AppService plan but that does not work.
How can I change everything back as it was?
the code below i have written:
<rule name="[RULE NAME]" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="false">
<add input="{HTTP_HOST}{REQUEST_URI}" pattern="[OLD URL]" />
<add input="{HTTP_HOST}{REQUEST_URI}" pattern="www.[OLD URL]" />
</conditions>
<action type="Redirect" url="http://[NEW URL]" redirectType="Permanent"/>
</rule>
You had a Permanent redirect. That will result in a HTTP 301 code, which in most normal circumstances will be cached.
It may help to clear your browser's cache. Or try a different browser.
See How long do browsers cache HTTP 301s?.