要約
- WebDAV binding は複数 URI を一つの資源へ結べる。対象がコレクションなら、別 binding から同じ子孫へ届き、祖先へ戻る循環も作り得る。
- binding を理解する
Depth: infinityPROPFIND では、一つの出現を 200 として展開する。後続経路は 208 Already Reported の response として残るが、その子孫をもう一度列挙しない。 DAV:resource-idが経路の下に安定した資源同一性を置く。クライアントは全 binding を保存しつつ、共有コレクションを一度だけ展開する。208 を理解しない相手には、説明不能な省略ではなく 508 による停止が必要になる。
二つの入口と一つの保管庫
同じ保管庫に東西二つの入口があれば、入口は二つとも建物の事実である。しかし中の棚が二組になるわけではない。
経路だけで再帰する目録係は、各入口から同じ棚を数える。通路が上位階へ戻れば、有限の建物から無限の経路名を作る。反対に、同じ部屋だと分かった瞬間に二つ目の入口を記録から消せば、探索は止まるが平面図が嘘になる。
208 は入口と内部展開を分離した。別経路は報告する。共有先の同一性を示す。そして既に済んだ子孫探索だけを繰り返さない。
省略対象は名前空間ではなく、作業である。
207 は既に内訳を読むよう要求していた
2007 年の RFC 4918 は、WebDAV コレクションの状態を、パスセグメントから資源への mapping とコレクション自身の property として定義する。メンバー名は資源そのものではなく、資源へ到達する関係である。
PROPFIND は Depth 0、1、infinity を使う。深さ無限なら全子孫を対象にし、応答は 207 Multi-Status の中に平らな DAV:response の集合として入る。各 href が経路を、各 propstat の内側の status が property の結果を示す。
外側の 207 は全項目の判決ではない。クライアントは本文の内訳を読む必要がある。この入れ子構造が、後に 208 を一つの binding 出現へ割り当てる場所になった。
基礎 WebDAV も一資源を複数 URI が識別し得ると認めていた。クライアントが既存資源への新経路を作る方法は binding 拡張が加えた。
BIND は複製ではなく関係を作った
2010 年 4 月の RFC 5842 は Experimental RFC であり、BIND、UNBIND、REBIND を定める。BIND はコレクション内のパスセグメントを既存資源へ関連付け、新しい URI から同じ対象へ要求を送れるようにする。
新しいのは binding であり、資源ではない。別々の親コレクションが同じ資源を指すなら、それぞれ独立した binding state を持つ。
Binding integrity により、一つの binding を除いても他の binding を壊してはならず、別経路が残るうちに資源を回収してはならない。関係は明示的な削除・変更操作まで存在し、同じ対象を指し続ける。
別名は表示上の重複ではない。管理可能だが、他の経路を支配しない辺である。
コレクションへの別名は子孫 URI も増やした
葉資源への binding は新しい URI を一つ加える。コレクションへの binding は、その内部 binding を複製せずに、子孫を新しい接頭辞から到達可能にする。
そのため資源数が一定でも URI mapping 数は増える。自分自身または祖先へ binding すれば、同じセグメントを何度も繰り返す無限の URI 列が生じ得る。
RFC 5842 は Depth: infinity 処理時の collection bind loop 検出を必須にする。サーバーは循環を作る要求自体を拒否してもよい。循環対応は任意だが、受け入れた後の検出は省略できない。
無限なのは格納物ではない。経路を対象と誤認した再帰の結果である。
resource-id は経路より長く残った
URI の違いだけでは対象の違いを証明できない。内容一致も同一性の証明にならない。二つの独立資源が同じ内容を持つことはある。
RFC 5842 は必須の DAV:resource-id を導入する。資源作成時に割り当て、全資源で永久に一意であり、既存資源の更新や REBIND で変えてはならず、どの URI からも到達不能になった後も再利用できない。
別 binding から得た値が文字単位で同一なら、クライアントは二経路が同一資源へ達すると確認できる。この ID は canonical URI ではなく、URI が増減しても残る対象証拠である。
PROPFIND でこの property を要求すれば、どの経路が共有ノードへ入るのかを復元できる。
辺の台帳と展開の台帳
忠実な探索には二つの visited が要る。一つは binding edge を記録するため、もう一つはどの collection identity の子孫を本応答で既に展開したかを記録するためである。
URI だけで管理すると全辺は残るが、同一ノードを何度も開く。resource-id だけで早期に統合すると循環は止まるが、二つ目の正当な辺が消える。
まず href と親子関係を保存し、その後で対象 ID の展開済み状態を調べる。重複排除は辺ではなく再帰作業に作用しなければならない。
208 は二台帳を結ぶ記録である。この経路は存在するが、その先のコレクションは既に別経路から列挙済みだと伝える。
208 は後続 binding を消さなかった
仕様上、208 は Depth: infinity のとき DAV:propstat 内で使える。同一コレクションへの複数 binding のうち、一つは 200 として報告される。後続 binding の DAV:response は 208 を持ち、その子孫 response は含めない。
重要なのは後続 response 自体が残ることだ。href が別経路を示し、resource-id が先の 200 出現と同一ノードであることを証明する。
RFC の例では /Coll/ と /Coll/Bar が同じ ID を返す。前者でメンバーを展開し、後者は 208 になる。さらに /Coll/Bar/Bar を作らない。
Already Reported はこの Multi-Status 内の展開履歴を指す。URI の価値や存続を否定しない。
最初の 200 は正統経路を決めない
有限な応答には展開担当の一出現が必要だ。しかし、その 200 経路が原本、所有者、永久 canonical になるとは RFC は述べない。
各 binding は親コレクションの独立した状態であり、異なるナビゲーション、権限、監査文脈を持ち得る。208 経路を「重複」として捨てれば、UNBIND を資源削除と誤認したり、一つの親に他の辺まで支配させたりする。
本応答で先に歩いたことと、名前空間上の権限は別である。
木へ戻すために中心経路を発明してはならない。
208 の外側には 207 があった
要求レベルの応答は通常 207 Multi-Status で、208 は本文中の特定 property result に現れる。
従って 208 は「HTTP 要求そのものが重複した」でも「応答全体を以前送った」でもない。一つの collection binding の子孫が本応答中の別 occurrence で既に報告された、という内訳である。
外側は複数結果を読むよう指示し、href は経路を、resource-id は対象を、200/208 は展開位置を示す。
これを成功真偽値一つに変換する中継層は、状態コードを運んでもグラフ証拠を失う。
省略には能力宣言が必要だった
子孫の不在は、既報か欠落か、意味を知らなければ区別できない。そこで binding 対応サーバーは OPTIONS の DAV 応答ヘッダーで bind compliance class を示す。クライアントも DAV: bind を送り、特に 208 を理解する必要がある。
後方互換性のため、クライアントが対応を示さない限り、Multi-Status 本文で 208 を使うべきではない。古い実装は未知 status を失敗と解釈したり、子のない collection と誤認したりする。
省略はサーバーだけの圧縮判断ではない。受信側が、何を省き、どこで既報となり、どの ID で接続するかを理解する共有契約である。
508 は継続不能を表した
binding 非対応クライアントの depth-infinity 探索が循環に出会う場合、仕様は未知の 208 より 508 Loop Detected を選ぶ。送信開始前に分かれば top-level 508、Multi-Status の streaming 中に分かれば内訳での失敗表現が可能になる。
208 なら、対応クライアントは別経路を保持し、重複子孫だけを止め、残りの探索を続けられる。508 は無限ループのため操作を終了し、全体が失敗したことを示す。
両者は成功と失敗の程度差ではない。参照を理解して継続できるか、理解不能なので停止するかの差である。
曖昧な部分成功より明示的失敗の方が互換性を守る場合がある。
binding は攻撃面も増やした
BIND により、クライアントは偶然または悪意で loop を作りやすくなる。深い探索時の検出は必須だが、208 だけで全資源消費を防げるわけではない。
RFC 5842 は cross-server binding による負荷誘導、DAV:parent-set による私的場所の露出、他管理領域から増やされる親一覧の維持コストを指摘する。
208 が抑えるのは一応答内の重複列挙である。CPU、メモリ、ノード、応答サイズの予算や binding 作成権限は別に必要だ。有限グラフも巨大になり得る。
一つの増幅経路を閉じる状態を、完全な安全政策へ膨らませてはならない。
同一資源でも全 property が経路非依存とは限らない
同じ resource-id は対象同一性を示すが、すべての観測値が同じとは限らない。dead property は binding 数や提出経路から独立する一方、live property は個別定義に従い、経路文脈を持つものもある。
ID だけですべてを統合すれば文脈を失う。値が違うたびに別資源とすれば同一性を失う。
資源の事実、binding の事実、経路依存観測を別レイヤーとして保存する必要がある。208 が共有 ID を使うのは展開判断の範囲だけであり、他レイヤーを消す権限ではない。
最小共通層は、証拠が支えられる以上の権力を持たないとき強い。
IANA の登録も意味を一般化しない
現在の IANA HTTP Status Code Registry は 208 Already Reported を RFC 5842 に結び付ける。同じ Experimental RFC が 508 を定義し、207 は RFC 4918 を参照する。
登録は RFC 5842 を Internet Standard にせず、現在の普及率も証明しない。208 はデータベース重複、冪等性、cache hit の汎用コードでもない。
意味は binding-aware な WebDAV、Depth infinity、Multi-Status という狭い組合せから生まれる。
用途の狭さが「既に」という語を過剰な省略許可から守る。
全経路を残し、展開は一度
HTTP 208 はグラフを木に偽装しなかった。経路と対象を別に保ち、作業だけを有限にした。
Binding は実在するので全部報告する。資源は一 URI に属さないので安定 ID を持つ。同一 collection の子孫は再列挙しても構造が増えないので一度だけ展開する。省略には理由が必要なので 208 を置く。
一つの経路が中心権力にならず、alias が copy にならず、cycle が無限資源を作らない。
二つ目の入口は目録に残る。その先の棚をもう一度数える必要はない。
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
