Search code examples
iisurl-rewritingweb-config

How to specify the file path in web.config for checking file existence?


A website's file directory looks like the following: enter image description here

In IIS. the website's directory is set to C:\mywebiste, and is bound port 8086. The following web page can be browsed without any problem:

https://localhost:8086/home/dist/

I want to use IIS rewrite to use the compressed foo.dat ONLY if it exists, so the web.config looks like the following:

<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="{APPL_PHYSICAL_PATH}home\dist\_compressed_br\foo.dat" matchType="IsFile" negate="false" />
  </conditions>
  <action type="Rewrite" url="_compressed_br/foo.dat" />
</rule>

It works fine. Since I may distribute 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 place them. This question is an extension from another similar question per the suggestion of the kind answer provider.

[Edit] 2019-10-03 Based on the excellent well commented answer, I can rewrite for all the files now:

<rule name="Rewrite br" stopProcessing="true">
  <match url="^(.*)$"/>
  <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
    <!-- Match brotli requests -->
    <add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
    <!-- following condition captures a group {C:1} with the value "C:\some\directory" for a path "c:\some\directory\foo.dat" -->
    <!-- so we can use in the next condition to check whether the compressed version exists -->
    <add input="{REQUEST_FILENAME}" pattern="^(.*)\\([^\\]*)$"/>
    <!-- Check if the pre-compressed file exists on the disk -->
    <!-- {C:1} used as requested file's parent folder -->
    <add input="{C:1}\_compressed_br\{C:2}" matchType="IsFile"/>
    </conditions>
  <action type="Rewrite" url="_compressed_br/{C:2}" />
  <serverVariables>
    <set name="RESPONSE_Content-Encoding" value="br"/>
  </serverVariables>
</rule>   

Solution

  • If I understood you correctly, you always want to rewrite the version under the _compressed_br folder next to the web.config.

    If so, give the following a try:

    <rule name="foo" stopProcessing="true">
        <match url="^foo\.dat$"/>
        <!-- trackAllCaptures="true" is required to capture regex groups across conditions -->
        <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
            <add input="{HTTP_ACCEPT_ENCODING}" pattern="br"/>
            <!-- following condition captures a group {C:1} with the value "C:\some\directory" for a path "c:\some\directory\foo.dat" -->
            <!-- so we can use in the next condition to check whether the compressed version exists -->
            <add input="{REQUEST_FILENAME}" pattern="^(.*)\\foo\.dat$"/>
            <!-- {C:1} used as requested file's parent folder -->
            <add input="{C:1}\_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>