跳转至

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.4.0,发布于 2026 年 2 月 3 日。


codecov

一个用于 nginx 的模块,用于处理使用 multipart/form-data 编码(RFC 1867)的文件上传,以及按照此协议进行的可恢复上传。

描述

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

指令

upload_pass

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

指定将请求体传递到的 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

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

  • $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

指定为传递给后端的请求体中每个上传文件生成的一个或多个包含聚合属性的表单字段。name 和 value 都可以包含标准 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_sha256:文件的 SHA256 校验和
  • $upload_file_sha256_uc:文件的大写字母形式的 SHA256 校验和
  • $upload_file_sha512:文件的 SHA512 校验和
  • $upload_file_sha512_uc:文件的大写字母形式的 SHA512 校验和
  • $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

指定一个正则表达式模式,用于匹配将从原始请求体传递到后端的字段名称。该指令可以在每个 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(Request entity too large)。该指令的值为零表示不应对输出体长度施加任何限制。

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 指定的 location。对命名 location 无效。示例:

<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;

    # Upload form should be submitted to this location
    location /upload/ {
        # Pass altered request body to this location
        upload_pass @test;

        # Store files to this directory
        # The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist
        upload_store /tmp 1;

        # Allow uploaded files to be read only by user
        upload_store_access user:r;

        # Set specified fields in request body
        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";

        # Inform backend about hash and size of a file
        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;
    }

    # Pass altered request body to a backend
    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>