Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I apply <clientCache /> settings to a specific extension in IIS?

I am hosting a web app on Azure with the following Web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <staticContent>
      <mimeMap fileExtension=".text" mimeType="text/plain" />
      <clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
    </staticContent>
  </system.webServer>
</configuration>

This works but I would like to vary the cache age by extension. I would like to set the max age of .html files to 1 day and the max age of everything else to 365 days. The reason being that all of the assets in the html have their filenames revved on change and are served from a CDN, so they never need to expire, but the html pages themselves need to always be fresh so the user can see new content.

I see that the <location> element allows filtering the Web.config to specific locations, but I don't see a way to limit it to certain extensions.

Please note that I don't require being able to do this in the Web.config: any means possible with an Azure Web App is fine.

like image 303
Alan Avatar asked Apr 22 '16 01:04

Alan


People also ask

What is clientCache?

The <clientCache> element of the <staticContent> element specifies cache-related HTTP headers that IIS 7 and later sends to Web clients, which control how Web clients and proxy servers will cache the content that IIS 7 and later returns.


3 Answers

As others have mentioned it is not possible so I would like to suggest a workaround to do the job.
You can take advantage of the capabilities of the URL Rewrite Module by creating an outbound rule to replace Cache-Control header of the html files.

Here's the config.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <staticContent>
            <mimeMap fileExtension=".text" mimeType="text/plain" />
            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00" />
        </staticContent>
        <rewrite>
            <outboundRules>
                <rule name="RewriteCacheControlForHTMLFiles" preCondition="FileEndsWithHtml">
                    <match serverVariable="RESPONSE_Cache_Control" pattern=".*" />
                    <action type="Rewrite" value="max-age=86400" />
                </rule>
                <preConditions>
                    <preCondition name="FileEndsWithHtml">
                        <add input="{REQUEST_FILENAME}" pattern="\.html$" />
                    </preCondition>
                </preConditions>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

A screenshot of my test:

enter image description here

like image 119
Kul-Tigin Avatar answered Nov 05 '22 12:11

Kul-Tigin


Are these files (html vs content) in separate folders? If so, you can setup a folder specific caching age

<configuration>
<location path="[html files path]">
    <system.webServer>
      <staticContent>
        <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="[your requirement]" ></clientCache>
      </staticContent>
    </system.webServer>
  </location>
</configuration>
like image 3
Gandhali Samant Avatar answered Nov 05 '22 12:11

Gandhali Samant


Unfortunately the <location> element doesn't support regex or wildcards so you won't be able to do exactly what you are asking.

I can think of a couple of ways to achieve your goal though. The first is to write an http module that intercepts requests to images and changes the caching headers.

The other option is to leave your html unchanged but to move all your images to an images folder. You could then set a caching rule on that folder. You could use a redirect rule to redirect requests for images to that images folder. If you choose this path I can give you more information about how you might set it up.

like image 1
Sudsy Avatar answered Nov 05 '22 11:11

Sudsy