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

豫言操作系统授权服务 0.3.0

豫言 · 库

向获授权的内部服务发送限定请求,增量读取或原流转交其回应。

授权服务接口规范 0.3.0

此能力组调用已经由宿主资源许可授予的内部服务绑定。应用给出绑定名、绝对 HTTPS 网址、GET 或 POST 方法、要从当前入站请求复制的标头名列表、固定标头键值列表,以及是否直接转送入站正文流。宿主须先检查绑定名授权,再发请求;目标网址仍由应用选择,不授予普通外网 fetch。服务回应的重定向不自动跟随,3xx 状态和 Location 作为原回应交给应用,避免凭据随重定向离开授权目标。无当前入站请求时调用失败。

可复制的标头只限 Cookie、Authorization、Content-Type、Idempotency-Key、CF-Connecting-IP;固定标头只限 Origin、Accept。两列表合计最多 16 项,同名重复时报错,未出现的入站标头略过。宿主不得复制其他入站标头。GET 不得转送正文;POST 可以转送,保留原始流,不先解析或缓冲。绑定、网址、方法、标头或正文状态不合规时调用失败。

返回的字符串是仅在当前请求有效的私有回应句柄,不是可持久化的服务地址。读取授权服务状态 返回原 HTTP 状态码;读取授权服务癸象正文文 在回应副本上解析 JSON,正文上限为 2 MiB,原回应流仍能交给 回应入站以授权服务原答。后者直接交付原 Response,保留状态、标头及正文流;一次入站请求只能交付一个最终响应。调用方若已消耗原流或复用失效句柄,宿主应报错。资源授权与接口版本须分别核对。

0.3.0 新增:带正文请求与增量读取

0.3.0 只新增五个函数,0.2.0 的四个函数签名与语义不变。新增部分服务于必须“边读边处理”上游流式响应(SSE、NDJSON)的应用:向内部模型服务、编译服务发 POST,逐块读取答复,中途可取消,全程受期限约束。

带正文请求

请求授权服务带正文(绑定名, 网址, 方法, 固定标头, 正文, 超时毫秒) 返回“(成功,响应柄或错误文)”。它不需要当前入站请求,可用于定时、队列、持久对象等事件。

  • 绑定名:非空,且已获 SERVICE 许可;未授权或不存在属部署错误,由宿主直接报错。
  • 方法:精确的 GET 或 POST。GET 的正文必须为空字符串。
  • 网址:绝对 HTTPS,长 1 至 2048 字节,可被 URL 标准解析,无用户名和口令,不含空白、控制字符与反斜线。主机部分只是服务绑定的内部占位名,宿主不据主机名选路。
  • 固定标头:至多 16 项。名只允许 Content-Type、Accept 和以 X-Yuyan- 开头(其后至少一个令牌字符)者,不区分大小写,不得重复(不区分大小写),须是合法标头令牌。值至多 512 字节,只含可见 ASCII 字符(0x20 至 0x7E),首尾不得为空格。Authorization、Cookie、Origin 等不在此列,不得经此函数设定。
  • 正文:UTF-8 文字,至多 8 MiB(8388608 字节)。宿主按字节发送,不经 JSON 转义,任意字符(含引号、反斜线、换行、制表、四字节字符)原样送达;不自动补 Content-Type。
  • 超时毫秒:1 至 900000。宿主以 AbortSignal.timeout 令期限覆盖“发请求、等响应头、读响应正文”的整次交换;宿主自身另有事件时限,二者取先到者。
  • 不跟随重定向。3xx 状态与 Location 原样交给应用,由应用视为失败或另行处理。

违反上列任一规则抛豫言异常,且不发出请求。传输失败,或响应头到达前期限已满,返回“阴”和以 授权服务请求失败或超时: 或 授权服务请求超时 开头的错误文,此为可恢复情形。成功返回“阳”和响应柄。

响应柄

