Manual content compression in Apache

2019-07-21 02:17发布

I need a manual compression solution on Apache. My goals:

  • Provide gzip-encoded content on my server along with uncompressed.
  • Files are pre-compressed.
  • Not all files are served compressed. I want to specify these files and the choice isn't type (extension) based.
  • Many content-types (custom ones) are served, and new types are showing up from time to time. Also, file extension doesn't determine if it will be compressed or not (!!!).
  • Keep overhead minimal (the less extra headers, the better).
  • Always provide Content-Length header and never send chunked response (this disqualifies mod_deflate).

Ideal Functionality

Ideal functionality would work like that:

  • Web client asks for file file.ext.
  • If file.ext.gz exists on server:
    • Content-Encoding is set to gzip.
    • Content-Type is set to value of file.ext (!!!).
    • Server returns file.ext.gz.
  • Otherwise, file.ext is returned.

I tested a number of solutions, this article contains a good compilation, but there was always a problem with parts marked with (!!!). I have hundreds of thousands of files and dozens of content types and because of that I'm looking for some automatic solution, without need of adding ForceType for each file.


What I tried

Multiviews

How this works:

  • Rename a file file.ext to file.ext.en
  • Create a file file.ext.gz
  • Configure Apache:

    Options +MultiViews
    AddEncoding x-gzip .gz
    RemoveType .gz
    

Works almost as expected, except it requires the original file (file.ext) to not exist and it adds many (useless to me) headers (TCN, Content-Language and few more) that can't be removed (Header unset doesn't remove them).

Rewrite

How this works: - Create file.ext.gz file. - Configure Apache:

<pre>
RewriteEngine On
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule (.*)$ $1.gz [L]
AddEncoding x-gzip .gz

<Files file.ext>
    ForceType my-custom/mime-type
</FilesMatch>
</pre>

This works well, but requires a ForceType for each compressed file. As I said before, I can't rely on extensions because not all files of certain type will be compressed.

mod_deflate

I didn't investigate it too much, the problem is that if file is too big, then it's split into pieces and sent in chunks and Content-Length is not provided. Increasing size of compression buffers can't eliminate this problem.


Is it possible at all to configure Apache to work as I'd liked to?

I tried to dynamically get Content-Type of file.ext and set it to file.ext.gz, but I didn't find the way how to do this.

0条回答
登录 后发表回答