URL Rewrite same host different port in IIS 8.5 - regex

I have a server with three websites:
Default website, port 80 (no content)
Website A, port 81
Website B, port 82
I would like to use URL Rewrite to access Website A and Website B like:
http://myserver/A
http://myserver/B
instead of
http://myserver:81
http://myserver:82
I have installed the URL Rewrite and Application Request Routing modules and enabled the proxy for ARR.
On the default website I created two rewrite rules using the regex pattern /A/(.*) and /B/(.*):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="WebsiteA" stopProcessing="true">
<match url="/A/(.*)" />
<action type="Rewrite" url="http://localhost:81/{R:1}" />
</rule>
<rule name="WebsiteB" stopProcessing="true">
<match url="/B/(.*)" />
<action type="Rewrite" url="http://localhost:82/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Using the Test pattern... functionality I could verify that {R:0} contained the entire test URL and {R:1} just the part after A/ or B/. The rewrite URL I sat to point to either port 81 or 82. I still regard regular expressions as pure magic but the test gave me what I wanted. Trying to connect to the websites through /A/ and /B/ gave me 404 errors.
Seeing that this is a very common problem with lots of questions and answers I picked one suggesting to use the regex pattern ^A(.*)$:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="WebsiteA" stopProcessing="true">
<match url="^A(.*)$" />
<action type="Rewrite" url="http://localhost:81/{R:1}" />
</rule>
<rule name="WebsiteB" stopProcessing="true">
<match url="^B(.*)$" />
<action type="Rewrite" url="http://localhost:82/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Using the test functionality my test URLs failed to match that pattern, but when I tried to access the sites using the new pattern, it worked.
Question: I am going with the later solution but is it pure luck that it works and should I perhaps do something different?
Is it normal for the test functionality to not successfully match the same URL's that works when I feed them to the server?

Related

IIS Rewrite rule - ignore for localhost

