POST操作使用HTML表单将文件上传到指定的Bucket。POST是另一种形式的PUT操作,POST可以让使用者通过Browser-based的方式,将文件上传到指定Bucket中。PUT的参数是通过HTTP Header提交的,而POST通过使用multipart/form-data编码的消息体中的字段进行提交。用户必须对操作的Bucket有写权限。OOS不存储部分文件:如果收到成功的响应,那么文件就是存储成功了。
为了保证数据在网络传输过程中没有损坏,可以使用Content-MD5字段进行校验。如果请求参数中有Content-MD5,OOS将会计算用户提交的文件的MD5值。如果计算出的值与用户提供的值不一致,OOS将会返回一个错误给用户。或者,用户可以在上传文件到OOS时计算文件的MD5值,并与OOS在响应中返回的ETag进行比较。ETag是文件内容的MD5值,不包括metadata。
请求语法
POST /HTTP/1.1
Host: BucketName.oos-cn.ctyunapi.cn
User-Agent: browser_data
Accept: file_types
Accept-Language: Regions
Accept-Encoding: encoding
Accept-Charset: character_set
Keep-Alive: 300
Connection: keep-alive
Content-Type: multipart/form-data; boundary=9431149156168
Content-Length: length
--9431149156168
Content-Disposition: form-data; name="key"
Key
--9431149156168
Content-Disposition: form-data; name="success_action_redirect"
success_redirect
--9431149156168
Content-Disposition: form-data; name="Content-Type"
content_type
--9431149156168
Content-Disposition: form-data; name="x-amz-meta-uuid"
uuid
--9431149156168
Content-Disposition: form-data; name="x-amz-meta-tag"
metadata
--9431149156168
Content-Disposition: form-data; name="AWSAccessKeyId"
access-key-id
--9431149156168
Content-Disposition: form-data; name="Policy"
encoded_policy
--9431149156168
Content-Disposition: form-data; name="Signature"
signature=
--9431149156168
Content-Disposition: form-data; name="file"; filename="MyFilename.jpg"
Content-Type: image/jpeg
file_content
--9431149156168
Content-Disposition: form-data; name="submit"
Upload to OOS
--9431149156168—
表单字段
说明
表单中指定的每个表单字段(AWSAccessKeyId、signature、x-amz-signature、file、policy和带x-ignore-前缀的字段名称除外)必须包含在policy条件列表中,两者需要保持一致。
名称 | 描述 | 是否必须 |
---|---|---|
AWSAccessKeyId | 根用户或拥有权限的子用户的访问密钥ID。如果请求包含policy,对于V2签名,则此字段为必填字段。 类型:字符串。 | 条件 |
Cache-Control, Content-Type, Content-Disposition, Content-Encoding, Expires | 特定于REST的请求头。有关更多信息,请参阅PUT Object。 类型:字符串。 | 否 |
file | 文件或文本内容。文件或文本内容必须是Form表单的最后一个字段。一次只能上传一个文件。 类型:文件或文本内容。 | 是 |
key | 上传文件的名称。 ${filename}为用户提供的文件名。例如,如果用户Betty上传的文件名为lolcatz.jpg, 字段值指定为/user/betty/${filename},那么保存的文件名称将会是/user/betty/lolcatz.jpg。 类型:字符串 | 是 |
policy | 描述请求中允许的内容的安全策略。对于非匿名请求,policy字段是必须的。 在V2或者V4签名计算中,policy字段是您签名的字符串。 类型:字符串。 | 条件 |
signature | 使用V2签名计算的签名。如果请求包含policy,对于V2签名,则此字段为必填字段。 signature = Base64(HMAC-SHA1(YourSecrectKey,StringToSign))。 | 条件 |
X-Amz-Algorithm | V4签名算法。如果请求包含policy,对于V4签名,则此字段为必填字段。 取值:AWS4-HMAC-SHA256。 | 条件 |
X-Amz-Credential | 用户的accessKeyId和范围信息,范围信息包括请求日期、区域、服务、终止字符串aws4_request,格式如下: <your-access-key-id>/<date>/<region>/<service>/aws4_request 其中:
如果请求包含policy,对于V4签名,则此字段为必填字段。 | 条件 |
X-Amz-Date | 日期和时间格式必须遵循ISO 8601标准,并且必须使用“yyyyMMddT HHmmssZ”格式进行格式化。例如,如果日期和时间是“08/01/2018 15:32:41.982-700”,则必须首先将其转换为UTC(协调世界时),然后提交为“20180801T083241Z”。 如果请求包含policy,对于V4签名,则此字段为必填字段。 | 条件 |
X-Amz-Signature | 使用V4签名计算的签名。如果请求包含policy,对于V4签名,则此字段为必填字段。 x-amz-signature=hex(HMAC-SHA256(SigningKey, StringToSign))。 | 条件 |
X-Amz-security-token | 临时会话使用的安全令牌。使用临时密钥构造V2或者V4签名请求时,此字段为必填字段。 | 条件 |
success_action_redirect,redirect | 上传成功后客户端重定向到的URL。OOS将Bucket、文件名和etag值作为查询字符串参数附加到URL。
类型:字符串。 注意 redirect后续可能会被移除,建议使用success_action_redirect。 | 否 |
success_action_status | 如果没有指定success_action_redirect,上传成功后状态代码将返回到客户端。 取值:200、201或204(默认)。
注意 某些版本的AdobeFlashplayer无法正确处理使用空白正文的HTTP响应。要通过AdobeFlash支持上传,建议您将success_action_status设置为201。 | 否 |
x-amz-storage-class | 数据的存储类型。 类型:字符串。 取值:
默认值为STANDARD。 | 否 |
x-amz-meta-* | 任何头以这个前缀开始都会被认为是用户的元数据,当用户检索时,它将会和文件一起被存储并返回。更多信息请参考PUT Object 类型:字符串。 | 否 |
x-amz-website-redirect-location | 如果Bucket配置为网站,重定向对这个文件的请求到相同Bucket的另外一个文件或者到一个其他的URL。OOS会保存这个值到文件的metadata。 下面这个例子表示请求头设置重定向到相同Bucket的另一个文件(anotherPage.html)。 x-amz-website-redirect-location: /anotherPage.html 重定向到其他网站的例子: x-amz-website-redirect-location: https://example-bucket.oos-cn.ctyunapi.cn。 注意 这个值必须以“/”、https://或http://开头,且长度不能超过2KiB。 | 否 |
x-ctyun-data-location | 设置数据存储的位置。 注意 香港节点不支持此参数。 类型:key-value形式。 取值: 格式为:type=Local,scheduleStrategy=scheduleStrategy或者type=Specified,location=location,scheduleStrategy=scheduleStrategy
| 否 |
响应头
除了通用的响应头以外,本操作可以包括以下响应头。
名称 | 描述 |
---|---|
x-amz-expiration | 如果文件设置了过期时间(参考PUT Bucket Lifecycle章节),响应头会增加过期信息。过期信息包括过期日期和rule-id的key和value。rule-id的value是经过URL编码的。 类型:字符串。 |
success_action_redirect, redirect | 上传成功重定向的URL。 类型:字符串。 |
响应结果
名称 | 描述 |
---|---|
Bucket | 存储Object的Bucket名称。 类型:字符串。 父元素:PostResponse。 |
ETag | ETag是文件内容经过MD5哈希后得到的值。用户可以在GET请求中使用If-Match请求头。ETag仅反映文件内容的变化,不包括元数据。 类型:字符串。 父元素:PostResponse。 |
Key | 文件名称。 类型:字符串。 父元素:PostResponse。 |
Location | 文件的URL。 类型:字符串。 父元素: PostResponse。 |
请求示例1
使用V4签名:
POST / HTTP/1.1
Content-Type: multipart/form-data; boundary=jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR; charset=UTF-8
Host: a--12.oos-cn.ctyunapi.cn
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.7 (Java/1.8.0_351)
Content-Length: 1387
--jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR
Content-Disposition: form-data; name="x-amz-algorithm"
AWS4-HMAC-SHA256
--jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR
Content-Disposition: form-data; name="X-Amz-Credential"
25e67be754a9b2c85870/20240523/cn/s3/aws4_request
--jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR
Content-Disposition: form-data; name="x-amz-date"
20240523T092508Z
--jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR
Content-Disposition: form-data; name="key"
test01-post
--jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR
Content-Disposition: form-data; name="policy"
eyJleHBpcmF0aW9uIjoiMjAyNC0xMi0wMVQxMjowMDowMC4wMDBaIiwiY29uZGl0aW9ucyI6W3siYnVja2V0IjoiYS0tMTIifSx7ImtleSI6InRlc3QwMS1wb3N0In0seyJ4LWFtei1hbGdvcml0aG0iOiJBV1M0LUhNQUMtU0hBMjU2In0seyJ4LWFtei1jcmVkZW50aWFsIjoiMjVlNjdiZTc1NGE5YjJjODU4NzAvMjAyNDA1MjMvY24vczMvYXdzNF9yZXF1ZXN0In0seyJ4LWFtei1kYXRlIjoiMjAyNDA1MjNUMDkyNTA4WiJ9XX0=
--jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR
Content-Disposition: form-data; name="x-amz-signature"
91a935c2c409851f810cff5db53edb24415292edd651292de67432bc672169d7
--jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR
Content-Disposition: form-data; name="file"; filename="test01-post"
Content-Type: text/plain; charset=UTF-8
hello world!12345!@#$%^&*()_+":[]\?>,.adsf
--jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR
Content-Disposition: form-data; name="submit"
upload to oos
--jOgLwKAuIgki-MzA2jxfztAlGcp-wO0rfdR--
响应示例1
HTTP/1.1 204 No Content
ETag: "85c974a5ac9c67c64f55dba5d7c803a1"
Date: Thu, 23 May 2024 01:25:08 GMT
x-amz-request-id: c0e2170effd74bba0b7e71807582848a494b513f4143454749
Location: http://a--12.oos-cn.ctyunapi.cn/test01-post
Server: CTYUN
请求示例2
使用V2签名:
POST / HTTP/1.1
Content-Type: multipart/form-data; boundary=Ov8XWNyC3VX8y9lKZ4KPHJvpsN8TfDNqN5l; charset=UTF-8
Host: a--12.oos-cn.ctyunapi.cn
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.7 (Java/1.8.0_351)
Accept-Encoding: gzip,deflate
Content-Length: 841
--Ov8XWNyC3VX8y9lKZ4KPHJvpsN8TfDNqN5l
Content-Disposition: form-data; name="AWSAccessKeyId"
25e67be754a9b2c85870
--Ov8XWNyC3VX8y9lKZ4KPHJvpsN8TfDNqN5l
Content-Disposition: form-data; name="key"
1.post
--Ov8XWNyC3VX8y9lKZ4KPHJvpsN8TfDNqN5l
Content-Disposition: form-data; name="policy"
eyJleHBpcmF0aW9uIjoiMjAyNS0xMS0zMVQxMjowMDowMC4wMDBaIiwiY29uZGl0aW9ucyI6W3siYnVja2V0IjoiYS0tMTIifSx7ImtleSI6IjEucG9zdCJ9XX0=
--Ov8XWNyC3VX8y9lKZ4KPHJvpsN8TfDNqN5l
Content-Disposition: form-data; name="signature"
R0y00Fj0FoIFFSuXQvo0i52Gd0Y=
--Ov8XWNyC3VX8y9lKZ4KPHJvpsN8TfDNqN5l
Content-Disposition: form-data; name="file"; filename="1.post"
Content-Type: image/jpeg; charset=UTF-8
123
--Ov8XWNyC3VX8y9lKZ4KPHJvpsN8TfDNqN5l
Content-Disposition: form-data; name="submit"
upload to oos
--Ov8XWNyC3VX8y9lKZ4KPHJvpsN8TfDNqN5l--
响应示例2
HTTP/1.1 204 No Content
ETag: "202cb962ac59075b964b07152d234b70"
Date: Thu, 23 May 2024 02:27:01 GMT
x-amz-request-id: 9d721961d2b14a5a0a7d707f74818389484a543e4042444648
Location: http://a--12.oos-cn.ctyunapi.cn/1.post
Server: CTYUN
说明
表单声明包含三个部分:action、method和enctype。如果这些值当中的任意一个设置不正确,请求将失败。action指定处理请求的URL,必须将它设置为Bucket的URL。例如:Bucket的名称是BucketName,则URL为http://BucketName.oos-cn.ctyunapi.cn/。
<form action="http:// BucketName.oos-cn.ctyunapi.cn /" method="post" enctype="multipart/form-data">
</form>
Post Policy字段的构造
Policy是使用UTF-8和Base64编码的JSON文档,即需要对源码进行转换:先确保源码符合UTF-8编码格式,然后再进行Base-64编码。它指定了请求必须满足的条件并且用于对内容进行身份验证。根据您设计策略文档的方式,您可以对每次上传、每个用户、所有上传或根据其他能够满足您需要的设计来使用它们。
下面是一个简单的Post Policy示例:
Policy源码由过期(expiration)和条件(conditions)两部分构成,且符合UTF-8编码格式(如果不符合UTF-8编码格式,需要转换成符合UTF-8编码格式的编码):
{ "expiration": "2007-12-01T12:00:00.000Z", "conditions": [ { "bucket": "johnsmith" }, [ "starts-with", "$key", "user/eric/" ] ] }
对源码进行Base64编码。
ewogICAgImV4cGlyYXRpb24iOiAiMjAwNy0xMi0wMVQxMjowMDowMC4wMDBaIiwKICAgICJjb25kaXRpb25zIjogWwogICAgICAgIHsKICAgICAgICAgICAgImJ1Y2tldCI6ICJqb2huc21pdGgiCiAgICAgICAgfSwKICAgICAgICBbCiAgICAgICAgICAgICJzdGFydHMtd2l0aCIsCiAgICAgICAgICAgICIka2V5IiwKICAgICAgICAgICAgInVzZXIvZXJpYy8iCiAgICAgICAgXQogICAgXQp9
过期
过期元素采用ISO 8601UTC日期格式来指定策略的过期日期。例如,“2007-12-01T12:00:00.000Z”指定策略在2007年12月1日午夜UTC之后失效。在策略文档中过期字段是必需的。
条件
策略文档中的条件验证上传的文件的内容。表单中指定的每个表单字段(AWSAccessKeyId、signature、X-Amz-signature、file、policy和带x-ignore-前缀的字段名称除外)必须包含在policy条件列表中,两者需要保持一致。如果您有多个具有相同名称的字段,使用逗号进行分隔。例如,如果您有两个名为x- amz-meta-tag的字段,第一个字段的值为Ninja,第二个字段的值为Stallman,您可以将策略文档设置为Ninja,Stallman。
针对扩展的字段执行前缀匹配。例如,如果您将文件名称字段设置为user/betty/${filename},您的策略可能是["starts-with", "$key", "user/betty/" ]。请勿输入["starts-with", "$key", "user/betty/${filename}"]。
元素名称 | 说明 |
---|---|
X-Amz-Algorithm | V4签名算法。如果请求包含policy,对于V4签名,则此字段为必填字段。 取值:AWS4-HMAC-SHA256。 |
X-Amz-Credential | 用户的accessKeyId和范围信息,范围信息包括请求日期、区域、服务、终止字符串aws4_request,格式如下: <your-access-key-id>/<date>/<region>/<service>/aws4_request 其中:
如果请求包含policy,对于V4签名,则此字段为必填字段。 |
X-Amz-Date | 日期和时间格式必须遵循ISO 8601标准,并且必须使用“yyyyMMddT HHmmssZ”格式进行格式化。例如,如果日期和时间是“08/01/2018 15:32:41.982-700”,则必须首先将其转换为UTC(协调世界时),然后提交为“20180801T083241Z”。 如果请求包含policy,对于V4签名,则此字段为必填字段。 |
X-Amz-Security-Token | 临时会话使用的安全令牌。使用临时密钥构造V2或者V4签名请求时,此字段为必填字段。 |
x-amz-* | 以x-amz-开头的系统定义的元数据。(如x-amz-website-redirect-location、x-amz-storage-class,不含x-amz-signature)。 支持精确匹配。 |
bucket | 指定上传内容允许的Bucket。 支持精确匹配和starts-with。 |
content-length-range | 指定已上传内容允许长度的最小值和最大值。 支持范围匹配。 |
Cache-Control, Content-Type, Content-Disposition, Content- Encoding, Expires | 特定于 REST 的标头。 支持精确匹配和starts-with。 |
Key | 已上传文件的名称或文件名称前缀。 支持精确匹配和 starts-with。 |
success_action_redirect, redirect | 上传成功后客户端重定向到的URL。 支持精确匹配和starts-with。 |
success_action_status | 如果没有指定 success_action_redirect,上传成功后状态代码将返回到客户端。 支持精确匹配。 |
x-amz-meta- * | 特定于用户的元数据。 支持精确匹配和 starts-with。 |
注意
如果您的工具包添加了其他字段(例如,Flash添加了文件名),您必须将它们添加到策略文档。如果您可以控制此功能,将 x-ignore- 添加为字段的前缀以使OOS忽略此功能并使其不影响此功能的未来版本。
条件匹配
下表介绍条件匹配类型。尽管您必须为您在表单中指定的每个表单字段指定一个条件,您也可以通过为某个表单字段指定多个条件来创建更复杂的匹配条件。
条件 | 说明 |
---|---|
精确匹配 | 精确匹配将验证字段是否匹配特定的值。此示例指示Bucket必须设置为BucketName: {"bucket": "BucketName"} 也可写为: [ "eq", "bucket": "BucketName"] |
Starts With | 如果值必须从某个特定的值开始,请使用starts-with。本示例指示密钥必须从 user/betty 开始: ["starts-with", "$key", "user/betty/"] |
匹配任何内容 | 要配置策略以允许字段中的任何内容,请使用 starts-with 和一个空值。本示例允许任何 success_action_redirect: ["starts-with", "$success_action_redirect", ""] |
指定范围 | 对于接受范围的字段,请使用逗号来分隔上限和下限值。本示例允许1到10 MiB 的文件大小: ["content-length-range", 1048579, 10485760] |
字符串转义
转义序列 | 描述 |
---|---|
\ | 反斜杠。 |
$ | 美元符号。 |
\b | 退格键。 |
\f | 换页。 |
\n | 新建行。 |
\r | 回车。 |
\t | 水平选项卡。 |
\v | 垂直选项卡。 |
\uxxxx | 所有Unicode 字符。 |
Signature字段的构造步骤
使用UTF-8对policy内容进行编码。
使用Base64对步骤1中的UTF-8字节进行编码,得出签名字符串(StringTosign)。
使用HMAC SHA-1算法,对步骤2中的签名字符串和您的秘密访问密钥进行计算得出签名:HMAC-SHA1(SecretAccessKey,StringToSign)。
使用Base64对SHA-1签名进行编码:Signature=Base64(HMAC-SHA1(SecretAccessKey,StringToSign))。
X-Amz-Signature字段的构造步骤
使用UTF-8对policy内容进行编码。
使用Base64对这些UTF-8字节进行编码,得出签名字符串(StringTosign)。
推算出签名用的密钥(SigningKey)。推算过程:
使用HMAC SHA256算法,对步骤2和步骤3中的签名字符串和签名密钥进行计算得出签名。
使用十六进制编码对签名进行编码:X-Amz-Signature=hex(HMAC-SHA256(SigningKey, StringToSign))。