处理结果另存(saveas)
简介
我们提供名为saveas
的数据处理接口,将处理结果作为资源保存到指定空间内,并赋以指定 Key。保存成功后,下一次可直接通过指定 Key 来访问该资源,以达到提升下载速度的效果。
限制说明
-
源Bucket和目标Bucket必须在同一区域,即
处理结果不能跨区域另存
,例如华东Bucket内的文件经处理后结果无法另存到华北的Bucket。 -
支持
同步调用
和持久化(pfop)调用
,两者调用方式有轻微的差异。大多数使用场景下,建议使用 持久化处理 来实现处理结果存储,避免使用同步操作的 saveas 接口,提升访问速度。- 注意:当持久化处理(pfop)调用,不用
saveas
接口时,系统会默认生成输出结果文件,输出空间默认跟随源文件,结果文件命名根据源文件hash和处理命令生成一个唯一标识的文件名。
- 注意:当持久化处理(pfop)调用,不用
-
urlsafe_base64_encode() 函数按照标准的RFC 4648实现,开发者可以参考github.com/qiniu上各 SDK 的样例代码。
-
当持久化保存的 fop 耗时较长的时候,saveas 请求会返回 CDN 超时,但是只要保证发送的 saveas 请求合法,七牛服务器还是会对请求做正确处理。
-
此处签名内容不包含 Scheme 部分,与 DownloadToken 签名不一样。
-
c# http 库发送请求的时候会把 | 转成 %7c,由于签名签的是 | ,导致报 400 错误。可以在发送请求的时候,把 url 中的 | 改为 %7c,或者签名的时候签 %7c。
持久化调用
接口规格
saveas/<EncodedEntryURI>/deleteAfterDays/<deleteAfterDays>
参数名称 | 必填 | 类型 | 说明 |
---|---|---|---|
<EncodedEntryURI> |
是 | string | 以 EncodedEntryURI 格式组织的目标 Bucket 与 Key;其中bucket 必填,key 非必填。 |
<deleteAfterDays> |
否 | int | 最小单位为天,数值 >= 1。表示从保存数据开始算起多少天之后自动从 bucket 删除文件。不设置表示资源不会被自动删除 |
savePattern |
否 | 自定义输出文件资源名,变量值都是 基于输入文件获取 ,需要经过 urlsafe_base64_encode 。支持文件名变量,包括: bucket、key、etag、fname、fsize、mimeType、endUser、ext、fprefix、keybase 。注意: 1. 和 saveKey 互斥,不能共用;2. 和 <EncodedEntryURI> 指定 key 时一起存在时,优先使用 savePattern 。 |
|
saveKey |
否 | 自定义输出文件资源名,变量值都是 基于输出文件获取 ,需要经过 urlsafe_base64_encode 。可使用文件名变量,包括: etag, year, mon, day, hour, min, sec 。注意: 1. 和 savePattern 互斥,不能共用;2. 仅当 <EncodedEntryURI> 没有指定 key 时起作用,不能同时指定。 |
在 持久化处理(pfop)调用中设置,直接在命令后跟 |saveas/SafeBase64(bucket:key)/deleteAfterDays/< deleteAfterDays >
即可。
-
上传时自动触发,设置
persistentOps
字段:"persistentOps":"avthumb/mp3/ab/192k|saveas/dGVzdDoxLm1wMw==/deleteAfterDays/3"
-
已有资源主动触发,设置
fops
字段:"fops":"avthumb/mp3/ab/192k|saveas/dGVzdDoxLm1wMw==/deleteAfterDays/3"
表示处理后的数据名称为指定的 key 并且上传到指定的 bucket,在 3 天之后会从 bucket 自动删除。
同步调用
同步调用需要签名。
接口规格
saveas/<EncodedEntryURI>/sign/<Sign>/deleteAfterDays/<deleteAfterDays>
参数名称 | 必填 | 类型 | 说明 |
---|---|---|---|
<EncodedEntryURI> |
是 | string | 以 EncodedEntryURI 格式组织的目标 Bucket 与 Key |
<Sign> |
是 | string | 请求签名部分,算法见下方,在 pfop 操作中不用指定该参数 |
<deleteAfterDays> |
否 | int | 多少天之后自动从 bucket 删除文件,从保存数据开始算起 |
savePattern |
否 | 自定义输出文件资源名,变量值都是 基于输入文件获取 ,需要经过 urlsafe_base64_encode 。支持文件名变量,包括: bucket、key、etag、fsize、mimeType、keybase 。注意: 1. 和 saveKey 互斥,不能共用;2. 和 <EncodedEntryURI> 指定 key 时一起存在时,优先使用 savePattern 。 |
|
saveKey |
否 | 自定义输出文件资源名,变量值都是 基于输出文件获取 ,需要经过 urlsafe_base64_encode 。可使用文件名变量,包括: etag, year, mon, day, hour, min, sec 。注意: 1. 和 savePattern 互斥,不能共用;2. 仅当 <EncodedEntryURI> 没有指定 key 时起作用,不能同时指定。 |
签名算法
1.在下载 URL(不含 Scheme 部分,即去除 http : //)后附加 saveas 接口(不含签名部分):
NewURL = URL + "|saveas/<EncodedEntryURI>"
2.使用 SecretKey 对新的下载 URL 进行HMAC1-SHA1签名:
Sign = hmac_sha1(SecretKey, NewURL)
3.对签名进行URL安全的Base64编码:
EncodedSign = urlsafe_base64_encode(Sign)
4.在新的下载 URL 后拼接签名参数:
FinalURL = NewURL + "/sign/<AccessKey>:<EncodedSign>"
同步调用 saveas 算法示例,生成 saveas 请求的完整 Go 代码如下:
func makeSaveasUrl(URL, accessKey string, secretKey []byte, saveBucket, saveKey string) string {
encodedEntryURI := base64.URLEncoding.EncodeToString([]byte(saveBucket+":"+saveKey))
URL += "|saveas/" + encodedEntryURI
h := hmac.New(sha1.New, secretKey)
// 签名内容不包括Scheme,仅含如下部分:
// <Domain>/<Path>?<Query>
u, _ := url.Parse(URL)
io.WriteString(h, u.Host + u.RequestURI())
d := h.Sum(nil)
sign := accessKey + ":" + base64.URLEncoding.EncodeToString(d)
return URL + "/sign/" + sign
}
文件名变量
文件名变量是一组预先定义的变量,可以使用 $(变量名)
或${变量名}
形式求值。
1. savePattern 参数,可用变量如下:
变量名 | 变量说明 | 适用范围 |
---|---|---|
bucket | 获得上传的目标空间名。 | 持久化调用 同步调用 |
key | 获得文件保存在空间中的资源名。 | 持久化调用 同步调用 |
etag | 文件上传成功后的 HTTPETag。若上传时未指定资源ID,Etag将作为资源ID使用。 | 持久化调用 同步调用 |
fsize | 资源尺寸,单位为字节。 | 持久化调用 同步调用 |
mimeType | 资源类型,例如JPG图片的资源类型为image/jpg 。 |
持久化调用 同步调用 |
keybase | 获得空间资源名忽略后缀,即$(key) 忽略 $(ext) 。 | 持久化调用 同步调用 |
fname | 上传的原始文件名。 | 持久化调用 ●只适用于上传时自动触发数据处理,persistentOps |
fprefix | 获得上传原始文件名忽略后缀,即$(fname) 忽略 $(ext) 。 | 持久化调用 ●只适用于上传时自动触发数据处理,persistentOps |
ext | 上传资源的后缀名,通过 $(fname) 的后缀或者自动检测的 mimeType 来获取。优先使用 $(fname) 的后缀 | 持久化调用 ●只适用于上传时自动触发数据处理,persistentOps |
endUser | 上传时指定的endUser 字段,通常用于区分不同终端用户的请求。 |
持久化调用 ●只适用于上传时自动触发数据处理,persistentOps |
2. saveKey 参数,可用变量如下:
变量名 | 变量说明 | 适用范围 |
---|---|---|
etag | 输出文件上传成功后的 HTTPETag。若上传时未指定资源ID,Etag将作为资源ID使用。 | 持久化调用 同步调用 |
year | 输出文件上传时的年份。 | 持久化调用 同步调用 |
mon | 输出文件上传时的月份。 | 持久化调用 同步调用 |
day | 输出文件上传时的日期。 | 持久化调用 同步调用 |
hour | 输出文件上传时的小时。 | 持久化调用 同步调用 |
min | 输出文件上传时的分钟。 | 持久化调用 同步调用 |
sec | 输出文件上传时的秒钟。 | 持久化调用 同步调用 |
求值示例
输入文件上传原始文件名=demo.mp4
输入文件空间资源名= file.mp4
输出文件上传日期=2024.06.05 12:30:50
输出文件etag=FukjnhlamMYsy-SvkpxsDzQBP0_9
savePattern 填写如下文件名变量,输出结果文件会是:
- savePattern=trancode${fname} ,结果文件=trancodedemo.mp4
- savePattern=${keybase}.m3u8,结果文件=file.m3u8
saveKey 填写如下文件名变量,输出结果文件会是:
- saveKey=file${year}${.mon}${day}${hour}${min}.m3u8, 结果文件为=file202406051230.m3u8
- saveKey=${etag}.m3u8, 结果文件为=FukjnhlamMYsy-SvkpxsDzQBP0_9.m3u8
EncodedEntryURI 格式
本格式用于在 URI中指定目标资源空间与目标资源名,格式如下:
entry = '<Bucket>:<Key>'
encodedEntryURI = urlsafe_base64_encode(entry)
假设 entry 为 qiniuphotos:gogopher.jpg
,则对应的 encodedEntryURI 为 cWluaXVwaG90b3M6Z29nb3BoZXIuanBn=
。
URL安全的Base64编码
URL安全的Base64编码适用于以URL方式传递Base64编码结果的场景。该编码方式的基本过程是先将内容以Base64格式编码为字符串,然后检查该结果字符串,将字符串中的加号+
换成中划线-
,并且将斜杠/
换成下划线_
。
示例
1.原资源是一个名为 resource/Ship.jpg 的图片:
http://78re52.com1.z0.glb.clouddn.com/resource/Ship.jpg
2.将图片做缩略处理:
http://78re52.com1.z0.glb.clouddn.com/resource/Ship.jpg?imageView2/2/w/200/h/200
3.对上述云处理结果进行持久化保存:
# 另存操作的目标空间与资源名
entryURI = "qiniu-developer:Ship-thumb-200.jpg"
#编码结果
encodedEntryURI = "cWluaXUtZGV2ZWxvcGVyOlNoaXAtdGh1bWItMjAwLmpwZw=="
#需要签名的部分
signingStr = "78re52.com1.z0.glb.clouddn.com/resource/Ship.jpg?imageView2/2/w/200/h/200|saveas/cWluaXUtZGV2ZWxvcGVyOlNoaXAtdGh1bWItMjAwLmpwZw=="
#签名结果
sign = "bcgojLbLKTsTlhm3XFMYq0cn3lW2G3NAuJYXZDDf:jGo09Pmq5vyG4c-rRb4qF3_dH1g="
4.最终得到的完整下载 URL:
http://78re52.com1.z0.glb.clouddn.com/resource/Ship.jpg?imageView2/2/w/200/h/200|saveas/cWluaXUtZGV2ZWxvcGVyOlNoaXAtdGh1bWItMjAwLmpwZw==/sign/bcgojLbLKTsTlhm3XFMYq0cn3lW2G3NAuJYXZDDf:jGo09Pmq5vyG4c-rRb4qF3_dH1g=
5.保存转码后资源可通过如下 URL 访问:
http://78re52.com1.z0.glb.clouddn.com/Ship-thumb-200.jpg