授权服务公约 0.3.0
此包惟请宿主已授之内部服务。客献绑定名、HTTPS 绝对址、GET 或 POST 之法、应从当前请取之白头名列、定头键值列,及原流转正文之爻。宿主先核绑定之权,乃发请;目标仍由客定,此权不等于外网任取。遇改向不自追,三百号与 Location 仍归客,以免凭据随改向逸出所授之址。无当前入站请则败。
可复制者惟 Cookie、Authorization、Content-Type、Idempotency-Key、CF-Connecting-IP;可定者惟 Origin、Accept。两列合至多十六,同名重出则败,原请无头则略。宿主不得暗渡他头。GET 不可带正文;POST 可原流转之,不先析亦不缓冲。绑定、网址、法、头或流失规则败。
所返文为私柄,惟当前请有效,不可久存。读取授权服务状态 取原状态;读取授权服务癸象正文文 克隆而析 JSON,至多二 MiB,原流仍可回。回应入站以授权服务原答 以原回应径交当前请,状态、头及正文流皆守。一请惟一终答;原流已耗或柄失效则败。资源之权与接口之版当各核。
〇点三新增:带正文之请与渐读
〇点三惟增五术,〇点二之四术,其型与义不变。所增者,为必边读边处上游流答(SSE、NDJSON)之客而设:向内模型、编译之服发 POST,逐块读其答,中途可止,全程受期限之约。
带正文之请
请求授权服务带正文(绑定名, 网址, 方法, 固定标头, 正文, 超时毫秒) 返「(成否,答柄或误文)」。不须当前入站请,定时、队列、持久对象诸事皆可用。
- 绑定名:非空,且已受
SERVICE之许;未授或无此绑定,乃部署之误,宿主径报。 - 法:正为
GET或POST。GET之正文必空。 - 网址:HTTPS 绝对址,长一至二〇四八字节,可依 URL 标准析之,无用户名口令,无空白、控字、反斜线。其主机惟服务绑定之内名,宿主不据以选路。
- 定头:至多十六项。名惟
Content-Type、Accept,及以X-Yuyan-起而其后至少一令牌字者,不分大小写,不得重出(亦不分大小写),须为合法头令牌。值至多五一二字节,惟可见 ASCII 字(自空格至~),首尾不得为空格。Authorization、Cookie、Origin等不在其列,不得由此术定。 - 正文:UTF-8 文,至多八 MiB(八三八八六〇八字节)。宿主以字节发之,不经 JSON 转义,凡字(引号、反斜线、换行、制表、四字节字)皆原样而达;不自补
Content-Type。 - 超时毫秒:一至九〇〇〇〇〇。宿主以
AbortSignal.timeout令期限贯“发请、候答头、读答文”之全程;宿主自有事时之限,二者先至者胜。 - 不随改向。三百号与
Location原样归客,或视为败,或另处之。
违上列任一则告豫言异常,且不发请。传输败,或答头未至而期满,则返“阴”与误文,误文以 授权服务请求失败或超时: 或 授权服务请求超时 始,此为可复之情。成则返“阳”与答柄。
答柄
答柄为不透明之文,惟创之之事有效,不可存、不可序、不可伪。请求授权服务 与 请求授权服务带正文 所发之柄,皆可用于 读取授权服务状态 及下列诸读术;非本包所发之文(他能力包之柄、入站请之句柄号)皆告豫言异常。同一柄之读当有序;异柄互不相扰,可错综而读。
渐读则耗而锁答文。柄一旦始渐读(或已定局),读取授权服务癸象正文文 与 回应入站以授权服务原答 于其皆告豫言异常,不复崩于宿主;欲整读者,当改用 读取授权服务响应有限文字。
头与状态
读取授权服务响应标头(柄, 名) 返答中该头之值,名不分大小写,无则空文;名须为一至一二八字节之合法头令牌,否则告豫言异常。读取授权服务状态(柄) 承〇点二,返原 HTTP 状态号。
渐读文块
读取授权服务响应块(柄, 最大字节) 返「(状态,文)」。最大字节当在一至六五五三六之间,否则告豫言异常。
- 状态零:得一块。文为答文之次段。宿主流式解 UTF-8:跨上游块而裂之多字节字,必正相衔;非法之序各易为 U+FFFD;流首之字节序记去之;所返之文绝无半字。上游块不足一整字(解得空文)者不单返,宿主续读,至得非空之文、流终、败或期满(若上游连送六十四空块以上,宿主可返文空之状态零,客照常续读可也)。
- 文长:每返之文,其 UTF-8 字节数不逾最大字节(最大字节不足四者,以四计,以单字至多四字节也)。上游一块过大,或坏字节易为三字节之 U+FFFD 而溢者,其余留于宿主,由后续之调依次返之,宿主不为此复读上游。
- 状态一:答文已读尽,文空。无正文之答(如二〇四、HEAD)首读即得此状态。流末残缺之字序,先以一 U+FFFD 为状态零之块返之,乃返状态一。
- 状态二:读败,文为平台所报之因,形如“名称: 消息”。
- 状态三:期限已满,或客已止之,或有限整读因逾限已止。文为简短之说(
超时、已取消、正文超过上限,已取消),惟供察验。期满时宿主同止上游。 - 状态一、二、三为终态:此后再调,返同一终态与文。
有限整读
读取授权服务响应有限文字(柄, 字节上限) 一次读毕答文之余,返「(状态,文)」。字节上限当在一至八三八八六〇八之间,否则告豫言异常。
- 状态零:成,文为余下之正文(含此前渐读未交之部)。
- 状态一:逾上限,文空,宿主已止上游。先观答之
Content-Length,所称已逾上限则一字不读;无所称或所称不实,则流式累计,累计原字节逾上限即止而返状态一,逾出之部不归客;平台流内部之预读不计。恰等于上限不为逾。 - 状态二:读败,文为因。状态三:期满或已止。
- 上限以上游原字节计;解码之则同渐读(宽解,非法序为 U+FFFD,去字节序记)。
止
取消授权服务响应(柄) 止读答文,且对上游流行 cancel(于外发之连则断其连);上游服务能否即回调其流之 cancel,视平台而定,不作保证(云工本地 workerd 于服务绑定与持久对象不回调,与径用 JavaScript 同);此后之读返状态三与 已取消。幂等:已定局或重止皆无害。柄无效则告豫言异常。客欲弃读,当先止之,免上游徒产。
败之分类
| 情形 | 类 | | --- | --- | | 绑定名、法、址、头、正文、时限、块限、字节上限、头名诸参违规;柄无效;渐读之后复整读或转原答 | 告豫言异常,不发请 | | 服务绑定未授或无此绑定 | 部署之误,宿主报之 | | 发请败,或答头未至而期满 | 返“阴”与因 | | 读时上游出错、期满、已止、逾限 | 读术之状态二、三、一 | | HTTP 四百、五百、三百号 | 得答之成,由客按状态号处之 |
限额
定头十六项、值五一二字节;址二〇四八字节;请正文八 MiB;时限九〇〇〇〇〇毫秒;块六五五三六字节;有限整读八 MiB;读取授权服务癸象正文文 仍二 MiB。
异宿主之一致
异宿主必守:流式解 UTF-8 而相衔;块内无半字;期限贯全程,期满则读返状态三并对上游流行 cancel;止则对上游流行 cancel(上游能否得见,视平台);先观所称之长而后读;参违则不发请;柄惟本事有效;不随改向。宿主之事限若短于所给时限,以先至者为准,按状态三或事败处之。
一致之例
- 五帧 SSE,以七字节切块(裂汉字与帧),逐块读之,累计原字节,等于全流之字节数;文拼之,等于整体解码。
- 上游先予首块,其后久不出块,时限三〇〇毫秒:先得首块,次得状态三,宿主对上游流行 cancel(因
TimeoutError;能回调 cancel 之宿主可察之)。 - 上游中途出错:先得已至之块,后得状态二与因。
- 读一块而止:宿主对上游流行 cancel(能回调 cancel 之宿主可察之);再读得状态三;再止无害。
- 答带
Content-Length: 5000,字节上限一〇〇〇:得状态一,上游一次未被读。 - 无所称之长,共二十块每块五〇〇字节,字节上限一〇〇〇:得状态一,宿主已对上游流行 cancel,且远未读尽。
- 恰一〇〇〇字节、上限一〇〇〇:得状态零;一〇〇一字节:得状态一。
- 正文
甲"乙\丙<换行>丁<制表>戊<表情>,POST 而达,上游所收之字节与原文 UTF-8 逐字节同。 - 定头含
Authorization、含换行之值、重出之Accept、逾十六项:皆告异常,上游未得请。 - 正文八三八八六〇八字节可发,多一字节则告异常。
界
宿主不保证上游服务得见其止或断,惟保证读者一方立得状态三、不复拉取上游。此包不予:于诸流择先至者之术;写向服务之请流(正文一次予足);跨事而存答柄;HTTP/2 推送与升级;自动重试。答文惟读一次,不可回绕。宿主事之总限由宿主配之,此包惟保证依所给期限令读败,不延宿主之限。
补:服务绑定之败可捕(路由代理之修)
请求授权服务(〇点二起之旧术)遇服务绑定之 fetch 同步抛出或返被拒之 Promise(目标 Worker 抛异常、部署更替、连接中断之类),旧时宿主之异越 Wasm 之界而使全事败,应用不能捕,遂无从答客以五百零三。今适配以安全之调,转为可捕之豫言异常,辞以 授权服务请求失败: 起,继以 名称: 消息。参数违规仍先于发请而告(不发请);带正文之术 请求授权服务带正文 素返(阴,因),不受此累。读取授权服务癸象正文文 亦然:答文非有效 JSON(如关口返二百而文为 HTML)时,旧时宿主之 SyntaxError 使全事败;今告可捕之豫言异常,辞以 授权服务 JSON 正文无效: 起,继以 名称: 消息。此修不改术之型,不升版。
一致之例(补):服务绑定之 fetch 抛 Error('服务挂了')(或返被拒之 Promise):请求授权服务 告辞为 授权服务请求失败:Error: 服务挂了 之豫言异常,应用可以 尝试运行 捕之而改答五百零三,事不败。