响应柄是不透明字符串,仅在创建它的事件内有效,不可保存、序列化或伪造。请求授权服务 与 请求授权服务带正文 签发的柄,都可用于 读取授权服务状态 与下列读取函数;不是本包签发的字符串(包括其他能力包的柄、入站请求的句柄号)一律抛豫言异常。同一柄的读取应当串行;不同柄互不干扰,可交错读取。

增量读取会消耗并锁定响应正文。某柄一经开始增量读取(或已定局),读取授权服务癸象正文文 与 回应入站以授权服务原答 对它抛豫言异常,不再崩溃于宿主;要整体读取应改用 读取授权服务响应有限文字。

标头与状态

读取授权服务响应标头(柄, 名) 返回响应中该标头的值,名不区分大小写,缺失返回空字符串;名须是 1 至 128 字节的合法标头令牌,否则抛豫言异常。读取授权服务状态(柄) 沿用 0.2.0,返回原 HTTP 状态码。

增量读取文字块

读取授权服务响应块(柄, 最大字节) 返回“(状态,文字)”。最大字节须在 1 至 65536 之间,否则抛豫言异常。

  • 状态 0:数据块。文字是响应正文的下一段。宿主做流式 UTF-8 解码:跨上游块拆开的多字节字符正确拼接,非法序列各换成 U+FFFD,流首的字节序标记去掉,返回的文字绝不含被截断的半个字符。不足一个完整字符的上游块(解码所得为空)不单独返回,宿主继续读取直到得到非空文字、流结束、失败或期满(若上游连续送来 64 个以上空块,宿主可返回文字为空的状态 0,应用照常继续读取即可)。
  • 文字长度:每次返回文字的 UTF-8 字节数不超过最大字节(最大字节小于 4 时按 4 计,因单个字符至多 4 字节)。上游一块过大,或非法字节换成三字节的 U+FFFD 而超出,多出部分留在宿主,由后续调用依序返回,宿主不再为此读取上游。
  • 状态 1:正文已读尽,文字为空。响应没有正文(如 204、HEAD)时首次读取即得此状态。流末尾残缺的字符序列先以一个 U+FFFD 作状态 0 的块返回,再返回状态 1。
  • 状态 2:读取错误,文字为平台报告的原因,形如“名称: 消息”。
  • 状态 3:期限已满,或应用已取消,或有限读取因超限已取消。文字是简短说明(超时、已取消、正文超过上限,已取消),仅供诊断。期满时宿主同时取消上游。
  • 状态 1、2、3 是终态:此后再调用返回同样的终态与文字。

有限整读

读取授权服务响应有限文字(柄, 字节上限) 一次读完响应剩余正文,返回“(状态,文字)”。字节上限须在 1 至 8388608 之间,否则抛豫言异常。

  • 状态 0:成功,文字是剩余正文(含此前增量读取尚未交付的部分)。
  • 状态 1:超过上限,文字为空,宿主已取消上游。先看响应的 Content-Length,声明超过上限则一字不读;无声明或声明不实则流式累计,累计原始字节超过上限即取消并返回状态 1,超出的部分不返回给应用;平台流内部的预读缓冲不计入。恰等于上限不算超限。
  • 状态 2:读取错误,文字为原因。状态 3:期限已满或已取消。
  • 上限按上游原始字节计;解码规则同增量读取(宽松解码,非法序列成 U+FFFD,字节序标记去掉)。

取消

取消授权服务响应(柄) 取消对响应正文的读取,并对上游流执行 cancel(对外发连接即断开连接);上游服务能否即时回调其流的 cancel 取决于平台,不作保证(云工本地 workerd 对服务绑定与持久对象不回调,与直接用 JavaScript 相同);此后读取返回状态 3 与 已取消。幂等:已定局或重复取消无害。无效的柄抛豫言异常。应用在放弃读取前应当取消,以免上游继续生产。

失败分类

| 情形 | 类别 | | --- | --- | | 绑定名、方法、网址、标头、正文、超时、块上限、字节上限、标头名等参数违规;无效响应柄;已增量读取后再整读或转原答 | 抛豫言异常,不发请求 | | 服务绑定未授权或不存在 | 部署错误,宿主报错 | | 发请求失败,或响应头到达前期满 | 返回“阴”和原因 | | 读取中上游出错、期满、取消、超限 | 读取函数的状态 2、3、1 | | HTTP 4xx、5xx、3xx | 成功响应,由应用按状态码处理 |

