跳转至

zip: NGINX 的流式 ZIP 压缩模块

安装

您可以在任何基于 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,于 2022 年 7 月 20 日发布。


mod_zip 动态组装 ZIP 压缩包。它可以通过 NGINX 的原生代理代码从上游服务器流式传输组件文件,因此在组装可能达到几 GB 大小的压缩包时,过程不会占用超过几 KB 的 RAM。

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;

文件列表中的文件名将被视为已经在系统本地字符集中的内容。因此,指示 UTF-8 编码名称的 ZIP 通用目的标志(位 11)将不会被设置,归档程序将知道这是本地字符集。

有时将 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

提示

  1. 如果您希望客户端将文件命名为 "foobar.zip",请在上游响应中添加头 "Content-Disposition: attachment; filename=foobar.zip"。

  2. 为了节省带宽,请在上游响应中添加 "Last-Modified" 头;mod_zip 将尊重来自客户端的 "If-Range" 头。

  3. 要从发送给客户端的响应中删除 X-Archive-Files 头,请使用 headers_more 模块:http://wiki.nginx.org/NginxHttpHeadersMoreModule

  4. 为了提高性能,请确保后端不返回 gzipped 文件。您可以在组件文件的位置块中使用 proxy_set_header Accept-Encoding ""; 来实现这一点。

问题/补丁可以发送给 Evan Miller,emmiller@gmail.com

GitHub

您可以在 nginx-module-zip 的 GitHub 仓库 中找到此模块的其他配置提示和文档。