Understanding web.config rewrite module

There are many reasons for needing to perform redirects or simple rewrites on your website. A few of the most common reasons are:

  • User-friendly URLs.
  • Rewrite old folder/files to a new location.
  • Redirect all traffic to HTTPS://.
  • Restrict access to specific folder(s) by IP Address.

There are many other purposes for utilizing the IIS Rewrite Module, although these are the most common.

IIS Rewrite Module

Firstly let’s explain exactly what IIS is and what it stands for. IIS is a Microsoft product and stands for Microsoft Internet Information Services. This is Microsoft’s web server software used to handle and serve web request (website request).

Knowing that IIS is used to handle website request we can then determine that the IIS Rewrite Module is a website rewrite handler. This module is not built into IIS by default, although we do typically install this module when creating new servers in our environment.

If IIS Rewrite Module is not installed on your server, then you can create a support ticket with our team and we’ll get this installed on your behalf.

Inbound Rules vs. Outbound Rules

An inbound rule allows you to manipulate the incoming request to your website before your website application even loads (such as your WordPress application). This allows you to rewrite the request if needed, or perform any of the other supported rewrite functionality built into this module.

An outbound rule allows you to manipulate request coming out of your website, such as from a link on your website: As an example: <a href="http://example.com?id=1&example=2"></a>

Inbound rules are used more frequently than outbound rules as typically the application used on the website properly handles the links a website uses and sends visitors to when clicked.

Creating Rules via GUI Method

It is highly recommended to use the GUI (graphical user interface) when creating rules for your website as it provides a much easier method of developing working patterns. Some developers may find it easier though to use the manual method of creating the code from scratch as they may be more familiar with the syntax.

Note: If you do not have access to your server via RDP (such as being on a shared server), then you can still use the GUI by installing IIS and URL Rewrite module on your local computer. Once installed you could access the GUI on your local computer just like you would on a dedicated server.

