purple OSS分析与实现分析

概述

对象存储服务(Object Storage Service,简称OSS),OSS提供统一存储的解决方案

方便、快捷的使用方式

提供标准的RESTful API接口、丰富的SDK包、客户端工具、控制台。您可以像使用文件一样方便地上传、下载、检索、管理用于Web网站或者移动应用的海量数据。
不限文件数量和大小。您可以根据所需存储量无限扩展存储空间,解决了传统硬件存储扩容问题。
支持流式写入和读出。特别适合视频等大文件的边写边读业务场景。
支持数据生命周期管理。您可以自定义将到期数据批量删除或者转入到低成本的归档服务。
强大、灵活的安全机制

灵活的鉴权,授权机制。

提供URL鉴权和授权机制,以及白名单、防盗链、主子账号功能。
提供用户级别资源隔离机制和多集群同步机制(可选)。

扩展服务

图片处理:支持jpg、png、bmp、gif、webp、tiff等多种图片格式的转换,以及缩略图、剪裁、水印、缩放等多种操作。
音视频转码:提供高质量、高速并行的音视频转码能力,让您的音视频文件轻松应对各种终端设备。
内容加速分发:OSS作为源站,搭配CDN进行加速分发,具有稳定、无回源带宽限制、性价比高、一键配置的特点。

典型应用场景

1.云端数据处理
上传文件到OSS后,可以使用应用插件实现图片处理实现云端数据处理。

场景

2.qisp申报服务
企业上传excel到oss服务器,通过excel转json实现预览,读取,简化excel操作

3.mle移动查验平台
平板通拍照上传实现,实现多系统图片共享

4.nqp口岸云服务平台
手机端拍照上传,微信端图片上传备份

对象列表

Bucket 存储空间
Object 对象
ObjectPlugin 扩展插件
Acl访问控制

目录


api概览

Bucket操作

列出Bucket
Get/get
创建Bucket
Post/{bucketName}
获取Bucket
Get/{buckName}
删除Bucket
Delete/{buckName}

Object的操作

上传Object
Put/{buckName}/{文件名}
获取Object
Get/{bucketName}/{文件名}
eg: http://dev.xxx.com/oss/nqp/images|tr@jpg

ObjectPlugin扩展插件

  1. 图片缩放处理+背景填充
    /{bucketName}{文件名}?size=100w_100h_4e_100-0-0bgc
  1. 图片水印处理
    /{bucketName}{文件名}?watermark=1&text=base64(水印文字)
  2. excel转json输出
    /{bucketName}{文件名}?export=json&exportId={导出配置id}
  3. 输出pdf
    /{bucketName}{文件名}?export=pdf
  4. 在线预览[pdf,xls,xlsx,word]
    /{bucketName}{文件名}?preview=pdf

bucket

POST Bucket

创建Bucket

请求语法

POST / HTTP/1.1
url: Post /{bucketName}
body:{扩展属性}

请求元素(Request Elements)

名称 描述
bucketName 存储空间名称

细节分析

  1. bucketName名称规范
    1.1 只能包含小写字母,数字和短横线
    1.2 必须以小写字母和数字开头和结尾
    1.3 bucketName的长度限制在3-63之间
    1.4 不能使用保留关键字 admin,local,config,master

实现分析

  1. MongolDB实现
    1.1.新建bucket将创建一个数据库
    1.2.bucket中信息存储于master库中
  2. SqlServer实现
    2.1 多个空间实现在同一个数据库
    2.2 bucket存储在一张表中

示例

请求示例:

POST / HTTP/1.1
url: Post/{bucketName}
body:{扩展属性}

返回示例:

200

列出Bucket

Get /get

获取Bucket

Get /{buckName}

删除Bucket

Delete/{buckName}


PUT Object

上传对象

请求语法

PUT / HTTP/1.1
url:/{bucketName}/object

请求Header(Request Elements)

