腾讯云对象存储PostObject

腾讯云对象存储开通地址 https://cloud.tencent.com/product/cos

PostObject使用HTML表单上传文件到指定bucket。

基于浏览器利用HTTPPOST直传文件到对象存储的Bucket中,可以降低延迟。PostObject的消息实体通过多重表单格式(multipart/form-data)编码,在PutObject操作中参数通过HTTP请求头传递,在Post操作中参数则作为消息实体中的表单域传递。此接口兼容S3,仅支持腾讯云对象存储的兼容S3服务域名,参见服务器域名。

请求语法

POST/HTTP/1.1Host:bucket.s3.region.jdcloud-oss.comContent-Length:lengthContent-Type:multipart/form-data;boundary=your_boundary--your_boundaryContent-Disposition:form-data;name="key"object_key--your_boundaryContent-Disposition:form-data;name="X-Amz-Credential"youraccessKey/date/region/s3/aws4_request--your_boundaryContent-Disposition:form-data;name="X-Amz-Algorithm"AWS4-HMAC-SHA256--your_boundaryContent-Disposition:form-data;name="X-Amz-Date"date--your_boundaryContent-Disposition:form-data;name="Policy"base64Encoded_policy--your_boundaryContent-Disposition:form-data;name="X-Amz-Signature"signature--your_boundaryContent-Disposition:form-data;name="file";filename=filenameContent-Type:content_typefile_content--your_boundaryContent-Disposition:form-data;name="submit"Uploadto腾讯云对象存储--your_boundary--Header特别提示:名称描述必须Content-Type标准的httpheader,但类型必须为multipart/form-data,并指定boundary,
例如:Content-Type:multipart/form-data;boundary=your_boundary是

表单域

名称类型描述必须Cache-Control字符串标准的httpheader,参考PutObject,将记为object元数据信息,
默认值:无否Content-Type字符串标准的httpheader,参考PutObject,将记为object元数据信息,
默认值:无否Content-Disposition字符串标准的httpheader,参考PutObject,将记为object元数据信息,
默认值:无否Content-Encoding字符串标准的httpheader,参考PutObject,将记为object元数据信息,
默认值:无否Expires字符串标准的httpheader,参考PutObject,将记为object元数据信息,
默认值:无否key字符串上传的object名字。支持变量${filename}(仅支持变量${filename}),例如指定key为bucket/${filename},此时你上传了一个名为test.jpg的图片,那么oss保存的key为:bucket/test.jpg,
默认值:无是policy字符串用于限制本次请求为经过UTF-8编码和Base64编码的JSON,
默认值:无对于需要签名的请求来说是必须的success_action_redirect字符串当上传成功时client跳转地址,如果success_action_redirect没有被指定,或者指定了但是腾讯云对象存储没有解析成功,那么腾讯云对象存储将按照success_action_status的设置进行返回(默认返回204)如果上传文件失败,那么腾讯云对象存储将会返回error并不做跳转,
默认值:无否success_action_status字符串指定了上传文件成功时返回的状态码,前提是success_action_redirect没有被指定,如果值为200或204,腾讯云对象存储返回内容为空。如果值为201,则返回的状态码为201,httpbody内容为xml格式的object相关信息
默认值:204
有效值:200,201,204(默认)否x-amz-algorithm字符串签名算法,值为:AWS4-HMAC-SHA256
默认值:无
仅支持AWS4-HMAC-SHA256对于需要签名的请求来说是必须的x-amz-credential字符串如果使用S3API,则格式为:your-access-key-id/date/region/s3/aws4_request例子:AKIAIOSFODNN7EXAMPLEYYYYYYYYYYYY/20180601/cn-north-1/s3/aws4_request
默认值:无对于需要签名的请求来说是必须的x-amz-date字符串ISO8601时间格式,例如:20180601T000000Z,policy中x-amz-date属性的值应该与它相同。注意,此时计算签名的时间为20180601
默认值:无对于需要签名的请求来说是必须的x-amz-signature字符串签名字符串
默认值:无对于需要签名的请求来说是必须的x-amz-storage-class字符串Object的存储类型
默认值:STANDARD(标准存储)
有效值:STANDARD(标准存储)、GLACIER(归档存储)、REDUCED_REDUNDANCY(低冗余存储)、STANDARD_IA(低频存储)否file字符串文件或文本内容,此属性必须放在form最后,否则file后的属性将被忽略,不支持多个文件同时上传
默认值:无是x-amz-meta-字符串以x-amz-meta-前缀开头的Header为用户自定义Header。自定义Header的大小(包括key、value)UTF-8编码下不能超过2K。否

