天天看点

OSS PostObject错误及排查

post object消息包括消息头(header)和消息体(body)。header和body之间,由<code>\r\n--{boundary}</code>分割。body由一系列的表单域构成,表单域格式如下 <code>content-disposition: form-data; name="{key}"\r\n\r\n{value}\r\n--{boundary}</code>。 常见的header有host、user-agent、content-length、content-type、content-md5等,表单域字段有key、ossaccesskeyid、signature、content-disposition、object meta(x-oss-meta-*)、x-oss-security-token、其它http header(cache-control/content-type/cache-control/content-type/content-disposition/content-encoding/expires/content-encoding/expires)、file等。表单域中<code>file</code>必须是最后一个。

postobject常见错误见下表:

序号

错误

原因

解法

1

errorcode: malformedpostrequest

errormessage: the body of your post request is not well-formed multipart/form-data

表单域格式不符合要求

表单域格式请参看表后的<code>putobject表单域格式</code>

2

errorcode: invalidaccesskeyid

errormessage: the oss access key id you provided does not exist in our records.

<code>accesskeyid</code>禁用或不存在,或者过期的临时用户accesskeyid,或者临时用户没有提供sts token

3

errorcode: accessdenied

errormessage: invalid according to policy: policy expired.

表单域policy中的<code>expiration</code>过期

请调整policy中的<code>expiration</code>,注意expiration的格式 iso8601 gmt

4

errormessage: signaturedoesnotmatch the request signature we calculated does not match the signature you provided. check your key and signing method.

签名错误

签名方法请参看下面的<code>putobject中的签名</code>

5

errorcode: invalidpolicydocument

errormessage: invalid policy: invalid simple-condition: simple-conditions must have exactly one property specified.

请求中policy至少包含一个condition

请参看表后的 <code>putobject中的policy格式</code>

6

errormessage: invalid policy: invalid json: unknown char e

请求中的<code>policy</code>格式不正确

请检查policy格式,<code>"</code>是否加缺失,转义字符是否加<code>\</code>

7

errormessage: invalid policy: invalid json: , or ] expected

policy中是否缺少 <code>,</code> 或 <code>]</code>

8

errormessage: invalid according to policy: policy condition failed: ["starts-with", "$key", "user/eric/"]

请求指定的<code>key</code>与<code>policy</code>限定的不符

请检查请求中表单域<code>key</code>的值

9

errormessage: invalid according to policy: policy condition failed: ["eq", "$bucket", "mingdi-bjx"]

请求指定<code>bucket</code>与<code>policy</code>限定的不符

请检查endpoint中的<code>bucket</code>的值

10

errormessage: invalid according to policy: policy condition failed: ["starts-with", "$x-oss-meta-prop", "prop-"]

请求指定的文件元数据<code>x-oss-meta-prop</code>与policy限定的不符

请检查请求中的<code>x-oss-meta-prop</code>的值

11

errormessage: invalid according to policy: policy condition failed: ["eq", "${field}", "${value}"]

表单域中指定的<code>{field}</code>与policy中限定的值不符,或者在请求中没有指定

请检查请求中的<code>{field}</code>的值

12

errormessage: you have no right to access this object because of bucket acl.

当前用户无权限

13

errorcode: invalidargument

errormessage: the bucket post must contain the specified 'key'. if it is specified, please check the order of the fields

表单域没有指定<code>key</code>,或者放在了表单域<code>file</code>后

请添加表单域<code>key</code>或调整顺序

putobject请求格式,有以下注意点:

header一定要有 <code>content-type: multipart/form-data; boundary={boundary}</code> ;

header和body之间由 <code>\r\n--{boundary}</code> 分割 ;

表单域格式 <code>content-disposition: form-data; name="{key}"\r\n\r\n{value}\r\n--{boundary}</code> ;

表单域 <code>file</code> 必须为最后一个表单域;

表单域名称大小写敏感,如policy、key、file、ossaccesskeyid、ossaccesskeyid、content-disposition;

bucket为 <code>public-read-write</code> 时,可以不指定表单域ossaccesskeyid、policy、signature;一旦指定ossaccesskeyid、policy、 signature中的任意一个,无论bucket是否为public-read-write,则另两个必须指定。

下面是postobject请求的示例:

提示: 上面示例请求中<code>\r\n</code>显示为新行,即换行,后面的示例请求类似;

