阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

nginx-upload-module模块实现文件断点续传

81次阅读
没有评论

共计 3298 个字符,预计需要花费 9 分钟才能阅读完成。

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

下载模块:

cd /tmp
wget https://codeload.github.com/vkholodkov/nginx-upload-module/zip/2.2
unzip 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 发送一些必要的信息,如文件上传的路径,这里涉及了几个指令:

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

断点续传示例

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;}
    [...]
    }

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

上传文件第一个片段
POST /upload HTTP/1.1
Host: example.com
Content-Length: 51201
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="big.TXT"
X-Content-Range: bytes 0-51200/511920
Session-ID: 1111215056
    
<0-51200 的字节文件数据 >
上传文件第一个片段服务器响应
HTTP/1.1 201 Created
Date: Thu, 02 Sep 2010 12:54:40 GMT
Content-Length: 14
Connection: close
Range: 0-51200/511920
     
0-51200/511920
上传文件最后一个片段
POST /upload HTTP/1.1
Host: example.com
Content-Length: 51111
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="big.TXT"
X-Content-Range: bytes 460809-511919/511920
Session-ID: 1111215056

<460809-511919 字节文件数据 >
上传文件最后一个片段服务器响应
HTTP/1.1 200 OK
Date: Thu, 02 Sep 2010 12:54:43 GMT
Content-Type: text/html
Connection: close
Content-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.path
import requests
import 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 id
def 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()

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计3298字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中