跳转至

upload: 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-upload
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-upload

通过在 /etc/nginx/nginx.conf 顶部添加以下内容来启用该模块:

load_module modules/ngx_http_upload_module.so;

本文档描述了 nginx-module-upload v2.3.0,于 2018 年 8 月 02 日发布。


这是一个用于处理文件上传的 nginx 模块,使用 multipart/form-data 编码 (RFC 1867) 和根据 this 协议进行可恢复上传。

描述

该模块解析请求体,存储所有上传的文件到由 upload_store 指令指定的目录。文件随后将从请求体中剥离,并将修改后的请求传递到由 upload_pass 指令指定的位置,从而允许任意处理上传的文件。每个文件字段都将被由 upload_set_form_field 指令指定的一组字段替换。每个上传文件的内容可以从由 $upload_tmp_path 变量指定的文件中读取,或者文件可以简单地移动到最终目的地。输出文件的删除由 upload_cleanup 指令控制。如果请求的方法不是 POST,模块将返回错误 405(方法不允许)。具有此类方法的请求可以通过 error_page 指令在替代位置进行处理。

指令

upload_pass

语法: upload_pass location
默认:
上下文: server,location

指定将请求体传递到的位置。文件字段将被剥离并替换为包含处理上传文件所需信息的字段。

upload_resumable

语法: upload_resumable on | off
默认: upload_resumable off
上下文: main,server,location

启用可恢复上传。

upload_store

语法: upload_store directory [level1 [level2]] ...
默认:
上下文: server,location

指定将输出文件保存到的目录。该目录可以是哈希的。在这种情况下,所有子目录在启动 nginx 之前应存在。

upload_state_store

语法: upload_state_store directory [level1 [level2]] ...
默认:
上下文: server,location

指定将包含可恢复上传状态文件的目录。该目录可以是哈希的。在这种情况下,所有子目录在启动 nginx 之前应存在。

upload_store_access

语法: upload_store_access mode
默认: upload_store_access user:rw
上下文: server,location

指定用于创建输出文件的访问模式。

upload_set_form_field

语法: upload_set_form_field name value
默认:
上下文: server,location

指定在传递给后端的请求体中为每个上传文件生成的表单字段。namevalue 都可以包含以下特殊变量:

  • $upload_field_name: 原始文件字段的名称
  • $upload_content_type: 上传文件的内容类型
  • $upload_file_name: 正在上传的文件的原始名称,前导路径元素在 DOS 和 UNIX 表示法中被剥离。即 "D:\Documents And Settings\My Dcouments\My Pictures\Picture.jpg" 将被转换为 "Picture.jpg",而 "/etc/passwd" 将被转换为 "passwd"。
  • $upload_tmp_path: 原始文件内容存储的路径。输出文件名由 10 位数字组成,并使用与 proxy_temp_path 指令相同的算法生成。

这些变量仅在处理原始请求体的一个部分期间有效。

使用示例:

upload_set_form_field $upload_field_name.name "$upload_file_name";
upload_set_form_field $upload_field_name.content_type "$upload_content_type";
upload_set_form_field $upload_field_name.path "$upload_tmp_path";

upload_aggregate_form_field

语法: upload_aggregate_form_field name value
默认:
上下文: server,location

指定在传递给后端的请求体中为每个上传文件生成的包含聚合属性的表单字段。namevalue 都可以包含标准 nginx 变量、来自 upload_set_form_field 指令的变量以及以下附加特殊变量:

  • $upload_file_md5: 文件的 MD5 校验和
  • $upload_file_md5_uc: 文件的 MD5 校验和(大写字母)
  • $upload_file_sha1: 文件的 SHA1 校验和
  • $upload_file_sha1_uc: 文件的 SHA1 校验和(大写字母)
  • $upload_file_crc32: 文件的 CRC32 的十六进制值
  • $upload_file_size: 文件的大小(以字节为单位)
  • $upload_file_number: 请求体中文件的序号

此指令指定的字段的值在文件成功上传后进行评估,因此这些变量仅在处理原始请求体的一个部分结束时有效。

警告:: 变量 $upload_file_md5$upload_file_md5_uc$upload_file_sha1$upload_file_sha1_uc 使用额外的资源来计算 MD5 和 SHA1 校验和。

使用示例:

upload_aggregate_form_field $upload_field_name.md5 "$upload_file_md5";
upload_aggregate_form_field $upload_field_name.size "$upload_file_size";

upload_pass_form_field

