对象存储云工适配
以当前 Worker 许可中之 R2 绑定承公共[对象存储公约](../../../豫言操作系统接口/对象存储/规范.文言.md)(许可.json 例:{"R2":["PACKAGES"]},桶名由客授),悉以豫言书于 云工宿主通用句柄桥之上(云工绑定句柄('R2', 桶名) 与 云工调用方法安全),不藏宿主 JS。
| 公约之术 | R2 之召 |
| --- | --- |
| 取对象元数据 | head(键),读 size、etag、httpEtag、uploaded(Date 以 getTime 取之)、httpMetadata、customMetadata |
| 读取对象文字 | get(键);size 逾上限则不读正文;否则 arrayBuffer() 后以 new TextDecoder('utf-8', {fatal: true, ignoreBOM: true}) 严解 |
| 读取对象字节 | get(键);size 逾上限则不读正文而抛异;否则 arrayBuffer() 后以 云工句柄取字节 径取字节串(不经 JSON) |
| 写入对象、写入对象文字 | put(键, Uint8Array, {onlyIf: Headers, sha256, httpMetadata, customMetadata});返 null 即前提不合 |
| 删除对象 | delete([键…]) |
| 列举对象 | list({limit, prefix, cursor, delimiter, include}) |
| 回应入站以对象存储对象 | GET:get(键) 后以 body 流授 new Response(body, {status, headers}) 而 设置响应句柄;HEAD:head(键) 与无体之 Response |
要点:
- JSON 字面原样而出:对象之键、
etag、httpEtag、customMetadata、正文文字,皆宿主JSON.stringify所给之合法字面,适配不于豫言解而复书(豫言 JSON 编码器于控制字符之转义不可恃,且大文逐字符转义太慢);惟整数(大小、毫秒)与httpMetadata之五字符串字段乃解之。故读取对象文字之限取二 MiB:控制字符最坏膨胀六倍,仍低于值桥之十六 MiB。 - 条件写用真 `Headers`:本地 workerd 探之,
onlyIf授纯对象则 R2 静默忽其条件而照覆,故适配以构造对象('Headers', …)造If-None-Match: *或If-Match: "etag"。 - `list` 之果为纯对象,其 `objects` 之元乃 `HeadResult` 类实例(宿主桥发柄);未截断时
cursor键在而值为undefined(桥书为{"$未定义":true}),适配惟于truncated为真时取续标。含include时本地 R2 每页约百项,客当循cursor续列。 - 柄:宿主事之柄表有四零九六项之限;
head、get、put之果、uploaded之 Date、arrayBuffer、TextDecoder、直通之答与头、请求体之流,用毕皆释;桶柄不释(同桶之柄于事内复用)。试验于同一事内重取元六千次、列二百次,不触其限。 - 校在豫言:桶名、键、选项 JSON(未知字段、型、互斥、长、保留名)、标头名与值、状;违者抛豫言之异,平台之故之辞存原文。校未过,不造任何宿主柄。
- 直通不入 Wasm 内存:GET 之径惟读
size、httpEtag、body,正文流授 Response;试验于六十四 MiB 之对象断言arrayBuffer/text/bytes/json/blob一次未召。
验:同一试验于 Node(R2 为形取自真 workerd 之类实例仿造)与 wrangler 4.129.0 之本地 workerd(真 R2 绑定,本地存储)皆过,见 一致性验证/。平台所察:sha256 不合之辞含 (10037);键逾一零二四字节为 (10020);list 之 limit 逾一千为 (10022);本地 R2 先验摘要而后判前提;可压缩之类而客户端受 gzip 时,workerd 改用分块传输而不存 Content-Length。