Как я могу предварительно сжать файлы с помощью mod_deflate в Apache 2.x?
Я передаю весь контент через Apache с Content-Encoding: zip
но это сжимается на лету. Хорошее количество моего контента - статические файлы на диске. Я хочу сжать файлы заранее, а не сжимать их каждый раз, когда они запрашиваются.
Это то, что, я считаю, mod_gzip
сделал в Apache 1.x автоматически, но просто с файлом с.gz рядом с ним. Это больше не относится к mod_deflate
,
8 ответов
В любом случае, эта функциональность была неуместна в mod_gzip. В Apache 2.x вы делаете это с помощью согласования контента. В частности, вам нужно включить MultiViews
с Options
директива, и вам нужно указать типы кодирования с помощью AddEncoding
директива
Чтобы ответить на мой собственный вопрос с очень простой строкой, которую мне не хватало в моей конфигурации:
Options FollowSymLinks MultiViews
Мне не хватало опции MultiViews. Он есть в конфигурации веб-сервера Ubuntu по умолчанию, так что не будь таким, как я, и оставь его.
Также я написал быстрое задание Rake, чтобы сжать все файлы.
namespace :static do
desc "Gzip compress the static content so Apache doesn't need to do it on-the-fly."
task :compress do
puts "Gzipping js, html and css files."
Dir.glob("#{RAILS_ROOT}/public/**/*.{js,html,css}") do |file|
system "gzip -c -9 #{file} > #{file}.gz"
end
end
end
Можно обслуживать предварительно сжатые файлы, используя mod_negotiation
хотя это немного привередливо. Основная сложность заключается в том, что согласовываются только запросы на файлы, которые не существуют. Так что если foo.js
а также foo.js.gz
оба существуют, ответы на /foo.js
всегда будет без сжатия (хотя ответы на /foo
будет работать правильно).
Самым простым решением, которое я нашел ( от Франсуа Мариера), является переименование несжатых файлов с двойным расширением, поэтому foo.js
развернут как foo.js.js
поэтому запросы на /foo.js
вести переговоры между foo.js.js
(без кодирования) и foo.js.gz
(кодировка gzip).
Я комбинирую этот трюк со следующей конфигурацией:
Options +MultiViews
RemoveType .gz
AddEncoding gzip .gz
# Send .tar.gz without Content-Encoding: gzip
<FilesMatch ".+\.tar\.gz$">
RemoveEncoding .gz
# Note: Can use application/x-gzip for backwards-compatibility
AddType application/gzip .gz
</FilesMatch>
Я написал пост, в котором подробно обсуждаются причины этой конфигурации и некоторые альтернативы.
Я боюсь, что MultiViews не будут работать должным образом: в документе говорится, что Multiviews работает, "если сервер получает запрос на / some / dir / foo, если / some / dir имеет включенные MultiViews, и / some / dir / foo не существует...", другими словами: если у вас есть файлы foo.js и foo.js.gz в одном каталоге, простая активация MultiViews не приведет к отправке файла.gz, даже если заголовок gzip AcceptEncoding передается браузер (вы можете проверить это поведение, временно отключив mod_deflate и отслеживая ответ, например, с помощью HTTPFox).
Я не уверен, есть ли способ обойти это с помощью MultiViews (возможно, вы можете переименовать исходный файл, а затем добавить специальную директиву AddEncoding), но я считаю, что вы можете создать правило mod_rewrite, чтобы справиться с этим.
У меня есть Apache 2, собранный из исходного кода, и я обнаружил, что мне пришлось изменить следующее в моем файле httpd.conf:
Добавить MultiViews к параметрам:
Options Indexes FollowSymLinks MultiViews
Удалить комментарий AddEncoding:
AddEncoding x-compress .Z AddEncoding x-gzip .gz .tgz
Комментарий AddType:
#AddType application/x-compress .Z #AddType application/x-gzip .gz .tgz
mod_gzip также сжатый контент на лету. Вы можете предварительно сжать файлы, фактически войдя на сервер и выполнив это из оболочки.
cd /var/www/.../data/
for file in *; do
gzip -c $file > $file.gz;
done;
Ты можешь использовать mod_cache
для прокси локального контента в памяти или на диске. Я не знаю, будет ли это работать как ожидалось с mod_deflate
,
У меня много больших файлов.json. Большинство читателей в этой ситуации. Ответы предварительного просмотра не говорили о возвращенном "Типе контента".
Если вы хотите, чтобы следующий запрос возвращал предварительно сжатый файл с "Content-Type: application/json" прозрачно, используйте Multiview с ForceType
http://www.domain.com/(...)/bigfile.json
-> Content-Encoding:gzip, Content-Type: Content-Encoding:gzip
1) файлы должны быть переименованы: "file.ext.ext"
2) Multiview прекрасно работает с ForceType
В файловой системе:
// Note there is no bigfile.json
(...)/bigfile.json.gz
(...)/bigfile.json.json
В вашем конфиге apache:
<Directory (...)>
AddEncoding gzip .gz
Options +Multiviews
<Files *.json.gz>
ForceType application/json
</Files>
</Directory>
Коротко и просто:)