11 アクセス認証 HTTP は、サーバがクライアントにリクエストを誰何{challenge} するため、 あるいはクライアントが認証情報を提供するために使用する事ができる、い くつかの *オプショナル* な誰何-応答{challenge-response} 認証メカニズ ムを提供する。アクセス認証の全体の枠組、そして "基本" 及び "ダイジェ スト" 認証の仕様については、"HTTP Authentication: Basic and Digest Access Authentication" [43] にて記述されている。この仕様書では、その 仕様書にある "challenge" と "credentials" の定義を採用する。 12 コンテントネゴシエーション 多くの HTTP レスポンスは、人間ユーザによって解釈される情報から成るエ ンティティを含む。当然、リクエストに対応した "最も利用できる" エンテ ィティをユーザに供給するのが望ましい。サーバやキャッシュにとって不幸 な事は、すべてのユーザが "最上" なものについて同じ優先度を持たせてい るわけではないし、すべてのユーザエージェントがすべてのエンティティタ イプを等しく表現できるわけではないという事である。この理由により、 HTTP は "コンテントネゴシエーション"、すなわち複数の利用可能な表現が ある時に与えられたレスポンスにとって最上の表現を選択するための処理の ためのいくつかのメカニズムを持っている。 注意: これは、ある別の表現として、メディアタイプは同じであるが使用 言語が異っている等、そのタイプとは異なる能力{capabilities} を使用 するかもしれないので、"フォーマットネゴシエーション" とは呼ばれな い。 エンティティボディを含むあらゆるレスポンスは、エラーレスポンスを含め ネゴシエーションを受けさせる事が *できる*。 HTTP で可能なコンテントネゴシエーションには二種類ある。サーバ駆動型ネ ゴシエーションとエージェント駆動型ネゴシエーションである。これら二つ のネゴシエーションは直交{orthogonal} し、故に別々にあるいは組み合わせ て使う事ができる。一つの組み合わせ方として、透過的ネゴシエーションと 呼ばれる方法は、キャッシュが以降のリクエストに対してサーバ駆動型ネゴ シエーションを提供するためにオリジンサーバによって供給されるエージェ ント駆動型ネゴシエーション情報を使用する時に発生する。 12.1 サーバ駆動型ネゴシエーション レスポンスとしての最適な表現の選択がサーバに設けられたアルゴリズムに よって行われた場合、これはサーバ駆動型ネゴシエーションと呼ばれる。選 択は、利用可能なレスポンスの表現 (それが変化できる次元、例えば言語や 内容コーディング等) や、リクエストメッセージ内の特定のヘッダフィール ドの内容、あるいはそのリクエストに関するその他の情報 (例えばクライア ントのネットワークアドレス) に基づく。 サーバ駆動型ネゴシエーションは、利用可能な表現の中から選択するための アルゴリズムがユーザエージェントに説明するのが難しい時や、サーバが最 初のレスポンスと一緒にクライアントに自身の "最適な推測" を送る事を望 む (もしその "最適な推測" がユーザにとって十分なものであれば、以降の リクエストの round-trip delay を避けられる) 時に有益である。サーバの 推測を改善するため、ユーザエージェントはそのようなレスポンスのための 自身の優先度を表すリクエストヘッダフィールド (Accept, Acctpt-Length, Accept-Encoding 等) を含む事が *できる*。 サーバ駆動型ネゴシエーションは以下の不都合を持つ。 1. ユーザエージェントの能力とレスポンスの使用目的 (例えば、ユーザ はそれをスクリーンに表示させたいのか、それとも紙に印刷したいの か?) の両方の完全な情報が必要なので、サーバがそのユーザにとっ て "最適" であるものをすべて正確に決定するのは不可能である。 2. リクエスト毎にユーザエージェントに自身の能力を記述させる事は、 非常に能率が悪く (レスポンスが複数の表現を持っている確率は少な いため)、ユーザのプライバシーの潜在的な侵害となりうる。 3. リクエストに対してレスポンスを生成するため、オリジンサーバのイ ンプリメンテーションとそのアルゴリズムが複雑になってしまう。 4. 複数のユーザのリクエストに同じレスポンスを使う共有キャッシュの 能力を制限するかもしれない。 HTTP/1.1 は、ユーザエージェントの能力とユーザの設定の記述を通してサー バ駆動型ネゴシエーションを可能にするための、以下のリクエストヘッダフ ィールドを含んでいる。すなわち、Accept (section 14.1), Accept-Charset (section 14.2), Accept-Encoding (section 14.3), Accept-Length (section 14.4), User-Agent (section 14.43) である。しかしながら、オリ ジンサーバはそれらの次元に限定されないし、リクエストヘッダフィールド の外部やこの仕様書にて定義されていない拡張ヘッダフィールド内部の情報 を含めた、リクエストのあらゆる面に基づいてレスポンスを変える事が *で きる*。 Vary ヘッダフィールドは、サーバがサーバ駆動型ネゴシエーションを受ける 表現を選択するために使うパラメータを表すために使う事ができる。キャッ シュによる Vary ヘッダフィールドの使用については section 13.6 を、サ ーバによる Vary ヘッダフィールドの使用については section 14.44 を、そ れぞれ参照の事。 12.2 エージェント駆動型ネゴシエーション エージェント駆動型ネゴシエーションの場合、レスポンスとしての最適な表 現の選択は、オリジンサーバからの最初のレスポンスを受けとった後にユー ザエージェントによって実行される。選択は、最初のレスポンスのヘッダフ ィールドやエンティティボディに含まれる利用可能なレスポンスの表現のリ ストに基づき、それぞれの表現毎に自身の URI によって識別される。表現内 からの選択は、 (ユーザエージェントがそうする能力があれば) 自動的に、 あるいは生成された (おそらくハイパーテキストの) メニューからのユーザ の選択によって手動的に行われるだろう。 エージェント駆動型ネゴシエーションは、レスポンスが一般的に使われる次 元{commonly-used dimensions} (例えばタイプ、言語、エンコーディング のような) と異なる時、オリジンサーバがリクエストの評価からはユーザエ ジェントの能力を決定できない時、そして一般的に共有キャッシュがサーバ の負荷を分散し、ネットワークの使用を減らすために使用される時に有益で ある。 エージェント駆動型ネゴシエーションは、最適な入れ替わるべき表現を得る ために次のリクエストが必要となるという不都合がある。次のリクエストは キャッシングが使用されている時にのみ効率的である。さらに、この仕様書 では自動選択をサポートするどんなメカニズムも拡張として改良したり、 HTTP/1.1 内で使用したりする事を禁止しないが、そのいかなるメカニズムも 定義しない。 HTTP/1.1 は、サーバがサーバ駆動型ネゴシエーションで使って異なるレスポ ンスを供給しようとしない、あるいはできない時にエージェント駆動型ネゴ シエーションを可能にするため、300 (Multiple Choices) と 406 (Not Acceptable) ステータスコードを定義する。 12.3 透過的ネゴシエーション 透過的ネゴシエーションは、サーバ駆動型ネゴシエーションとエージェント 駆動型ネゴシエーションの両方の組み合わせである。キャッシュが (エージ ェント駆動型ネゴシエーションの中で) レスポンスとして利用可能な表現の リストのフォームを供給され、その違いの次元をキャッシュが完全に理解で きた時、キャッシュはそのリソースへの以降のリクエストのためにオリジン サーバに代わってサーバ駆動型ネゴシエーションを実行できるようになる。 透過的ネゴシエーションは、他の方法でオリジンサーバに要求されるネゴシ エーション作業の分散と、キャッシュが正しいレスポンスを正しく推測する 事ができる時にエージェント駆動型ネゴシエーションの次のリクエストによ る遅れを無くするという利点を持つ。 この仕様書では、透過的ネゴシエーションのためのどんなメカニズムも拡張 として改良したり、HTTP/1.1 内で使用したりする事を禁止しないが、そのい かなるメカニズムも定義しない。 13 HTTP におけるキャッシング HTTP は基本的に情報配布システムとして使われるが、そのパフォーマンスは レスポンスキャッシュの使用によって改善する事ができる。HTTP/1.1 プロト コルは、できるだけキャッシング作業を行おうとするためのいくつかの要素 を含む。これらの要素はプロトコルの別の側面からは解決できず、それらが 相互に作用するため、メソッド、ヘッダ、レスポンスコードなどの詳細な記 述とは別に HTTP の基本的なキャッシングデザインを記述する事は有用であ る。 もし十分にパフォーマンスを高めなければ、キャッシングは役に立たないで あろう。HTTP/1.1 におけるキャッシングが目指すものは、多くの場合でリク エストを送る必要を無くし、また別の多くの場合において全レスポンスを送 る必要を無くす事である。前者は、多くの操作に対して必要とされるネット ワークラウンドトリップ{round-trip} をいくらか減らす。我々は、この目的 のため "期限" メカニズムを使用する (section 13.2 参照)。後者は、必要 なネットワークバンド幅を減らす。我々は、この目的のため "検証" メカニ ズムを使用する (section 13.3 参照)。 パフォーマンス、有用性、分離された操作のための要求は、我々に意味的透 過性の目標点を緩める{relax} 事ができるように要求する。HTTP/1.1 プロト コルによって、オリジンサーバ、キャッシュ、クライアントは必要な時に透 過性を明白に減らす事ができる。しかしながら、非透過な操作は専門家以外 のユーザを混乱させるかもしれないし、ある (商品の注文用等の) サーバア プリケーションとは互換性が無いかもしれないので、プロトコルは以下の透 過性を緩める必要がある。 - クライアントやオリジンサーバによって緩められた時は、明示的なプロ トコルレベルのリクエストによってのみ - キャッシュやクライアントによって緩められた時は、エンドユーザに明 示的な警告を伴うもののみ それ故に、HTTP/1.1 プロトコルは以下の重要な要素を提供する。 1. それがすべてのパーティによって要求される時に完全なセマンティク スを供給するプロトコル機能。 2. オリジンサーバやユーザエージェントが明示的に非透過操作を要求で き、制御できるプロトコル機能。 3. キャッシュがリクエストされた意味的透過性の概略を保存しないレス ポンスに警告を付け加えられるプロトコル機能。 基本原理はクライアントが意味的透過性のあらゆる潜在的な緩和も検出可能 でなければならないという事である。 注意: サーバ、キャッシュもしくはクライアント実装者はこの仕様書にお いて明確に論議されないデザインの決定に直面するだろう。もし決定が意 味的透過性に影響するなら、注意深く完全な分析が透過性の破壊で重要な 恩恵を表す以外、実装者は透過性を維持する面からは離れた間違いを犯す はずである。 13.1.1 キャッシュの正当性 正当なキャッシュは、以下の状況の一つに合うリクエスト (section 13.2.5, 13.2.6, 13.12 参照) に適した、キャッシュが持っている最新のレスポンス をもってリクエストに答え *なければならない*。 1. オリジンサーバがレスポンスの再検証によってオリジンサーバで返さ れたものとの等価性が確認されている (section 13.3)。 2. "十分に新鮮" (section 13.2 参照) である。デフォルトの場合、これ はクライアント、オリジンサーバ、キャッシュの最低限の新鮮度要求 に合う事を意味する (section 14.9 参照)。オリジンサーバがそう指 定する場合、それはオリジンサーバ単独の新鮮度要求である。 保存されたレスポンスがクライアントとオリジンサーバの両方の最も 限定的な新鮮度要求から "十分に新鮮" で無い場合、そのようなレス ポンスが禁じられている (例えば "no-store" キャッシュ指示子や、 "no-cache" キャッシュリクエスト指示子等;section 14.9 参照) の で無ければ、深く考慮された環境ではキャッシュが適切な Warning ヘ ッダを伴ってそのレスポンスを返しても *よい*。 3. 適切な 304 (Not Modified), 305 (Proxy Redirect) かエラー (4xx か 5xx) レスポンスメッセージである。 キャッシュがオリジンサーバと通信できない時、レスポンスがキャッシュか ら正しく対応させる事ができるならば、正しいキャッシュは上記のものを返 す *べきであり*、そうでなければ通信失敗があった事を示すエラーか警告を 返さ *なければならない*。 キャッシュがリクエストしているクライアントに普通に転送するレスポンス (レスポンス全体か、304 (Not Modified) レスポンス) を受け取り、その受 け取ったレスポンスが既に新鮮で無い場合、キャッシュはそれに新しい Warning を追加する事無く (しかし存在するどんな Warning ヘッダも削除す る事も無く) リクエストしているクライアントに転送す *べきである*。レス ポンスは転送において新鮮で無くなったのかもしれないので、キャッシュは 簡単にそのレスポンスの再検証を試す *べきではない*。それによって無限ル ープを引き起こすかもしれない。Warning を伴わない新鮮で無いレスポンス を受け取ったユーザエージェントは、ユーザに示すための警告を表示する事 が *できる*。 13.1.2 Warnings キャッシュがファーストハンドでも無く、 (section 13.1.1 での二つの状態 の意味において) "十分に新鮮" でも無いレスポンスを返す時は、常に Warning 一般レスポンスヘッダを使って、その結果に警告を付加し *なけれ ばならない*。Warning ヘッダと現在定義されている警告は section 14.46 に記されている。この警告はクライアントが適切な動作を行えるようにす る。 警告は、キャッシュに関係するものと別のものの両方とも、他の目的で使用 する事が *できる*。エラーステータスコードではなく、警告を使う事によっ てこれらのレスポンスと真の失敗{true failures} とを区別する。 警告には、3 桁の warn-code が割り当てられる。最初の数字は、その警告が 再検証が成功した後に保存されているキャッシュエントリから削除し *なけ ればならない*、またはし *てはならない* かどうかを表している。 1xx の警告はレスポンスの新鮮度やステータスの再検証を表し、再検証が成 功した後に削除され *なければならない*。1XX warn-code は、キャッシュが キャッシュされたエントリを再検証した時にキャッシュによってのみ生成 *できる*。クライアントが生成し *てはならない*。 2xx の警告は、再検証によって改正されないエンティティボディやエンティ ティヘッダ (例えばエンティティボディの不可逆圧縮{lossy compression}) の点についてを表し、再検証が成功した後に削除し *てはならない*。 コード自体の定義については section 14.46 参照。 HTTP/1.0 キャッシュは、始めのカテゴリの一つを消す事無くすべての警告を レスポンスとしてキャッシュするだろう。HTTP/1.0 キャッシュを通したレス ポンスの警告は特別な warning-date フィールドを含んでおり、これで将来 の HTTP/1.1 受信者が謝ってキャッシュの警告を信じない様にする。 警告は警告テキストも含んでいる。このテキストは適切な (おそらくクライ アントの Accept ヘッダに基づいた) 自然言語で記され、どんな文字セット が使用されているかの *オプショナルな* 指示を含んでいる。 レスポンスには、同じコード番号の複数の警告を含む、複数の警告を (オリ ジンサーバかキャッシュによって) 付加する事が *できる*。例えば、サーバ は英語とバスク語の両方のテキストで同じ警告を供給できる。 複数の警告がレスポンスに付加されている時、ユーザにそれらすべてを表示 するのは実用的でも合理的でも無いかもしれない。HTTP のこのバージョンで はどの警告を表示するか、あるいはその優先順序を決定するための厳密な優 先ルールを記述しないが、いくつかの発見的教授方法を提案する。 13.1.3 キャッシュコントロールメカニズム HTTP/1.1 における基本的なキャッシュメカニズム (サーバに指定された期限 時刻とバリディタ) はキャッシュにとっての暗黙的命令である。いくつかの 場合で、サーバやクライアントは HTTP キャッシュに明示的指示を提供する 必要があるかもしれない。我々はこの目的のため Cache-Control ヘッダを使 用する。 Cache-Control ヘッダによって、クライアントやサーバはリクエストやレス ポンスにおける様々な指示が伝えられるようになる。これらの指示子は、典 型的にデフォルトのキャッシングアルゴリズムを無効にする。一般的なルー ルとして、もしヘッダ値の間に明らかな矛盾が存在するなら、最も限定的な 解釈が適用される (これは、セマンティクス等価性を維持するために最適な ものである)。しかしながら、いくつかの場合では、Cache-Control 指示子は セマンティクス等価性の概略を弱めるように明示的に詳述される (例えば "max-stale" や "public")。 Cache-Control 指示子は section 14.9 において詳細に記述されている。 13.1.4 明示的なユーザエージェントの警告 多くのユーザエージェントでは、ユーザが基本的なキャッシングメカニズム とは別の物を使えるようにさせている。例えば、ユーザエージェントはユー ザに (明らかに古くなっているものでさえ) キャッシュされたエンティティ は決して検証されないという事を指定できるようにするだろう。あるいは、 ユーザエージェントはリクエスト毎に "Cache-Control: max-stale=3600" を 習慣的に追加するかもしれない。ユーザエージェントは透過的で無い振る舞 いや、異常に効果の無いキャッシングを引き起こす振る舞いをデフォルトと す *べきではない* が、ユーザの明示的な動作によってはそうするように形 成する事ができる。 もしユーザが基本的なキャッシングメカニズムとは別の物を使うならば、ユ ーザエージェントは、それがサーバの透過的要求に合っていないという情報 の表示という結果になる時はいつでも (特に、表示されたエンティティが古 くなっていると分かっている場合は) ユーザに明示的に示す *べきである*。 プロトコルは、通常ユーザエージェントにレスポンスが古くなっているかど うかを決定できるようにさせているので、この指示はそれが実際に起こった 時にのみ表示される必要がある。この指示はダイアログボックスである必要 は無く、アイコン (例えば、腐った魚の絵) や別の表示機であってもよい。 もしユーザがキャッシュの有効性を異常に減少するであろう方法でキャッシ ングメカニズムを上書きしているなら、ユーザが不注意に余分なリソースを 消費したり過度の待ち時間に苦しまないようにユーザエージェントは続けて 現在の状態をユーザに (例えば、炎の中の通貨の絵を示す事で) 表示す *べ きである*。 13.1.5 規則と警告の例外 いくつかの場合、キャッシュのオペレータはクライアントによって要求され ない時に古くなったレスポンスを返すような設定を選ぶ事が *できる*。 この決定は気軽に行われるべきではないが、有用性やパフォーマンス上の理 由、特にキャッシュがオリジンサーバとの接続が不十分である時に必要であ ろう。キャッシュが古くなったレスポンスを返す時はいつでも、クライアン トソフトウェアがユーザに潜在的な問題があるかもしれないという事を警告 できるようにするために (Warning ヘッダを使って) そのように印付けてお か *なければならない*。 ユーザエージェントがファーストハンドあるいは新鮮なレスポンスを得ると いう処置を行う事もできる。この理由により、クライアントが明示的にファ ーストハンドあるいは新鮮なレスポンスを要求している場合、技術的もしく はポリシー上の理由のために応ずる事ができないというので無ければ、キャ ッシュは古くなったレスポンスを返す *べきではない*。 13.1.6 クライアントにコントロールされた振る舞い オリジンサーバ (とレスポンスの経過時間へ寄与するより小さな範囲の中間 キャッシュ) が期限切れについての情報のプライマリリソースである間、い くつかの場合クライアントはキャッシュされたレスポンスを再検証する事無 く返すかどうかについてのキャッシュの決定を制御する必要があるかもしれ ない。クライアントは、いくつかの Cache-Control ヘッダの指示子を使って これを行う。 クライアントのリクエストは、正当性が検証されていないレスポンスの受け 取りを意図して最大経過時間を指定する事が *できる*。ゼロの値の記述すれ ば、強制的にキャッシュにすべてのレスポンスの正当性を再検証させる。ま た、クライアントはレスポンスが期限切れになる前に残される最小時間を指 定する事も *できる*。これらオプションは両方とも、キャッシュの振る舞い の制約を増やすもので、キャッシュの意味的透過性の概略をそれ以上緩める 事はできない。 クライアントは古くなったレスポンスを受け入れる意図で、ある古さまでの 最大量を指定する事も *できる*。これはキャッシュの制約を緩め、オリジン サーバに記述された意味的透過性の制約に違反する事になるかもしれない が、非接続時の操作や貧弱な接続に直面した時の高い有用性をサポートする ために必要かもしれない。 13.2 期限{Expiration} モデル 13.2.1 サーバが指定した期限 HTTP キャッシングは、キャッシュがオリジンサーバにリクエストを送るとい う事を完全に避ける事ができる時に最善に動作する。リクエストを避けるた めの第一のメカニズムは、レスポンスが以降のリクエストを満足させるため に使用する事が *できる* という事を含め、オリジンサーバが将来において 明確な期限切れになる時間を提供する事である。言い換えれば、キャッシュ はサーバに先に接続する前に新鮮なレスポンスを返す事ができる。 我々が期待する事は、有効期限が切れる前にエンティティは意味的に重要な 方法では変更無いであろう、という確信を持って、サーバがレスポンスに将 来の明確な有効期限を割り当てているだろう事である。これは普通、サーバ が期限を注意深く選んでいる間は、意味的な透過性を維持する。 期限メカニズムは、キャッシュから取得したレスポンスのみに適用され、リ クエストしているクライアントに直ちに転送されたファーストハンドのレス ポンスには適用されない。 オリジンサーバがすべてのリクエストで強制的に意味的に透過なキャッシュ の検証を望む場合、過去における明示的有効期限を割り当てる事が *でき る*。これは、そのレスポンスは既に古いので、キャッシュは以降のリクエス トでそれを使用する前にその正当性を検証す *べきである* という事を意味 する。強制的な再検証のためのより限定的な方法については section 14.9.5 参照。 もしオリジンサーバがすべての HTTP/1.1 キャッシュを、それがどのように 設定されているかに関わらず、すべてのリクエストで強制的に検証させたい 場合、"must-revalidate" cache-control 指示子 (section 14.9 参照) を使 う *べきである*。 サーバは、Expires ヘッダか Cache-Control ヘッダの max-age 指示子のど ちらかを使って明示的有効期限を指定する。 有効期限は、表示の更新や、リソースのリロードをユーザエージェントに強 制するために使う事はできない。そのセマンティクスはキャッシングメカニ ズムにのみ適用され、そのようなメカニズムはそのリソースへの新しいリク エストが始められた時にそのリソースの期限ステータスのみをチェックする 必要がある。キャッシュと履歴メカニズムの違いについての説明は section 13.13 参照。 13.2.2 帰納的有効期限 オリジンサーバは明示的有効期限を常に提供するわけではないので、HTTP キ ャッシュは典型的に、本当の有効期限を見積もるために (Last-Modified の 時間のような) 別のヘッダ値を使うようなアルゴリズムを使って、帰納的有 効期限を割り当てる。HTTP/1.1 仕様書では詳細なアルゴリズムを提供しない が、その結果への最悪の場合の制約を課す。帰納的有効期限は意味的な透過 性を損なうかもしれないので、それらは慎重に使用されるべきであり、我々 はオリジンサーバが可能な限り明確な有効期限を提供するという事を推奨す る。 13.2.3 経過時間の計算 キャッシュエントリが新鮮かどうかを知るために、キャッシュは経過時間が その有効期間を超えているかどうかを知る必要がある。我々は、section 13.2.4 において後者、すなわち有効期限の計算方法についてを論議する。こ の章ではレスポンスやキャッシュエントリの経過時間の計算方法についてを 記述する。 この議論で、我々は "now" という用語を "計算が行われているホストの現在 の時刻" という意味で使用する。HTTP を使用する、特にオリジンサーバとキ ャッシュを実行しているホストは、それらの時計を世界的に正確な標準時刻 に同期させるため NTP [28] やそれと同じようなプロトコルを使用す *べき である*。 HTTP/1.1 では、オリジンサーバが可能であればすべてのレスポンスに、レス ポンスが生成された時間を与えた Date ヘッダを送る事を要求する (section 14.18 参照)。我々は "date_value" という用語を、演算のための適切な形式 において Date ヘッダの値を示すものとして使用する。 HTTP/1.1 では、レスポンスメッセージがキャッシュから得られた時にその経 過時間の見積もりを伝えるために Age レスポンスヘッダを使用する。Age フ ィールド値は、レスポンスがオリジンサーバによって生成、あるいは再検証 されてからのキャッシュの時間量の見積もりである。 本質的に、Age 値はオリジンサーバからの経路に沿ってあるそれぞれのキャ ッシュでレスポンスが存在する時間と、ネットワーク経路に沿う転送にかか った時間の合計である。 我々は "age_value" という用語を、演算のための適切な形式で Age ヘッダ の値を示すために使用する。 レスポンスの経過時間は二つの完全に独立した方法で計算する事ができる。 1. もしローカルの時計がオリジンサーバの時計と十分に同期しているな らば、now から date_value を引く。もしその結果が負になったら、 それをゼロに置き換える。 2. もしレスポンス経路上のすべてのキャッシュが HTTP/1.1 を実装して いれば、age_value である。 レスポンスを受け取った時にその経過時間を計算するために二つの独立した 方法を与える事で、我々はそれらを以下のように組み合わせる事ができる。 corrected_received_age = max(now - date_value, age_value) 我々は、ほとんど同期している時計か、あるいはすべてが HTTP/1.1 を実装 した経路のどちらかを持つならば、信頼できる (保守的な) 結果を得る。 ネットワークに課される遅れによって、サーバがレスポンスを生成してから 次のアウトバウンドのキャッシュやクライアントに受け取られるまでの間に 多少の重要な間隔が経過するかもしれない。もしこれが訂正されなければ、 この遅延は不適当に少ない経過時間をもたらす事になる。 返された Age 値をもたらしたリクエストはその Age 値の生成より前に開始 していなければならないので、リクエストを開始した時間を記録する事によ ってネットワークによって課された遅れを是正する事ができる。従って、Age 値が受信された時には、それはレスポンスが受信された時間に関してでは無 く、リクエストが開始された時間に関して解釈され *なければならない*。こ のアルゴリズムでは、どれくらいの遅延が発生したかに関わらず保守的な振 る舞いに帰着する。そのため、我々は以下のものを計算する。 corrected_initial_age = corrected_received_age + (now - request_time) ここで "request_time" は、このレスポンスを引き起こしたリクエストが送 信された時の (ローカルの時計による) 時間である。 キャッシュがレスポンスを受け取った時の経過時間の計算アルゴリズムの要 約は以下の通りである。 /* * age_value * このレスポンスを持つキャッシュが受け取った Age: ヘッダの値 * date_value * オリジンサーバの Date: ヘッダの値 * request_time * キャッシュがそのキャッシュされたレスポンスを生み出したリク * エストを作った (ローカルの) 時間 * response_time * キャッシュがレスポンスを受け取った (ローカルの) 時間 * now * 現在の (ローカルの) 時間 */ apparent_age = max(0, response_time - date_value); corrected_received_age = max(apparent_age, age_value); response_delay = response_time - request_time; corrected_initial_age = corrected_received_age + response_delay; resident_time = now - response_time; current_age = corrected_initial_age + resident_time; キャッシュエントリの current_age は、corrected_initial_age にキャッシ ュエントリがオリジンサーバによって最後に検証されてから (秒単位の) 時 間量が加えられる事によって計算される。レスポンスがキャッシュエントリ によって生成された時、キャッシュはキャッシュエントリの current_age と 等しい値をレスポンスに単一の Age ヘッダフィールドを含め *なければなら ない*。 レスポンスに Age ヘッダフィールドがあれば、レスポンスはファーストハン ドでは無いという事を暗黙的に意味する。しかし、リクエスト経路のすべて のキャッシュが HTTP/1.1 に従順で無ければ、レスポンスに Age ヘッダフィ ールドが無い事がレスポンスがファーストハンドである事を意味しないの で、逆は真ではない (古い HTTP キャッシュは Age ヘッダフィールドを実装 していないので)。 13.2.4 期限の計算 レスポンスが新鮮かどうかを決定するために、その有効期間と経過時間とを 比較する必要がある。経過時間は、section 13.2.3 にて表されているように 計算されるが、この章では有効期間の計算方法と、レスポンスの期限が切れ たかどうかの決定方法を記述する。以下の議論において、その値は演算に対 する適当な形式において表される。 我々は、"expires_value" という用語を Expires ヘッダの値を示すものとし て使用する。また、"max_age_value" という用語をレスポンス中の Cache- Control ヘッダの max-age 指示子 (section 14.9.3 参照) によって伝えら れた秒数の適切な値を示すものとして使用する。 max-age 指示子は Expires より優先されるので、もし max-age がレスポン ス中にあれば、その計算は簡単である。 freshness_lifetime = max_age_value そうで無い場合に、もし Expires がレスポンス中にあれば、その計算は次の 様になる。 freshness_lifetime = expires_value - date_value それらの情報のすべてがオリジンサーバからのものなので、どちらの計算も 時計のずれに影響は受けない事に注意せよ。 レスポンスに Expires, Cache-Control: max-age, Cache-Control: s-maxage (section 14.9.3 参照) のいずれも無く、レスポンスがキャッシングにおい て別の制限を受けていなければ、キャッシュは帰納的な方法を使って有効期 限を計算しても *よい*。キャッシュは、その経過時間が 24 時間を越えてい ながら Warning 113 の警告が付け加えられていないレスポンスがあれば、警 告を追加し *なければならない*。 また、もしレスポンスが Last-Modified 時間を持っていたら、帰納的有効期 限値は多くてもその時間からの間隔のある分数にす *べきである*。この分数 の典型的な設定値は 10% である。 レスポンスの期限が切れたかどうかを決定する計算は極めて単純である。 response_is_fresh = (freshness_lifetime > current_age) 13.2.5 期限値を曖昧にしない事 期限値が楽天的に割り当てられるために、二つのキャッシュが同じリソース に対して異なる新鮮度値を含む事が可能である。 もし回収を実行しているクライアントが自身のキャッシュにおいて既に新鮮 であるリクエストに対してファーストハンドで無いレスポンスを受け取り、 存在するキャッシュエントリの Date ヘッダが新しいレスポンスの Date ヘ ッダよりも新しければ、クライアントはそのレスポンスを無視する事が *で きる*。その場合、オリジンサーバに強制的にチェックするため、"Cache- Control: max-age=0" 指示子 (section 14.9 参照) を持ったリクエストを再 試行 *できる*。 もしキャッシュが同じ表現だが異なるバリディタを持つ二つの新鮮なレスポ ンスを持つなら、Date ヘッダが新しい方を使わ *なければならない*。この 状況は、キャッシュが別のキャッシュからのレスポンスを共有するため、あ るいはクライアントが明らかに新鮮なキャッシュエントリの再ロードや再検 証を要求したために生じるかもしれない。 13.2.6 複数のレスポンスを曖昧にしない事 クライアントは複数の経路からレスポンスを受け取る事ができるので、ある レスポンスがあるキャッシュのセットを通って流れ、別のレスポンスが別の キャッシュのセットを通って流れる場合、クライアントはオリジンサーバが レスポンスを送った時とは違う順番でレスポンスを受け取るかもしれない。 もし古いレスポンスがまだ明らかに新鮮であっても、クライアントは最も新 しく生成されたレスポンスを使うした方が良い。 後のレスポンスはより早い有効期限を故意に指定する事ができるので、エン ティティタグや期限値でレスポンスに順序付けを課す事はできない。Date 値 に秒の粒状性{granularity} を定めた。 クライアントがキャッシュエントリの再検証を試行し、受信したレスポンス が既存のエントリの Date ヘッダよりも古い Date ヘッダを含んでいる時、 クライアントはそのリクエストを無条件に繰り返す *べきであり*、そこに Cache-Control: max-age=0 を、あらゆる中間キャッシュにオリジンサーバへそれらのコピーの検証を強 制的に行わせるために含むか、あるいは Cache-Control: no-cache を、あらゆる中間キャッシュにオリジンサーバからの新しいコピーを強制的 に取得させるために含む *べきである*。 Date 値が等しい場合、クライアントはどちらのレスポンスでも使う事が *で きる* (あるいは極端に慎重になるでのあれば、新しいレスポンスを要求して も *よい*)。もし同じ秒の間に生成されたレスポンスの有効期限が重複して いたら、サーバはその選択の決定についてそれができるクライアントを当て にし *てはならない*。 13.3 検証{Validation} モデル キャッシュがクライアントのリクエストへのレスポンスとして使いたいよう な新鮮で無いエントリを持っている時、そのキャッシュされたエントリがま だ使用可能かどうかを確かめるために最初にオリジンサーバ (かあるいは新 鮮なレスポンスを持っている中間キャッシュ) へチェックしなければならな い。我々はこれをキャッシュエントリの "検証{validating}" と呼ぶ。もし キャッシュされたエントリで良ければ我々は完全なレスポンスの再転送によ るオーバーヘッドを望まないし、キャッシュされたエンティティが適切で無 ければ余分なラウンドトリップによるオーバーヘッドを望まないので、 HTTP/1.1 プロトコルは条件付きメソッドの使用をサポートしている。 条件付きメソッドをサポートするための重要なプロトコルの機能は、"キャッ シュバリディタ" に関するものである。オリジンサーバが全体のレスポンス を生成する時、それにある種のバリディタを付けられ、キャッシュエントリ と共に保存される。クライアント (ユーザエージェントやプロクシキャッシ ュ) がキャッシュエントリに持つリソースに条件付きリクエストを作る時、 リクエストに関するバリディタを追加する。 この時サーバはそのバリディタと現在のエンティティのバリディタを調べ、 もしそれらが一致すれば (section 13.3.3 参照) 、エンティティボディを含 まない特別なレスポンスコード (通常は 304 (Not Modified)) を返す。そう で無ければ、完全なレスポンス (エンティティボディを含む) を返す。従っ て、もしバリディタが一致すれば完全なレスポンスを転送する事は避けられ るし、一致しなければ余分なラウンドトリップを避けられる。 HTTP/1.1 において、条件付きリクエストは、暗にそのメソッド (通常 GET) を条件付きにする (バリディタを含んだ) 特別なヘッダを含む事を除けば、 同じリソースに対する通常のリクエストと全く同じに見える。 プロトコルは、キャッシュの検証条件の肯定的と否定的の両方の意図を持っ ている。つまり、バリディタが一致した時のみ、あるいはバリディタが一致 しなかった時のみ、のどちらかでメソッドが実行されるという事を要求する 事ができる。 注意: バリディタの無いレスポンスは、もしそれが Cache-Control 指示 子によって明示的に禁止されていなければ、その期限が切れるまでキャッ シュされ、また使用されるであろう。しかし、もしキャッシュがそのエン ティティのバリディタを持っていなければ条件付き回収を行う事ができな い。これはその期限が切れた後も再び新しくする事はできないだろうとい う事を意味する。 13.3.1 Last-modified の日付 Last-Modified エンティティヘッダフィールド値はしばしばキャッシュバリ ディタとして使われる。簡単な条件としては、もしエンティティが Last- Modified 値から更新されていなければキャッシュエントリは有効であるとみ なせる。 13.3.2 エンティティタグのキャッシュバリディタ ETag レスポンスヘッダフィールド値、すなわちエンティティタグは、"曖昧 なわかりにくい{opaque}" キャッシュバリディタを提供する。これによっ て、更新時刻を保存する事が不都合な状況、HTTP 日付値の秒単位の解析が十 分でない状況、オリジンサーバが更新時刻の使用から起こるであろうある種 の矛盾を避ける事を望む状況でより信頼できる検証ができるようになるだろ う。 エンティティタグは section 3.11 にて記述される。エンティティタグと共 に使われるヘッダは section 14.19, 14.24, 14.26, 14.44 にてそれぞれ記 述される。 13.3.3 弱いバリディタと強いバリディタ オリジンサーバやキャッシュの両方でそれが同じエンティティを表すかどう かを決定するために二つのバリディタを比較するため、通常はエンティティ (エンティティボディかエンティティヘッダ) が何らかの理由で変わっていた ら、それに関するバリディタも同様に変更しているだろうという事を期待で きる。これが真である場合、我々はこのバリディタを "強いバリディタ" と 呼ぶ。 しかしながら、サーバがエンティティの意味的に重要な変更時にのみバリデ ィタを変更し、重要でない側面にはバリディタを変更したがらない場合があ るかもしれない。リソースの変更時に常に変更されないバリディタは "弱い バリディタ" である。 エンティティタグは通常 "強いバリディタ" であるが、このプロトコルでは "弱い" エンティティタグを付けるためのメカニズムを提供している。強いバ リディタはエンティティが少しでも変更した時に変更されるもので、弱いバ リディタはエンティティの意味が変更した時に変更される、と考える事がで きる。または、強いバリディタは特定のエンティティの識別子{identifier} の一部であり、弱いバリディタは意味的に等しいエンティティのセットの識 別子の一部である、と考える事もできる。 注意: 強いバリディタの一例に、安定した記憶装置においてエンティティ が変更される毎に増加される整数がある。 エンティティの更新時間は、リソースを 1 秒以内に 2 度更新する事は可 能なので、もしそれが秒解像度に相当するなら弱いバリディタである。 弱いバリディタのサポートはオプションである。しかしながら、弱いバリ ディタによって同等のオブジェクトのより効率的なキャッシングができる ようになる。例えば、あるサイトのヒットカウンタが数日や数週毎に更新 されるのであればおそらくそれで十分に良く、その期間内のあらゆる値は 多分 "十分に良く{good enough}" 等しい。 バリディタの "使用" は、クライアントがリクエストを生成し検証用ヘッダ フィールドにバリディタを含む時、あるいはサーバが二つのバリディタを比 較する時のどちらかである。 強いバリディタはいかなる状況にも使う事ができる。弱いバリディタはエン ティティの正確な等価性に頼らない状況においてのみ使う事ができる。例え ば、完全なエンティティの条件付き GET のためにどちらかの種類を使う事が できる。しかし、別の方法ではクライアントが内部的に一致しないエンティ ティとなってしまうかもしれないので、サブレンジ回収のためには強いバリ ディタのみを使う事ができる。 クライアントは、単純な (非サブレンジ) GET リクエストの発行には弱いバ リディタも強いバリディタも使う事が *できる*。その他のリクエストの形式 には弱いバリディタを使っ *てはならない*。 HTTP/1.1 プロトコルがバリディタに定義している機能は比較のみである。二 つのバリディタ比較機能があり、これは比較状況が弱いバリディタの使用を 許すかどうかに依存する。 - 強い比較機能: 等しさを検討するため、両方のバリディタはあらゆる方 法で同一でなければならなく、両方のバリディタは共に弱くない。 - 弱い比較機能: 等しさを検討するため、両方のバリディタはあらゆる方 法で同一でなければならない。ただし、これらのどちらかもしくは両方 は結果に影響する事なく "弱い" とマークされている。 明確に弱いと印されていなければエンティティタグは強い。section 3.11 で はエンティティタグのための構文を与えている。 Last-Modified 時間がリクエストにおいてバリディタとして使用された時、 以下のルールを使ってそれが強いと推定できなければ暗黙的に弱い。 - そのバリディタがオリジンサーバによってエンティティに対する実際の 現在のバリディタと比較されており、 - オリジンサーバが関連するエンティティが与えられたバリディタが扱え る秒の間に二度変更していない事を確実に知っている。 あるいは - クライアントが関連するエンティティについてのキャッシュエントリを 持っているので、If-Modified-Since か If-Unmodified-Since ヘッダ 内でそのバリディタを使おうとしているところであり、 - そのキャッシュエントリが、オリジンサーバが元々のレスポンスを送っ た時の時刻を与える Date 値を含み、 - 与えられた Last-Modified 時刻は、その Date 値から最低 60 秒前で ある。 あるいは - そのバリディタが中間キャッシュによってエンティティに対する自身の キャッシュエントリに保存しているバリディタと比較され、 - そのキャッシュエントリが、オリジンサーバが元々のレスポンスを送っ た時の時刻を与える Date 値を含み、 - 与えられた Last-Modified 時刻は、その Date 値から最低 60 秒前で ある。 この方法は、二つの異なるレスポンスが同じ秒にオリジンサーバから送られ たが、両方とも同じ Last-Modified 時刻を持っていた場合に、それらのレス ポンスの少なくとも一つはその Last-Modified 時刻と同じ Date 値を持って いるであろうという事実を当てにしている。独断的な 60 秒制限は Date と Last-Modified 値が別の時計から、あるいはレスポンスの準備の間のわずか に異なる時間に生成されるという可能性について警戒する。もしインプリメ ンテーションが 60 秒はあまりに短いと思うのであれば、60 秒より大きな値 を使用しても *よい*。 もしクライアントが Last-Modified 時刻のみを持ち曖昧なバリディタを持た ない値のサブレンジ回収を行いたければ、Last-Modified 時刻がここで記述 された意図において強い場合のみこれを行う事が *できる*。 完全なボディの GET リクエスト以外の、条件付きリクエストを受信するキャ ッシュやオリジンサーバは、条件を評価するために強い比較機能を使わ *な ければならない*。 これらのルールによって、HTTP/1.1 キャッシュやクライアントは HTTP/1.0 サーバから得られた値のサブレンジ回収を安全に実行できるようになる。 13.3.4 エンティティタグや Last-Modified の日付を使う場合のルール 我々は様々なバリディタタイプがいつ、何の目的で使用されるべきかに関す るオリジンサーバ、クライアント、キャッシュのためのルールと推薦のセッ トを採用する。 HTTP/1.1 オリジンサーバについて - エンティティタグバリディタを生成する事が不可能で無いのであれば、 それを送る *べきである*。 - パフォーマンス考慮が弱いエンティティタグの使用を支持しているか、 強いエンティティタグを送る事を不可能であるならば、強いエンティテ ィタグの代わりに弱いエンティティタグを送る事が *できる*。 - Last-Modified 値を送る事が可能で、If-Modified-Since ヘッダ中にこ の日付の使う事から生じる、意味的な透過性における故障の危険が深刻 な問題を引き起さなければ、Last-Modified 値を送る *べきである*。 言い換えれば、HTTP/1.1 オリジンサーバにとってより望まれる動作とは強い エンティティタグと Last-Modified 値の両方を送る事である。 規格上適正であるため、強いエンティティタグは関連するエンティティ値に どんな点においての変化があっても変わら *なければならない*。弱いエンテ ィティタグは関連するエンティティタグが意味上で重要な点において変わる 時に変わる *べきである*。 注意: 意味的に透過なキャッシングを提供するため、オリジンサーバは二 つの異なるエンティティに対しての特定の強いエンティティタグ値の再使 用、あるいは二つの意味的に異なるエンティティに対しての特定の弱いエ ンティティタグ値の再使用を避けなければならない。キャッシュエントリ は有効期限に関係なく、任意に長期間持続するかもしれないので、キャッ シュが過去のある点で得られたバリディタを使ってエントリの検証を再び 試みる事は無いだろうと期待する事は不適当であろう。 HTTP/1.1 クライアントについて - エンティティタグがオリジンサーバによって提供されていたら、あらゆ るキャッシュ条件付きリクエスト内で (If-Match か If-None-Match を 使って) 内でこのエンティティタグを使わ *なければならない*。 - Last-Modified 値のみがオリジンサーバによって提供されていたら、非 サブレンジキャッシュ条件付きリクエスト内で (If-Modified-Since を 使って) この値を使う *べきである*。 - Last-Modified 値のみが HTTP/1.0 オリジンサーバによって提供されて いたら、サブレンジキャッシュ条件付きリクエスト (If-Unmodified- Since を使った) においてこの値を使う事が *できる*。これが難しい 場合、ユーザエージェントはこれを無効にする方法を提供す *べきであ る*。 - エンティティタグと Last-Modified 値の両方がオリジンサーバによっ て提供されていたら、キャッシュ条件付きリクエスト内で両方のバリデ ィタを使う *べきである*。これによって HTTP/1.0 と HTTP/1.1 キャ ッシュが適切に応答できるようになる。 Last-Modified 時刻 (例えば If-Modified-Since や If-Unmodified-Since 各ヘッダフィールド内で) と一つ以上のエンティティタグ (例えば If- Match, If-None-Match, If-Range 各ヘッダフィールド内で) をキャッシュバ リディタとして含む条件付きリクエストを受信した HTTP/1.1 オリジンサー バは、その行いがそのリクエスト内の条件付きヘッダフィールドのすべてに 一致しているのでなければ 304 (Not Modified) ステータスを返し *てはな らない*。 Last-Modified 時刻と一つ以上のエンティティタグをキャッシュバリディタ として含む条件付きリクエストを受信したHTTP/1.1 キャッシングプロクシ は、キャッシュされたレスポンスががそのリクエスト内の条件付きヘッダフ ィールドのすべてに一致しているのでなければクライアントに局地的にキャ ッシュされたレスポンスを返し *てはならない*。 注意: これらのルールの背景にある一般的な基本方針は、HTTP/1.1 サー バとクライアントがそれらのレスポンスやリクエストで利用可能であるよ うな同等に余分過ぎない情報の転送を行うべきであるという事である。こ の情報を受信する HTTP/1.1 システムは、それらが受信するバリディタに ついて最も保守的な仮定を行うだろう。 HTTP/1.0 クライアントやキャッシュは、エンティティタグを無視するだ ろう。一般的に、これらのシステムによって受信され、使われる Last- Modified 値は透過的で効果的なキャッシングをサポートするであろうか ら、HTTP/1.1 オリジンサーバは Last-Modified 値を提供すべきである。 HTTP/1.0 システムによってバリディタとして Last-Modified 値を使う事 が深刻な問題を引き起こすというようなまれな場合では、HTTP/1.1 オリ ジンサーバはこれを提供すべきではない。 13.3.5 非検証条件 エンティティタグの背景にある原理は、サービスの著者のみが適切なキャッ シュバリディタメカニズムを選択するのに十分なリソースのセマンティクス を知る事で、バイト等価性よりも複雑なあらゆるバリディタ比較機能につい ての仕様書は虫の缶{can of worms} を開ける事になるだろう。従って、その 他のヘッダの比較は (HTTP/1.0 互換性のための Last-Modified を除いて) キャッシュエントリの検証の目的では決して使用されない。 13.4 レスポンスのキャッシュ可能性 Cache-Control (section 14.9) 指示子によって特に強制されていなければ、 キャッシングシステムはキャッシュエントリとして成功したレスポンス (section 13.8 参照) を常に保存 *でき*、それが新鮮であれば検証無しにそ れを返す事が *でき*、検証の後にそれを返す事も *できる*。もしレスポン スに関連するキャッシュバリディタも明示的有効期限も無ければ、我々はそ れがキャッシュされる事を期待しないが、特定のキャッシュはこの期待に違 反する事が *できる* (例えば、ほとんどもしくは全くネットワーク接続が利 用できない時)。クライアントは、Date ヘッダと現在時刻を比較する事によ ってそのようなレスポンスがキャッシュから取得された事をたいてい検出 できる。 注意: HTTP/1.0 キャッシュの中には、どんな Warning も提供せずにこの 期待を違反する物がある事が知られている。 しかし、いくつかの場合でキャッシュがエンティティを保持し、あるいは以 降のリクエストのレスポンスとしてそれを返す事は不適切かもしれない。こ れは絶対的な意味的透過性がサービスの著者によって必要であると思われる ため、あるいはセキュリティやプライバシーへの配慮のためであろう。それ 故に、サーバがあるリソースエンティティ、あるいはその一部分について が、それらの考慮に関わらずキャッシュされないという事を示せるように特 定の Cache-Control 指示子が提供される。 section 14.8 では、そのリクエストが Authorization ヘッダを含んでいた ら、通常は共有されたキャッシュは以前のリクエストへのレスポンスを保存 したり返したりできないようにしている事に注意せよ。 200, 203, 206, 300, 301, 410 のステータスコードと共に受信されたレスポ ンスは、cache-control 指示子がキャッシングを禁止していなければ、キャ ッシュによって保存され、以降のリクエストへの応答に使用され、期限メカ ニズムに従う事が *できる*。しかし、Range と Content-Range ヘッダをサ ポートしていないキャッシュは 206 (Partial Content) レスポンスをキャッ シュし *てはならない*。 それ以外のステータスコード (例えば 302 や 307) と共に受信されたレスポ ンスは、明示的にそれを認める cache-control 指示子や別のヘッダが無けれ ば、以降のリクエストへの応答として返され *てはならない*。例えば、これ らは以下の物を含む: Expires ヘッダ (section 14.21); "max-age", "s- maxage", "must-revalidate", "proxy-revalidate", "public", "private" 各 cache-control 指示子 (section 14.9)。 13.5 キャッシュからの構築したレスポンス HTTP キャッシュの目的は、将来のリクエストへの応答での使用するためにリ クエストへのレスポンスで受信した情報を保存する事である。多くの場合、 キャッシュはリクエスト者へ単純にレスポンスの適切な部分を返す。しかし ながら、もしキャッシュが以前のレスポンスに基づくキャッシュエントリを 持っていたら、新しいレスポンスの部分とキャッシュエントリとして持って いるものとを結び付ける事ができる。 13.5.1 エンドトゥエンドヘッダとホップバイホップヘッダ キャッシュや非キャッシュプロクシの振る舞いを定義する目的のために、我 々は HTTP ヘッダを二つのカテゴリに分ける。 - エンドトゥエンドヘッダ。これはリクエストやレスポンスの最後の受信 者に転送されるものである。レスポンス中のエンドトゥエンドヘッダは キャッシュエントリの一部として保存され *なければならない* し、ま たキャッシュエントリから形成されたあらゆるレスポンスで転送され *なければならない*。 - ホップバイホップヘッダ。これは単一の転送レベル接続に対してのみ意 味を持ち、キャッシュによって保存されたりプロクシによって転送され たりしないものである。 以下の HTTP/1.1 ヘッダはホップバイホップヘッダである。 - Connection - Keep-Alive - Proxy-Authenticate - Proxy-Authorization - TE - Trailers (※) - Transfer-Encoding - Upgrade (※訳注) "Trailer" (section 14.40) の Typo と思われる。 HTTP/1.1 で定義されている他のすべてのヘッダはエンドトゥエンドヘッダで ある。 HTTP/1.1 (あるいはそれ以降) に導入されるその他のホップバイホップヘッ ダは、Connection ヘッダにおいて列挙され *なければならない* (section 14.10)。 13.5.2 修正できないヘッダ ダイジェスト認証のような、HTTP/1.1 プロトコルのいくつかの機能では、特 定のエンドトゥエンドヘッダの値に依存する。透過的プロクシは、そのヘッ ダの定義がそれを要求していたり、あるいはそれが特に許されている場合以 外は、エンドトゥエンドヘッダを修正す *べきではない*。 透過的プロクシはリクエストやレスポンス中の以下のフィールドのどれも修 正し *てはならない* し、それが存在していなければそれらを追加し *ては ならない*。 - Content-Location - Content-MD5 - ETag - Last-Modified 透過的プロクシはレスポンス中の以下のフィールドについては修正し *ては ならない*。 - Expires しかし、それが存在していなければそれらを追加する事が *できる*。 Expires ヘッダが追加された場合、その field-value にはそのレスポンス中 の Date ヘッダと同じ値が与えられ *なければならない*。 プロクシは、no-transform cache-control 指示子を含んでいるメッセージ、 あるいはあらゆるリクエストにおいて、以下のフィールドのどれも修正した り追加し *てはならない*。 - Content-Encoding - Content-Range - Content-Type 非透過的プロクシは no-transform を含まないメッセージにはこれらのフィ ールドを修正したり追加したり *できる* が、そうする場合、メッセージ中 にそれがまだ示されていなければ Warning 214 (Transformation applied) を追加し *なければならない* (section 14.46 参照)。 警告: もし HTTP の以降のバージョンでより強固な認証メカニズムが導入 されるなら、エンドトゥエンドヘッダを不必要に修正する事は認証失敗を 引き起こすかもしれない。そのような認証メカニズムはここで列挙されな いヘッダフィールドの値を当てにする *かもしれない*。 リクエストやレスポンスの Content-Length フィールドは section 4.4 の規 則に従って追加されたり消去される。透過的プロクシは transfer-length (section 4.4) を変更する事は *できる* が、エンティティボディの entity-length (section 7.2.2) は維持し *なければならない*。 13.5.3 ヘッダの連結 キャッシュがサーバに検証リクエストを送り、サーバが 304 (Not Modified) か 206 (Partial Content) レスポンスを返した場合、キャッシュはリクエス トしたクライアントに返すレスポンスを構築する。 ステータスコードが 304 (Not Modified) の場合、キャッシュは出力するレ スポンスのエンティティボディとしてキャッシュエントリに保存されたエン ティティボディを使う。ステータスコードが 206 (Partial Content) で ETag か Last-Modified 各ヘッダが正確に一致した場合、キャッシュはキャ ッシュエントリに保存された内容とレスポンスとして新たに受信した内容を 連結 *でき*、出力するレスポンスのエンティティボディとしてそれを使う事 が *できる* (section 13.5.4 参照)。 キャッシュエントリに保存されたエンドトゥエンドヘッダは、以下を除いて 構築されたレスポンスのために使われる。 - warn-code 1xx を持った Warning ヘッダ (section 14.46 参照) はす べてキャッシュエントリや転送されるレスポンスから削除され *なけれ ばならない*。 - warn-code 2xx を持った Warning ヘッダはすべてキャッシュエントリ や転送されるレスポンス中で保持され *なければならない*。 - 304 や 206 各レスポンス中にあるエンドトゥエンドヘッダはキャッシ ュエントリから対応するヘッダを置き換え *なければならない*。 キャッシュがそのキャッシュエントリの削除を決めた場合以外は、すぐ上で 示したように Warning ヘッダを除いて、キャッシュエントリと共に保存され たエンドトゥエンドヘッダを入ってきたレスポンス中に含まれる対応するヘ ッダと置き換え *なければならない*。もし入ってきたレスポンス中のヘッダ フィールド名がキャッシュエントリ中の二つ以上のヘッダに一致したら、そ のようなすべての古いヘッダは置きかえられ *なければならない*。 言い換えれば、入ってきたレスポンスで受信したエンドトゥエンドヘッダの セットはキャッシュエントリと共に保存されているすべての対応するエンド トゥエンドヘッダを上書きする (warn-code 1xx と共に保存される Warning ヘッダを除く、これは例え上書きされなくても削除される)。 注意: この規則によってオリジンサーバは 304 (Not Modified) や 206 (Partial Content) 各レスポンスを同じエンティティやその一部分に対す る以前のレスポンスに関連するあらゆるヘッダを更新するために使えるよ うになるが、それが常に意味を持ったり常にそうするのが正しいわけでは ない。この規則ではオリジンサーバが 304 (Not Modified) や 206 (Partial Content) 各レスポンスを以前のレスポンスにて提供されたヘッ ダを完全に削除する事はできない。 13.5.4 バイトレンジの連結 リクエストが一つ以上の Range 詳述を含んでいたり、接続が早まって切断さ れたりするので、レスポンスはエンティティボディのバイトのサブレンジの みを転送できる。そのようないくつかの転送の後、キャッシュは同じエンテ ィティボディのいくつかの範囲を受信する事ができる。 もしキャッシュがエンティティに対するサブレンジの保存された空でないセ ットを持っており、入ってきたレスポンスが別のサブレンジを転送するよう な時に、以下の両方の条件を満たすのであれば、キャッシュは新しいサブレ ンジを既存のセットと連結 *できる*。 - 入ってきたレスポンスとキャッシュエントリの両方がキャッシュバリデ ィタを持っている。 - 二つのキャッシュバリディタは強い比較機能 (section 13.3.3 参照) を使って一致しなければならない。 この要求のどちらかを満たせない場合、キャッシュは最新の部分的なレスポ ンス (レスポンス毎に転送された Date 値に基づき、またそれらの値が等し いか欠けているのであれば入ってきたレスポンス) のみを使用し *なければ ならない* し、他の部分的な情報は破棄し *なければならない*。 13.6 ネゴシエートされたレスポンスのキャッシング レスポンス中の Vary ヘッダフィールドの存在によって示されるような、サ ーバ駆動型コンテントネゴシエーション (section 12.1) を使う事は、キャ ッシュが以降のリクエストのためにそのレスポンスを使う事ができる事によ ってその条件と手続きを変更する。サーバによる Vary ヘッダフィールドの 使用については section 14.44 を見よ。 サーバは、サーバ駆動型ネゴシエーションを受ける複数のキャッシュ可能な レスポンスの表現から選択するためにどんなヘッダフィールドが使用された かをキャッシュに知らせるために Vary ヘッダフィールドを使う *べきであ る*。Vary フィールド値によって名付けられたヘッダフィールドのセットは "選択用{selecting}" リクエストヘッダとして知られる。 キャッシュはその Request-URI が Vary ヘッダフィールドを含んだ一つ以上 のキャッシュエントリを指定するような以降のリクエストを受信した時、新 しいリクエスト中のすべての選択用リクエストヘッダがもとのリクエスト中 の対応する保存されたリクエストヘッダに一致しなければ新しいリクエスト へのレスポンスを構築するためにそのようなキャッシュエントリを使っ *て はならない*。 二つのリクエストからの選択用リクエストヘッダは、最初のリクエスト中の 選択用リクエストヘッダが対応する BNF が許す場所において連続した空白 (LWS) を加えたり除いたりする事によって、また section 4.2 のメッセージ ヘッダについての規則に従って同じフィールド名を持つ複数のメッセージヘ ッダを連結する事によって、二番目のリクエスト中の選択用リクエストヘッ ダに変換できる場合のみに一致すると定義される。 Vary ヘッダフィールド値が "*" の時は、常に一致に失敗し、そのリソース への以降のリクエストはオリジンサーバによってのみ適切に解釈する事がで きる。 キャッシュされたエントリの選択用リクエストヘッダフィールドが新しいリ クエストの選択用リクエストヘッダフィールドに一致しない場合に、もしそ れが条件付きリクエストでオリジンサーバへ新しいリクエストを送り、サー バが 304 (Not Modified) と共に使用されるエンティティを指し示すエンテ ィティタグか Content-Location を返すので無ければ、キャッシュはリクエ ストを満足させるためにキャッシュされたエントリを使っ *てはならない*。 エンティティタグがキャッシュされた表現に割り当てられていた場合、転送 されたリクエストは条件付きである *べきであり*、そのリソースに対するす べてのキャッシュエントリからの If-None-Match ヘッダフィールド中にエン ティティタグを含む *べきである*。これは現在キャッシュが保有しているエ ンティティのセットをサーバへ転送するもので、そのためそれらエンティテ ィの内どれか一つがリクエストされたエンティティに一致した場合、サーバ はキャッシュにエントリが適切をある事を伝えるためにその 304 (Not Modified) レスポンス中で ETag ヘッダフィールドを使う事ができる。新し いレスポンスのエンティティタグが既存のエントリのものと一致する場合、 新しいレスポンスは既存のエントリのヘッダフィールドを更新するために使 用される *べきであり*、その結果はクライアントに返され *なければならな い*。 既存のキャッシュエントリのいかなる物も関連するエンティティについての 部分的な内容のみを含んでいる場合に、もしそのリクエストがそのエントリ が完全に満足する範囲に対するものでなければそのエンティティタグは If- None-Match ヘッダに含まれる *べきではない*。 キャッシュが その Content-Location フィールドが同じ Request-URI に対 する既存のキャッシュエントリの物のと一致し、そのエンティティタグが既 存のエントリの物とは異なり、そしてその Date が既存のエントリの物より 新しいような成功レスポンスを受信した場合、既存のエントリは将来のリク エストへのレスポンスとして返される *べきではなく*、それをキャッシュか ら削除す *べきである*。 13.7 共有キャッシュと非共有キャッシュ セキュリティやプライバシー上の理由により、"共有{shared}" キャッシュと "非共有{non-shared}" キャッシュとの間に区別を付ける必要がある。非共有 キャッシュは単一のユーザのみがアクセス可能なものである。この場合のア クセス可能性とは、適切なセキュリティメカニズムによって施行される *べ きである*。他のキャッシュはすべて "共有" されたとみなされる。この仕様 書の別の章ではプライバシーの損失やアクセス制御の失敗を防止するために 共有されたキャッシュの操作へのある制約をかけている。 13.8 エラーや不完全なレスポンスのキャッシュの振る舞い 不完全なレスポンス (例えば、Content-Length ヘッダで記述されたものより 少ないデータのバイトを伴うもの) を受信するキャッシュはレスポンスを保 存する事が *できる*。しかし、キャッシュは部分的なレスポンスとしてこれ を扱わ *なければならない*。部分的なレスポンスは section 13.5.4 にて定 義されているように結合する事ができるが、その結果は完全なレスポンスか もしれないし、まだ部分的であるかもしれない。キャッシュは 206 (Partial Content) ステータスコードを使ってそれを明示的にそれを示さなければ、ク ライアントに部分的なレスポンスを返し *てはならない*。キャッシュは 200 (OK) ステータスコードを使って 部分的なレスポンスを返してはならない。 もしキャッシュがエントリの正当性再検証を試みる一方で 5xx レスポンスを 受信したら、リクエストしているクライアントにこのレスポンスを転送する か、あるいはまるでサーバが応答に失敗したかのように動作するかどちらか を行う事が *できる*。後者の場合、キャッシュされたエントリが "must- revalidate" cache-control 指示子 (section 14.9 参照) を含んでいなけれ ば、以前に受信したレスポンスを返す事が *できる*。 13.9 GET や HEAD の副作用 オリジンサーバがそれらのレスポンスのキャッシングを明示的に禁止してい ない場合に、あらゆるリソースへ GET や HEAD メソッドを適用する事によっ てそれらのレスポンスがキャッシュから取り出されたならば、誤った動作を 導くような副作用を抱える *べきではない*。それらは副作用を抱える *かも しれない* が、キャッシュはそのキャッシング決定においてそのような副作 用を考慮必要は無い。キャッシュは常にキャッシングにおいてオリジンサー バの明示的な制限を観察する事が期待される。 この規則の一つの例外について記す。アプリケーションの中には伝統的に重 要な副作用を抱えた操作を実行するためにクエリ URL (それらは rel_path 部分に "?" を含んでいる) を伴う GET や HEAD を使用しているものがある ので、キャッシュはサーバが明示的有効期限を与えていなければそのような URI へのレスポンスを新鮮であるように扱っ *てはならない*。これは、その ような URI に対する HTTP/1.0 サーバからのレスポンスはキャッシュから取 り出される *べきではない* という事を特に意味している。関連する情報に ついては section 9.1.1 参照。 13.10 更新や削除後の無効化 オリジンサーバ上のリソースに行われるあるメソッドの影響によって一つ以 上の既存のキャッシュエントリが非透過で無効なものになってしまうかもし れない。つまり、それらは "新鮮" であり続けるかもしれないが、それらは オリジンサーバがそのリソースへの新しいリクエストに対して返すであろう ものを正確に反映していないという事である。 HTTP プロトコルでは、そのようなキャッシュエントリすべてが無効であると 示す事を保証するための方法は無い。例えば、オリジンサーバ上で変更を引 き起こすリクエストはキャッシュエントリが保存されているプロクシを通り 抜けていないかもしれない。しかし、いくつかのルールは間違った振る舞い の可能性を減らす助けとなる。 この章では、"エンティティを無効にする" というフレーズは、キャッシュは その保存媒体からそのエンティティのすべてのインスタンスを削除する、あ るいはそれらが以降のリクエストへのレスポンスとして返される前にそれら を "不正" と印し強制的に再検証を行う必要があるであろうという意味であ る。 HTTP メソッドによってはキャッシュがエンティティを無効にしなければいけ ないものがある。これは Request-URI によって参照されるエンティティ、あ るいは (それが存在するならば) Location や Content-Location レスポンス フィールドによって参照されるエンティティのどちらかである。そのメソッ ドは以下のものである。 - PUT - DELETE - POST サービス不能攻撃を防ぐために、Location や Content-Location ヘッダ中の URI に基づく無効化はそのホスト部分が Request-URI のものと同じ場合にの み実行され *なければならない*。 自身が理解できないメソッドを使ったリクエストを通すキャッシュは、その Request-URI によって参照されるあらゆるエンティティを無効化す *べきで ある*。 13.11 Write-Through の強制 オリジンサーバのリソースに修正をさせる事が期待されるすべてのメソッド は、オリジンサーバへと通されて書かれる{write through} もので *なけれ ばならない*。これは現在 GET と HEAD 以外のすべてのメソッドが含まれ る。キャッシュはインバウンドサーバへとリクエストを転送し、インバウン ドサーバからそれに対応するレスポンスを受け取る前には、そのようなクラ イアントからのリクエストに応答し *てはならない*。これは、キャッシュが インバウンドサーバが最後の応答を送信する前にプロクシキャッシュが 100 (Continue) レスポンスを送る事は妨げない。 一貫した更新を提供する事が難しい事、また write-back より前のサーバ、 キャッシュ、ネットワークの失敗から生じる問題のために、("write-back" や "copy-back" キャッシングとして知られる) 代替案は HTTP/1.1 において 認められていない。 13.12 キャッシュの代替 もしあるリソースについてのレスポンスが既にキャッシュされている時に、 同じリソースから新しくキャッシュ可能な (section 14.9.2, 13.2.5, 13.2.6, 13.8 参照) レスポンスが受信された場合、キャッシュは現在のリク エストへの応答には新しいレスポンスを使用す *べきである*。キャッシュは それをキャッシュ保存媒体に書き込む事が *でき*、もし他のすべての要求を 満たすのであれば、以前には古いレスポンスが返されるであろう将来のリク エストへ応答するためにそれを使用する事が *できる*。キャッシュ保存媒体 に新しいレスポンスを書き込む時は、section 13.5.3 の規則が適用される。 注意: 既存のキャッシュされたレスポンスより古い Date ヘッダ値を持つ 新しいレスポンスはキャッシュ可能ではない。 13.13 履歴表 ユーザエージェントはしばしば、"戻る" ボタンと履歴リストのような履歴メ カニズムを持っていて、セッションにおいて以前に回収したエンティティを 再表示するために使う事ができる。 履歴メカニズムとキャッシュは異なる。特に履歴メカニズムはリソースの現 在の状態の意味的に透過なビューを表示しようとはす *べきではない*。むし ろ、履歴メカニズムはリソースが回収された時刻を正確に表示するという意 味を持つ。 デフォルトでは、有効期限は履歴メカニズムには適用されない。もしそのエ ンティティがまだ保存していて、ユーザが特にエージェントを期限切れの履 歴文書をリフレッシュするように設定していなければ、履歴メカニズムは例 えエンティティの期限が切れていてもそれを表示す *べきである*。 これは、履歴システムがユーザにビューが古くなっているかもしれないとい う事を知らせる事を禁止すると解釈されるものではない。 注意: もし履歴表メカニズムがユーザが古くなったリソースを見る事を不 必要に妨げるのであれば、サービスの著者が別の方法を望む場合に、HTTP の期限制御とキャッシュ制御を強制的に使わせないようにする傾向がある だろう。サービスの著者は、ユーザが前もって回収したリソースを見るた めに (「戻る」のような) ナビゲーション制御を使う時にユーザがエラー メッセージや警告メッセージが見えない事を重要だと考えるかもしれな い。例え、時にそのようなリソースはキャッシュされるべきではなく、す ぐに期限が切れるべきだとしても、不適当に機能している履歴メカニズム の影響のよって苦しまないためにユーザインターフェースはサービスの著 者にキャッシングさせないようにするための別の方法 (例: "一度きりの" URL) に強制的に訴える事ができるように考慮されている。