对象存储公约 0.2.0
此包使客于获授之对象桶,可读元、读文、读字节、写(可附条件与摘要之验)、删、列,且能以对象之正文流径为当前入站请求之终答。此乃云工专用之能,今映于 Cloudflare R2 之绑定。桶名者,客所授之绑定名也,由宿主资源之许核之(如 {"R2":["PACKAGES"]}),公约不刻具体绑定之名。结构之数以 JSON 文书之;事之可复者,以返值示之(对象无则返 null,条件写不合则返 {"written":false},直通之对象无则返阴),违规、逾限与平台之故,则抛豫言之异,客可以「尝试运行」取之,平台之故其异辞存平台所报原文(如 R2 之错码文)。桶名不在许,或在许而未绑,乃部署配置之误,宿主径止当前请,客不当图复。
桶名与键
- 桶名:一至六十四字节,首为字母或下划线,余为字母、数字或下划线;不合则抛异。得授与否,另由宿主之许核之。
- 键:一至一零二四字节(UTF-8),不含控制字符(U+0000 至 U+001F 及 U+007F,含 NUL),不以斜杠
/始;不合则抛异,且不召平台。此严于 R2 自身之规:R2 容控制字符与首斜杠,此包宁严勿松,使日志、标头与 JSON 不受控制字符所累。列举所得之键不受此限,依对象实有之键原样而返。
元
对象之元,书为 JSON 文,字段之序固定:{"size":字节数,"etag":"…","httpEtag":"\"…\"","uploaded":上传时刻之 Unix 毫秒整数,"httpMetadata":{…},"customMetadata":{…}}。etag 为不带引号之校验值,httpEtag 为带双引号之形(可径用于 ETag、If-Match);httpMetadata 惟含所有之字段:contentType、contentLanguage、contentDisposition、contentEncoding、cacheControl(字符串)及 cacheExpiry(Unix 毫秒整数);customMetadata 为字符串对字符串之 JSON 对象,无则 {}。
取对象元数据
取对象元数据 桶 键 惟读其元,不读正文。对象无则返字面 null。
读取对象文字
读取对象文字 桶 键 字节上限 读对象之正文为字符串。字节上限当在 一至二零九七一五二(二 MiB) 之间,越界抛异。
- 无:返字面
null。 - 对象字节数大于字节上限:不读正文,不截断,返
{"tooLarge":true,"size":字节数}。 - 否则以严格之 UTF-8 解之(非法之序、截断之多字节字、过长之编码、代理项之编,皆抛异),返
{"text":"…","size":字节数,"httpEtag":"…","customMetadata":{…}}。首之 BOM(U+FEFF)原存于text,size乃原字节数。对象空则"text":""。 - 何以上限为二 MiB 而非宿主值桥之十六 MiB:正文经宿主书为 JSON 字符串字面而越值桥,控制字符于 JSON 最坏膨胀六倍(
\u0001),二 MiB 之最坏约十二 MiB,仍在十六 MiB 之内;更大之文,宜用流式直通,或由客自分块而理之。
读取对象字节
读取对象字节 桶 键 字节上限 读对象之正文为字节串,返(爻,字节串)二元组。字节上限当在 一至一六七七七二一六(十六 MiB) 之间,越界抛异。
- 无:(阴,空字节串),不抛异。
- 有而对象字节数不逾字节上限:(阳,全部正文字节)。对象空则(阳,空字节串)。
- 对象字节数大于字节上限:不读正文,抛异(异于
读取对象文字之返tooLarge:读字节者多已知其大小,欲辨则先以取对象元数据察size)。 - 字节经宿主值桥以二进制径传,不经 JSON 转义,故上限可至值桥之十六 MiB;正文不解不验(欲严格之文,用
读取对象文字)。 - 用:须于内存改写较大之对象(如为已成之 HTML 页补链)而二 MiB 之文上限不足时用之;惟欲授之于客者,仍当流式直通,勿读入内存。
写入对象与写入对象文字
写入对象 桶 键 选项JSON 正文(正文为字节串)与 写入对象文字 桶 键 选项JSON 正文(正文为字符串,依其 UTF-8 字节而写)写一对象,同名者覆之。正文不得逾 十六 MiB。
选项 JSON 为对象,诸字段皆可缺;空字符串、null、{} 皆示无选项;见未知之字段、重复之字段、型不合者,抛异:
| 字段 | 型与规 | 义 |
| --- | --- | --- |
| ifNoneMatch | 惟 "*" | 对象无乃写 |
| ifMatch | 带双引号之 etag,引内一至六十四个字母、数字或连字符(如 httpEtag 之形) | 对象有而 etag 合乃写 |
| sha256 | 六十四个小写十六进制字符 | 由平台验正文之 SHA-256 |
| contentType | 一至二五六字节之可见 ASCII | 存为 httpMetadata.contentType |
| cacheControl | 一至二五六字节之可见 ASCII | 存为 httpMetadata.cacheControl |
| customMetadata | 字符串对字符串之对象:至多六十四项;键一至一二八字节;值至多一零二四字节;键值皆无控制字符;键不得为 $句柄、$未定义、$大整数、$数字(宿主桥之保留名,将被当作句柄之引) | 自定之元;平台另有总量之限,逾则平台报错 |
ifNoneMatch 与 ifMatch 不得并给。条件写以真正之 Headers 授平台(R2 于纯对象形之条件静默忽之,故适配不用)。
返 JSON:成则 {"written":true,"size":n,"etag":"…","httpEtag":"…"};前提不合(ifNoneMatch 而对象已有,ifMatch 而 etag 不合或对象无)则 {"written":false},对象如故,不抛异。sha256 不合、正文逾限、选项违规、平台之故,皆抛异,摘要不合之异辞存平台原文(含 The SHA-256 checksum you specified did not match what we received 及错码 10037),且不留对象。条件与摘要并给,先判孰者由平台定(本地 workerd 之 R2 先验摘要:摘要不合,虽条件亦不合,仍抛异),客不当恃此序。
删除对象
删除对象 桶 键们(键们为字符串之列)删至多 一千 个对象;键无者不为过;列空则不召平台;列逾千项或任一键不合规,则整批抛异,且不召平台(不删其半)。
列举对象
列举对象 桶 选项JSON 列诸对象,选项诸字段皆可缺(空字符串、null、{} 示无选项):prefix(字符串,零至一零二四字节)、limit(整数一至一千,缺省一千)、cursor(前次所返之续标,一至四零九六字节)、delimiter(一至十六字节)、include(数组,惟受 ["customMetadata"]);前缀、续标、分隔符皆不得含控制字符;未知或重复之字段、型不合者,抛异。
返 {"objects":[{"key":"…","size":n,"etag":"…","uploaded":毫秒,"customMetadata":{…}}],"truncated":真假,"cursor":"…"或null,"delimitedPrefixes":[…]}:customMetadata 惟 include 含之乃现;truncated 为真则 cursor 为续标,否则 null;给 delimiter 则含分隔符之键折入 delimitedPrefixes。所得依键之 UTF-8 字节序而列。给 `include` 时,平台或每页少于 `limit` 项(R2 文云:设 include 或得少于 limit 之果),客当以 truncated 与 cursor 续列,不得以所返之数是否等于 limit 断其有无下页。
回应入站以对象存储对象
回应入站以对象存储对象 桶 键 状态 附加标头 以对象之正文流式径通为当前入站请求之终答,正文不入豫言内存(故不受十六 MiB 值桥之限,大小不拘)。返爻:对象有而已设终答则阳;对象无则阴,此时不占终答,客可续回四百零四。
- 答自带
Content-Length(对象字节数)与ETag(httpEtag),复叠附加标头。 - 当前请求之法为
HEAD则惟读其元(用head),答无体而带Content-Length与ETag;他法则读正文之流。不支持范围之请:恒交全对象。 - 状当在二百至二百九十九之间,且非无体之二零四、二零五,亦非须按范围交付之二零六;否则抛异。
- 附加标头为(名,值)对之列,至多六十四项:名当为 HTTP 标记(字母、数字及
!#$%&'*+-.^_|~),一至一二八字节;值当为可见 ASCII(0x20 至 0x7E),至多四零九六字节,首尾不得为空格;名不分大小写,不得重复;下列诸名由平台或本术所设,或涉连接与帧,不得给:Content-Length、Transfer-Encoding、Connection、Keep-Alive、Upgrade、TE、Trailer、Proxy-Authenticate、Proxy-Authorization、Proxy-Connection、Set-Cookie、ETag`。违者抛异。 - 无当前入站请求(如队列或定时之事),或此请已有终答(含重复召之),乃调用之误,宿主止此次之行。一请惟一终答。
- 平台行为之示:可压缩之内容类型(如
text/*),客户端受压缩时,平台或自压缩而改用分块传输,此时答无Content-Length,ETag亦或弱化;欲严守长度与强校验之下载,当用不可压缩之类(如application/octet-stream)。
诸限
| 项 | 限 | 违者 |
| --- | --- | --- |
| 桶名 | 一至六十四字节之绑定名 | 豫言之异 |
| 键 | 一至一零二四字节,无控制字符,不以斜杠始 | 豫言之异 |
| 写入正文 | 十六 MiB | 豫言之异 |
| 读文之字节上限 | 一至二 MiB | 豫言之异;对象更大则返 tooLarge |
| 读字节之字节上限 | 一至十六 MiB | 豫言之异;对象更大亦抛豫言之异 |
| 选项 JSON | 六十四 KiB | 豫言之异 |
| 删 | 一千键 | 豫言之异 |
| 列 | limit 一至一千 | 豫言之异 |
| 直通之附加标头 | 六十四项,值四零九六字节 | 豫言之异 |
诸宿主同一
凡实现,须使:对象无则 取对象元数据 与 读取对象文字 返 null,直通返阴而不占终答;条件写不合则返 {"written":false} 而对象不变;摘要不合则不留对象;tooLarge 不读正文;直通不复制正文入客之内存;uploaded 为 Unix 毫秒整数;列之续标为不透明之串,惟由前次所返之 cursor 得之。R2 之外之实现(如文件系统或他对象存储)亦须守上述之义与限。
同一之例
- 写
abc而{"ifNoneMatch":"*"}:对象无,得{"written":true,"size":3,"etag":"900150983cd24fb0d6963f7d28e17f72","httpEtag":"\"900150983cd24fb0d6963f7d28e17f72\""},再写一次得{"written":false}。 - 写
abd而sha256为abc之摘要:抛异,辞含did not match,取对象元数据得null。 - 写一千字节后
读取对象文字 … 999得{"tooLarge":true,"size":1000},上限一千则得全文。 - 写
00 ff 0a(含 NUL 及非 UTF-8 之字节)后读取对象字节 … 一六七七七二一六得(阳,同三字节);键无则(阴,空);上限二而对象三字节则抛异;上限零或一六七七七二一七则抛异。 - 键
/a、空键、含换行之键、一零二五字节之键:抛异;一零二四字节之键可用。 - 列七对象,
limit三:三页(三、三、一),前二页truncated为真,末页为假而cursor为null。 - 直通
GET:答体等于对象之字节,Content-Length为对象字节数,ETag为httpEtag;HEAD:无体而头同;对象无:阴,客别回四百零四。
界
此包不为:分片上传、范围读取、按条件读取、复制或迁移对象、不重写正文而改元、预签名之址、对象生命周期与桶之治;读字节(读取对象字节)至多十六 MiB,更大者惟用直通;不释对象内容之式。存储类别、加密密钥诸 R2 之高阶选项未开。