Получите Apache для автоматической распаковки файла, но только при необходимости
Я бы хотел, чтобы все статические файлы моего веб-сервера были локально сжаты, и обслуживать их либо сжатыми, либо нет, в зависимости от запроса.
Ответы в разделе Как предварительно сжать файлы с помощью mod_deflate в Apache 2.x?, близко, так как действительно, включив MultiViews и используя правильное AddEncoding, я могу заставить Apache вернуть мне сжатый foo.tar.gz
файл с моего веб-сервера, когда я запрашиваю foo.tar
и это идет с надлежащим Content-Encoding:
заголовок.
Но это работает только если клиент включает Accept-Encoding: gzip
в заголовках он отправляет на сервер. OTOH, если клиент не поддерживает кодировку gzip, мой сервер просто говорит мне, что нет "приемлемого" foo.tar
для меня.
Я могу заставить Apache распаковать этот tarball перед отправкой, если я использую AddOutputFilter INFLATE tar
, Но если я это сделаю, то сервер также распаковывает содержимое, когда я запрашиваю foo.tar.gz
(или когда я указываю, что принимаю кодировку gzip), чего я явно не хочу.
Так как же заставить Apache распаковывать файлы, когда клиент не поддерживает кодировку содержимого gzip, а обслуживает предварительно сжатый файл в других случаях?
РЕДАКТИРОВАТЬ: Основываясь на предложении @covener, я попробовал следующее:
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>
[Используя Apache-2.2.22 здесь. ] Но результат на самом деле хуже, чем с первыми тремя строками: когда я запрашиваю файл.tar.gz, он теперь возвращается без "Content-Encoding:", а когда я запрашиваю файл.tar, я получаю содержимое tar.gz (т.е. все еще сжатое) независимо от заголовка "Accept-Encoding:" и без содержимого "Content-Encoding:".
2 ответа
(убедитесь, что у вас есть AddEncoding gzip или x-gzip gz, иначе он сломается)
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>
Попробуй это:
DirectoryIndex "index.html.gz" "index.html"
# Don't list the compressed files in directory indexes - you probably don't want to expose
# the .gz URLs to the outside. They're also misleading, since requesting them will give the
# original files rather than compressed ones.
IndexIgnore "*.html.gz" "*.css.gz"
RewriteEngine On
# Rewrite requests for .html/.css files to their .gz counterparts, if they exist.
RewriteCond "%{DOCUMENT_ROOT}%{REQUEST_FILENAME}.gz" -s
RewriteRule "^(.*)\.(html|css)$" "$1\.$2\.gz" [QSA]
# Serve compressed HTML/CSS with the correct Content-Type header.
RewriteRule "\.html\.gz$" "-" [T=text/html,E=no-gzip:1]
RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1]
# Define a filter which decompresses the content using zcat.
# CAVEAT: This will fork a new process for every request made by a client that doesn't
# support gzip compression (most browsers do), so may not be suitable if you're running a
# very busy site.
ExtFilterDefine zcat cmd="/bin/zcat -"
<FilesMatch "\.(html|css)\.gz$">
<If "%{HTTP:Accept-Encoding} =~ /gzip/">
# Client supports gzip compression - pass it through.
Header append Content-Encoding gzip
</If>
<Else>
# Client doesn't support gzip compression - decompress it.
SetOutputFilter zcat
</Else>
# Force proxies to cache gzipped & non-gzipped css/js files separately.
Header append Vary Accept-Encoding
</FilesMatch>
Заимствовано Дэниэлом Коллинзом, « Обслуживание статического содержимого, сжатого с помощью gzip, с помощью Apache» .