Reputation: 1947
my angular2 projects build pre-compressed gzip files for my web-app but my IIS only serves the normal ".js" files instead of the compressed ".gzip" files. My browser is willing to accept gzip.
What is the correct setting for IIS to allow gzip responses?
I already searched google/SO/SU but only found solutions for not "pre-compressed" content.
Upvotes: 8
Views: 4607
Reputation: 983
A more neat and elegant solution:
NOTICE: The file extension .gzip
seems strange, in general, we name a gziped file as .gz
, so in this example, we use .gz
instead .gzip
, if you insist on .gzip
, just replace all the extensions in the following config file.
Code first, this is what all we need for web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".js.gz" />
<remove fileExtension=".css.gz" />
<remove fileExtension=".png.gz" />
<remove fileExtension=".jpg.gz" />
<remove fileExtension=".gif.gz" />
<remove fileExtension=".svg.gz" />
<remove fileExtension=".html.gz" />
<remove fileExtension=".json.gz" />
<mimeMap fileExtension=".js.gz" mimeType="application/javascript" />
<mimeMap fileExtension=".css.gz" mimeType="text/css" />
<mimeMap fileExtension=".png.gz" mimeType="image/png" />
<mimeMap fileExtension=".jpg.gz" mimeType="image/jpeg" />
<mimeMap fileExtension=".gif.gz" mimeType="image/gif" />
<mimeMap fileExtension=".svg.gz" mimeType="image/svg+xml" />
<mimeMap fileExtension=".html.gz" mimeType="text/html" />
<mimeMap fileExtension=".json.gz" mimeType="application/json" />
</staticContent>
<rewrite>
<outboundRules rewriteBeforeCache="true">
<rule name="Custom gzip file header">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<conditions>
<add input="{REQUEST_URI}" pattern="\.gz$" />
</conditions>
<action type="Rewrite" value="gzip"/>
</rule>
</outboundRules>
<rules>
<rule name="Rewrite gzip file">
<match url="(.*)"/>
<conditions>
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<add input="{REQUEST_FILENAME}.gz" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.gz" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
And, here are how it works:
In order to achieve a successful gziped data transmission, we need:
Accept-Encoding
Content-Encoding
application/gzip
The four conditions must be satisfied at the same time.
If you send an uncompressed file with Content-Encoding: gzip
, the browser will return an error;
If you send a compressed file without a Content-Encoding
header, or a mismatched MIME type, the page may return some Zenith Star's text.
So what we are doing is:
Content-Encoding
, only if the client side send the header Accept-Encoding
This solution works on my IIS7, not sure if it will also work on IIS10.
If you met any problem, let me know :D
Upvotes: 9
Reputation: 1947
After a long time searching I found a workaround with URL-Rewrite.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<rewrite>
<rules>
<clear />
<rule name="Https redirect" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^domain.com$" />
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
<rule name="LetsEncrypt">
<match url=".well-known/acme-challenge/*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="None" />
</rule>
<rule name="Angular Routes" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
<rule name="br_rewrite" enabled="true" stopProcessing="true">
<match url="(.*).(js$|svg|css)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:2}.br" logRewrittenUrl="true" />
</rule>
<rule name="gzip_rewrite" enabled="true" stopProcessing="true">
<match url="(.*).(js$|svg|css)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:2}.gz" logRewrittenUrl="true" />
</rule>
</rules>
<outboundRules rewriteBeforeCache="true">
<rule name="Remove Server header" enabled="true">
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
<rule name="Rewrite content-encoding header gzip" preCondition="IsGZ" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<action type="Rewrite" value="gzip" />
</rule>
<rule name="Rewrite content-encoding header br" preCondition="IsBR" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<action type="Rewrite" value="br" />
</rule>
<rule name="css content type" preCondition="IsCSS" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="(.*)" />
<action type="Rewrite" value="text/css" />
</rule>
<rule name="js content type" preCondition="IsJS" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="(.*)" />
<action type="Rewrite" value="application/javascript" />
</rule>
<rule name="svg content type" preCondition="IsSVG" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="(.*)" />
<action type="Rewrite" value="image/svg+xml" />
</rule>
<preConditions>
<preCondition name="IsGZ">
<add input="{URL}" pattern="\.gz$" />
</preCondition>
<preCondition name="IsBR">
<add input="{URL}" pattern="\.br$" />
</preCondition>
<preCondition name="IsCSS">
<add input="{URL}" pattern="css" />
</preCondition>
<preCondition name="IsJS">
<add input="{URL}" pattern="js" />
</preCondition>
<preCondition name="IsSVG">
<add input="{URL}" pattern="svg" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression doStaticCompression="true" doDynamicCompression="false" />
<httpCompression sendCacheHeaders="false" />
<staticContent>
<mimeMap fileExtension=".br" mimeType="application/brotli" />
<clientCache cacheControlMode="UseMaxAge" />
</staticContent>
</system.webServer>
</configuration>
It's successfull handels BR and GZIP requests for pre-build angular files (JS, CSS, SVG).
I hope this helps someone else. If you know a better solution let me know.
Upvotes: 2