When the IIS Rewrite module is installed on the server the GUI should become available. To access the GUI for creating rewrite rules on your website follow the steps below:

  1. Open IIS Manager (latest version installed) on the server.

  2. Expand the server node, then click on ‘Sites’.

  3. Search for the website you want to create a rewrite rule on. Double click the site to go into its settings.

  4. You should see several features listed for the website. Find and open the feature labeled ‘URL Rewrite’.

    url rewrite

  5. You should now see a list of any existing rules you have set up, if any. To create a new rule select the option in the right-side actions pane labeled ‘Add Rule(s)’.

    add rules

  6. You should now be asked what kind of rule you want to have created. In most cases, the option for ‘Blank rule’ is used which allows you to create the rule from scratch with your desired input.

    rule_options

  7. The next step is very easy… as you just want to be sure to name your rule something that is informative of what type of behavior you are looking to accomplish (such as 'HTTP to HTTP Rewrite).

  8. After naming the rule you will have four main sections (Match URL, Conditions, Server Variables, and finally Action). We’ll go each of these sections now:

    1. Match URL: This section will tell the rewrite handler whether the requested incoming URL matches the pattern or not. This particular section is related to everything that comes after the website. So for example in the URL http://example.com?id=1&example=2 the pattern would be checking to see if it matched ?id=1&example=2 or not.

      By default, you can use regular expressions for advanced pattern checking. There are other pattern types such as wildcard searching, or an exact match. You can change the pattern type by selecting the ‘Using’ drop-down.

    2. Conditions: This section will tell the rewrite handler that even if the above MatchURL succeeds that specific conditions must be met in order for the rule to truly succeed. For example, you can set the Input type to {HTTP_HOST} and then set the pattern to ^www\. then the rule would only succeed if the domain being browsed to contained www in the name. This would be an easy way to redirect any non-www traffic to the www version of the website.

    3. Server Variables: This section allows you to easily change the server variable types (such as GET request to POST request). This is not commonly used in any rules and in most cases you can ignore this section.

    4. Action: This section will determine what course of action is taken if the rule is triggered. The rule will be triggered if the Match URL and Conditions are successfully met. There are several options available for the actions, which the most commonly used are Rewrite and Redirect.

      With the rewrite option you can easily manipulate the incoming request without changing what the visitor of the website sees in the URL. For example, you can make any request to HTML files actually be processed by PHP or another language.

      The redirect option you can easily redirect the user to another URL of your choosing. You can take advantage of capturing information from the original URL (with Regular Expressions) and manipulating the redirect URL with those variables.

      The last part of the actions pane is the option to stop processing all subsequent rules. This means if the rule is triggered, then stop processing all other rules that fall below this rule in order.

  9. Once you are satisfied with your rule you can save it by clicking the ‘Apply’ option from the right-side actions pane.

    Apply_rule

Note: The rule you create will automatically be added to your websites web.config file. This configuration file maintains several configuration values that you are essentially overriding in IIS for your specific website and/or folder.

Creating Rules Manually via Web.Config

As mentioned earlier it is highly recommended to use the GUI for creating rewrite rules unless you are familiar with web.config syntax. Even if you do not have access to the server your website resides on (such as a shared server) you can still use the IIS GUI on your local computer at home.

If you want to create or modify rules in your web.config, which is considered the manual way, then follow the steps below:

  1. Access your websites web.config file (should be in the ‘wwwroot’ directory of your website). You can access this either with direct file location on your server via RDP or via downloading the file to your local computer via FTP.

    If your website doesn’t have a web.config file, then create one now.

  2. Open the file up in your favorite text editor (such as NotePad ++, Atom, Sublime, etc…).

  3. Below is an example of a web.config file. If you did not have a web.config file, then copy/paste this information to the file once you create it. If you do have a web.config file, then just make sure you have the tags <system.webServer><rewrite><rules> and </rules></rewrite> </system.webServer> tags and everything between them. You’ll want to make sure you do not have duplicates of any of these tags, as well as that you do not remove any previous configurations set within them if they already existed.

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
       <system.webServer>
    		<rewrite>
    			<rules>
    				
    			</rules>
    		</rewrite>
       </system.webServer>
    </configuration>
    
    
  4. Now that you have the correct configuration setup to be able to add the rules you need… you can add the necessary rules using the tag <rule> and it’s closing tag </rule>.

    An example of valid rewrite rules can be found below.

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
       <system.webServer>
    		<rewrite>
    			<rules>
    				<rule name="Imported Rule 1">
    				   <match url="^" ignoreCase="false" />
    					 <conditions>
    					   <add input="{HTTP_HOST}" pattern="^$" ignoreCase="false" negate="true" />
    					   <add input="{HTTP_HOST}" pattern="^www\." negate="true" />
    					   <add input="{HTTPS}s" pattern="^on(s)|" ignoreCase="false" />
    					 </conditions>
    				   <action type="Redirect" redirectType="Permanent" url="http{C:1}://www.{HTTP_HOST}{URL}" />
    				 </rule>
    				 <rule name="Imported Rule 1">
    				   <match url="(.*)" ignoreCase="false" />
    					<conditions>
    					  <!--## Redirect HTTP to HTTPS-->
    					  <!--# Only trigger rule if a non-ssl port is being used-->
    					   <add input="{SERVER_PORT}" pattern="443" ignoreCase="false" negate="true" />
    					</conditions>
    				  <action type="Redirect" redirectType="Permanent" url="https://{HTTP_HOST}/{R:1}" />
    				 </rule>
    			</rules>
    		</rewrite>
       </system.webServer>
    </configuration>
    
    

    The above rule would redirect any non-www traffic to the www version of the website, as well as it would redirect any request that is not coming in over SSL (https) to the secure version of the website.

    Note: If placed in a sub-directory the rewrite rules will only take effect for that specific directory and any sub-directories beneath it.

Rule Examples

The above sections explain the configuration of a web.config and how rewrite module works. There are a ton of rules and other things you can do with the rewrite module. We’ll include some of the common rules below that you can implement in your application with little to no modification needed, depending on the rule.

Note: The ‘Rule name’ value can be anything that you want. I recommend organizing your redirect rules by name to make it easier to manage. Especially, if there are a lot of them.

Redirecting To A Different Domain

If you need to redirect your website to another website.

<rewrite>
 <rules>
   <rule name="Imported Rule 1">
    <match url="^(.*)$" ignoreCase="false" />
     <conditions>
       <add input="{HTTP_HOST}" pattern="^(www\.)?domain\.com$" />
      </conditions>
     <action type="Redirect" redirectType="Permanent" url="http://www.newdomain.com/{R:1}"   appendQueryString="true" />
   </rule>
 </rules>

Redirecting To A Different Folder

Add the following code to direct your site to another directory.

<rewrite>
 <rules>
  <rule name="Imported Rule 1" stopProcessing="true">
   <match url="^oldfolder$" />
   <action type="Redirect" redirectType="Permanent" url="/correctfolder" />
  </rule>
 </rules>
</rewrite>

Redirecting File Names

To have your index.htm page auto redirect to index.asp user this example.

<rewrite>
 <rules>
   <rule name="Imported Rule 1" stopProcessing="true">
    <match url="index.htm" ignoreCase="false" />
    <action type="Redirect" redirectType="Permanent" url="index.asp" />
   </rule>
  </rules>
</rewrite>

SubFolder Rewrite

To redirect your domain to a subfolder of that domain example: www.domain.com to www.domain.com/folder

<rewrite>
   <rules>
    <!--# Exclude requests already going to /subfolder to avoid an infinite loop-->
     <rule name="Imported Rule 1" stopProcessing="true">
       <match url="^subfolder.*$" />
       <action type="None" />
     </rule>
    <!--# Rewrite normal requests to /subfolder-->
      <rule name="Imported Rule 2" stopProcessing="true">
        <match url="^(.*)$" ignoreCase="false" />
        <action type="Rewrite" url="/subfolder/{R:1}" />
      </rule>
   </rules>
 </rewrite>

NON-WWW. To WWW. Redirect

Redirecting non-www version to www., for example, domain.com to www.domain.com

<rewrite>
  <rules>
    <rule name="Imported Rule 1" stopProcessing="true">
       <match url="^" ignoreCase="false" />
         <conditions>
           <add input="{HTTP_HOST}" pattern="^$" ignoreCase="false" negate="true" />
           <add input="{HTTP_HOST}" pattern="^www\." negate="true" />
           <add input="{HTTPS}s" pattern="^on(s)|" ignoreCase="false" />
         </conditions>
       <action type="Redirect" redirectType="Permanent" url="http{C:1}://www.{HTTP_HOST}{URL}" />
     </rule>
   </rules>
</rewrite>

WWW. To NON-WWW. Redirect

Redirecting www version to non-www., for example, www.domain.com to domain.com

<rewrite>
  <rules>
    <rule name="Imported Rule 1" stopProcessing="true">
      <match url="^" ignoreCase="false" />
       <conditions>
        <add input="{HTTP_HOST}" pattern="^www.domain.com" ignoreCase="false" />
       </conditions>
      <action type="Redirect" redirectType="Permanent" url="http://domain.com{URL}" />
    </rule>
   </rules>
</rewrite>

URL Rewrite

Suppose you have URL like www.example.com/foo.asp?a=A&b=B&c=C and you want to access it as www.example.com/foo.asp/a/A/b/B/c/

<rewrite>
  <rules>
    <rule name="Imported Rule 1">
     <match url="^(.*?\.asp)/([^/]*)/([^/]*)(/.+)?" />
     <action type="Rewrite" url="{R:1}{R:4}?{R:2}={R:3}" appendQueryString="true" />
    </rule>
  </rules>
</rewrite> 

WordPress Permalinks

WordPress Permalinks using mod_rewrite are for Linux, but ISAPI_Rewrite does offer the equivalent. If you want to have index.php not show in the URL try using these in your .htaccess file.

If your WordPress site is in the wwwroot folder.

<rewrite>
  <rules>
    <rule name="Imported Rule 1" stopProcessing="true">
      <match url="." />
      <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="/index.php" />
    </rule>
   </rules>
</rewrite>

If your WordPress site is in a subfolder.

<rewrite>
  <rules>
    <rule name="Imported Rule 1" stopProcessing="true">
      <match url="." />
      <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="/subfolder/index.php" />
    </rule>
  </rules>
</rewrite>

Site Crawlers

Example on how to prevent certain spiders from crawling your site.

<rewrite>
  <rules>
    <rule name="Imported Rule 1">
      <match url=".*" ignoreCase="false" />
        <conditions>
          <add input="{HTTP_USER_AGENT}" pattern="^Baiduspider.*$" ignoreCase="false" />
        </conditions>
      <action type="Rewrite" url="/block.htm" />
    </rule>
    <rule name="Imported Rule 2">
      <match url=".*" ignoreCase="false" />
        <conditions>
          <add input="{HTTP_USER_AGENT}" pattern="^Yandex.*$" ignoreCase="false" />
        </conditions>
      <action type="Rewrite" url="/block.htm" />
    </rule>
  </rules>
</rewrite>

Variable URLs

Let’s say you want to have a URL display like: http://your_domain.com/some-folder/34-77-some-key-word.html But you want that to really process a query like: http://your_domain.com/folder/search.asp?country=34&city=77

<rewrite>
  <rules>
    <rule name="Imported Rule 1">
      <match url="^some-folder/([^-]+)-([^-]+)-.*$" ignoreCase="false" />
      <action type="Rewrite" url="/folder/search.asp?country={R:1}&amp;city={R:2}" appendQueryString="false" />
    </rule>
  </rules>
</rewrite>

Wild-Card Subdomains

Rewrite all wild-card sub-domain requests to a folder without affecting "your_domain.com" or "www.your_domain.com"

<rewrite>
  <rules>
    <!--# Ignore requests that are already rewritten-->
      <rule name="Imported Rule 1" stopProcessing="true">
        <match url="^subdomainfolder/.*$" />
        <action type="None" />
      </rule>
      <rule name="Imported Rule 2" stopProcessing="true">
        <match url="^(.*)$" ignoreCase="false" />
          <conditions>
           <!--# Rewrite all requests to non-www sub-domains to /subdomainfolder-->
            <add input="{HTTP_HOST}" pattern="^(www\.)?your_domain\.com$" negate="true" />
          </conditions>
        <action type="Rewrite" url="/subdomainfolder/{R:1}" />
      </rule>
  </rules>
</rewrite>

HTTP To HTTPS SSL Rewrites

Suppose you have URL like http://shop.example.com and you want your visitors to be redirected to https://shop.example.com

Here are some examples of how to force SSL. Simply place the following rules into your .htaccess file:

http To https redirect

This rule will detect if the request is incoming over the secure https protocol, if not it will force the request over the SSL port.

<rewrite>
   <rules>
    <!--# Redirect to HTTPS-->
     <rule name="Imported Rule 1">
       <match url="(.*)" ignoreCase="false" />
        <conditions>
          <!--## Redirect HTTP to HTTPS-->
          <!--# Only trigger rule if a non-ssl port is being used-->
           <add input="{SERVER_PORT}" pattern="443" ignoreCase="false" negate="true" />
        </conditions>
      <action type="Redirect" redirectType="Permanent" url="https://{HTTP_HOST}/{R:1}" />
     </rule>
   </rules>
</rewrite>

http To https with WWW redirect

This version will be both redirected to HTTPS as well as add “www.” to the beginning of the hostname if it is missing.

<rewrite>
   <rules>
     <!--# Redirect to HTTPS with www-->
      <rule name="Imported Rule 1">
        <match url="(.*)" ignoreCase="false" />
          <conditions>
           <!--# Enable rewrite rules-->
           <!--## Redirect HTTP to HTTPS with www-->
           <!--# Only trigger rule if a non-ssl port is being used-->
             <add input="{SERVER_PORT}" pattern="443" ignoreCase="false" negate="true" />
           <!--# Extract non-www portion of HTTP_HOST-->
             <add input="{HTTP_HOST}" pattern="^(www\.)?(.*)" />
         </conditions>
       <action type="Redirect" redirectType="Permanent" url="https://www.{C:2}/{R:1}" />
     </rule>
   </rules>
</rewrite>