响应

响应元素(ResponseElements)

当且仅当返回码为201时,有以下返回

名称类型描述PostResponse容器object存储的bucketname子节点:Bucket,Key,Etag+Bucket字符串object存储的bucketname父节点:PostResponse+Key字符串objectname父节点:PostResponse+Etag字符串在每个Object生成的时候被创建,Post请求创建的Object,可以用于检查该Object内容是否发生变化父节点:PostResponse+Location字符串新创建Object的URL,注意:location中的key将进行urlencode父节点:PostResponse

细节分析:

1.进行Post操作要求对bucket有写权限,如果bucket为public-read-write,可以不上传签名信息,否则要求对该操作进行签名验证,如果postform中没有提供足够的签名请求所需要的属性,那么本次请求将被视为匿名请求。

2.如果POST请求中包含Header签名信息或URL签名信息,腾讯云对象存储不会对它们做检查。(即PostObject只以Form中为准)

3.form中缺少必要属性。例如:缺少key,返回400InvalidArgument;缺少file,返回400IncorrectNumberOfFilesInPostRequest

4.form属性不区分大小写,例如:x-amz-signature和X-Amz-Signature等价,但是表单域的值为大小写敏感的。

5.form大小限制20K(不包含file大小),否则返回400,MaxPostPreDataLengthExceeded

6.Post请求的body总长度不允许超过5G。若文件长度过大,会返回错误码:EntityTooLarge,如果你要上传大于5G的文件建议使用分片上传。

7.key的value如果指定变量(仅支持变量${filename}),此时上传的文件名含有路径,即"/"或"",那么${filename}将会被替换为最后一个"/"或""之后的部分。例如:上传的文件名为:C:ProgramFilesdirectory1 ile.txt,那么key属性中${filename}将会被替换为file.txt

8.腾讯云对象存储不识别的属性将会被忽略,但是form里面的属性也需要在policy里面进行限制,否则将返回403AccessDenied。

9.如果用户表单域中指定Content-MD5(请求头中的MD5不会被验证),腾讯云对象存储会计算body的Content-MD5并检查一致性,如果不一致,将返回BadDigest错误码。

10.当form中包含success_action_redirect时,跳转目标地址为:url+?bucket=key=ETag=etag.此处query部分将进行urlencode

11.表单和policy必须使用UTF-8编码,policy为经过UTF-8编码和base64编码的JSON。

12.由于目前没有版本管理,如果用户上传同名文件将会被覆盖。

示例:

请求示例:

