要約

  • RFC 9651が確認するのは、受信した値を宣言済みのHTTP構造として解釈できることまでである。
  • 意味の確定、保護された文脈、主体の認可、状態変更は、それぞれ別の規則と証拠によって判断されなければならない。

自動化されたHTTP処理で、最も誤解されやすい成功は解析成功である。ライブラリがDictionaryやListを返すと、その値は急に「理解済み」で「使ってよい」ものに見える。だが、解析器が知っているのは文字列の構造だけだ。誰が書いたのか、その人に書く資格があったのか、この要求の対象で意味を持つのか、その値に従って状態を変えてよいのかは、解析結果の外にある。

RFC 9651は、HTTPフィールドのために再利用可能な抽象データ型と、そのための具体的な表現を定める。新しいフィールドの設計者は、各自で似たような記法を作る代わりに、Item、List、Dictionaryのいずれかを選び、共通の解析・直列化規則を使える。これは相互運用性にとって大きな利点である。同じ受信値が、慎重に実装された別のシステムでも同じ形として読まれやすくなるからだ。

しかし形は意味ではない。RFC 9651は、新しいStructured Fieldを定義する者に、型を指定するだけでなく、値の意味、追加の制約、制約違反時の扱いを定義するよう求める。汎用の解析器には、あるキーが診断情報なのか、優先度なのか、能力の主張なのか、あるいは無視すべき拡張なのかを知る方法がない。共通なのは文法であり、作用を決める規則はそのフィールド固有である。

解析が成功した値からは、限定された事実しか導けない。その値は宣言された文法のもとで読めた。そこから発信者の同一性は出てこない。途中のコンポーネントが値を追加・削除・置換していないことも分からない。発信者がその主張をする権限、リクエスト主体がそれを利用する権限、アプリケーションが実際に変更をコミットした事実も、そこには含まれない。

RFC 9651の厳格な処理は、その限界を弱くするのではなく、むしろ見えるようにする。不適合な入力は、受信側が都合よく修正するのではなく、解析全体を失敗させる。これにより実装ごとの勝手な寛容さが相互運用性を壊すことを避ける。ただし、解析失敗は意図や虚偽の判断ではない。一つのフィールドに複数の構成要素が値を追加している場合、どこか一つの不整合で全体が解析不能になることもある。失敗が何を意味するかは、なお別に調べる必要がある。

次に必要なのはフィールド固有の解釈である。IANAのHTTP Field Name RegistryにあるStructured Typeは、そのフィールドがDictionary、List、Itemのどれかを示すにすぎない。それは意味の目録でも、権限の目録でもない。利用者は当該フィールドの仕様に戻り、どのメンバーが許されるか、どの範囲に適用されるか、違反時に無視・拒否・保留のどれを行うかを確認しなければならない。構文として正しいDictionaryでも、このendpointでは何の効力も持たない場合がある。

さらに、文脈の保護が要る。RFC 9651は、新しいHTTPフィールドを注入できる当事者がStructured Fieldの意味を変えられること、しかも解析失敗だけでは常にそれを検出できないことを述べる。敵対的な変更に耐える必要があるなら、保護は明示的に選ぶ必要がある。TLSは接続の性質を保護し、署名は選んだコンポーネントを保護できる。RFC 9421が重要なのは、何を署名対象にしたかを明示し、検証要件を別途持たせる点にある。解析されたオブジェクトが、それだけで署名済みになることはない。

最後に、実行するendpointが局所的な判断を下す。解釈済みの値を、認証された主体、対象資源、現在の状態、適用中の方針と結び付ける場面である。フィールドが存在しても命令とは限らない。命令として読めても、この対象に適用できるとは限らない。適用できても認可されるとは限らない。認可されても、競合や前提条件によってコミットされないことがある。これらを「ヘッダーは有効だった」という一文に畳み込めば、説明すべき違いが失われる。

RFC 8941からRFC 9651への更新は、もう一つの注意点を示す。新しい解析器は、古い実装では不正とされた形式を読めるようになるかもしれない。しかしそのことは、古いフィールド定義が新しい型や拡張を受け入れることを意味しない。読み取れる表現の範囲が増えても、送信者が従わせられる範囲は増えない。

卢恒のRunning-Code Primacyをここで使うなら、技術的な節度として使うべきだ。表示された構造と、現実に実行される効果は別の層にある。共通形式は曖昧さを減らせるが、実行するローカルな判断の代わりにはならない。

情報源