purple OSS分析与实现分析

概述

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

方便、快捷的使用方式

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

灵活的鉴权,授权机制。

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

扩展服务

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

典型应用场景

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

purple OSS分析与实现分析_第1张图片
场景

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. 对象插件扩展

你可能感兴趣的:(purple OSS分析与实现分析)