跳到正文
豫言包管理
← 全部包

豫言操作系统对象存储 0.2.0

豫言 · 库

读写(文字与字节)、列举、删除授权对象桶中的对象,并把对象正文流直通为入站响应。

对象存储接口规范 0.2.0

本包让应用对已授权的对象桶读取元数据、读取文字与字节、写入(可带条件与摘要校验)、删除、列举,并把对象正文流直接作为当前入站请求的最终响应。它是云工专用能力,当前映射到 Cloudflare R2 绑定。桶名是应用传入的绑定名,由宿主的资源许可核对(例如 {"R2":["PACKAGES"]}),规范不硬编码具体绑定名。结构化数据用 JSON 文字;可恢复的业务情形用返回值表示(对象不存在返回 null,条件写不满足返回 {"written":false},直通对象不存在返回阴),违规、超限和平台故障抛出豫言异常,应用可用「尝试运行」捕获,平台故障的异常消息保留平台报告的原文(如 R2 的错误码文字)。桶名不在许可内、许可内的桶未绑定,属于部署配置错误,宿主直接中止当前请求,应用不应尝试恢复。

桶名与键

  • 桶名:1 至 64 字节,首字节为字母或下划线,其余为字母、数字或下划线;不符抛出异常。是否获授权另由宿主许可核对。
  • 键:1 至 1024 字节(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。

读取对象文字

读取对象文字 桶 键 字节上限 把对象正文读成字符串。字节上限须在 1 至 2097152(2 MiB) 之间,越界抛出异常。

  • 不存在:字面量 null。
  • 对象字节数大于字节上限:不读取正文、不截断,返回 {"tooLarge":true,"size":字节数}。
  • 否则用严格的 UTF-8 解码(非法序列、截断的多字节字符、过长编码、代理项编码都抛出异常),返回 {"text":"…","size":字节数,"httpEtag":"…","customMetadata":{…}}。开头的 BOM(U+FEFF)原样保留在 text 里,size 是原始字节数。空对象得 "text":""。
  • 为什么上限是 2 MiB 而不是宿主值桥的 16 MiB:正文经宿主转成 JSON 字符串字面量后越过值桥,控制字符在 JSON 里最坏膨胀为六倍(\u0001),2 MiB 的最坏情形约 12 MiB,仍在 16 MiB 之内;更大的文字对象应改用流式直通,或由应用自己分块管理。

读取对象字节

读取对象字节 桶 键 字节上限 把对象正文读成字节串,返回(爻,字节串)二元组。字节上限须在 1 至 16777216(16 MiB) 之间,越界抛出异常。

  • 不存在:(阴,空字节串),不抛异常。
  • 存在且对象字节数不大于字节上限:(阳,全部正文字节)。空对象得(阳,空字节串)。
  • 对象字节数大于字节上限:不读取正文,抛出异常(不同于 读取对象文字 返回 tooLarge:字节读取的调用者通常已经知道大小,需要区分时先用 取对象元数据 查 size)。
  • 字节经宿主值桥以二进制直接传递,不经 JSON 转义,因此上限可以到值桥的 16 MiB;正文不做任何解码,也不做 UTF-8 检查(要严格文字请用 读取对象文字)。
  • 用途:需要在内存里改写较大的对象(例如给已渲染的 HTML 页面补链接)而 2 MiB 的文字上限不够时使用;只是把对象交给客户端时仍应使用流式直通,不要读进内存。

写入对象与写入对象文字

写入对象 桶 键 选项JSON 正文(正文为字节串)与 写入对象文字 桶 键 选项JSON 正文(正文为字符串,按其 UTF-8 字节写入)写入一个对象,覆盖同名对象。正文不得超过 16 MiB。

选项 JSON 是对象,所有字段都可缺省;空字符串、null 和 {} 都表示无选项;出现未知字段、重复字段、类型不符都抛出异常:

| 字段 | 类型与规则 | 含义 | | --- | --- | --- | | ifNoneMatch | 只能是 "*" | 仅当对象不存在时写入 | | ifMatch | 带双引号的 etag,双引号内 1 至 64 个字母、数字或连字符(形如 httpEtag) | 仅当对象存在且 etag 相符时写入 | | sha256 | 64 个小写十六进制字符 | 由平台校验正文的 SHA-256 | | contentType | 1 至 256 字节的可见 ASCII | 保存为 httpMetadata.contentType | | cacheControl | 1 至 256 字节的可见 ASCII | 保存为 httpMetadata.cacheControl | | customMetadata | 字符串到字符串的对象:至多 64 项;键 1 至 128 字节;值至多 1024 字节;键值都不含控制字符;键不得是 $句柄、$未定义、$大整数、$数字(宿主桥的保留名,会被当作句柄引用) | 自定义元数据;平台另有总大小限制,超出由平台报错 |

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 先校验摘要:摘要不符即使条件也不满足仍抛出异常),应用不应依赖这一顺序。