POST/HTTP/1.1Host:testBucket.s3.cn-north-1.jdcloud-oss.comContent-Length:lengthContent-Type:multipart/form-data;boundary=123456789000--123456789000Content-Disposition:form-data;name="key"test.txt--123456789000Content-Disposition:form-data;name="X-Amz-Credential"AKIAIOSFODNN7EXAMPLEYYYYYYYYYYYY/20180601/cn-north-1/s3/aws4_request--123456789000Content-Disposition:form-data;name="X-Amz-Algorithm"AWS4-HMAC-SHA256--123456789000Content-Disposition:form-data;name="X-Amz-Date"20180601T000000Z--123456789000Content-Disposition:form-data;name="Policy"eyJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJ5b3VoZS10ZXN0In0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJwb3N0LyJdLHsic3VjY2Vzc19hY3Rpb25fc3RhdHVzIjoiMjAxIn0seyJ4LWFtei1jcmVkZW50aWFsIjoiQUtJQUkyTUtVS0ZFUjRMNEJaNFEvMjAxODA3MTUvdXMtd2VzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LHsieC1hbXotYWxnb3JpdGhtIjoiQVdTNC1ITUFDLVNIQTI1NiJ9LHsieC1hbXotZGF0ZSI6IjIwMTgwNzE1VDAzNTcyN1oifSxbImNvbnRlbnQtbGVuZ3RoLXJhbmdlIiwiMCIsIjkiXV0sImV4cGlyYXRpb24iOiIyMDE4LTA3LTMwVDEyOjAwOjAwLjAwMFoifQ==--123456789000Content-Disposition:form-data;name="X-Amz-Signature"1b336b54bb3c7800f2137ee5b2d5d7ee676376800d388a17004ec2bee607897a--123456789000Content-Disposition:form-data;name="file";filename=”d:/test.txt”Content-Type:text/plainwrwe--123456789000Content-Disposition:form-data;name="submit"Uploadto腾讯云对象存储--123456789000--

返回示例:

?xmlversion="1.0"encoding="utf-8"?PostResponseBuckettestBucket/BucketKeytest.txt/KeyETag"1b6be8aac90401fe1cd5e4dd1c4b138f"/ETagLocationhttp://s3.cn-north-1.jdcloud-oss.com/testBucket/test.txt/Location/PostResponse

PostPolicy

Post请求的policy表单域用于验证请求的合法性,可以控制post请求的权限。policy为一段经过UTF-8和base64编码的JSON文本,声明了Post请求必须满足的条件。虽然对于public-read-write的bucket上传时,post表单域为可选项,强烈建议你使用该域来限制Post请求。policy示例:

{"expiration":"2018-12-01T12:00:00.000Z","conditions":{"bucket":"myBucketName"},["starts-with","$key","user/yuyu/"],]}

Postpolicy中必须包含expiration和condtions。

expiration

post请求policy的过期时间,时间格式为ISO8601GMT。例如:”2018-06-01T12:00:00.000Z”,指定Post请求必须发生在2018年6月1日12点之前。

Conditions

Conditions是一个列表,可以用于指定Post请求的表单域的合法值。Policy中支持的conditions项见下表:

名称描述bucketobject上传到的bucket名字
支持exactmatching匹配类型content-length-range上传内容的最大长度和最小长度限制
支持content-length-range匹配类型Cache-Control
Content-Type
Content-Disposition
Content-Encoding
Expires标准的httpheader,参考PutObject
支持exactmatching和starts-with匹配类型key上传object的名字
支持exactmatching和starts-with匹配类型success_action_redirect上传成功后跳转的url地址
支持exactmatching和starts-with匹配类型success_action_status当上传文件成功但success_action_redirect没有被指定时返回的状态码
支持exactmatching匹配类型x-amz-algorithm签名算法,值为:AWS4-HMAC-SHA256码
支持exactmatching匹配类型x-amz-credential如果使用S3API,则格式为:///s3/aws4_request
例子:AKIAIOSFODNN7EXAMPLEYYYYYYYYYYYY/20180601/cn-north-1/s3/aws4_request
支持exactmatching匹配类型x-amz-dateISO8601时间格式,例如:20180601T000000Z注意,此时计算签名的时间为20180601
支持exactmatching匹配类型x-amz-storage-classObject的存储类型,默认值是”STANDARD”(标准存储)。支持”STANDARD”(标准存储)和”REDUCED_REDUNDANCY”(低冗余存储)两种存储类型
支持exactmatching匹配类型

Conditions匹配方式

