Sharing is Caring

Convert Apache .htaccess to IIS web.config

Convert your .htaccess to web.config with help from this post. This post describes some of the IIS URL Rewrite equivalents of commonly used Apache .htaccess settings. You may find this useful when you want to convert your .htaccess to web.config. The second part of this series outlines how to use Internet Information Services Manager to import and convert .htaccess to web.config.

Convert Apache .htaccess to IIS web.config

IIS 7.5 / 8.0 web.config equivalents for Apache’s .htaccess (modules like mod_dir, mod_headers, mod_mime mod_rewrite and mod_gzip). Most Apache .htaccess modules are supported in the IIS URL Rewrite module or as web.config configuration directive.

You just need to know where to find the correct IIS equivalent for Apache .htaccess, follow the post to find out…

IIS URL Rewrite equivalent for Apache mod_dir

http://httpd.apache.org/docs/2.2/mod/mod_dir.html, Provides for “trailing slash” redirects and serving directory index files.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Add trailing slash" stopProcessing="true">
          <match url="(.*[^/])$" />
          <conditions>
            <!-- if no file by that name exists -->
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <!-- if a directory by that name does exist -->
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="false" />
          </conditions>
          <action type="Redirect" redirectType="Permanent" url="{R:1}/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Configure default documents in IIS, or directory index

defaultDocument: list of resources to look for when the client requests a directory

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <defaultDocument>
      <files>
        <!-- delete all currently configured index files -->
        <clear />
        <!-- add first index file -->
        <add value="index.php" />
        <!-- add second index file -->
        <add value="index.html" />
      </files>
    </defaultDocument>
  </system.webServer>
</configuration>

IIS web.config: enable and disable directory browsing

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <!-- set to false to disable -->
    <directoryBrowse enabled="true" />
  </system.webServer>
</configuration>

Apache mod_headers in IIS web.config

http://httpd.apache.org/docs/2.2/mod/mod_headers.html. Customization of HTTP request and response headers

Customize response headers in IIS:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <remove name="ETag"/>
        <!-- Set a Access-Control-Allow-Origin header -->
        <add name="Access-Control-Allow-Origin" value="*"/>
        <!-- Set a X-UA-Compatible header -->
        <add name="X-UA-Compatible" value="IE=Edge,chrome=1"/>
        <!-- remove the X-Powered-By header -->
        <remove name="X-Powered-By"/>
        <!-- Set a Cache-Control header with max-age=691200 value -->
        <add name="Cache-Control" value="max-age=691200" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

Learn how to set an HSTS HTTP Strict-Transport-Security header.

Set MIME-type and charset for file extensions in IIS (Apache mod_mime equivalent)

http://httpd.apache.org/docs/2.2/mod/mod_mime.html. Associates the requested filename’s extensions with the file’s behavior (handlers and filters) and content (mime-type, language, character set and encoding)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <httpProtocol>
      <staticContent>
        <remove fileExtension=".html" />
        <mimeMap fileExtension=".html" mimeType="text/html; charset=UTF-8" />
        <remove fileExtension=".htm" />
        <mimeMap fileExtension=".htm" mimeType="text/html; charset=UTF-8" />
        <!-- DON'T set UTF-8 for .css, it breaks markup in Internet Explorer -->
        <!--
          <remove fileExtension=".css" />
          <mimeMap fileExtension=".css" mimeType="text/css; charset=UTF-8" />
        -->
        <remove fileExtension=".css" />
        <mimeMap fileExtension=".css" mimeType="text/css" />
        <remove fileExtension=".js" />
        <mimeMap fileExtension=".js" mimeType="text/javascript; charset=UTF-8" />
      </staticContent>
    </httpProtocol>
  </system.webServer>
</configuration>

IIS URL Rewrite equivalent for mod_rewrite in Apache (most commonly used variant)

http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html. Provides a rule-based rewriting engine to rewrite requested URLs on the fly

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="wordpress" patternSyntax="Wildcard">
	  <match url="*" />
	    <conditions>
	      <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
	      <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
	    </conditions>
	    <action type="Rewrite" url="index.php" />
	</rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Do you use WordPress? Check out my WordPress web.config!

Apache mod_deflate: Gzip compression in IIS, for both static and dynamic file types

http://httpd.apache.org/docs/2.2/mod/mod_deflate.html. Compress content before it is delivered to the client

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <!-- set minFileSizeForComp to 256 kilobytes, the minimum size to allow compression -->
    <httpCompression minFileSizeForComp="256">
      <cheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
      <dynamicTypes>
        <clear />
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <!-- text/javascript MUST BE the same as in the mimeMap -->
        <add mimeType="text/javascript" enabled="true" />
        <add mimeType="*/*" enabled="false" />
      </dynamicTypes>
      <staticTypes>
        <clear />
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <!-- text/javascript MUST BE the same as in the mimeMap -->
        <add mimeType="text/javascript" enabled="true" />
        <add mimeType="*/*" enabled="false" />
      </staticTypes>
    </httpCompression>
    <urlCompression doStaticCompression="true" doDynamicCompression="true" dynamicCompressionBeforeCache="true" />
  </system.webServer>