删除对象

删除对象 桶 键们(键们是字符串列表)删除至多 1000 个对象;不存在的键不报错;空列表不调用平台;列表超过 1000 项或任一键不合规,整批抛出异常,且不调用平台(不会删除一部分)。

列举对象

列举对象 桶 选项JSON 列举对象,选项字段都可缺省(空字符串、null、{} 表示无选项):prefix(字符串,0 至 1024 字节)、limit(整数 1 至 1000,缺省 1000)、cursor(上次返回的续标,1 至 4096 字节)、delimiter(1 至 16 字节)、include(数组,只接受 ["customMetadata"]);前缀、续标、分隔符都不得含控制字符;未知或重复字段、类型不符抛出异常。

返回 {"objects":[{"key":"…","size":n,"etag":"…","uploaded":毫秒,"customMetadata":{…}}],"truncated":真假,"cursor":"…"或null,"delimitedPrefixes":[…]}:customMetadata 仅在 include 含 customMetadata 时出现;truncated 为真时 cursor 是续标,否则为 null;给了 delimiter 时,含分隔符的键折叠进 delimitedPrefixes。结果按键的 UTF-8 字节序排列。给了 `include` 时,平台可能每页返回少于 `limit` 项(R2 文档:设置了 include 可能得到少于 limit 的结果),应用必须以 truncated 与 cursor 续列,不能用返回数是否等于 limit 判断是否还有下一页。

回应入站以对象存储对象

回应入站以对象存储对象 桶 键 状态 附加标头 把对象正文流式直通为当前入站请求的最终响应,正文不进入豫言内存(因此不受 16 MiB 的值桥限制,可以是任意大小)。返回爻:对象存在并已设置最终响应为阳;对象不存在为阴,此时不占用最终响应,应用可以接着回 404。

  • 响应自动带 Content-Length(对象字节数)与 ETag(httpEtag),再叠加附加标头。
  • 当前请求方法为 HEAD 时只读元数据(用 head),响应无正文但带 Content-Length 与 ETag;其他方法读取正文流。不支持范围请求:始终交付整个对象。
  • 状态须在 200 至 299 之间,且不能是无正文的 204、205,也不能是须按范围交付的 206;否则抛出异常。
  • 附加标头是(名, 值)对列表,至多 64 项:名须是 HTTP token(字母、数字及 !#$%&'*+-.^_|~),1 至 128 字节;值须是可见 ASCII(0x20 至 0x7E),至多 4096 字节,首尾不得为空格;名不区分大小写,不得重复;下列名由平台或本函数设定,或涉及连接与帧,不得给出: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)。

限额一览

| 项目 | 限额 | 违规时 | | --- | --- | --- | | 桶名 | 1 至 64 字节的绑定名 | 豫言异常 | | 键 | 1 至 1024 字节,无控制字符,不以斜杠开头 | 豫言异常 | | 写入正文 | 16 MiB | 豫言异常 | | 读取对象文字的字节上限 | 1 至 2 MiB | 豫言异常;对象更大时返回 tooLarge | | 读取对象字节的字节上限 | 1 至 16 MiB | 豫言异常;对象更大时也抛出豫言异常 | | 选项 JSON | 64 KiB | 豫言异常 | | 删除 | 1000 个键 | 豫言异常 | | 列举 | limit 1 至 1000 | 豫言异常 | | 直通附加标头 | 64 项,值 4096 字节 | 豫言异常 |

跨宿主一致性

任何实现须满足:对象不存在时 取对象元数据 与 读取对象文字 返回 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。
  • 写入 1000 字节后 读取对象文字 … 999 得 {"tooLarge":true,"size":1000},上限为 1000 时得全文。
  • 写入 00 ff 0a(含 NUL 与非 UTF-8 字节)后 读取对象字节 … 16777216 得(阳,同样三个字节);不存在的键得(阴,空);上限为 2 而对象有 3 字节抛出异常;上限为 0 或 16777217 抛出异常。
  • 键 /a、空键、含换行的键、1025 字节的键:抛出异常;1024 字节的键可用。
  • 列举 7 个对象,limit 3:三页(3、3、1),前两页 truncated 为真,末页为假且 cursor 为 null。
  • 直通 GET:响应体等于对象字节,Content-Length 为对象字节数,ETag 为 httpEtag;HEAD:无体、头相同;对象不存在:阴,应用另回 404。

边界

本包不做:分片上传、范围读取、按条件读取、复制或移动对象、改写元数据而不重写正文、预签名地址、对象生命周期与桶管理;字节读取(读取对象字节)至多 16 MiB,更大的对象只能用直通;不解释对象内容的格式。存储类别、加密密钥等 R2 的高级选项未开放。

依赖

查看包配置

上传历史

当前上传修订:1 ·

  1. 上传修订 1
    下载 ZIP

包层级

父包:豫言操作系统接口

没有子包。