限额

固定标头 16 项、值 512 字节;网址 2048 字节;请求正文 8 MiB;超时 900000 毫秒;块 65536 字节;有限整读 8 MiB;读取授权服务癸象正文文 沿用 2 MiB。

跨宿主一致性

不同宿主须满足:流式 UTF-8 解码与拼接;块内不含半个字符;期限覆盖全程且期满后读取返回状态 3 并对上游流执行 cancel;取消对上游流执行 cancel(上游能否观察到取决于平台);先看声明长度再读;参数违规不发请求;句柄仅本事件有效;不跟随重定向。宿主的事件时限若短于所给超时,以先到者为准,并按状态 3 或事件失败处理。

一致性样例

  • 5 帧 SSE,按 7 字节切块(切开汉字与帧),逐块读取,累计原始字节,等于整个流的字节数;文字拼起来等于整体解码。
  • 上游先给首块,其后长久不出块,超时 300 毫秒:先得首块,再得状态 3,宿主对上游流执行 cancel(原因 TimeoutError;能回调 cancel 的宿主可观察到)。
  • 上游中途出错:先得已到的块,再得状态 2 与原因。
  • 读一块后取消:宿主对上游流执行 cancel(能回调 cancel 的宿主可观察到);再读得状态 3;再取消无害。
  • 响应带 Content-Length: 5000,字节上限 1000:得状态 1,上游一次也未被读取。
  • 无声明长度、共 20 块每块 500 字节,字节上限 1000:得状态 1,宿主已对上游流执行 cancel,且远未读尽。
  • 恰 1000 字节、上限 1000:得状态 0;1001 字节:得状态 1。
  • 正文 甲"乙\丙<换行>丁<制表>戊<表情>,POST 送达,上游收到的字节与原文 UTF-8 逐字节相同。
  • 固定标头含 Authorization、含换行的值、重复的 Accept、超过 16 项:均抛异常,上游未收到请求。
  • 正文 8388608 字节可发,多一字节抛异常。

边界

宿主不保证上游服务观察到取消或断开,只保证读取一方立即得到状态 3、不再拉取上游。本包不提供:选择多个流中先到者的原语;写入服务的请求流(正文一次给足);跨事件保存响应柄;HTTP/2 推送与升级;自动重试。响应正文只读取一次,不可回绕。宿主执行事件的总时限由宿主配置,本包只保证按给定期限令读取失败,不延长宿主时限。

补充:服务绑定失败可捕获(路由代理修订)

请求授权服务(0.2.0 起的旧函数)在服务绑定的 fetch 同步抛出或返回被拒绝的 Promise 时(目标 Worker 抛出异常、部署切换、连接中断等),此前宿主异常会穿过 Wasm 边界使整个事件失败,应用无法捕获,也就无法向客户端回应 503。现在适配用安全调用,把它转为可捕获的豫言异常,消息以 授权服务请求失败: 起首,其后是 名称: 消息。参数违规仍在发请求之前抛出(不发请求);带正文版本 请求授权服务带正文 一直返回(阴,原因),不受影响。读取授权服务癸象正文文 同理:响应正文不是有效 JSON(例如网关返回 200 与 HTML)时,此前宿主的 SyntaxError 会使整个事件失败;现在抛出可捕获的豫言异常,消息以 授权服务 JSON 正文无效: 起首,其后是 名称: 消息。这一修订不改任何函数签名,不升版本。

一致性样例(补充):服务绑定的 fetch 抛出 Error('服务挂了')(或返回被拒绝的 Promise):请求授权服务 抛出消息为 授权服务请求失败:Error: 服务挂了 的豫言异常,应用可用 尝试运行 捕获并改答 503,事件不失败。

依赖

查看包配置

上传历史

当前上传修订:1 ·

  1. 上传修订 1
    下载 ZIP

包层级

父包:豫言操作系统接口

没有子包。