Search code examples
iisurl-rewritingweb-config

How to check a file in a sub-folder for IIS Rewrite?


The following in web.config for rewrite works fine:

<rule name="foo" stopProcessing="true">
  <match url="foo.dat$"/>
  <conditions>
    <!-- Match brotli requests -->
    <add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
  </conditions>
  <action type="Rewrite" url="_compressed_br/foo.dat" />
</rule>

I want to add a condition to make sure the rewriting is done only if the compressed file in the sub-folder exists:

<rule name="foo" stopProcessing="true">
  <match url="foo.dat$"/>
  <conditions>
    <!-- Match brotli requests -->
    <add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
    <!-- Check if the pre-compressed file exists on the disk -->
    <add input="{DOCUMENT_ROOT}/_compressed_br/foo.dat" matchType="IsFile" negate="false" />
  </conditions>
  <action type="Rewrite" url="_compressed_br/foo.dat" />
</rule>

The rewriting never happens with the condition. This means the checking always returns false. I have also tried the following for the condition to no avail:

<add input="{DOCUMENT_ROOT}_compressed_br/foo.dat" matchType="IsFile" negate="false" />
<add input="/_compressed_br/foo.dat" matchType="IsFile" negate="false" />
<add input="_compressed_br/foo.dat" matchType="IsFile" negate="false" />

Could you anyone offer a tip on this?

Edit (2019-09-27): Folder structure:

enter image description here

Web app foo's directory is ...\dist. The URL to open the web application is: http://localhost/foo/

Edit (2019-09-30): enter image description here

Edit (2019-10-01):

The accepted answer works like a charm for the above problem.

I have a new challenge. If I put the web file in the following directory: C:\mywebsite\home\dist\web.config

The website is bound to port 8086. I can browse the following web page: https://localhost:8086/home/dist/

To make the rewrite work, I would have to use the following:

 <add input="{APPL_PHYSICAL_PATH}home\dist\_compressed_br\foo.dat" matchType="IsFile" negate="false" />

Since I may put the contents under folder dist with the corresponding web.config in any directory, I am wondering if there is a parameter that can replace "{APPL_PHYSICAL_PATH}home\dist" so that I can use the same web.config no matter where I put them.


Solution

  • You can use {APPL_PHYSICAL_PATH} to locate your Web app foo's root folder.

    Setting a response header Content-Encoding: br may also be required to prevent unexpected behaviors such as a file download dialog for foo.dat rather than displaying its decoded response.

    So here's the rule you need:

    <rule name="foo" stopProcessing="true">
        <match url="^foo\.dat$" />
        <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
            <add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
            <!-- {APPL_PHYSICAL_PATH} equals to {DOCUMENT_ROOT} + "dist\" in your setup -->
            <add input="{APPL_PHYSICAL_PATH}_compressed_br\foo.dat" matchType="IsFile" />
        </conditions>
        <action type="Rewrite" url="_compressed_br/foo.dat" />
        <serverVariables>
            <set name="RESPONSE_Content-Encoding" value="br" />
        </serverVariables>
    </rule>