Yefei.Blog

个人日记 WIKI

用户工具


NGINX Upload Module

注意事项

太高版本的 nginx 可能不支持, 最少我测试 1.11 的版本就不行,降版本到 1.2.9, 同时需要 openssl 支持, ubuntu 安装 libssl-dev,他这个模块长时间不维护了,可能有BUG。 需要加入 ssl 模块才能编译成功。

./configure –prefix=/opt/nginx –with-http_ssl_module –add-module=./nginx-upload-module-2.2

配置文件样例

location = /upload {
    upload_pass /upload_success?$query_string;
    upload_store /tmp/nginx_upload_temp;
    upload_state_store /tmp/nginx_upload_state;
    upload_resumable on;
    upload_set_form_field "filename" $upload_file_name;
    upload_set_form_field "content-type" $upload_content_type;
    upload_set_form_field "tmp-path" $upload_tmp_path;
    upload_aggregate_form_field "md5" $upload_file_md5;
    upload_aggregate_form_field "size" $upload_file_size;
    upload_cleanup 200 400 404 499 500-505;
    upload_pass_form_field "^access_id$|^path$";
}

表单上传

<form action="/upload" method="POST" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="hidden" name="access_id" value="aaaaaa">
    <button type="submit">Upload</button>
</form>

在上传成功后就会调用 upload_pass 配置的 URL。 并把 upload_set_form_field 所设置的参数一并带进去

分片断点上传

下面几个参数必须指定,文件内容直接使用 Request Body

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="upload_test.gif"
Content-Range: bytes {start}-{end}/{total}
Session-ID: 当前文件的唯一ID或内容hash,用于确保分片上传的同一个文件

Content-Range 中 start=文件的开始字节(0为起始), end=为结束字节(start+当前大小-1), total=文件总大小

上传代码示例

import os
import requests
import hashlib
 
SESSION_ID = hashlib.md5(os.urandom(32)).hexdigest()
 
with open("test.gif", 'rb') as fp:
    # 移动指针到结尾获取文件总大小
    fp.seek(0, os.SEEK_END)
    total = fp.tell()
    print 'file size:', total
    # 恢复指针到开始位置
    fp.seek(0)
 
    headres = {
        'Content-Type': 'image/gif',
        'Content-Disposition': 'attachment; filename="test.gif"',
        'Session-ID': SESSION_ID,
    }
 
    while True:
        start = fp.tell()
        data = fp.read(1024*1024)
        headres['Content-Range'] = 'bytes %d-%d/%d' % (start, fp.tell() - 1, total)
        r = requests.post('/upload', data=data, headers=headres)
        print r.content
        if fp.tell() == total:
            break

问题

使用分片上传没有 hash 值?
这个问题已经查看过源码,确实是故意去除分片上传HASH计算。


皖ICP备15000265号

皖公网安备 34110302000106号