Architecture:
User --> ARR Server --> LB --> 2 Web Server serving 2 different sites
Web Server1 serving -> https://xxxx-green-xxxx-xxxx.net/xxx/xxx?xx=xxxx where green keyword comes in any place in domain name
Web Server2 serving -> https://xxxx-yellow-xxxx-xxxx.net/xxx/xxx?xx=xxxx where yellow keyword comes in any place in domain name
Requirement:
Request format: https://xxxx-green-xxxx-xxxx.net/xxx/xxx?xx=xxxx or yellow URL
In ARR we need to filter the URL with green and yellow keyword in URL and send it to respective Web Server IP.
But all my requests are landing to home page only. and even i am confused that whether changing the host will work but i need to give IP which is different for each web server in LB
We have set this Rule and getting below results:
<rule name="Green" enabled="true" stopProcessing="true">
<match url="(.*xxx.net)(/.*)" />
<conditions logicalGrouping="MatchAll"
trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="green" />
</conditions>
<action type="Rewrite" url="https://xx.xxx.xx.xx/{R:2}"
appendQueryString="true" />
</rule>
Where R:2 is --> xxx/xxx?xx=xxxx
As per your question.
You need to write Custom rewrite rule for that.
So first refer this link
Into link you can handle your requirement and rewrite to other other web server.
So please follow all the step and write you logic into
Rewrite(string value) method.
Into this method you need to pass your server url from IIS rules and check via condition like below.
public string Rewrite(string value)
{
if(value.Contains("green"))
{
return // your rewrite URL here
}
else if(value.Contains("yellow"))
{
return // your rewrite URL here
}
return value;
}
So it's working as per your requirement.
Related
We have an application that is run in a virtual folder in IIS. We don't want the virtual folder name to be part our links though (primarily to preserve original link names for SEO reasons).
So here is one example of a rewrite rule we're using:
<rule name="Rewrite Account controller to UI">
<match url="/Account(.*)"/>
<action type="Rewrite" url="ui/Account{R:1}"/>
<conditions>
<add input="{URL}" pattern="\.axd$" negate="true" ignoreCase="true"/>
</conditions>
</rule>
The problem with this rule is that it would also match "~/someothercontroller/258642/Accounting-Essentials" and turn it into "/ui/Accounting-Essentials". And I don't want to include the host because the host is different in each environment.
What would this need to look like to match only if the expression is the first thing after the host?
Edit:
Sorry, I guess my post wasn't as clear as I thought it was. An example would be http://x/Account. This should rewrite to http://x/ui/Account. The x could be any host name with any number of periods but it's only the host name so it wouldn't contain any slashes.
You can see in the rule I have above that I want it to include anything that comes after Account however I realize that's not quite right either because it shouldn't match "http://x/Accounting", but it should match "http://x/Account/whatever".
So essentially, you want to make sure that Account comes right after the host, and also that Account is the full name of the directory. You can achieve this like so:
<rule name="Rewrite Account controller to UI">
<match url="^Account(/.*)?"/>
<action type="Rewrite" url="ui/Account{R:1}"/>
<conditions>
<add input="{URL}" pattern="\.axd$" negate="true" ignoreCase="true"/>
</conditions>
</rule>
The ^ ensures that this is the beginning of the string that you are evaluating.
The / after Account ensures that you only rewrite the url if "Account" is the full name of the directory.
It appears from the documentation that the inital / will not be included in the string you're evaluating (which is why I removed it), but you can test it both ways to be sure.
Also note that I added a / before {R:1}.
Edit: Another way
You could also add a rule that verifies that the whole URL matches a certain pattern. This might actually be an easier way:
<rule name="Rewrite Account controller to UI">
<match url="/Account(.*)"/>
<action type="Rewrite" url="ui/Account{R:1}"/>
<conditions>
<add input="{URL}" pattern="\.axd$" negate="true" ignoreCase="true"/>
<add input="{REQUEST_URI}" pattern="^/Account(/.*)?" ignoreCase="true"/>
</conditions>
</rule>
The Microsoft docs give this example of the server variable values:
For example, if a request was made for this URL:
http://www.example.com/content/default.aspx?tabid=2&subtabid=3, and a rewrite rule was defined on the site level then:
The rule pattern gets the URL string content/default.aspx as an input.
The QUERY_STRING server variable contains tabid=2&subtabid=3.
The HTTP_HOST server variable contains www.example.com.
The SERVER_PORT server variable contains 80.
The SERVER_PORT_SECURE server variable contains 0 and HTTPS contains OFF.
The REQUEST_URI server variable contains /content/default.aspx?tabid=2&subtabid=3.
The PATH_INFO server variable contains /content/default.aspx.
Our application depends on the client IP address for various features. We've updated our infrastructure and changed how we load balance our application. Because of the change, the CGI.REMOTE_ADDR being reported to the application is that static load balancer IP not the client IP. To fix this, the LB support said to add a rule to both the LB and IIS. The LB is now configured to send a header [http_x_forwarded_for] with the client ip.
The rewrite rule in IIS looks like this:
<rule name="REMOTE_ADDR rewrite" enabled="true" patternSyntax="ECMAScript">
<match url="^((?!GetImage).)*$" />
<serverVariables>
<set name="REMOTE_ADDR" value="{HTTP_X_FORWARDED_FOR}" />
</serverVariables>
<action type="Rewrite" url="{R:0}" appendQueryString="true" logRewrittenUrl="false" />
</rule>
<rule name="REMOTE_ADDR blank URL rewrite" enabled="true">
<match url="^$" />
<serverVariables>
<set name="REMOTE_ADDR" value="{HTTP_X_FORWARDED_FOR}" />
</serverVariables>
<action type="Rewrite" url="default.cfm" />
</rule>
The first rule is for any pages requested excluding the GetImage page. The second is for no page.
For the most part this works correctly. We haven't had to make any adjustments to the application because the CGI.REMOTE_ADDR is correct.
But we were told that in some circumstances the LB may pass multiple IP addresses and to use only the first one in the list. This is causing a problem.
In some cases CGI.REMOTE_ADDR is coming through like this '100.200.200.200, 123,123,123,123'.
Testing the RegEx in IIS with that string shows group {R:0} is 100.200.200.200, 123,123,123,123.
The question is is it possible to write the rule so that {R:0} is the first matched IP address in the list?
Realized after I posted this I was attacking it (or asking..) the wrong way.
The URL Rule regex is to match the URL to apply the rule. All requested URLS that match will map the http_x_forwarded_for header value into the REMOTE_ADDR server variable. The value of this variable which could be invalid what the problem.
To fix this, a new OUTBOUND rule needed to be added. In this rule you can specify the REMOTE_ADDR as the INPUT and matching against a regex to rewrite it. By adding the rule, a regex to match the first IP addr found in the variable, and then rewrite the variable with the back trace I was able to solve the problem.
<outboundRules>
<rule name="Format IP Address">
<match serverVariable="REMOTE_ADDR" pattern="^([0-9]{0,3}\.[0-9]{0,3}\.[0-9]{0,3}\.[0-9]{0,3})(.)*$" />
<action type="Rewrite" value="{R;1}" />
</rule>
</outboundRules>
I am using:
IIS 7
Url Rewrite Module Version 1.1
Asp.Net MVC 4
I am hosting my sites in a shared hosting environment.
No site is hosted in the root folder as all sites are in their own physical folder and I use the domain name of the site as the physical folder name.
I would like to change my urls from this
http://www.mysite1.com/mysite1
http://mysite1.com/mysite1
to this
http://www.mysite1.com/
http://mysite1.com/
I have this and it doesn't work.
**DOES NOT WORK**
<rule name="RemoveFolder" stopProcessing="true">
<match url="mysite1/(.*)" />
<action type="Rewrite" url="/{R:0}" appendQueryString="true" />
</rule>
Can someone give me a regular expression that would add www to any urls and remove the folder that is showing up in the url?
OK. What I typed below, doesn't work for me. I thought it did, but I realized it didn't.
#Cheesemacfly, I'm trying to remove the subfolder from the url,
Redirect the user back to the site with the url MINUS the subfolder,
Make sure that there is NOT a continuous loop.
Cheesemacfly, your answer didn't work, but it did put me on the path to the full correct answer.
Thank you chesse for putting me on the right path.
This rule removes the subfolder from the url and redirects the user back to the page without the subfolder. The condition makes sure that I don't have a continual redirect. Once the url has been rewritten, that conditional will stop the url from matching again.
I placed this rule in the ROOT web.config of my hosting account.
The root ONLY contains a web.config and all of the subfolders.
<rule name="Cleanup" stopProcessing="true">
<match url="theFolderINeedToRemove/(.*)" ignoreCase="true" />
<conditions>
<add input="{HTTP_HOST}" pattern="^mywebsite.com/theFolderINeedToRemove$" />
</conditions>
<action type="Redirect" url="/{R:1}" appendQueryString="true" />
</rule>
I have a website with many links to *.index.html pages that do not exist any more, all default documents have now changed to index.htm, I'm trying to set a URL redirect/rewrite to the new pages but with no luck, here is an exmaple:
http://example.com/somedirectory/maybeanotherdirectory/index.html
I need to redirect that request to:
http://example.com/somedirectory/maybeanotherdirectory/index.htm
I have added different rules to the web.config but so far I can only redirect to:
http://example.com/index.htm
How do I sustain the exact path while only changing index.html to index.htm?
Such an old question, and I stumbled across it purely by happenstance. In case anybody comes across it in look for an answer, you can install the IIS URL ReWrite module, and add the following to your web.config:
<rewrite>
<rules>
<rule name="Html to htm">
<match url="(.*)\.html" />
<action type="Rewrite" url="{R:1}.htm" />
</rule>
</rules>
</rewrite>
Cheers!
I am using ColdFusion 9.0.1
I have a new site that is accessible through a few domains such as:
mydomain.com
www.mydomain.com
foo.mydomain.com
For SEO and tracking purposes, I want to make sure that only "mydomain.com" is indexed and accessed. So, every request that tries to access my site through other domains will be 301 directed to "mydomain.com".
I want to make sure that I capture and preserve the query string so that I don't just send people to the home page.
I will also make sure that I can access the site locally at 127.0.0.1
I wondering where in the code is the best place to do this SPECIFIC type of redirect. My guess it's in application.cfc near the top, in the onRequestStart() method.
Is this best place to put the code and does is this code complete? Is there a better way to code this?
<cfscript>
ThisHost = CGI.HTTP_HOST;
QString = CGI.QUERY_STRING;
GoToURL = "http://mydomain.com?" & QString;
if (ThisHost != "mydomain.com" && ThisHost != "127.0.0.1") {
writeOutput("<cfheader statuscode='301' statustext='Moved permanently'>");
writeOutput("<cfheader name='location' value='#GoToURL#'>");
abort;
}
</cfscript>
UPDATE
I know this isn't the best way to accomplish what I need, because this task is much better suited to the web server's skill set. Here's my code till I can implement this on the web server:
<cfscript
ThisHost = CGI.HTTP_HOST;
QString = CGI.QUERY_STRING;
GoToURL = "http://flyingpiston.com/?" & QString;
if (ThisHost != "flyingpiston.com" && ThisHost != "127.0.0.1:8500") {
location(GoToURL, false, 301);
}
<cfscript
I agree with other comments and answers that doing this at the web server is a better solution. I would also point out that if you want to use the script syntax, this is entirely wrong and will simply return a string to the browser:
writeOutput("<cfheader name='location' value='#GoToURL#'>");
In ColdFusion 9, you would instead use the location() function:
location("url", addtoken, statusCode);
In your case:
location(GoToURL, false, 301);
Your GoToURL variable is also missing the page name, so you'd need to add CGI.SCRIPT_NAME into the mix just before the ? to get the full URL being called.
With the tag syntax (as of ColdFusion 8 I believe), there is no need to use the CFHEADER tag for a 301 redirect. The CFLOCATION tag now supports a statuscode attribute which can be set to 301 as needed.
If you are on IIS 7.0 the you may be able configure your web.config file for a canonical redirect like so:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect to WWW" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="^domain.com$" />
</conditions>
<action type="Redirect" url="http://www.domain.com/{R:0}"
redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Check out this link for additional options.
The previous answer shows how to redirect domain.com to www.domain.com. If you want to redirect www.domain.com to 'domain.com', you will need a web.config file that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<location path="" overrideMode="Inherit">
<system.webServer>
<rewrite>
<rules>
<rule name="remove www" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="www.*" />
<add input="{HTTP_HOST}" pattern="foo.*" />
</conditions>
<serverVariables />
<action type="Redirect" url="http://{C:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</location>
</configuration>
The above web.config file was created on IIS 7.5 (Windows Server 2008 R2).
Your host will need to install the URL Rewrite Module as mentioned above in order for this to work.
The web.config file is stored in the root folder of your site.
The above example will redirect 'www' and 'foo' sub-domains to the domain.
This 10 URL Rewriting Tips and Tricks article has been a good reference for me.