apachemod-deflatemod-negotiation

Get Apache to auto-decompress a file, but only if needed


I'd like to keep all the static files of my web-server locally compressed, and to serve them either compressed or not, depending on the request.

The answers in How can I pre-compress files with mod_deflate in Apache 2.x? , are close, since indeed by enabling MultiViews and using the right AddEncoding, I can get Apache to return me the compressed foo.tar.gz file from my web-server when I request foo.tar, and it comes with the proper Content-Encoding: header.

But this only works if the client includes Accept-Encoding: gzip in the headers it sends to the server. OTOH if the client does not support the gzip encoding, my server just tells me there's no "acceptable" foo.tar for me.

I can get Apache to decompress that tarball before sending it if I use AddOutputFilter INFLATE tar. But if I do that, then the server also decompresses the content when I request foo.tar.gz (or when I specify that I accept the gzip encoding), which I clearly don't want.

So how do I get Apache to decompress the files when the client doesn't support the gzip content-encoding, but to serve the pre-compressed file in the other cases?

EDIT: Based on @covener's suggestion I tried the following:

AddEncoding x-gzip .gz .tgz
RemoveType application/x-gzip .gz .tgz
AddType application/x-tar .tgz

<Location /packages>
  FilterDeclare smgunzip CONTENT_SET
  FilterProvider smgunzip INFLATE req=Accept-Encoding !$gzip
  FilterChain smgunzip
</Location>

[ Using Apache-2.2.22 here. ] But the result is actually worse than with just the first three lines: when I request the .tar.gz file, it now gets returned without the "Content-Encoding:", and when I request the .tar file, I receive the content of the tar.gz (i.e. still compressed) regardless of the "Accept-Encoding:" header and still without the "Content-Encoding:".


Solution

  • (make sure you have AddEncoding gzip or x-gzip gz or it will break)

    2.4:

    <Directory /home/covener/SRC/2.4.x/built/htdocs>
      Options +MultiViews
      MultiviewsMatch Any
      FilterDeclare gzip CONTENT_SET
      FilterProvider gzip INFLATE "! req('Accept-Encoding') =~ /gzip/"
      FilterChain gzip
    </Directory>
    

    2.2:

    <Directory /home/covener/SRC/2.2.x/built/htdocs>
      Options +MultiViews
      MultiviewsMatch Any
      FilterDeclare gzip CONTENT_SET
      FilterProvider gzip INFLATE req=Accept-Encoding !$gzip
      FilterChain gzip
    </Directory>