分块上传

技术支持发表于:2016年03月29日 16:38:06更新于:2017年03月29日 16:25:13

在上传大文件的时候,面对有可能因为网络质量等其他原因而造成的上传失败,使用分块上传和断点续传机制就显得非常有必要。

API 基本域名

m0.api.upyun.com

名称概念

  • 文件分块:直接切分二进制文件成小块。具体文件的每个分块的大小以及分块数目,可以根据自己情况调整(eg. 10MB 的文件,可以定每个分块 1MB,则分块数目即为 10 块)

  • 请求参数(Request Params): 即是指常规的请求中所带参数

  • 参数组(Meta Params): 包含文件上传存储及校验相关的必要信息,也是每次请求时候计算 policy 和 signature 所需的参数组。

  • signature: 校验签名

  • policy: 存储/校验信息

signature 和 policy 算法

signature

1. 将所需的参数组键值对按照键的字典顺序排列,并连接成为字符串

2. 将第 1 步中所得字符串与您的表单 API(可登录 UPYUN 官网获取)字符串拼接

注:在分块上传数据和合并文件请求中,需要将此处所用表单 API替换为上次请求返回的 token_secret,再进行 signature 计算

3. 将第 2 步中所得的字符串计算 md5,所得即为 signature

policy

  1. 将请求所需的参数组键值对转换为 JSON 字符串

  2. 将第 1 步中所得字符串进行 base64 编码,所得即为 policy

eg. 假设一个请求所需的的策略参数如下表:

path/demo.png
expiration1409200758
file_blocks1
file_hashb1143cbc07c8e768d517fa5e73cb79ca
file_size653252

另设,该空间表单 API 为:cAnyet74l9hdUag34h2dZu8z7gU=

则, 计算 signature 相应步骤所的结果如下:

第一步,将参数组键值对排序后所得:

expiration1409200758file_blocks1file_hashb1143cbc07c8e768d517fa5e73cb79cafile_size653252path/demo.png

第二步,第一步结果加上表单 API 后:

expiration1409200758file_blocks1file_hashb1143cbc07c8e768d517fa5e73cb79cafile_size653252path/demo.pngcAnyet74l9hdUag34h2dZu8z7gU=

注:在分块上传数据和合并文件请求中,需要将此处所用表单 API替换为上次请求返回的 token_secret,再进行 signature 计算

第三步,将第二步所得字符计算 md5 后:

a178e6e3ff4656e437811616ca842c48

计算 policy 相应步骤所得结果如下:

第一步,将参数组转换为 JSON 字符串后:

{"path":"/demo.png","expiration":1409200758,"file_blocks":1,"file_size":653252,"file_hash":"b1143cbc07c8e768d517fa5e73cb79ca"}

第二步,将第一步所得字符串 base64 编码后:

eyJwYXRoIjoiL2RlbW8ucG5nIiwiZXhwaXJhdGlvbiI6MTQwOTIwMDc1OCwiZmlsZV9ibG9ja3MiOjEsImZpbGVfc2l6ZSI6NjUzMjUyLCJmaWxlX2hhc2giOiJiMTE0M2NiYzA3YzhlNzY4ZDUxN2ZhNWU3M2NiNzljYSJ9

上传步骤

表单分块上传的整个步骤分为:

  1. 初始化上传

  2. 分块上传数据

  3. 文件合并完成上传

初始化上传

POST /<bucket-name>/

请求类型

Content-Type: application/x-www-form-urlencoded

请求参数

参数参数类型必选参数说明
policystringtrue文件存储/校验信息,见算法
signaturestringtrue校验签名,见算法

参数组

参数参数说明
path文件存储路径
expiration授权有效期,Unix UTC 时间戳
file_blocks本次所上传的文件的分块数目
file_hash所上传文件整个文件的 md5 hash 值
file_size所上传文件整个文件的大小(单位 Byte)

注:请选取适当的 file_blocks 以保证分块的大小 不超过 5M ,并且除最后一块外其余分块 不小于 100K 

其他可选参数如下:

参数可选性备注
allow-file-type文件类型限制,制定允许上传的文件扩展名
content-length-range文件大小限制,格式:min,max,单位:字节,如 102400,1024000,允许上传 100Kb~1Mb 的文件
content-md5所上传的文件的 MD5 校验值,UPYUN 根据此来校验文件上传是否正确
content-secret原图访问密钥 [表单 API 注 2]
content-typeUPYUN 默认根据扩展名判断,手动指定可提高精确性
image-width-range图片宽度限制,格式:min,max,单位:像素,如 0,1024,允许上传宽度为 0~1024px 之间
image-height-range图片高度限制,格式:min,max,单位:像素,如 0,1024,允许上传高度在 0~1024px 之间
notify-url异步通知 URL,见 [表单 API 通知规则]
return-url同步通知 URL,见 [表单 API 通知规则]
x-gmkerl-thumbnail缩略图版本名称,仅支持图片类空间,可搭配其他 x-gmkerl-* 参数使用 [表单 API 注 3]
x-gmkerl-type缩略类型 [表单 API 注 4]
x-gmkerl-value缩略类型对应的参数值 [表单 API 注 4]
x-gmkerl-quality默认 95缩略图压缩质量
x-gmkerl-unsharp默认锐化(true)是否进行锐化处理
x-gmkerl-rotate图片旋转(顺时针),可选:auto,90,180,270 之一
x-gmkerl-crop图片裁剪,格式:<w>x<h>a<x>a<y>。 其中 w, h 分别表示裁剪后的宽和高,x, y 表示左上角坐标。如 100x100a0a0。
x-gmkerl-exif-switch是否保留 EXIF 信息,仅在搭配 x-gmkerl-crop,x-gmkerl-type,x-gmkerl-thumbnail 时有效。
ext-param额外参数,UTF-8 编码,并小于 255 个字符 [表单 API 注 5]

