要約

  • RFC 9659はHTTP zstd decoderに8 MB以下のwindow対応を要求し、encoderには8 MBを超えるwindowを必要とするframeの生成を禁じる。
  • libraryの機能試験、正しいHTTP header、HTTP 200は、組み込みprocessの実効memory予算や特定representationの復号成功を証明しない。
  • 実用的なreceiptは、生成frame、途中の変換、cache variant、clientの制限、decode result、application acceptanceを同じbyte identityで結ぶ。

圧縮libraryの互換表には「8 MB対応」と記載されていた。単体試験も成功した。しかし、そのlibraryを組み込んだprocessは、同時実行数を守るために1要求あたりのmemoryをより小さく制限していた。短いresponseは通り、境界に近いframeだけが失敗する。libraryの説明もprocessの制限も正しい。誤っているのは、前者を後者の実行結果として扱う判断である。

RFC 9659 はHTTPの zstd content codingに対して対称な契約を置く。decoderは8 MBまでを含む Window_Size を支えなければならず、encoderは8 MBより大きいwindowを要求するframeを作ってはならない。生産者と受信者が同じ線を使うことで、memory保護と相互運用を両立させる。

windowは復号に必要な履歴を決める

RFC 8878 はZstandard frame formatを定義する。windowはback-referenceが以前に復号したdataへ遡れる最大距離を表し、decoderが保持すべき履歴量に関係する。format自体は1 KBから約3.75 TBまでを許す。大きいwindowはcompression ratioを改善し得るが、その費用は受信側memoryにも現れる。

RFC 8878はHTTP利用について8 MBを推奨していたが、義務ではなかった。そのため、encoderの最適化とbrowser等のmemory防御が衝突し得た。RFC 9659は推奨を要求へ変え、この曖昧さを閉じる。canonical text と XML source には同じ境界が保持されている。

RFC Editorの情報 は、RFC 9659がRFC 8878を更新するInformational RFCであることを示す。errata検索 と Datatracker history は、運用policyがどの公開textと訂正状態に基づくかを追跡するための材料になる。

HTTP headerはwindowを運ばない

RFC 9110 において、Accept-Encoding: zstd は受信者がcodingを受け入れられるという選択情報であり、Content-Encoding: zstd は選ばれたrepresentationに適用されたcodingを示す。どちらもZstandard windowの値を表さない。どのbinaryがframeを作ったか、intermediaryが再圧縮したか、processが必要量を割り当てたか、applicationが内容を受理したかも示さない。

したがって、zstd 選択数やHTTP 200数はdecode成功数ではない。serverはbody送信前に選択を記録できる。edgeはclientが復号する前に成功を記録できる。小さいobjectだけのcanaryは境界を通らない。機能表は能力の上限を示しても、その瞬間のresource状態を示さない。

RFC 7694 はrequest bodyに対してserverが受け入れるcontent codingを知らせる方法を扱う。ここでもadvertisementと特定requestの処理結果は別である。response側でもrequest側でも、offer、selection、実bytes、resultを分離する必要がある。

cache variantは別世代のframeを届ける

RFC 9111 が示す通り、cacheはHTTP deliveryの一部である。encoder設定を直しても、古い zstd objectはfreshなまま残り得る。edgeごとにgenerationが異なり、purgeが一部のkeyだけに届くこともある。fallbackが曖昧なvariant identityで保存されれば、別のclientへ再利用される。

監査対象はURLでも現在のorigin設定でもなく、serveされたbytesである。object hash、variant key、generation、age、invalidation、transformation、frame header、client classを同じ記録に結ぶ必要がある。新しいorigin objectが正しくても、古いedge objectが違えば、両者は別々の事実である。

IANA HTTP Parameters registry は zstd を8 MB以下の Window_Size を持つZstandard byte streamとして記述する。registryはtokenの公的意味を守るが、cache objectを検査しない。意味の登録とbytesの適合は、権限の異なる二つの層である。

実効budgetを測る

decoder libraryが8 MBに対応していても、callerはより小さいlimitを設けられる。memory pressure、container制限、並行処理、timeoutによってallocationが失敗することもある。decode完了後にparserが拒否する場合もある。「対応」はlibrary version、process設定、request時点、observed resultまで限定して述べるべきだ。

受信側の証拠には、user agentまたはlibrary version、実効limit、観測window、decode result、分類されたerrorが必要である。oversized window、truncation、corruption、unknown coding、allocation failure、dictionary mismatch、application rejectionを同じ失敗にまとめてはならない。

RFC 9659は、非準拠のoversized frameが到着し、decoderが失敗し得ることも明記する。8 MB対応は無制限memoryの約束ではない。境界外を拒否することと、境界内を処理できないことは、運用上まったく違う。

dcz の境界を混ぜない

RFC 9842 はCompression Dictionary Transportと dcz codingを定義する。そのZstandard利用ではdictionary sizeに応じたwindowを扱い、最大128 MBまでの別契約が存在する。これは通常の zstd に対するRFC 9659の8 MB線を変更しない。

同じlibraryが両方を実装すると、管理画面の一つのwindow設定が意味の違いを隠しやすい。証拠にはcoding token、dictionary identity、frame contextが必要である。code reuseは可能でも、protocol contractまで同一にはならない。

receipt chainの作り方

producerではencoder binary、version、effective configuration、coding、object hash、frame headerを保存する。intermediaryではpass-through、decode、recompress、replaceの判断を保存する。cacheではvariant key、generation、freshness、purge historyを保存する。recipientではversion、effective budget、window、decode result、errorを保存する。applicationではtransport完了から推測せず、acceptanceを記録する。

全件保存が難しくても、境界中心のsamplingはできる。大きなresponse、旧generation、複数edge、制約client、rollback、fallback、key変更を含める。8 MB超frame、説明のないhash差、cap変更後の旧object、negotiation数とapplication完了数の乖離を監視する。

Heng LuのMinimum Initial Specification は、共同線を8 MBと明確なfailure semanticsに絞り、その内側の実装自由を残す考え方を与える。Reality Layers は zstd labelをdecode resultと同一視させない。Running-Code Primacy は実際のframeと実行processに最終的な証拠権限を戻す。

RFC 9659が保証するのは共有可能な境界である。その境界を越えずに結果まで届いたことは、各実行のreceiptで示すしかない。

Sources