I have the following rule which is working well for redirecting my www requests to the root.
However I can't seem to turn it off for localhost. Here is what I have now:
<rule name="CanonicalHostNameRule1">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://example.com/{R:1}" />
</rule>
I've tried many things including things like:
<rule name="CanonicalHostNameRule1">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^localhost$" negate="true" />
<add input="{HTTP_HOST}" pattern="^example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://example.com/{R:1}" />
</rule>
Could you help? Regexes are my weakness alas
How about using a condition to only match requests that start with www. instead of trying to negate when you don't want the rule to apply? This avoids the need to negate localhost because localhost never matches in the conditions:
<rule name="Strip WWW" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.(.*)" />
</conditions>
<action type="Redirect" url="https://{C:1}/{URL}" />
</rule>
However, your example of the rule you tried (your second code block) also works for me in testing with IIS on a Windows 10 VM. I can browse to localhost without a redirect. Perhaps there is another issue here.
I would not mix the rules of different hosting environments; localhost (for local development) and www, your live environment.
If you keep them separate, you don't have to enable and disable rules depending on the environment.
The rules section has a configSource attribute via which you can point to an other separate file, eg. RewriteRules.config.
Doing so, web.config will look like here below.
<configuration>
<!-- Other settings go here. -->
<system.webServer>
<!-- other settings go here --->
<rewrite>
<rules configSource="RewriteRules.config">
</rewrite>
</system.webServer>
</configuration>
The RewriteRules.config file contains the rules.
<rules>
<rule name="CanonicalHostNameRule1">
<!-- Rule details go here -->
</rule>
</rules>
You make a separte version of this RewriteRules.configfile per environment, containing only the appropriate rules and deploy it to the concerned webserver.
This has many benefits.
Only the rules for the concerned environment are being evaluated, which is better for performance.
It is more flexible if you have other environments like QA (http://qa. ...) and dev (http://dev. ...).
You don't have to worry (and test) whether the rules of one environment will interfere with the ones of an other one, here: local vs live.
The deployment of the RewriteRules.config file can be included in a deployment automation.

How to create a EXCEPT Rewrite Rule at IIS

I have an IIS Site with Rewrite Rule to redirect all requests to HTTPS.
I have a internal web service which works with HTTP but rewrite rule modify "http" request to a "https". When happens is the web service returns an error "Object Moved". I tried use "AllowAutoRedirect" with true value but it doesn't work.
How to create a EXCEPT Rewrite Rule to access this web service? how to make web service work with HTTPS protocol?
One way is to add the rule before the "global redirect" and make sure to use stopProcessing="true" so that the next rule is not executed, for example the following rule will allow HTTP only on requests to the segment "foo/", everything else will redirect to SSL:
<rewrite>
<rules>
<rule name="Allow requests to the folder foo over non-https" stopProcessing="true">
<match url="^foo/.*" />
<action type="None" />
</rule>
<!-- Else redirect ALL request to HTTPS -->
<rule name="Redirect to https">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="Off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>

IIS ARR rules not working as expected in adding trailing slashes to my applications

I have a pool of applications that I want to run under a ARR server that should serve as a router for all my applications.
I have defined a set of rules that should be applied in waterfall, but something is not working the proper way.
The first rule should handle the trailing slashes, the other rules should map my applications to resolve for my internal DNS server with rewrite URL, but the problem seems to happen during the first rule.
The default behaviour is that, if I try to launch my application with http://myapp will return 404 code, if I try to run it by adding the slash (http://www.myapp/ ) everything works fine. So basically my rule should check for URL patterns without the slash: if the resource is a directory it should add the slash at the end of the Url.
So the pattern to catch the url is the following regular expression:
.*[^/]$
This should catch url without / at the end and I successfully tested it.
For every url that matches the regexp, I should check if it's a directory, and in the case I should set the trailing slash, so:
{REQUEST_FILE} -> Is a directory
But this doesn't work. I also tried to add the following rule with no success:
{REQUEST_FILE} -> Is not a file
The rule to apply is the following:
Redirect to (rewrite leads to same behaviour, too):
{R:O}/
It seems not to add the / to my urls and I don't know how to check which steps fail to succeed. The next rules basically follow this pattern:
mywebapp/* redirect to www.mydnsappaddress/{R:1}
EDIT: I add the web.config sample to show you the textual version of the rules.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="Trailing Slash" enabled="false" stopProcessing="true">
<match url=".*[^/]$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
</conditions>
<action type="Redirect" url="{R:0}/" />
</rule>
<rule name="app1" enabled="false" patternSyntax="Wildcard">
<match url="sites/doc/*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="http://mypersonaldnsaddress/{R:0}" />
</rule>
<rule name="ASTCO portale NWS" enabled="true" patternSyntax="Wildcard">
<match url="portale/*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="http://mypersonaldnsaddress/{R:0/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I have to ask the obvious: does your example deliberately have enabled set to false?
I was able to make this work exactly as you desire: if the directory exists, add a slash at the end, if it doesn't, don't.
<rule name="Trailing Slash" enabled="true" stopProcessing="true">
<match url=".*[^/]$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" />
</conditions>
<action type="Redirect" url="{R:0}/" />
</rule>

Web.config regex OR oporator

I have the following rule in my webconfig
<rule name="accommidationRewrite2" enabled="true" stopProcessing="true">
<match url="accommodation/(?!results|!property).*?(.*)/" />
<action type="Rewrite" url="/index.cfm/?path=/accommodation/results/params/location/{R:1}/" />
</rule>
I'm trying to get the rule to kick in is the URL is not 'accommodation/results/....' OR 'accommodation/property/.....'
At the moment it only work for the results URL. Can I get it to work for both URL's?
Remove the ! symbol which was present before the property ,
accommodation/(?!results|property).*?(.*)/

regex redirect "/service" IIS 7

I am new to .NET and IIS ans I am trying do a regular expression redirect with this pattern \/([^\/]+)(?=\/[^\/]+\/?$) so my url wil go from mysite.com/en/solutions/exemple to mysite.com/en/exemple but in the redirection IIS put /Service in my URL someone as a idea how to fix this?
here is the rule generated in my web.config by IIS 7
<rewrite>
<rules>
<rule name="redirect salesforce" stopProcessing="true">
<match url="\/([^\/]+)(?=\/[^\/]+\/?$)" />
<action type="Redirect" url="/en/{R:0}/coveo-for-salesforce" appendQueryString="false" />
</rule>
</rules>
</rewrite>
Thanks
UPDATE:I tried
<rewrite>
<rules>
<rule name="remove solutions from url" stopProcessing="true">
<match url="^([^/]+)(/[^/]+)(/.*)" />
<action type="Redirect" url="/{R:0}{R:1}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
I get a not not found
Please note that I am working on a Sitecore solution with 2 languages en and fr
If you want to remove the first level folder from the url, e.g.:
/en/solutions/example-page -> /en/example-page
/en/other-folder/another-page -> /en/another-page
/fr/one-more-folder/blah-page -> /fr/blah-page
with the 301 redirect code, use the following rule:
<rewrite>
<rules>
<rule name="remove solutions from url" stopProcessing="true">
<match url="^([^/]+)(/[^/]+)(/.*)" />
<action type="Redirect" url="/{R:1}{R:3}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
If you want to redirect with 301 code from mysite.com/en/solutions/exemple to mysite.com/en/exemple (so in fact remove solutions from all urls (but only if they are directly after language), you can use:
<rewrite>
<rules>
<rule name="remove solutions from url" stopProcessing="true">
<match url="^([^/]+)/solutions(/.*)" />
<action type="Redirect" url="/{R:1}{R:2}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
I've tested the solution on Sitecore application and it definitely works.