如果您还有疑问,请参考示例代码: 

putobject请求的 <code>policy</code> 表单域用于验证请求的合法性,声明了putobject请求必须满足的条件。限定条件为 utf-8格式的json文本,经过base64编码后放在表单域policy中。 policy中必须包含expiration和condtions,其中condtions至少有一项。下面是base64编码前的policy示例:

<code>expiration</code>项指定了请求的过期时间, iso8601 gmt 时间格式;如 <code>2018-01-01t12:00:00.000z</code>指定请求必须发生在2018年1月1日12点前。

post policy的支持的限定条件(conditions)如下:

名称

描述

示例

bucket

上传文件的bucket名称。支持精确匹配方式。

{"bucket": "johnsmith" } 或 ["eq", "$bucket", "johnsmith"]

key

上传文件的名称。支持精确匹配和前缀匹配方式。

["starts-with", "$key", "user/etc/"]

content-length-range

上传文件允许的最小、最大长度。

["content-length-range", 0, 104857600]

x-oss-meta-*

指定的object meta。支持精确匹配和前缀匹配方式。

["starts-with", "$x-oss-meta-prop", "prop-"]

success_action_redirect

上传成功后的跳转url地址。支持精确匹配和前缀匹配方式。

["starts-with", "$success_action_redirect", "http://www.aliyun.com"]

success_action_status

未指定success_action_redirect时,上传成功后的返回状态码。支持精确匹配和前缀匹配方式。

["eq", "$success_action_status", "204"]

cache-control, content-type, content-disposition, content-encoding, expires等

http请求头,作为表单域传递。支持精确匹配和前缀匹配方式。

["eq", "$content-encoding", "zlib"]

post policy有以下转义字符,使用 <code>\</code> 转义。

转义字符

/

斜杠

\

反斜杠

"

双引号

$

美元符

b

空格

f

换页

n

换行

r

回车

t

水平制表符

uxxxx

unicode字符

对于验证的post请求,请求中必须包含accesskeyid、policy、signature表单域。计算签名的流程如下:

创建一个<code>utf-8</code>编码的policy。

将policy进行<code>base64</code>编码,其值即为policy表单域该填入的值,将该值作为将要签名的字符串。

即:

计算出的签名在表单域<code>signature</code>中指定,如下所示:

key即object name,在表单域<code>key</code>中指定,示例如下:

object内容通过表单域<code>file</code>中指定,示例如下

注意: 表单域<code>file</code>必须是表单中的最后一个域,即表单域<code>file</code>必须放在所有表单域后; <code>filename</code>是上传的本地文件名称,而不是object name。

object类型在表单域<code>file</code>中指定<code>content-type</code>,而不是header中的<code>content-type</code>,示例如下:

在postobject请求头中指定<code>content-md5</code>,注意md5值是整个body的md5,即所有表单域的md5。请求header示例如下:

签名的计算方法请参看 <code>putobject中的签名</code> , 签名通过表单域 <code>signature</code> 携带。

临时用户密钥的accesskeyid、accesskeysecret用法跟主用户、子用户相同,token放在表单域 <code>x-oss-security-token</code> 中携带。示例如下:

上传回调(callback)通过表单域<code>callback</code>携带。示例如下:

callback的自定义参数也是通过表单域携带。示例如下:

在表单域<code>file</code>中指定<code>content-transfer-encoding</code>。<code>file</code>表单域示例如下:

用户自定义元信息,可以表单域指定,示例如下:

oss的postobject支持丰富的条件限制,可以满足高安全性要求。限定条件conditions可以通过表单域 <code>policy</code> 指定,详细的说明请参看上面的 <code>putobject中的policy格式</code> 。下面是一个policy的示例:

上面的policy,限定用户的postobject操作:<code>bucket</code> 必须是 <code>md-hz</code>,<code>key</code> 必须以<code>md/conf/</code> 开头,是上传的文件长度必须在100m以下;且请求时间在 <code>2018-01-01t12:00:00.000z</code>之前。

<a href="https://github.com/aliyun/aliyun-oss-csharp-sdk/blob/master/samples/samples/postpolicysample.cs">c# post demo</a>

<a href="https://github.com/aliyun/aliyun-oss-java-sdk/blob/master/src/samples/postobjectsample.java">java post demo</a>

<a href="https://help.aliyun.com/document_detail/31925.html">js post demo</a>