</configuration>

Gzip compression is mostly configured at the web server level and may be ignored in a website’s web.config. UrlCompression can be used in web.config files.

Freebies, IIS web.config examples

You can configure a lot of other neat stuff in your IIS web.config file. Three (3) examples.

Set Expire headers to 30 days for static content in IIS

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <httpProtocol>
      <staticContent>
        <!-- Set expire headers to 30 days for static content -->
        <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" />
      </staticContent>
    </httpProtocol>
  </system.webServer>
</configuration>

Remove or disable unused handlers

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <!-- remove Perl (.cgi, .pl) if unused -->
      <remove name="PerlPLX" />
      <!-- remove PHP3 (.php3) if unused -->
      <remove name="PHP3" />
      <!-- remove PHP4 (.php4) if unused -->
      <remove name="PHP4" />
      <!-- remove ISAPI_RewriteProxy 64-bit if unused -->
      <remove name="ISAPI_RewriteProxy-64" />
      <!-- remove ISAPI_RewriteProxy if unused -->
      <remove name="ISAPI_RewriteProxy" />
      <!-- remove PHP (.php) if unused -->
      <remove name="PHP" />
    </handlers>
  </system.webServer>
</configuration>

Remove or disable unused IIS-, .NET-modules

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <modules>
      <!-- remove Helicontech APE -->
      <remove name="Helicon.Ape" />
      <!-- Add Uri- File- and Token cache modules -->
      <!-- for IIS Output Cache -->
      <add name="UriCacheModule" />
      <add name="FileCacheModule" />
      <add name="TokenCacheModule" />
    </modules>
  </system.webServer>
</configuration>

IIS Manager .htaccess import

Import and convert .htaccess files with Internet Information Services (IIS) 7.0 Manager.

In the second part of this post series you can learn how to use Internet Information Services (IIS) 7.0 Manager to import and convert a .htaccess file to web.config:

IIS URL Rewrite Outbound Rules

IIS URL Rewrite also supports so called Outbound Rules. An Outbound Rule is applied to the output stream, from the web server to the client. This makes it possible to rewrite response statuses, HTTP content, and so on.

For more information on IIS Outbound Rules, see:


About the Author J. Reilink

My name is Jan. I am not a hacker, coder, developer, programmer or guru. I am merely a system administrator, doing my daily thing at Vevida in the Netherlands. With over 10 years of experience, my specialties include Windows Server, IIS, Linux (CentOS, Debian), security, PHP, websites & optimization.

follow me on:
  • Pingback: Add new WordPress Website to an existing IIS/PHP/SQL Server installation | MontArel Tech()

  • Cesar

    Hi Jan, first of all it’s a very nice article. To help I would like to share a tool that helps to convert .htaccess to web.config file.
    http://cbsa.com.br/tools/online-convert-htaccess-to-web-config.aspx

  • Hello,

    I have a Drupal 7 site on a (godaddy) shared server.

    It’s based on IIS 7 and it means (as far as I know) IIS ignores setting.php and we have to use web.config

    My goal: I need to get the (real) IP address of the client machine.

    The functions I tested (including ip_address()) are returning me the value of “REMOTE_ADDR” when in my scenario the real IP address of the user is in the the X-Forwarded-For header

    The solution in case of using setting.php is this:

    // Tell Drupal that we are behind a reverse proxy server $conf[‘reverse_proxy’] = TRUE; // List of trusted IPs (IP numbers of our reverse proxies) $conf[‘reverse_proxy_addresses’] = array( ‘127.0.0.1’, );

    Then my question is: How can we make these changes/settings using IIS/web.config file?

    I tried to create a rule (web.config) to rewrite the value of REMOTE_ADDR with the X-Forwarded-Fo but It doesn’t work for me. REMOTE_ADDR is not taking the real IP (X-Forwarded-Fo) of the user. Maybe I need to add something to override this value, before “run” this rule?

    I really appreciate any help with this.

    Regards,

    Leo.

  • Hi Leandro, thank you for your comment.

    I’m not sure what the problem is you’re describing, and I’m not familiar with GoDaddy hosting platform. IIS however, should not ignore Drupal’s settings.php file if PHP is set up correctly, it might ignore the .htaccess file.

    I have a very old Dutch post on how to retrieve the visitors IP address in PHP: https://www.saotn.org/het-remote-address-in-php-uitlezen-proxy-safe/ (the PHP code is self explanatory). An PHP example is:

    $ip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? 
        $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);

    Which is what Drupal uses.

    To use a web.config solution you need to have IIS’ Application Request Routing (or ARR) available, as far as I know. Maybe GoDaddy strips the X-Forwarded-For header or replaces it with its own header?

    If GoDaddy is giving you such a hard time (I’ve seen many posts by you about this issue on blogs and SO), just transfer your website to a different hosting company.

  • Pingback: How to using .htaccess files on Windows Server IIS - Sysadmins of the North()