Royi Namir
Royi Namir

Reputation: 148524

Angular's PRE-Gzipped files are not served via IIS?

I have prepared all the settings (at my home , Windows 10) for creating and serving js as gz files , but still - I get only the regular js files (with the original size).

Configuration

Angular's webpack file :

new CompressionPlugin({
      asset: "[path].gz[query]",
     algorithm: "gzip",
     test: /\.js$|\.css$|\.html$/,
     threshold: 10240,
     minRatio: 0.8
 })

Output files for that configuration:

enter image description here

Index.html file:

...
<body>
  <app-root>Loading...</app-root> 
  <script src="/dist/polyfills.bundle.js"></script>
  <script src="/dist/main.bundle.js"></script>
</body>
...

Diagnostics

When I navigate to http://kkk.com/index.html , I get the full size files :

enter image description here

Also - looking at the request headers , I do send the Accept-Encoding:gzip, deflate header :

enter image description here

Question

Why doesn't the GZ files served ?


Additional info :

enter image description here

enter image description here

enter image description here

Upvotes: 13

Views: 5827

Answers (2)

Royi Namir
Royi Namir

Reputation: 148524

OK. After searching a lot - I've managed to do it with URLREWRITE and with some IIS configuration.

First - I've disabled this :

enter image description here

Because I don't need CPU here. I already have the pre zipped files.

OK - the key here is those two sections:

1) Set contentType to application/javascript
2) Set contentEncoding to gzip.

So I've written these 2 urlrewrite rules :

The first section is to rewrite all js files to js.gz and the second rule which is an outboundrule is for adding the content encoding header with gzip value.

This is the config file :

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="https" enabled="true" stopProcessing="false">
                    <match url="(.*).js" />
                    <conditions></conditions>
                    <action type="Rewrite" url="{R:1}.js.gz" appendQueryString="true" logRewrittenUrl="true" />
                </rule>
            </rules>
            <outboundRules>
                <rule name="Rewrite content-encoding header" preCondition="IsGZ" stopProcessing="false">
                    <match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
                    <action type="Rewrite" value="gzip" />
                </rule>
                <preConditions>
                    <preCondition name="IsGZ">
                        <add input="{URL}" pattern="\.gz$" />
                    </preCondition>


        </preConditions>
        </outboundRules>
    </rewrite>
    <urlCompression doStaticCompression="false" />
</system.webServer>

Just paste it in the web.config file (even if you don't use Asp.net).

Also - you have to add this to the mime types :

enter image description here

Now , as you can see the response I do get the right size :

enter image description here

Going deeper :

enter image description here

Which is the one I have as preziiped :

enter image description here

That's all.

Upvotes: 7

Mortalus
Mortalus

Reputation: 10712

IIS does not support pre-compressed files. you could workaoround this fairly simply by using a solution from here: https://github.com/aspnet/StaticFiles/issues/7

the problem is that IIS is serving content as is or it compresses then and the adding the encoding header.

If you add the static compression to IIS it will gzip your files the second time. If you will not add static compression it will send them as is but will not add the encoding header.

so what you want is to hijack the request and manipulate the response grammatically.

here is an OWIN base implementation example. you could as easily use an HTTP handler for older version..

class Startup
{
    private StaticFileOptions StaticFileOptions
    {
        get
        {
            return new StaticFileOptions
            {
                OnPrepareResponse = OnPrepareResponse
            };                
        }
    }

    private void OnPrepareResponse(StaticFileResponseContext context)
    {
        var file = context.File;
        var request = context.Context.Request;
        var response = context.Context.Response;

        if (file.Name.EndsWith(".gz"))
        {
            response.Headers[HeaderNames.ContentEncoding] = "gzip";
            return;
        }

        if (file.Name.IndexOf(".min.", StringComparison.OrdinalIgnoreCase) != -1)
        {
            var requestPath = request.Path.Value;
            var filePath = file.PhysicalPath;

            if (IsDevelopment)
            {
                if (File.Exists(filePath.Replace(".min.", ".")))
                {
                    response.StatusCode = (int)HttpStatusCode.TemporaryRedirect;
                    response.Headers[HeaderNames.Location] = requestPath.Replace(".min.", ".");
                }
            }
            else
            {
                var acceptEncoding = (string)request.Headers[HeaderNames.AcceptEncoding];
                if (acceptEncoding.IndexOf("gzip", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    if (File.Exists(filePath + ".gz"))
                    {
                        response.StatusCode = (int)HttpStatusCode.MovedPermanently;
                        response.Headers[HeaderNames.Location] = requestPath + ".gz";
                    }
                }
            }
        }
    }

   public void Configure(IApplicationBuilder application)
   {
        application
            .UseDefaultFiles()
            .UseStaticFiles(StaticFileOptions)
    }
}

Upvotes: 2

Related Questions