- Introduction
- Installation
- Working with ISAPI_Rewrite
- ISAPI_Rewrite directives
- Examples
- Troubleshooting
- Release notes
Examples
Note! All rules in these examples are intended for httpd.conf file. In ISAPI_Rewrite as well as in Apache mod_rewrite base path for rules is different depending on a directory where you put .htaccess file. Initial leading slash only exist if you put rules in httpd.conf, while in .htaccess files virtual path to these files is truncated. Rules that rely on a root path are preceded with RewriteBase / directive to allow them to work in any location within httpd.conf and directory level .htaccess files.
Simple search engine friendly URLs
This example demonstrates how to easily hide query string parameters using loop flag. Suppose you have URL like http://www.mysite.com/foo.asp?a=A&b=B&c=C and you want to access it as http://www.myhost.com/foo.asp/a/A/b/B/c/C
Try the following rule to achieve desired result:
RewriteEngine on RewriteRule ^(.*?\.asp)/([^/]*)/([^/]*)(/.+)? $1$4?$2=$3 [NC,LP,QSA] |
Note that this rule may break page-relative links to CSSs, images, etc. This is happening due to a change of the base path (parent folder of the page) that is being used by a browser to calculate complete resource URI. This problem occurs only if you use directory separator as a replacement character. There are three possible solutions:
- Use the rule given below. It does not affect base path because does not use directory separator character '/'.
- Directly specify correct base path for a page with the help of <base href="/folder/"> tag.
- Change all page-relative links to either root-relative or absolute form.
There also exist many variations of this rule with different separator characters and file extensions. For example, to use URLs like http://www.myhost.com/foo.asp~a~A~b~B~c~C the following rule can be implemented:
RewriteEngine on RewriteRule ^(.*?\.asp)~([^~]*)~([^~]*)(.*) $1$4?$2=$3 [NC,LP,QSA] |
Keyword rich URLs
In previous example we have used general technique to simply hide query string markers. But much more useful solution for search engine optimization would be making your URL keyword rich. Consider following URL example: http://www.mysite.com/productpage.asp?productID=127 This is very usual situation for most web sites. But you can significantly increase rating of your page in search engines by using the following URL format instead: http://www.mysite.com/products/our_super_tool.asp Keywords “our super tool” in this URL will be indexed and improve page rank. But “our_super_tool” cannot be used to retract productID=127 directly. Several solutions to this problem exist.
The first solution that we would recommend if you have short URL format with only few parameters is to include in URL both keywords and numeric identifiers. In this case your URL may look as: http://www.mysite.com/products/our_super_tool_127.asp Only one rule will be needed to achieve this rewrite:
RewriteEngine on RewriteBase / RewriteRule ^products/[^?/]*_(\d+)\.asp productpage.asp?productID=$1 [QSA] |
Another and more complex solution is to create 1 to 1 map file and use it to map “our_super_tool” to 127. This solution is useful for some long URLs with many parameters and will allow you to hide even numeric identifier. The URL will look as http://www.mysite.com/products/our_super_tool.asp. Please note that “our_super_tool” part should uniquely identify the product and it’s identifier. Here is an example for this solution:
RewriteEngine on RewriteBase / RewriteMap mapfile txt:mapfile.txt RewriteRule ^products/([^?/]+)\.asp /productpage.asp?productID=${mapfile:$1} |
And you will need to create mapfile.txt map file with the following content:
one_product 1 another_product 2 our_super_tool 127 more_products 335 |
Advantage of this method is that you can use it to combine quite complex URL transformations, but this is a bit out of this small examples guide context.
Use IIS as reverse proxy
Assume you have internet server running IIS and several backend servers or applications running other platform or machine. These servers are not directly accessible from the internet but you need to provide access to these servers for others. Here is an example of how to simply map entire content of one web site into the folder on another site running ISAPI_Rewrite:
RewriteEngine on RewriteBase / RewriteRule ^mappoint(.+)$ http://sitedomain$1 [NC,P] |
Hide file extensions
While it is not possible to completely hide all file extensions on the site we can use ISAPI_Rewrite's file checking feature to hide some known extensions. Here is a rule example to hide .asp file extensions on the site:
RewriteEngine on #Redirect extension requests to avoid duplicate content RewriteRule ^([^?]+)\.asp$ $1 [NC,R=301,L] #Internally add extensions to request RewriteCond %{REQUEST_FILENAME}.asp -f RewriteRule (.*) $1.asp |
Emulating host-header-based virtual sites
For example you have registered two domains www.site1.com and www.site2.com. Now you can create two different sites using single physical site. Here is a rules example:
RewriteEngine on #Fix missing trailing slash char on folders RewriteRule ^([^.?]+[^.?/])$ $1/ [R,L] #Emulate site1 RewriteCond %{HTTP:Host} ^(?:www\.)?site1\.com$ RewriteRule (.*) /site1$1 [NC,L,NS] #Emulate site2 RewriteCond %{HTTP:Host} ^(?:www\.)?site2\.com$ RewriteRule (.*) /site2$1 [NC,L,NS] |
Now just place your sites in /site1 and /site2 directories. Note that www.site1.com and www.site2.com should be somehow mapped in IIS to this web site to allow ISAPI_Rewrite intercept request.
Or you can use more generic rules to map any request to the folder with the
same name as the host name in request:
RewriteEngine on #Fix missing trailing slash char on folders RewriteRule ^([^.?]+[^.?/])$ $1/ [R,L] #Map requests to the folders RewriteCond %{HTTP:Host} ^(www\.)?(.+) RewriteRule (.*) /%2$1 [NS] |
Directory names for sites should be like /somesite1.com, /somesite2.info, etc.
Blocking inline-images (stop hot linking)
Assume you have some pages with inline GIF graphics under http://www.mysite.com/. Some other sites incorporate this graphics via hyperlinks to their pages. This adds useless traffic to your site and you want to stop this practice.
While you cannot 100% protect the images from inclusion with ISAPI_Rewrite, only HotlinkBlocker product can do this, you can at least restrict the cases when browser sends HTTP Referer header. The following rules will allow only access to the images if referer is from the same host or empty.
RewriteEngine on RewriteCond %{HTTP:Host}#%{HTTP:Referer} ^([^#]+)#(?!http://\1).+ RewriteRule .*\.(?:gif|jpg|png) /block.gif [NC] |
Redirecting non-www version to www
If your web site is accessible through both versions of URL, i.e. http://helicontech.com and http://www.helicontech.com it is a good idea to redirect one version to another to avoid possible duplicate content penalty from search engines. Here is a rule to generally 301 redirect everything non-www to the corresponding www resource.
RewriteEngine on RewriteCond %{HTTPS} (on)? RewriteCond %{HTTP:Host} ^(?!www\.)(.+)$ [NC] RewriteCond %{REQUEST_URI} (.+) RewriteRule .? http(?%1s)://www.%2%3 [R=301,L] |
Force to SSL or non-SSL for certain locations
Here is example how to force SSL for certain folder. Simply put following rules into the .htaccess file in this folder:
RewriteEngine on #Fix missing trailing slash char on folders RewriteRule ^([^.?]+[^.?/])$ $1/ [R,L] #Redirect non-HTTPS to HTTPS RewriteCond %{HTTP:Host} (.*) RewriteCond %{HTTPS} off RewriteCond %{REQUEST_URI} (.*) RewriteRule .? https://%1%2 [R,L] |
And here is example how to do the contrary - force non-SSL for certain folder.
RewriteEngine on #Fix missing trailing slash char on folders RewriteRule ^([^.?]+[^.?/])$ $1/ [R,L] #Redirect HTTPS to non-HTTPS RewriteCond %{HTTP:Host} (.*) RewriteCond %{HTTPS} on RewriteCond %{REQUEST_URI} (.*) RewriteRule .? http://%1%2 [R,L] |
Moving site location
This is very usual problem when you move web site from one domain name to another, or just another folder. You want to redirect all requests from one web site to another preserving the requested resource name and parameters. This is incredibly useful especially when you want to preserve page ranks of existing pages and external links. The solution is to use ISAPI_Rewrite on the old web server:
RewriteEngine on #Permanent redirect to update old links RewriteRule (.+) http://newserver.com$1 [R=301,L] |
Browser-dependent content
It is sometimes necessary to provide browser-dependent content at least for important top-level pages, i.e. one has to provide a full-featured version for the Internet Explorer, a minimum-featured version for the Lynx browsers and an average-featured version for all others.
RewriteEngine on RewriteCond %{HTTP:User-Agent} MSIE RewriteRule /foo\.htm /foo.IE.htm [L] RewriteCond %{HTTP:User-Agent} (?:Lynx|Mozilla/[12]) RewriteRule /foo\.htm /foo.20.htm [L] RewriteRule /foo\.htm /foo.32.htm [L] |
Block annoying robots
Here is a useful example to block a number of known robots and retractors by their user agents. Please note this rule is long and we have divided it into lines. In order to work correctly no spaces can be added to the end or beginning of the lines:
RewriteEngine on #Block spambots RewriteCond %{HTTP:User-Agent} (?:Alexibot|Art-Online|asterias|BackDoorbot|Black.Hole|\ BlackWidow|BlowFish|botALot|BuiltbotTough|Bullseye|BunnySlippers|Cegbfeieh|Cheesebot|\ CherryPicker|ChinaClaw|CopyRightCheck|cosmos|Crescent|Custo|DISCo|DittoSpyder|DownloadsDemon|\ eCatch|EirGrabber|EmailCollector|EmailSiphon|EmailWolf|EroCrawler|ExpresssWebPictures|ExtractorPro|\ EyeNetIE|FlashGet|Foobot|FrontPage|GetRight|GetWeb!|Go-Ahead-Got-It|Go!Zilla|GrabNet|Grafula|\ Harvest|hloader|HMView|httplib|HTTrack|humanlinks|ImagesStripper|ImagesSucker|IndysLibrary|\ InfonaviRobot|InterGET|Internet\sNinja|Jennybot|JetCar|JOC\sWeb\sSpider|Kenjin.Spider|Keyword.Density|\ larbin|LeechFTP|Lexibot|libWeb/clsHTTP|LinkextractorPro|LinkScan/8.1a.Unix|LinkWalker|lwp-trivial|\ Mass\sDownloader|Mata.Hari|Microsoft.URL|MIDown\stool|MIIxpc|Mister.PiX|Mister\sPiX|moget|\ Mozilla/3.Mozilla/2.01|Mozilla.*NEWT|Navroad|NearSite|NetAnts|NetMechanic|NetSpider|Net\sVampire|\ NetZIP|NICErsPRO|NPbot|Octopus|Offline.Explorer|Offline\sExplorer|Offline\sNavigator|Openfind|\ Pagerabber|Papa\sFoto|pavuk|pcBrowser|Program\sShareware\s1|ProPowerbot/2.14|ProWebWalker|ProWebWalker|\ psbot/0.1|QueryN.Metasearch|ReGet|RepoMonkey|RMA|SiteSnagger|SlySearch|SmartDownload|Spankbot|spanner|\ Superbot|SuperHTTP|Surfbot|suzuran|Szukacz/1.4|tAkeOut|Teleport|Teleport\sPro|Telesoft|The.Intraformant|\ TheNomad|TightTwatbot|Titan|toCrawl/UrlDispatcher|toCrawl/UrlDispatcher|True_Robot|turingos|\ Turnitinbot/1.5|URLy.Warning|VCI|VoidEYE|WebAuto|WebBandit|WebCopier|WebEMailExtrac.*|WebEnhancer|\ WebFetch|WebGo\sIS|Web.Image.Collector|Web\sImage\sCollector|WebLeacher|WebmasterWorldForumbot|\ WebReaper|WebSauger|Website\seXtractor|Website.Quester|Website\sQuester|Webster.Pro|WebStripper|\ Web\sSucker|WebWhacker|WebZip|Wget|Widow|[Ww]eb[Bb]andit|WWW-Collector-E|WWWOFFLE|\ Xaldon\sWebSpider|Xenu's|Zeus) [NC] RewriteRule .? - [F] |
Dynamically generated robots.txt
robots.txt is a file that search engines use to discover URLs that should or should not be indexed. But creation of this file for large sites with lots of dynamic content can be a very complex task. Have you ever thought about robots.txt dynamically generated from a script? Let's write robots.asp script:
<%@ Language=JScript EnableSessionState=False%> <% //The script must return plain text Response.ContentType="text/plain"; /* Place generation code here */ %> |
Now make it available as robots.txt using single rule:
RewriteEngine on RewriteRule robots\.txt robots.asp [NC] |
Emulating load balancing
This example emulates some kind of DNS Round-Robin load balancing technique. Suppose you have main site www.mysite.com and a number of web servers which you have registered as www[1-9].mysite.com If you install ISAPI_Rewrite on the main server, you can spread traffic randomly between all servers by redirecting initial client request to some specific server. Once redirected, client will continue using this specific server. While this solution is not ideal, it can really spread your traffic and help to avoid problem with preserving session state.
Use the following rule to redirect clients:
RewriteEngine on RewriteMap hosts rnd:hosts.txt RewriteCond %{HTTP:Host} (www)\.mysite.com [NC] RewriteRule (.*) http://${hosts:%1}.mysite.com$1 [R,L] |
And here is hosts.txt file content:
www www1|www2|www3|www4|www5|www6|www7|www8|www9 |
Please find many other useful examples in Apache documentation here. Most of them can be used with ISAPI_Rewrite 3 without any modification.