zip: Стриминговый ZIP архиватор для NGINX
Установка
Вы можете установить этот модуль в любой дистрибутив, основанный на RHEL, включая, но не ограничиваясь:
- RedHat Enterprise Linux 7, 8, 9 и 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-zip
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-zip
Активируйте модуль, добавив следующее в начало файла /etc/nginx/nginx.conf:
load_module modules/ngx_http_zip_module.so;
Этот документ описывает nginx-module-zip v1.2.1, выпущенный 20 июля 2022 года.
mod_zip динамически собирает ZIP архивы. Он может стримить компонентные файлы с внешних серверов с помощью нативного проксирующего кода nginx, так что процесс никогда не занимает более нескольких КБ оперативной памяти за раз, даже при сборке архивов, которые (возможно) имеют гигабайты в размере.
mod_zip поддерживает ряд "современных" функций ZIP, включая большие файлы, UTC метки времени и имена файлов в кодировке UTF-8. Он позволяет клиентам возобновлять большие загрузки, используя заголовки "Range" и "If-Range", хотя эти функции требуют, чтобы сервер знал контрольные суммы файлов (CRC-32) заранее. Смотрите раздел "Использование" для подробностей.
Чтобы разархивировать файлы на лету, ознакомьтесь с nginx-unzip-module.
Использование
Модуль активируется, когда оригинальный ответ (предположительно от внешнего сервера) включает следующий HTTP заголовок:
X-Archive-Files: zip
Затем он сканирует тело ответа на наличие списка файлов. Синтаксис представляет собой список, разделенный пробелами, содержащий контрольную сумму файла (CRC-32), размер (в байтах), местоположение (правильно закодированное в URL) и имя файла. Один файл на строку. Местоположение файла соответствует местоположению в вашем nginx.conf; файл может находиться на диске, поступать с внешнего сервера или из другого модуля. Имя файла может включать путь к директории и будет извлечено из ZIP файла. Пример:
1034ab38 428 /foo.txt My Document1.txt
83e8110b 100339 /bar.txt My Other Document1.txt
0 0 @directory My empty directory
Файлы извлекаются и кодируются в порядке. Если файл не может быть найден или запрос файла возвращает какую-либо ошибку, загрузка прерывается.
CRC-32 является необязательным. Укажите "-" если вы не знаете CRC-32; обратите внимание, что в этом
случае mod_zip отключит поддержку заголовка Range.
Специальный маркер URL @directory может быть использован для объявления записи директории
внутри архива. Это очень удобно, когда вам нужно упаковать дерево
файлов, включая некоторые пустые директории, так как их нужно объявлять явно.
Если вы хотите, чтобы mod_zip включал некоторые HTTP заголовки оригинального запроса в подзапросах, которые извлекают содержимое файлов, передайте список их имен в следующем HTTP заголовке:
X-Archive-Pass-Headers: <header-name>[:<header-name>]*
Пере кодирование имен файлов
Чтобы пере кодировать имена файлов в UTF-8, добавьте следующий заголовок к ответу внешнего сервера:
X-Archive-Charset: [original charset name]
Имя оригинальной кодировки должно быть чем-то, что понимает iconv. (Эта функция работает только если iconv присутствует.)
Если вы установите оригинальную кодировку как native:
X-Archive-Charset: native;
имена файлов из списка файлов будут рассматриваться как уже находящиеся в системной нативной кодировке. Соответственно, общий флаг ZIP (бит 11), который указывает на имена, закодированные в UTF-8, не будет установлен, и архиваторы будут знать, что это нативная кодировка.
Иногда возникают проблемы с преобразованием имен в UTF-8 в нативную (CP866) кодировку, что вызывает сбои у популярных архиваторов. И в то же время вы хотите, чтобы данные не терялись, чтобы умные архиваторы могли использовать дополнительное поле Unicode Path. Вы можете предоставить собственное, адаптированное представление имени файла в нативной кодировке вместе с оригинальным именем в UTF-8 в одной строке. Вам просто нужно добавить следующий заголовок:
X-Archive-Name-Sep: [separator];
Таким образом, ваш список файлов должен выглядеть так:
<CRC-32> <size> <path> <native-filename><separator><utf8-filename>
...
тогда поле имени файла будет содержать native-filename, а дополнительное поле Unicode Path будет содержать utf8-filename.
Советы
-
Добавьте заголовок "Content-Disposition: attachment; filename=foobar.zip" в ответе внешнего сервера, если вы хотите, чтобы клиент назвал файл "foobar.zip".
-
Чтобы сэкономить трафик, добавьте заголовок "Last-Modified" в ответе внешнего сервера; mod_zip тогда будет учитывать заголовок "If-Range" от клиентов.
-
Чтобы удалить заголовок X-Archive-Files из ответа, отправляемого клиенту, используйте модуль headers_more: http://wiki.nginx.org/NginxHttpHeadersMoreModule
-
Для улучшения производительности убедитесь, что бэкенды не возвращают сжатые файлы. Вы можете добиться этого с помощью
proxy_set_header Accept-Encoding "";в блоках location для компонентных файлов.
Вопросы/патчи можно направлять Эвану Миллеру, emmiller@gmail.com.
GitHub
Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-zip.