名称 描述
bucketName 存储空间名称
Cache-Control 指定该Object被下载时的网页的缓存行为;更详细描述请参照RFC2616。 类型:字符串 默认值:无
Content-Disposition 指定该Object被下载时的名称;更详细描述请参照RFC2616。 类型:字符串 默认值:无
Content-Encoding 指定该Object被下载时的内容编码格式;更详细描述请参照RFC2616。 类型:字符串 默认值:无
Content-MD5 根据协议RFC 1864对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码为一个消息的Content-MD5值。该请求头可用于消息合法性的检查(消息内容是否与发送时一致)。虽然该请求头是可选项,OSS建议用户使用该请求头进行端到端检查。 类型:字符串 默认值:无 限制:无
Expires 过期时间;更详细描述请参照RFC2616。 类型:字符串 默认值:无 注意:OSS不会对这个值进行限制和验证
x-oss-object-acl 指定oss创建object时的访问权限。 类型:字符串 合法值:public-read,private,public-read-write

细节分析

  1. 如果用户上传了Content-MD5请求头,OSS会计算body的Content-MD5并检查一致性,如果不一致,将返回InvalidDigest错误码。
  2. 如果请求头中的“Content-Length”值小于实际请求体(body)中传输的数据长度,OSS仍将成功创建文件;但Object大小只等于“Content-Length”中定义的大小,其他数据将被丢弃。
  3. 如果试图添加的Object的同名文件已经存在,并且有访问权限。新添加的文件将覆盖原来的文件,成功返回200 OK。
  4. 如果在PutObject的时候,携带以x-oss-meta-为前缀的参数,则视为user meta,比如x-oss-meta-location。一个Object可以有多个类似的参数,但所有的user meta总大小不能超过8k。
  5. 如果Head中没有加入Content length参数,会返回411 Length Required错误。错误码:MissingContentLength。
  6. 如果设定了长度,但是没有发送消息Body,或者发送的body大小小于给定大小,服务器会一直等待,直到time out,返回400 Bad Request消息。错误码:RequestTimeout。
  7. 如果试图添加的Object所在的Bucket不存在,返回404 Not Found错误。错误码:NoSuchBucket。
  8. 如果试图添加的Object所在的Bucket没有访问权限,返回403 Forbidden错误。错误码:AccessDenied。
  9. 如果添加文件长度超过5G,返回错误消息400 Bad Request。错误码:InvalidArgument。
  10. 如果传入的Object key长度大于1023字节,返回400 Bad Request。错误码:InvalidObjectName。
  11. PUT一个Object的时候,OSS支持5个 HTTP RFC2616协议规定的Header 字段:Cache-Control、Expires、Content-Encoding、Content-Disposition、Content-Type。如果上传Object时设置了这些Header,则这个Object被下载时,相应的Header值会被自动设置成上传时的值。
  12. 如果上传Object时指定了x-oss-server-side-encryption Header,则必须设置其值为AES256,否则会返回400和相应错误提示:InvalidEncryptionAlgorithmError。指定该Header后,在响应头中也会返回该Header,OSS会对上传的Object进行加密编码存储,当这个Object被下载时,响应头中会包含x-oss-server-side-encryption,值被设置成该Object的加密算法。

实现分析

1.MongoDB实现
1.1

常见问题

Content-MD5计算方式错误

示例

请求示例:

POST /oss.jpg HTTP/1.1 Host: eas.nbeport.com Cache-control: no-cache Expires: Fri, 28 Feb 2012 05:38:42 GMT Content-Encoding: utf-8 Content-Disposition: attachment; ObjectName=oss_download.jpg Date: Fri, 24 Feb 2012 06:03:28 GMT Content-Type: image/jpg Content-Length: 344606 Authorization: sos-token [344606 bytes of object data]

返回示例:

HTTP/1.1 200 OK Server: dev .xxx.com/oss Date: Sat, 21 Nov 2015 18:52:34 GMT Content-Length: 0 Connection: keep-alive x-oss-request-id: 5650BD72207FB30443962F9A x-oss-bucket-version: 1418321259 ETag: "A797938C31D59EDD08D86188F6D5B872" { id:A797938C31D59EDD08D861, fileName:'/images/oss_download.jpg', backName:'nqp', }

Get Object

获取对象

请求语法

get / HTTP/1.1

  1. 通过文件名获取 get /{bucketName}/{objectName}
    url:http://dev.xxx.com/oss/{backetName}/{objectName}
  2. 通过id获取
    url:http://dev.xxx.com/oss/object/{id}

请求参数(Request Elements)

名称 描述
bucketName 存储空间名称
id 由oss系统生居guid
objectName 对象/文件名,规则 {bucket}/{filename} images\\tr@jpg 目录使用表示.用@表示 http://dev.xxx.com/oss/nqp/images\\tr@jpg

细节分析

示例

请求示例:

PUT /oss.jpg HTTP/1.1 Host: oss-example.oss-cn-hangzhou.aliyuncs.com Cache-control: no-cache Expires: Fri, 28 Feb 2012 05:38:42 GMT Content-Encoding: utf-8 Content-Disposition: attachment;filename=oss_download.jpg Date: Fri, 24 Feb 2012 06:03:28 GMT Content-Type: image/jpg Content-Length: 344606 Authorization: sos-token [344606 bytes of object data]

返回示例:

HTTP/1.1 200 OK Server: AliyunOSS Date: Sat, 21 Nov 2015 18:52:34 GMT Content-Length: 0 Connection: keep-alive x-oss-request-id: 5650BD72207FB30443962F9A x-oss-bucket-version: 1418321259 ETag: "A797938C31D59EDD08D86188F6D5B872" /{bucketName}

访问控制

在Header中包含签名

用户可以在HTTP请求中增加Authorization(授权)的Header来包含签名(Signature)信息,表明这个消息已被授权。

Authorization字段计算的方法

"Authorization: OSS "+AccessKeyId+":"+Signature
Signature=base64(hmac-sha1(AccessKeySecret,
VERB+ "\n”
+Content-MD5+ "\n”
+Content-Type+ "\n”
+Date))

+CanonicalizedOSSHeaders
+CanonicalizedResource)))

  1. AccessKeySecret表示签名所需的秘钥
  2. VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等“\n”表示换行符
  3. Content-MD5表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5
  4. Content-Type表示请求内容的类型,如”application/octet-stream”,也可以为空
  5. Date表示此次操作的时间,且必须为HTTP1.1中支持的GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT”

6.DATE时间和OSS服务器的时间差正负15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。
7.CanonicalizedOSSHeaders表示以“x-oss-”为前缀的http header的组合

构建CanonicalizedOSSHeaders的方法

所有以“x-oss-”为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下:
将所有以“x-oss-”为前缀的HTTP请求头的名字转换成小写字母。如’X-OSS-Meta-userName:hz24’转换成’x-oss-meta-username:hz24’。删除请求头和内容之间分隔符两端出现的任何空格。如’x-oss-meta-username:hz24’转换成:’x-oss-meta-name:hz24’。将每一个头和内容用”\n”分隔符分隔拼成最后的CanonicalizedOSSHeaders。

8.CanonicalizedResource 表示想要访问的OSS资源描述

计算签名头规则

1.签名的字符串必须为UTF-8格式。含有中文字符的签名字符串必须先进行UTF-8编码,再与AccessKeySecret计算最终签名。
2.签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为AccessKeySecret。
3.Content-Type和Content-MD5在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符“\n”代替。
4.在所有非HTTP标准定义的header中,只有以“x-oss-”开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。
5.以“x-oss-”开头的header在签名验证前需要符合以下规范:
header的名字需要变成小写。
header按字典序自小到大排序。
6.分割header name和value的冒号前后不能有空格。
每个Header之后都有一个换行符“\n”,如果没有Header,

