博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nginx-upload-module模块实现文件断点续传
阅读量:6146 次
发布时间:2019-06-21

本文共 4240 字,大约阅读时间需要 14 分钟。

导读 每当我们想简单的实现文件上传功能,而又不使用其他的语言(比如PHP、Java),或者想实现文件的断点续传。这个时候Nginx的一个模块nginx-upload-module就能满足我们的需求。
模块安装

下载模块:

cd /tmpwget https://codeload.github.com/vkholodkov/nginx-upload-module/zip/2.2unzip 2.2

安装模块:

.configure --add-module=/tmp/nginx-upload-module-2.2/
multipart/form-data表单上传示例

nginx.conf配置:

server {  [...]         location /upload {                upload_pass @uploadHandler;                upload_store /usr/local/nginx/upload_temp 1;                upload_set_form_field $upload_field_name.path "$upload_tmp_path";        }              location @uploadHandler {                proxy_pass http://backend-host;        }    [...]    }

这里在server里定义了upload location,这个location是上传的接口,还有@uploadHandler location,是当文件上传完成后,nginx模块会对这个location发送一些必要的信息,如文件上传的路径,这里涉及了几个指令:

upload_pass @uploadHandler:上传完成后会发送必要的数据到@uploadHandler;

upload_store /usr/local/nginx/upload_temp 1: 文件上传的临时目录;
upload_set_form_field $upload_field_name.path “$upload_tmp_path”: 设置文件上传完成后,把文件临时路径发送给upload_pass指定的location。

断点续传示例

nginx.conf配置

server {[...]        location /resumable_upload {               upload_resumable on;               upload_state_store /usr/local/nginx/upload_temp ;               upload_pass @drivers_upload_handler;               upload_store /usr/local/nginx/upload_temp;               upload_set_form_field $upload_field_name.path "$upload_tmp_path";            }              location @resumable_upload_handler {               proxy_pass http://localhost:8002;        }    [...]    }

与上一步multipart/form-data表单上传示例配置不同的地方有:

upload_resumable on: 开启断点续传功能;
upload_state_store /usr/local/nginx/upload_temp: 设置断点续传状态文件存储的目录。

上传文件第一个片段
POST /upload HTTP/1.1Host: example.comContent-Length: 51201Content-Type: application/octet-streamContent-Disposition: attachment; filename="big.TXT"X-Content-Range: bytes 0-51200/511920Session-ID: 1111215056    <0-51200的字节文件数据>
上传文件第一个片段服务器响应
HTTP/1.1 201 CreatedDate: Thu, 02 Sep 2010 12:54:40 GMTContent-Length: 14Connection: closeRange: 0-51200/511920     0-51200/511920
上传文件最后一个片段
POST /upload HTTP/1.1Host: example.comContent-Length: 51111Content-Type: application/octet-streamContent-Disposition: attachment; filename="big.TXT"X-Content-Range: bytes 460809-511919/511920Session-ID: 1111215056<460809-511919字节文件数据>
上传文件最后一个片段服务器响应
HTTP/1.1 200 OKDate: Thu, 02 Sep 2010 12:54:43 GMTContent-Type: text/htmlConnection: closeContent-Length: 2270     < 响应的内容>
请求头说明
请求头 	                      说明Content-Disposition  attachment, filename=“上传的文件名”Content-Type 	     待上传文件的mime type,如application/octet-stream(注:不能为multipart/form-data)X-Content-Range      待上传文件字节范围,如第一片段bytes 0-51200/511920,最后一个片段bytes 460809-511919/511920(注:文件第一个字节标号为0,最后一个字节标号为n-1,其中n为文件字节大小)X-Session-ID 	     上传文件的标识,由客户端随机指定.因为是断点续传,客户端必须确保同一个文件的所有片段上传标识一致Content-Length 	     上传片段的大小
Python上传demo
#!/usr/bin/python# -*- coding: utf-8 -*-      import os.pathimport requestsimport hashlib     # 待上传文件路径FILE_UPLOAD = "/tmp/testfile"# 上传接口地址UPLOAD_URL = "http://host/drivers_upload"# 单个片段上传的字节数SEGMENT_SIZE = 1048576    def upload(fp, file_pos, size, file_size):        session_id = get_session_id()        fp.seek(file_pos)        payload = fp.read(size)        content_range = "bytes {file_pos}-{pos_end}/{file_size}".format(file_pos=file_pos,                        pos_end=file_pos+size-1,file_size=file_size)        headers = {'Content-Disposition': 'attachment; filename="big.TXT"','Content-Type': 'application/octet-stream',                    'X-Content-Range':content_range,'Session-ID': session_id,'Content-Length': size}        res = requests.post(UPLOAD_URL, data=payload, headers=headers)        print(res.text)          # 根据文件名hash获得session iddef get_session_id():  m = hashlib.md5()  file_name = os.path.basename(FILE_UPLOAD)  m.update(file_name)  return m.hexdigest()     def main():  file_pos = 0  file_size = os.path.getsize(FILE_UPLOAD)  fp = open(FILE_UPLOAD,"r")       while True:   if file_pos + SEGMENT_SIZE >= file_size:       upload(fp, file_pos, file_size - file_pos, file_size)       fp.close()       break   else:     upload(fp, file_pos, SEGMENT_SIZE, file_size)     file_pos = file_pos + SEGMENT_SIZE     if __name__ == "__main__":        main()

免费提供最新Linux技术教程书籍,为开源技术爱好者努力做得更多更好:https://www.linuxprobe.com/

转载地址:http://pamya.baihongyu.com/

你可能感兴趣的文章
java父子进程通信
查看>>
Android ADB server didn't ACK * failed to start daemon * 简单有效的解决方案
查看>>
Olap学习笔记
查看>>
Codeforces Round #431 (Div. 1)
查看>>
如何进行数组去重
查看>>
将标题空格替换为 '_' , 并自动复制到剪切板上
查看>>
List Collections sort
查看>>
Mysql -- You can't specify target table 'address' for update in FROM clause
查看>>
使用局部标准差实现图像的局部对比度增强算法。
查看>>
2017-2018-1 20165313 《信息安全系统设计基础》第八周学习总结
查看>>
《代码敲不队》第四次作业:项目需求调研与分析
查看>>
菜鸡互啄队—— 团队合作
查看>>
HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法...
查看>>
SparseArray
查看>>
第二章
查看>>
android背景选择器selector用法汇总
查看>>
[转]Paul Adams:为社交设计
查看>>
showdialog弹出窗口刷新问题
查看>>
java
查看>>
Vue.js连接后台数据jsp页面  ̄▽ ̄
查看>>