要約

  • RFC 2774では、必須拡張を伴う要求のGETM-GETPUTM-PUTになった。仕組みを知らないサーバーに未知のメソッドとして拒否させ、条件を捨てたまま基本操作を成功させないためだった。
  • 対応する受信者は、拡張方針を満たせなければ510を返し、すべてを理解して従った場合はExtまたはC-Extで履行を示した。この実験は後にHistoricとなり、状態コードと関連フィールドは廃止扱いになった。

正常終了に見える意味の欠落

あるクライアントが文書をPUTし、その処理に追加の規則を必須としたとする。新しいサーバーは宣言を読み、規則を適用して保存する。古いサーバーはPUTだけを理解し、未知のフィールドを無視して同じバイト列を保存し、200 OKを返す。

ネットワーク上の結果は似ている。しかし送信者にとっては別の操作だ。未知の情報を寛容に読み飛ばすという通常の互換性戦略が、必須条件に適用されると、理解していない相手に「完了」と言わせてしまう。

2000年2月にExperimentalとして公表されたRFC 2774は、この曖昧さを断とうとした。必須拡張のある要求では、通常のメソッド名にM-を付ける。フレームワークを知らない実装はM-PUTを未知のメソッドとして扱うため、縮小されたPUTを誤って実行できない。

非互換性を防護壁にする

対応サーバーも、単にM-を外すだけでは済まない。まずエンドツーエンドとホップ単位の必須宣言をすべて特定し、そのメッセージで各拡張を扱えるか判断する。ひとつでも満たせなければ510 Not Extendedを返す。すべてに対応できる場合だけ、拡張と基礎メソッドの意味に従って処理する。

仕様は、すべての必須宣言を理解し遵守せずに要求を履行したと主張することを禁じた。後方互換性より明示的な失敗を選んだのである。副作用が起きる前に、相手の無理解を観測できるようにした。

必須性と作用範囲の二つの軸

宣言には二つの区分があった。必須か任意か、そして最終受信者向けか次の接続相手向けかである。組み合わせからManOptC-ManC-Optの四フィールドが生まれた。

この区分は権限を割り当てる。プロキシがエンドツーエンド宣言を読めても、それを消費する権利はない。ホップ単位の宣言は当該接続だけで意味を持ち、HTTP/1.1では関連するデータとともにConnectionで保護し、先へ誤転送されないようにする。

拡張はグローバルに一意なURIで識別された。条件を満たす標準フィールド名も識別子になり得た。宣言は16のような数字の接頭辞を割り当て、16-...というフィールド群をその拡張インスタンス専用にできた。名前衝突を避けつつ、ひとつの拡張がフィールド空間全体を占有しない設計だった。

510が表した不足

510は一般的なサーバー障害ではない。RFC 2774の第7節では、資源へのアクセス方針が満たされていない状態とされた。応答には、受け入れ可能な拡張要求を作るために必要な情報を示すことが推奨された。

不足する拡張をクライアントが用意できれば、要求を修正して再試行できる。できなければ、応答本体を診断として利用する。必須宣言が一つもないのにM-メソッドを送る場合も510になる。「必須である」と言いながら、何が必須か示していないからだ。

このコードは、HTTP自体の理解と、その資源が要求する拡張契約の成立を分けた。資源が存在し、通常メソッドが有効でも、追加の意味が欠ければ操作は成立しない。

成功にも専用の証拠が要る

失敗だけを定義しても、普通の成功と拡張を履行した成功は区別できない。そこでExtはエンドツーエンドの必須宣言すべてを満たしたことを、C-Extはホップ単位の宣言を満たしたことを示した。これらはアプリケーション情報を運ばず、確認だけを担った。

もちろん、拡張の安全性や業務結果の正しさを保証するものではない。それでも「基礎メソッドだけが動いた」のではないという限定的な証拠にはなった。

プロキシとキャッシュに広がる負担

意味は経路の各所で失われ得る。エンドツーエンド宣言は、内容を知らないプロキシを越える必要がある。ホップ宣言は正しい接続で止まらなければならない。キャッシュは、拡張付き要求から得た応答を拡張なしの要求に再利用してはならない。

RFC 2774は、エンドツーエンドの必須要求を履行した応答にCache-Control: no-cache="Ext"を使った。HTTP/1.0プロキシへの対策として、既に期限切れのExpiresも指定した。数字接頭辞付きフィールドによって応答が変わる場合、Varyにはそのフィールドと宣言フィールドの双方を含める必要があった。

細則には理由がある。宣言とデータが分離し、誤った相手に届き、別の要求へ再生される経路を閉じるためだ。同時に、クライアント、オリジン、複数世代のプロキシとキャッシュを一つの汎用枠組みで調整する重さも表れている。

Historicになった実験

出発時のIESG注記から慎重だった。文書はProposed Standardを求めていたが、Last CallとHTTP作業部会で評価が分かれ、HTTPの発展方向について合意が明確でなかったためExperimentalとなった。注記は、技術的欠陥を必ず意味するわけではなく、普遍的な拡張の設計図として扱うべきでもないと述べていた。

2021年、IETFはRFC 2774などのHTTP実験をHistoricへ移した。公式記録の理由は、実験が終了し、広範な利用を示す証拠がなかったことだ。IANAでは510がNot Extended (OBSOLETED)、六つの関連フィールドがobsoletedと記録されている。

この事実から、実装が皆無だったとも、単一の失敗原因があったとも断定できない。現在のHTTPで推奨される仕組みではない、というライフサイクル上の判断を示している。

残ったのは拡張点と登録制度

HTTPの拡張そのものは続いている。RFC 9110はメソッド、状態コード、フィールド名、認証方式、キャッシュ指令を恒久的な拡張点として挙げる。それぞれ明示的な登録簿と審査方針で意味と状態を管理し、RFC 2774の汎用宣言行列は使わない。

残る教訓は簡潔だ。新しい意味が任意か必須か、誰が解釈するのか、名前は衝突しないか、中間装置を越えるとき何が保存されるか、失敗と履行をどう証明するかを決めなければならない。

510は現役を退いた。しかし、配送の成功と意味の共有は同じではない。プロトコルで最も厄介な誤解は、何事もなかったように成功を返す誤解である。

出典