返回结果

{
  save_token: '68640c7ab4120b4992907cabc6ea2c48',
  token_secret: "89a3d8d8a26a8adb32a3651a63c0d5cc",
  bucket_name: 'example',
  blocks: 5,
  status: [0,0,0,0,0],
  expired_at: 1401784219
}

返回参数说明

参数说明
save_token分块上传索引 key,下一步分块上传数据时必须携带本参数
token_secret用于之后请求计算 policy 和 signature 所用,代替表单 API 密钥
bucket_name文件保存空间
blocks文件分块数量
status分块文件上传状态,1表示已完成上传,0表示分块未完成上传。数组索引表示分块序号, 从 0 开始 
expired_at当前分块上传数据有效期,超过有效期之后数据将会被清理

分块上传数据

POST /<bucket-name>/

请求类型

Content-Type: multipart/form-data

请求参数

参数参数类型必选参数说明
policyStringtrue文件存储/校验信息,见算法
signatureStringtrue校验签名,见算法
fileBlobtrue上传的文件分块数据

参数组

参数参数说明
save_token即初始化上传请求返回结果中的 save_token
expirationUnix UTC 时间戳,授权有效期,超过这个时间之后授权将会失效
block_index该分块在完整文件中的分块索引
block_hash该分块文件的 md5 值

返回结果

上传成功返回:

{
  save_token: '68640c7ab4120b4992907cabc6ea2c48',
  token_secret: "89a3d8d8a26a8adb32a3651a63c0d5cc",
  bucket_name: 'example',
  blocks: 5,
  status: [1,1,1,1,0],
  expired_at: 1401784219
}

返回参数说明

参数说明
save_token分块上传索引 key,下一步分块上传数据时必须携带本参数
token_secret用于之后请求计算 policy 和 signature 所用,代替表单 API 密钥
bucket_name文件保存空间
blocks文件分块数量
status分块文件上传状态,1表示已完成上传,0表示分块未完成上传。数组索引表示分块序号, 从 0 开始 
expired_at当前分块上传数据有效期,超过有效期之后数据将会被清理

文件合并完成上传

POST /<bucket-name>/

请求类型

Content-Type: application/x-www-form-urlencoded

请求参数

参数参数类型必选参数说明
policystringtrue文件存储/校验信息,见算法
signaturestringtrue校验签名,见算法

参数组

参数参数说明
save_token即初始化上传请求返回结果中的 save_token
expirationUnix UTC 时间戳,授权有效期,超过这个时间之后授权将会失效

返回结果

表单 API 结合 return-url 和 notify-url 两个,有三种方式将上传结果返回: HTTP Body 同步返回;在没有传递 return-url 时,都会使用这种方式以 JSON 字符串的方式返回数据到客户端; 客户端同步跳转回调;传递 return-url 参数时,会通过 HTTP 302 的方式在客户端跳转到回调地址,通过 GET 参数传递; 服务器异步队列通知;传递了 notify-url 参数时,会通过 UPYUN 的服务端异步队列发送 POST 请求以标准的x-www-form-urlencoded*表单进行通知,如果回调通知失败,再重试 10 次(累计一天时间)之后将丢弃这条回调任务;

三种方式将返回/提交一样的数据,签名验证机制也完全一样,以 HTTP Body 返回的数据为例上传成功返回:

{
  bucket_name: 'example',
  path: '/demo.png',
  mimetype: 'image/png',
  file_size: 65422,
  image_width: 800,
  image_height: 600,
  image_frames: 1,
  image_type: 'PNG',
  last_modified: 1402021925,
  signature: 'c0ec4d6b0bb0515b4b889a12436118aa'
}

返回参数说明

参数说明
bucket_name空间名
path文件保存路径
mimetype保存文件的 content-type
file_size文件大小
image_width图片宽度,仅图片返回
image_height图片高度,仅图片返回
image_frames图片帧数,仅图片返回
image_type图片类型,仅图片返回
last_modified文件最后修改时间,既本次上传操作成功创建文件的时间
signature校验签名,用于校验返回数据的合法性 ,生成方式参见签名算法
ext-param初始化时指定的额外参数(如果没有指定则不返回这个字段)

同步回调方式会通过 HTTP 302 的方式进行跳转:

> Access-Control-Allow-Methods:PUT,POST
> Access-Control-Allow-Origin:*
> X-Powered-By:Crocodile/0.0.1
> ...
> Location: http://www.example.com/callback/return.php?path=%2Fdemo.png&content_type=image%2Fpng&file_size=65422&image_width=800&image_height=600&image_frames=1&last_modified=1402021925&signature=bc0b1ee186486c050146616a6ec74747

错误代码说明

请参考 API 错误码表