IIS Rewrite Rule - 404 fallback result - iis

I'm relatively new to IIS Rewrite Rules so forgive me if this is not actually feasible in IIS Rewrite.
I'm trying to setup a 'fallback' route for some static content on a site. I always have the root content, but not necessarily the slug-path. E.g.
http://example.com/some-slug/foo.js
If /some-slug/foo.js doesnt exist, I want to fall back to /foo.js on the root of the site, and serve this as the response.
Is this achievable in IIS re-write?

Yes it is achievable
<rewrite>
<rules>
<rule name="rewritewithfallback">
<match url="some-slug/(.*)" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="{R:1}" />
</rule>
</rules>
</rewrite>

Related

IIS Rewrite IP:Port to {domain}/{thing}

What I'm trying to do:
I own a domain, let's say blahblahblah.com
On the server, it points to :80 and :443 properly - this is working
I want to remap so that if a user visits blahblahblah.com/thing1 then it maps to localhost:5000
Similarly, I also want to remap so that if a user visits blahblahblah.com/thing2 then it maps to another server and port on my local network (not exposed to the internet)
I essentially want to use my webserver to communicate with other servers on my network and other ports through "sub directories" or whatever they are called in this instance (site/subdir, site2/subdir). I've been trying to solve this issue for days! I've installed ARR (and enabled the Proxy) and the URL Rewrite modules on my IIS.
I've attempted god knows how many different rewrite templates on SO. I can get partial success, in which the route /thingx/ resolves, but all the resources are referencing blahblahblah.com and (appropriately) can't find the resources for the site at that address.
Current rewrite (resolves some resources at blahblahblah.com/thing1, but others are misrouted):
<rewrite>
<rules>
<rule name="Thing1" enabled="true">
<match url="(thing1*)" />
<action type="Rewrite" url="http://localhost:5000/{R:0}" />
</rule>
</rules>
</rewrite>
EDIT: I've updated my rules to the below, as per this article from Microsoft Docs: Reverse Proxy with URL Rewrite v2 and Application Request Routing . These rewrites supposedly do exactly what I need, but the result is not the same in my case, and I still have no clue why.
<rules>
<rule name="Thing1" enabled="true">
<match url="^thing1/(.*)" />
<action type="Rewrite" url="https://localhost:5000/{R:0}" />
</rule>
</rules>
<outboundRules>
<rule name="Add application prefix" preCondition="IsHTML">
<match filterByTags="A" pattern="^/(.*)" />
<conditions>
<add input="{URL}" pattern="^/(thing1)/.*" />
</conditions>
<action type="Rewrite" value="/{C:1}/{R:1}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
More Notes:
localhost:5000 works as expected
localhost/thing1 resolves in 404 Not Found
blahblahblah.com/thing1 resolves in pulling in the default HTML page, but none of the assets (javascript, css, etc), they return 404 Not Found.
EDIT: It may be important to note that these rules have been written into the default site (bound to :80, :443) on IIS' web.config. Writing these rules in C:\Windows\System32\inetsrv\config\applicationHost.config results in a 500.
Any feedback on what I'm doing wrong?
Part of this was due to the way SPAs are handled (# and history mode), but I ended up solving with the below webconfig for IIS, which allows me to nest everything under a /foobar endpoint:
<rewrite>
<rules>
<rule name="Subdirectory Index" stopProcessing="true">
<match url="^foobar/index\.html$" ignoreCase="false" />
<action type="None" />
</rule>
<rule name="Subdirectory Routes" stopProcessing="true">
<match url="." ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="/foobar/index.html" />
</rule>
</rules>
</rewrite>

iis web.config location path exclude files (= paths with extensions)

I want to add customHeaders to all my routes. But only to actual paths in my domain and not files.
<location path="???">
Headers should be added to:
domain.com
domain.com/dashboard
but not to
domain.com/someimage.jpg
You could use IIS rewrite module to write a custom outbound rule. It already has OOTB condition to check if a URL is a file. Something like below, this question is similar:
<rewrite>
<outboundRules>
<rule name="Set custom HTTP response header">
<match serverVariable="Custom header" pattern=".*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" value="Your value"/>
</rule>
</outboundRules>
</rewrite>

redirect https://www to https:// through web.config

I want to redirect anything to https://domain.com
I found this code:
<rewrite>
<rules>
<rule name="SecureRedirect" stopProcessing="true">
<match url="^(.*)$" />
<conditions>
<add input="{HTTPS}" pattern="off" />
<add input="{HTTP_HOST}" pattern="^(www\.)?(.*)$" />
</conditions>
<action type="Redirect" url="https://{C:2}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
And its working except on https://www.domain.com
My virtual server is Windows Server 2012 with IIS 8, and the domain is https://kajsystem.com
I would suggest using IIS 8 configurations including using the URL Rewrite module, which can handle forwarding and retain the entire requested URL. There is a fairly comprehensive article on MSDN site covering this:
MSDN redirect on IIS 7 and higher

Setting up URL Rewrite rule for a specific domain

For local dev testing, I need to catch all requests to www.somedomain.com/XXX (where X is the path), and send them on to localhost/somevdir/XXX.
I've added this to my HOSTS file (c:\windows\system32\drivers\etc):
127.0.0.1 www.mydomain.com
Then, in IIS8 (Windows 8), I've added a binding to my "Default Web Site" for the host www.mydomain.com. This works, I can now browse www.mydomain.com/test.html and see a test html page. My virtual dir is inside the Default web site. I then add a URL Rewrite URL to the web site for the last bit:
<rewrite>
<rules>
<rule name="mydomain.com" stopProcessing="true">
<match url="^www.mydomain.com/(.*)" />
<action type="Rewrite" url="localhost/MyVDir/{R:1}" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
But - that doesn't work. I get a 404 so it looks the the match never happens. I've tried redirect and rewrite, and I've tried without the ^ in the regex and a few other regex tweaks. Can someone explain what I've done wrong?
I think the following should work:
<rule name="mydomain.com" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^(mydomain\.com|www\.mydomain\.com)$" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Redirect" url="http://localhost/MyVDir/{R:1}" redirectType="Temporary" />
</rule>
The match on any URL makes sure the conditions are checked, and the HTTP_HOST server variable seems the most reliable way of checking the requested hostname. You could remove the REQUEST_FILENAME input condition, but it works as quite a nice sanity check to make sure static files are always served.
The following is better for catching both www. and non-www. versions of the domain so that you don't have to write the domain twice, which could possibly cause errors with being twice as likely to write a typo. (The parenthesis with the ? character means optional in regex terms.)
<rule name="mydomain.com" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^(www.)?mydomain\.com$" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Redirect" url="http://localhost/MyVDir/{R:1}" redirectType="Temporary" />
</rule>

IIS 7 URL Rewrite - CamelCase domain and lower case everything else

I am trying to setup rewrite rules for my site in iis 7 with the URL Rewrite module. If the site name is "WonderfulWidgets"
I want it to always be http://WonderfulWidgets.com.
NOT: wonderfulwidgets.com
NOT: WONDERFULWIDGETS.com
I also want everything after WonderfulWidgets.com to be lower case.
IE WonderfulWidgets.com/best-widgets.
I have accomplished the lower case url rewrite and I have also made it so it will remove any leading www before WonderfulWidgets.com
My problem is my lower case URL rewrite lowers the domain name too. I need help writing the CamelCase domain name that works with rewriting everything else as lower case.
Here's what I have in my web.config:
<rewrite>
<rules>
<rule name="CanonicalHostNameRule1">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^WonderfulWidgets\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://WonderfulWidgets.com/{R:1}" />
</rule>
<rule name="RemoveTrailingSlashRule1" stopProcessing="true">
<match url="(.*)/$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Redirect" url="{R:1}" />
</rule>
<rule name="Default Document URL Rewrite" stopProcessing="true">
<match url="(.*?)/?Default\.aspx$" />
<action type="Redirect" url="{R:1}/" />
<conditions>
<add input="{URL}" pattern="WebResource.axd" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>
DNS names are generally treated as case insensitive, and so most (all?) web browsers display the domain name in all lower-case in the address bar. To my knowledge you cannot change this behavior via changing what you return in your HTTP response.
From RFC 4343:
According to the original DNS design decision, comparisons on name
lookup for DNS queries should be case insensitive.
From Wikipedia:
Domain names are interpreted in case-independent manner.
The browsers all seem to prefer lower-case presentation.

Resources