语法: upload_pass_form_field regex
默认:
上下文: server,location

指定将从原始请求体传递到后端的字段名称的正则表达式模式。此指令可以在每个位置多次指定。字段将在第一个模式匹配时传递到后端。对于不支持 PCRE 的环境,此指令指定要传递到后端的字段的确切名称。如果省略此指令,则不会将任何字段从客户端传递到后端。

使用示例:

upload_pass_form_field "^submit$|^description$";

对于不支持 PCRE 的环境:

upload_pass_form_field "submit";
upload_pass_form_field "description";

upload_cleanup

语法: upload_cleanup status/range ...
默认:
上下文: server,location

指定在生成后,当前请求中成功上传的所有文件将被删除的 HTTP 状态。用于在后端或服务器故障后进行清理。如果后端出于某种原因不需要上传的文件,也可以明确发出错误状态。HTTP 状态必须是 400-599 范围内的数值,不允许有前导零。可以使用短横线指定状态范围。

使用示例:

upload_cleanup 400 404 499 500-505;

upload_buffer_size

语法: upload_buffer_size size
默认: 内存页面的大小(以字节为单位)
上下文: server,location

用于累积文件数据并将其写入磁盘的写缓冲区的大小(以字节为单位)。此指令旨在在内存使用与系统调用速率之间进行折衷。

upload_max_part_header_len

语法: upload_max_part_header_len size
默认: 512
上下文: server,location

指定部分头的最大长度(以字节为单位)。确定用于累积部分头的缓冲区的大小。

upload_max_file_size

语法: upload_max_file_size size
默认: 0
上下文: main,server,location

指定文件的最大大小。超过此指令值的文件将被忽略。此指令指定“软”限制,意味着在遇到超过指定限制的文件后,nginx 将继续处理请求体,尝试接收剩余文件。对于“硬”限制,必须使用 client_max_body_size 指令。此指令的零值表示不应对文件大小施加任何限制。

upload_limit_rate

语法: upload_limit_rate rate
默认: 0
上下文: main,server,location

指定每秒的上传速率限制(以字节为单位)。零表示速率无限制。

upload_max_output_body_len

语法: upload_max_output_body_len size
默认: 100k
上下文: main,server,location

指定输出体的最大长度。这防止在内存中堆积非文件表单字段。每当输出体超过指定限制时,将生成错误 413(请求实体过大)。此指令的零值表示不应对输出体长度施加任何限制。

upload_tame_arrays

语法: upload_tame_arrays on | off
默认: off
上下文: main,server,location

指定是否必须删除文件字段名称中的方括号(PHP 数组所需)。

upload_pass_args

语法: upload_pass_args on | off
默认: off
上下文: main,server,location

启用将查询参数转发到由 upload_pass 指定的位置。在命名位置中无效。示例:

<form action="/upload/?id=5">
<!-- ... -->
location /upload/ {
    upload_pass /internal_upload/;
    upload_pass_args on;
}

## ...

location /internal_upload/ {
    # ...
    proxy_pass http://backend;
}

在此示例中,后端获取请求 URI "/upload?id=5"。如果 upload_pass_args off,后端将获取 "/upload"。

示例配置

server {
    client_max_body_size 100m;
    listen 80;

    # 上传表单应提交到此位置
    location /upload/ {
        # 将修改后的请求体传递到此位置
        upload_pass @test;

        # 将文件存储到此目录
        # 该目录是哈希的,子目录 0 1 2 3 4 5 6 7 8 9 应该存在
        upload_store /tmp 1;

        # 允许仅用户读取上传的文件
        upload_store_access user:r;

        # 在请求体中设置指定字段
        upload_set_form_field $upload_field_name.name "$upload_file_name";
        upload_set_form_field $upload_field_name.content_type "$upload_content_type";
        upload_set_form_field $upload_field_name.path "$upload_tmp_path";

        # 通知后端文件的哈希和大小
        upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
        upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";

        upload_pass_form_field "^submit$|^description$";

        upload_cleanup 400 404 499 500-505;
    }

    # 将修改后的请求体传递到后端
    location @test {
        proxy_pass http://localhost:8080;
    }
}
<form name="upload" method="POST" enctype="multipart/form-data" action="/upload/">
<input type="file" name="file1">
<input type="file" name="file2">
<input type="hidden" name="test" value="value">
<input type="submit" name="submit" value="Upload">
</form>

GitHub

您可以在 GitHub nginx-module-upload 的存储库中找到有关此模块的其他配置提示和文档。