匹配方式描述精确匹配form属性必须准确匹配该值
例如{"bucket":"example-bucket"},则要求文件只能上传到名为"example-bucket"的bucket。
另一种写法:["eq","$bucket","example-bucket"]StartsWithform属性必须以指定值为前缀,
例如:["starts-with","$key","腾讯云对象存储/"]指定了上传的文件名必须以腾讯云对象存储/为前缀匹配任意值用于允许指定form属性的值为任何内容,使用StartsWith并赋值为空(””)
例如:["starts-with","$success_action_redirect",""]允许form中success_action_redirect可以为任何值指定文件大小只支持content-length,可以逗号分隔最小值和最大值
例如["content-length-range",1048579,10485760],限制了上传内容大小为1M~10M

转义字符

于在Postpolicy中$表示变量,所以如果要描述$,需要使用转义字符$。除此之外,JSON将对一些字符进行转义。下表描述了Postpolicy中需要进行转义的字符。

转义字符描述/斜杠|反斜杠$美元符空格 换页 换行 回车 水平制表符uxxxxUnicode字符

Postpolicy细节分析

1.policy中expiration和condition元素是必须的,否则policy验证失败,算作匿名请求。

2.上传的form里面除了x-amz-signature,file,policy,x-ignore-,其他属性必须要在policy中进行限制.否则将算作匿名访问

3.若policy格式不符合规范,如输入无效的ConditionMatchType等,都将当做匿名请求来处理。

4.policyconditions(除content-length-range)校验未通过或者form里面没有找到对应的属性都将算作匿名访问,content-length-range验证不通过会返回EntityTooLarge,EntityTooSmall

计算Signature

对于需要验证的Post请求,HTML表单中必须包含policy和signature(X-Amz-Signature)信息。policy控制请求中那些值是允许的。计算signature的具体流程为:

1.创建一个UTF-8编码的policy。

2.将policy进行base64编码,该值将作为签名计算的StringToSign字段。

3.将第二步得到字符串和其他签名所需信息,如AccessKeySecret等使用HMAC-SHA256算法进行签名计算。

4.将最后的结果进行16进制编码。

表单上传样例:

以下例子提供了如何使用POSTpolicy和表单完成上传一个文件到腾讯云对象存储。

Policy样例

{"expiration":"expirationexample:2018-08-30T12:00:00.000Z","conditions":[{"bucket":"yourbucket"},["starts-with","$key","yourobjectKeyprefix"],{"Content-Type":"typeexample:image/jpeg"},{"X-Amz-Credential":"youraccessKey/dateexample:20180709/region/s3/aws4_request"},{"X-Amz-Algorithm":"AWS4-HMAC-SHA256"},{"X-Amz-Date":"dateexample:20180709T053727Z"}]}
##form样例htmlheadmetahttp-equiv="Content-Type"content="text/html;charset=UTF-8"//headbodyformaction="http://yourbucket.s3.region.jdcloud-oss.com/"method="post"enctype="multipart/form-data"//Keytoupload:inputtype="input"name="key"value="yourobjectKey"/Content-Type:inputtype="input"name="Content-Type"value="typeexample:image/jpeg"/inputtype="text"name="X-Amz-Credential"value="youraccessKey/dateexample:20180709/region/s3/aws4_request"/inputtype="text"name="X-Amz-Algorithm"value="AWS4-HMAC-SHA256"/inputtype="text"name="X-Amz-Date"value="dateexample:20180709T053727Z"/inputtype="hidden"name="Policy"value='base64policy'/inputtype="hidden"name="X-Amz-Signature"value="signature"///File:inputtype="file"name="file"/!--Theelementsafterthiswillbeignored--inputtype="submit"name="submit"value="UploadtoJDcloud腾讯云对象存储"//form/html

说明:你需要替换有效的bucket名称,dates,credential,policy,和signature才能成功的上传文件到腾讯云对象存储。

标签