构建CanonicalizedOSSHeaders的方法

用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下:
将CanonicalizedResource置成空字符串(“”);
放入要访问的OSS资源:“ /BucketName/ObjectName”(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”)
如果请求的资源包括子资源(sub-resource) ,那么将所有的子资源按照字典序,从小到大排列并以&为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加“?”和子资源字符串。此时的CanonicalizedResource例子如:/BucketName/ObjectName?acl &uploadId=UploadId如果用户请求在查询字符串(query string)中指定了要重写(override)返回请求的header ,那么将这些查询字符串及其请求值按照字典序,从小到大排列,以&为分隔符,按参数的字典序添加到CanonicalizedResource中。此时的CanonicalizedResource例子:/BucketName/ObjectName?acl&response-content-type=ContentType & uploadId =UploadId。OSS支持的override请求头参考Get Object
OSS目前支持的子资源(sub-resource)包括:acl,uploadId,partNumber,uploads,logging,website,location,lifecycle,referer,cors,delete,append,position,bucketInfo

在URL中包含签名

除了使用Authorization Head,用户还可以在URL中加入签名信息,这样用户就可以把该URL转给第三方实现授权访问。

实现方式

URL中包含签名示例:
http://dev.nbxxx.com/oss/nqp|images|tr#jpg? AccessKeyId=44CF9590006BF252F707&expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D
在URL中实现签名,必须至少包含Signature,Expires,AccessKeyId三个参数。

  1. Expires这个参数的值是一个UNIX时间(自UTC时间1970年1月1号开始的秒数,详见wiki),用于标识该URL的超时时间。如果OSS接收到这个URL请求的时候晚于签名中包含的Expires参数时,则返回请求超时的错误码。例如:当前时间是1141889060,开发者希望创建一个60秒后自动失效的URL,则可以设置Expires时间为1141889120。
  2. AccessKeyId即AccessKeyId。
    Signature表示签名信息。所有的OSS支持的请求和各种Header参数,在URL中进行签名的算法和在Header中包含签名的算法基本一样。

Signature = urlencode(base64(hmac-sha1(AccessKeySecret,
VERB+"\n"
+CONTENT-MD5+"\n"
+CONTENT-TYPE+"\n"
+EXPIRES+"\n"
+CanonicalizedOSSHeaders
+CanonicalizedResource)))

  1. 其中,与header中包含签名相比主要区别如下:
    3.1通过URL包含签名时,之前的Date参数换成Expires参数。
    3.2不支持同时在URL和Head中包含签名。
    3.3如果传入的Signature,Expires,OSSAccessKeyId出现不止一次,以第一次为准。
    3.4请求先验证请求时间是否晚于Expires时间,然后再验证签名。
    将签名字符串放到url时,注意要对url进行urlencode

4.CanonicalizedOSSHeaders表示以“x-oss-”为前缀的http header的组合
5.CanonicalizedResource 表示用户想要访问的OSS资源
6.CanonicalizedOSSHeaders就设置为空。

下一阶段任务

  1. OSS应用推广
  2. MongoDB存储优化
  3. 对象插件扩展
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • API定义规范 本规范设计基于如下使用场景: 请求频率不是非常高:如果产品的使用周期内请求频率非常高,建议使用双通...
    有涯逐无涯阅读 2,446评论 0 6
  • 一、概念(载录于:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436...
    yuantao123434阅读 8,295评论 6 152
  • 1 TED演讲和其他一些普通的演讲有所不同,它更有宣传性鼓动性和说服性,演讲的主题一般都是关于对大脑深层认知和意识...
    鲁莽书生阅读 214评论 0 0
  • 失落能噬空身体 仿佛花很长时间垒砌而成的堡垒 瞬间垮塌 然后还要忍着一丝病痛般 笑着说:无所谓,前途是光明的 碎裂...
    书生亦百用阅读 186评论 2 3