#======================================================================# $Id: rfc2616_ja.txt,v 0.56 2004/05/16 20:08:14 H-Hash Exp $ 使用上の注意 以下は当リソースを利用するにあたっての注意事項です。 以下について了 承されない方は、速やかに当リソースを破棄して下さい。 ! 当リソースは、Hypertext Transfer Protocol -- HTTP/1.1 (RFC 2616) を *個人的* に日本語訳したリソースです。 ! 正式なる RFC は、英語版のみです。従って、当リソース中のすべての情報 についてその正確性・有効性を保証しません。それら情報の使用の際に生 じた損害等については、一切の責任は負わない事をご了承下さい。 ! 原版にある、ヘッダ、フッタ、改ページ制御文字等は削除しています。 ! 日本語訳が難しい語は、{ } にてその語を括っています。 ! また Typo 等があった場面では、(※) として訳注を付記しています。 ! 原版中の "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL" 各キーワー ド (これらの意味については、本文中 section 1.2 を参照) にあたる日本 語は、* * にて印付しています。 ! 当リソースの最新版は以下の URI から取得できます。 http://www.studyinghttp.net/rfc_ja/2616/ ! このリソースについての御意見・御要望は へ お送り下さい。 以上 #======================================================================# Network Working Group R. Fielding Request for Comments: 2616 UC Irvine Obsoletes: 2068 J. Gettys Category: Standards Track Compaq/W3C J. Mogul Compaq H. Frystyk W3C/MIT L. Masinter Xerox P. Leach Microsoft T. Berners-Lee W3C/MIT June 1999 ハイパーテキスト転送プロトコル -- HTTP/1.1 この文書の位置付け この文書は、インターネットコミュニティにおけるインターネット標準化過 程プロトコルを規定し、改良のために議論と提案を求めるものである。この プロトコルの標準化状態と状況については、"Internet Official Protocol Standards" (STD 1) の最新版を参照していただきたい。この文書の配布に制 限は無い。 著作権表示 Copyright (C) The Internet Society (1999). All Rights Reserved. 概要 ハイパーテキスト転送プロトコル (HTTP) は、分散・共同体ハイパーメディ ア情報システムのアプリケーションレベルプロトコルである。このプロトコ ルは、リクエストメソッド、エラーコード、ヘッダ等の拡張を経て、ネーム サーバや分散オブジェクト管理システム等、ハイパーテキストのために使う 以上に多くの作業のために用いる事ができる、一般的でステートレスなプロ トコルである [47]。HTTP の特徴として、データ表現のタイプ付け、及びネ ゴシエーションがあり、これによって転送されるデータの独立性が確立され るようなシステムが構築できる。 HTTP は、World-Wide Web グローバル情報利用の先進として、1990 年から使 われている。この仕様書は、"HTTP/1.1" と呼ばれるプロトコルを定義し、 RFC 2068 [33] を更新するものである。 目次 1 導入 1.1 目的 1.2 必要条件 1.3 専門用語 1.4 全体の動作 2 表記の慣習と一般文法 2.1 拡張 BNF 2.2 基本ルール 3 プロトコルパラメータ 3.1 HTTP のバージョン 3.2 Uniform Resource Identifiers 3.2.1 一般構文 3.2.2 http URL 3.2.3 URI の比較 3.3 日付/時刻フォーマット 3.3.1 完全な日付 3.3.2 秒差 3.4 文字セット 3.4.1 Charset の誤り 3.5 内容コーディング 3.6 転送コーディング 3.6.1 チャンク形式転送コーディング 3.7 メディアタイプ 3.7.1 公式化とテキストデフォルト 3.7.2 マルチパートタイプ 3.8 製品トークン 3.9 品質値 3.10 言語タグ 3.11 エンティティタグ 3.12 レンジ単位 4 HTTP のメッセージ 4.1 メッセージタイプ 4.2 メッセージヘッダ 4.3 メッセージボディ 4.4 メッセージの長さ 4.5 一般ヘッダフィールド 5 リクエスト 5.1 リクエストライン 5.1.1 メソッド 5.1.2 Request-URI 5.2 リクエストによって識別されるリソース 5.3 リクエストヘッダフィールド 6 レスポンス 6.1 ステータスライン 6.1.1 ステータスコードと説明句 6.2 レスポンスヘッダフィールド 7 エンティティ 7.1 エンティティヘッダフィールド 7.2 エンティティボディ 7.2.1 タイプ 7.2.2 エンティティの長さ 8 接続 8.1 持続的接続 8.1.1 目的 8.1.2 全体の動作 8.1.3 プロクシサーバ 8.1.4 現実的な考察 8.2 メッセージ転送の必要条件 8.2.1 持続的接続とフローコントロール 8.2.2 エラーステータスメッセージのための接続のモニタリング 8.2.3 100 (Continue) ステータスの使用 8.2.4 サーバが早まって接続を閉じた場合のクライアントの振る舞い 9 メソッドの定義 9.1 安全なメソッドと等冪{idempotent} なメソッド 9.1.1 安全なメソッド 9.1.2 等冪{Idempotent} なメソッド 9.2 OPTIONS 9.3 GET 9.4 HEAD 9.5 POST 9.6 PUT 9.7 DELETE 9.8 TRACE 9.9 CONNECT 10 ステータスコードの定義 10.1 Informational 1xx 10.1.1 100 Continue 10.1.2 101 Switching Protocols 10.2 Successful 2xx 10.2.1 200 OK 10.2.2 201 Created 10.2.3 202 Accepted 10.2.4 203 Non-Authoritative Information 10.2.5 204 No Content 10.2.6 205 Reset Content 10.2.7 206 Partial Content 10.3 Redirection 3xx 10.3.1 300 Multiple Choices 10.3.2 301 Moved Permanently 10.3.3 302 Found 10.3.4 303 See Other 10.3.5 304 Not Modified 10.3.6 305 Use Proxy 10.3.7 306 (Unused) 10.3.8 307 Temporary Redirect 10.4 Client Error 4xx 10.4.1 400 Bad Request 10.4.2 401 Unauthorized 10.4.3 402 Payment Required 10.4.4 403 Forbidden 10.4.5 404 Not Found 10.4.6 405 Method Not Allowed 10.4.7 406 Not Acceptable 10.4.8 407 Proxy Authentication Required 10.4.9 408 Request Timeout 10.4.10 409 Conflict 10.4.11 410 Gone 10.4.12 411 Length Required 10.4.13 412 Precondition Failed 10.4.14 413 Request Entity Too Large 10.4.15 414 Request-URI Too Long 10.4.16 415 Unsupported Media Type 10.4.17 416 Requested Range Not Satisfiable 10.4.18 417 Expectation Failed 10.5 Server Error 5xx 10.5.1 500 Internal Server Error 10.5.2 501 Not Implemented 10.5.3 502 Bad Gateway 10.5.4 503 Service Unavailable 10.5.5 504 Gateway Timeout 10.5.6 505 HTTP Version Not Supported 11 アクセス認証 12 コンテントネゴシエーション 12.1 サーバ駆動型ネゴシエーション 12.2 エージェント駆動型ネゴシエーション 12.3 透過的ネゴシエーション 13 HTTP におけるキャッシング 13.1.1 キャッシュの正当性 13.1.2 警告 13.1.3 キャッシュコントロールメカニズム 13.1.4 明示的なユーザエージェントの警告 13.1.5 規則と警告の例外 13.1.6 クライアントにコントロールされた振る舞い 13.2 期限{Expiration} モデル 13.2.1 サーバが指定した期限 13.2.2 帰納的有効期限 13.2.3 経過時間の計算 13.2.4 期限の計算 13.2.5 期限値を曖昧にしない事 13.2.6 複数のレスポンスを曖昧にしない事 13.3 検証{Validation} モデル 13.3.1 Last-Modified の日付 13.3.2 エンティティタグのキャッシュバリディタ 13.3.3 弱いバリディタと強いバリディタ 13.3.4 エンティティタグや Last-Modified の日付を使う場合のルール 13.3.5 非検証条件 13.4 レスポンスのキャッシュ可能性 13.5 キャッシュから構築したレスポンス 13.5.1 エンドトゥエンドヘッダとホップバイホップヘッダ 13.5.2 修正できないヘッダ 13.5.3 ヘッダの連結 13.5.4 バイトレンジの連結 13.6 ネゴシエートされたレスポンスのキャッシング 13.7 共有キャッシュと非共有キャッシュ 13.8 エラーや不完全なレスポンスのキャッシュの振る舞い 13.9 GET と HEAD の副作用 13.10 更新や削除後の無効化 13.11 Write-Through の強制 13.12 キャッシュの代替 13.13 履歴表 14 ヘッダフィールドの定義 14.1 Accept 14.2 Accept-Charset 14.3 Accept-Encoding 14.4 Accept-Language 14.5 Accept-Ranges 14.6 Age 14.7 Allow 14.8 Authorization 14.9 Cache-Control 14.9.1 キャッシュ可能とは何か 14.9.2 キャッシュによって保存されるものは何か 14.9.3 基本的な期限のメカニズムの修正 14.9.4 キャッシュの再検証とリロードコントロール 14.9.5 No-Transform 指示子 14.9.6 キャッシュコントロールの拡張 14.10 Connection 14.11 Content-Encoding 14.12 Content-Language 14.13 Content-Length 14.14 Content-Location 14.15 Content-MD5 14.16 Content-Range 14.17 Content-Type 14.18 Date 14.18.1 時計の無いサーバの動作 14.19 ETag 14.20 Expect 14.21 Expires 14.22 From 14.23 Host 14.24 If-Match 14.25 If-Modified-Since 14.26 If-None-Match 14.27 If-Range 14.28 If-Unmodified-Since 14.29 Last-Modified 14.30 Location 14.31 Max-Forwards 14.32 Pragma 14.33 Proxy-Authenticate 14.34 Proxy-Authorization 14.35 Range 14.35.1 バイトレンジ 14.35.2 レンジ更新リクエスト 14.36 Referer 14.37 Retry-After 14.38 Server 14.39 TE 14.40 Trailer 14.41 Transfer-Encoding 14.42 Upgrade 14.43 User-Agent 14.44 Vary 14.45 Via 14.46 Warning 14.47 WWW-Authenticate 15 セキュリティについての考察 15.1 個人情報 15.1.1 サーバログ情報の乱用 15.1.2 機密性の高い情報の転送 15.1.3 URI での機密性の高い情報のエンコード 15.1.4 Accept ヘッダに関連するプライバシーの問題 15.2 ファイル名やパス名に基づく攻撃 15.3 DNS スプーフィング 15.4 Location ヘッダとスプーフィング 15.5 Content-Disposition 問題 15.6 認証用証明書{credentials} と無配慮なクライアント 15.7 プロクシとキャッシング 15.7.1 プロクシを使ったサービス拒否攻撃 16 謝辞 17 参考文献 18 筆者のアドレス 19 付録 19.1 インターネットメディアタイプ message/http と application/http 19.2 インターネットメディアタイプ multipart/byteranges 19.3 寛容なアプリケーション 19.4 HTTP のエンティティと RFC 2045 のエンティティとの違い 19.4.1 MIME-Version 19.4.2 公式形式への変換 19.4.3 日付フォーマットの変換 19.4.4 内容コーディングの導入 19.4.5 No Content-Transfer-Encoding 19.4.6 転送エンコーディングの導入 19.4.7 MHTML と 行末制限 19.5 追加機能 19.5.1 Content-Disposition 19.6 前バージョンとの互換性 19.6.1 HTTP/1.0 からの変更点 19.6.2 HTTP/1.0 持続的接続との互換性 19.6.3 RFC 2068 からの変更点 20 索引 21 完全なる著作権宣言 1 導入 1.1 目的 ハイパーテキスト転送プロトコル (HTTP) は、分散・共同体ハイパーメディ ア情報システムのアプリケーションレベルプロトコルである。HTTP は、 World-Wide Web グローバル情報利用の先進として、1990 年から使われてい る。HTTP の最初のバージョンは、HTTP/0.9 と呼ばれ、インターネットを通 じて未加工のデータを転送するための単純なプロトコルであった。HTTP/1.0 は、RFC 1945 [6] にて定義され、転送されるデータに関する外部情報とリク エスト/レスポンスセマンティクスの修飾子を含んだ MIME-like なメッセー ジ形式のメッセージを付加する事によってプロトコルを改良した。しかし、 HTTP/1.0 ではプロクシやキャッシングの階層構造、持続的接続の必要性、仮 想ホストへの考慮が十分になされていなかった。さらに、実装が不完全なの に自身を "HTTP/1.0" だと称するアプリケーションの増加で、互いの通信ア プリケーションが互いに真の能力を決定するために、プロトコルバージョン を変更する必要性が出てきた。 この仕様書では、"HTTP/1.1" と呼ばれるプロトコルを定義している。このプ ロトコルはそれらの特徴の確実な実装を保証するため HTTP/1.0 よりも厳格 な要求を含んでいる。 実際の情報システムは、検索、フロントエンドの更新、注釈等を含む、単純 なリソースの回収よりもより多くの機能性を必要としている。HTTP はリクエ ストの目的を示すためのメソッドやヘッダの open-ended セットを認めてい る [47] 。これは、メソッドが適用されるリソースを示すための location (URL) [4] や name (URN) [20] としての Uniform Resource Identifier (URI) [3] によって供給される参照の規律に基づいている。メッセージは Multipurpose Internet Mail Extensions (MIME) [7] にて定義される、イン ターネットメール [9] により使用されている物に似たフォーマットで渡され る。 また HTTP は、ユーザエージェントと SMTP [16], NNTP [13], FTP [18], Gopher [2], WAIS [10] プロトコルをサポートするものを含む、別の情報シ ステムのプロクシ/ゲートウェイ間の通信用の、一般的なプロトコルとして も使用される。これによって、HTTP は様々なアプリケーションから利用でき るリソースへの基本的なハイパーメディアアクセスを可能にする。 1.2 必要条件 この文書中における "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL" という 各キーワードは、RFC 2119 [34] にて記述されるように解釈される。 もし、あるインプリメンテーションが、そのプロトコルの MUST あるいは REQUIRED レベルの要求の一つ以上を満足できないのならば、そのインプリメ ンテーションは従順なものではない。もし、あるインプリメンテーションが そのプロトコルのすべての MUST あるいは REQUIRED レベルと、すべての SHOULD レベルの要求を満足していれば、そのインプリメンテーションは "無 条件に従順" と呼ぶ。そして、すべての MUST レベルの要求は満たしている が、一つでも SHOULD 要求を満たしていないものは "条件付きで従順" と呼 ばれる。 1.3 専門用語 この仕様書では、HTTP 通信に参加する人間、あるいは物を参照するための専 門用語をいくつか使用する。 コネクション {connection} 通信の目的で二つのプログラム間に確立されるトランスポート層の仮想通 信路。 メッセージ {message} section 4 にて定義されるシンタックスを持ち構造化されたオクテットシ ーケンスから成り、接続を介して転送される、HTTP 通信での基本単位。 リクエスト {request} section 5 にあるような、HTTP リクエストメッセージ。 レスポンス {response} section 6 にあるような、HTTP レスポンスメッセージ。 リソース {resource} section 3.2 にて定義される URI によって判別されるネットワークデー タオブジェクト、あるいはサービス。リソースは複数の表現 (例えば、複 数の言語、データフォーマット、サイズ、解像度等) で利用したり、別の 方法で変更したりできる。 エンティティ {entity} リクエストやレスポンスの付加物{payload} として転送される情報。エン ティティは、section 7 で記述されるように、エンティティヘッダフィー ルドという形での外部情報と、エンティティボディという形での内容から 成る。 表現 {representation} section 12 にて記述されているようなコンテントネゴシエーションに従 ったレスポンスを含むエンティティ。特定のレスポンスステータスには、 関連する複数の表現が存在する事がある。 コンテントネゴシエーション {content negotiation} section 12 で記述されているように、リクエストを処理する時、適切な 表現を選択するためのメカニズム。エラーレスポンスも含めた、どんなレ スポンスにおいてもエンティティの表現はサーバと交渉 {negotiate} さ れる。 バリアント {variant} リソースはどの瞬間においても一つ、あるいは一つ以上、それに関連付け られた表現を持っている。それらの表現のそれぞれを `バリアント' と呼 ぶ。`バリアント' という語の使用が、そのリソースがコンテントネゴシ エーションされているという事を意図するわけではない。 クライアント {client} リクエストを送信する目的でコネクションを確立するプログラム。 ユーザエージェント {user agent} リクエストを発行するクライアント。これらはしばしば、ブラウザ、エデ ィタ、スパイダ (web ロボット) の事を指すが、その他のエンドユーザツ ールも指す。 サーバ {server} レスポンスを返す事で、リクエストを処理するためのコネクションを受け 入れるアプリケーションプログラム。プログラムの中にはクライアントと サーバの両方の機能を持つものがあるが、ここでは一般的なプログラムの 機能を表すというよりはむしろ、特定のコネクションのためにプログラム によって果たされる役割のみを表す。同様に、リクエストに応じてオリジ ンサーバ、プロクシ、ゲートウェイ、トンネルと振る舞いを切り換える場 合がある。 オリジンサーバ {origin server} 指定されるリソースが存在するか、あるいは生成されるサーバ。 プロクシ {proxy} 他のクライアントの代わりとしてリクエストを行うためにサーバとクライ アントの両方の役割を果たす中継プログラム。リクエストは、可能な変換 をもって、内部で処理されるか、あるいは他のサーバに渡される。プロク シは、この仕様書が要求するクライアントとサーバの両方の機能を実装し *なければならない*。"透過的プロクシ" とは、プロクシへの認証やクラ イアント自身の証明が要求されるようなもの以外のリクエストやレスポン スを修正しないようなプロクシである。"透過的でないプロクシ" とは、 ユーザエージェントに、ある種の翻訳、メディアタイプの変形、使用プロ トコルの制限、匿名性向上のためのフィルタリング等のような、追加的サ ービスを提供するためにリクエストやレスポンスを修正するようなプロク シである。その振る舞いが透過的であるか無いかが明言されている部分を 除けば、それぞれのプロクシは HTTP プロクシとして必要な要素を共に持 ち合わせている。 ゲートウェイ {gateway} 他のサーバを中継するサーバ。プロクシとは違い、ゲートウェイはまるで リクエストされたリソースのオリジンサーバのように、リクエストを受け る。リクエストしたクライアントは、それをゲートウェイと通信している という事を気付かないかもしれない。 トンネル {tunnel} 二つの接続の間をまるで目隠しリレーを行う様に振る舞う中継プログラ ム。一度起動したら、それが HTTP リクエストによるものであっても、ト ンネル自身は HTTP 通信における当事者とみなさない。トンネルは中継す る両端の通信が終了した時、終了する。 キャッシュ {cache} プログラムがレスポンスメッセージをローカルに記録しておく場所であ り、それらメッセージの保存、検索、削除を管理するサブシステムを指 す。キャッシュは、同様のリクエストが起きた際にレスポンス時間やネッ トワーク帯域幅の消費の軽減のために、キャッシュ可能なレスポンスを保 存する。どのようなクライアントもサーバもキャッシュを持つ事はできる が、トンネルとして振る舞っているサーバはキャッシュを使用できない。 キャッシュ可能 {cacheable} レスポンスは、もしキャッシュが後続のリクエストに答えるという目的で の使用のために、レスポンスメッセージのコピーを保存する事が許される ならばキャッシュ可能であるという。HTTP レスポンスのキャッシュ使用 の決定の決まりは section 13 にて定義されている。例えリソースがキャ ッシュ可能でも、キャッシュは特定のリクエストのためにキャッシュされ たコピーを使うかどうかについて制限を受ける可能性がある。 ファーストハンド {first-hand} レスポンスが、オリジンサーバ、あるいは一つ以上経由したプロクシから 不必要な遅れ無しに届くならば、それをファーストハンドであるという。 また、オリジンサーバで有効性を直接チェックされたレスポンスもファー ストハンドであるという。 明示的有効期限 {explicit expiration time} オリジンサーバが、エンティティの有効性の再確認無しにキャッシュを返 すべきではないとしている時刻。 帰納的有効期限 {heuristic expiration time} 有効期限が指定されていない時に、キャッシュによって指定される有効期 限。 経過時間 {age} レスポンスの経過時間とは、それがオリジンサーバから送られてから、あ るいはオリジンサーバによって十分に有効性が確認された時からの時間を 指す。 有効期間 {freshness lifetime} レスポンスが生成されてから有効期限までの時間の長さ。 新鮮である {fresh} レスポンスは、その経過時間が有効期間を経過していないものを新鮮であ るという。 新鮮でない {stale} レスポンスは、その経過時間が有効期間を経過したものを新鮮でないとい う。 意味的に透過である {semantically transparent} キャッシュは、パフォーマンスの向上以外に、リクエストしたクライアン トにもオリジンサーバにも影響が無い時、特定のレスポンス関して、意味 的に透過な方法で振る舞う。キャッシュが意味的に透過な時、クライアン トはオリジンサーバから直接処理された時に受け取るであろうリクエスト と全く同じレスポンスを受け取る。(ホップバイホップヘッダを除く) バリディタ {validator} キャッシュ内にあるリソースが、エンティティのコピーと同等かどうかが わかるとされている (例えば、エンティティタグや Last-Modified 時刻 等の) プロトコルエレメント。 アップストリーム/ダウンストリーム {upstream/downstream} アップストリームとダウンストリームとは、メッセージの流れを表す。す べてのメッセージは、上流{upstream} から下流{downstream} へと流れ る。 インバウンド/アウトバウンド {inbound/outbound} インバウンドとアウトバウンドは、メッセージを送るためのリクエストと レスポンスの道のりに従う。"インバウンド" とは "オリジンサーバに向 かって行く事" を、"アウトバウンド" とは "ユーザエージェントに向か かって行く事" を、それぞれ意味する。 1.4 全体の動作 HTTP プロトコルはリクエスト/レスポンスプロトコルである。クライアント は、サーバへの接続上で、リクエストメソッド、URI、そしてプロトコルバー ジョン、その後にリクエスト修飾子、クライアント情報、可能であれば内容 本体を含んだ MIME-like メッセージ形式をサーバにリクエストとして送る。 サーバは、メッセージのプロトコルバージョンと成功か失敗を表すコードを 含むステータス行に続き、サーバ情報、エンティティメタ情報、可能であれ ばエンティティボディの内容を含む MIME-like メッセージで応答する。HTTP と MIME の関係は、付録 19.4 に記述されている。 多くの HTTP 接続は、ユーザエージェントによって開始され、あるオリジン サーバ上のリソースに適用するためのリクエストから成り立つ。この最も簡 単な場合、ユーザエージェント (UA) とオリジンサーバ (O) との間の単一接 続経由 (v) で成し遂げられるだろう。 request chain ------------------------> UA -------------------v------------------- O <----------------------- response chain リクエスト/レスポンス連鎖中に一つ以上の中継者が現れると、状況はより 複雑になる。一般的な中継者には、プロクシ、ゲートウェイ、トンネルの三 つが存在する。プロクシは、その絶対形式の URI のリクエストを受け取り、 メッセージのすべてもしくは一部を書き換え、URI によって識別されるサー バに再フォーマットされたリクエストを転送する転送エージェントである。 ゲートウェイは、ある別のサーバ (群) の上の層として動作し、もし必要な らリクエストを根底にあるサーバのプロトコルに変換するための受信エージ ェントである。トンネルは、メッセージを変更する事なく二つの接続間の中 継点として動作する。トンネルは通信が (ファイアウォールのような) 中継 者を通して伝えられる必要がある時、さらに中継者がメッセージの内容を理 解できない時に使用される。 request chain --------------------------------------> UA -----v----- A -----v----- B -----v----- C -----v----- O <------------------------------------- response chain 上図は、ユーザエージェントとオリジンサーバの間の三中継者 (A, B, C) を 表している。リクエストやレスポンスのメッセージが移動する全体の連鎖は 四つに分ける事ができるであろう。HTTP 通信オプションによっては、適用 できる範囲が、隣の接続にのみだったり、トンネルではない隣接接続だった り、連鎖の終末のみだったり、あるいは連鎖上のすべての接続に適用できた りするので、この区別は重要である。図形では線形であるが、それぞれが複 数に、また同時に通信を行う事ができる。例えば、B は A からのリクエスト を処理すると同時に、A 以外の多くのクライアントからリクエストを受信し ているかもしれないし、あるいは C 以外のサーバにリクエストを転送してい るかもしれない。 トンネルとして動作していない 通信のすべてのパーティは、内部的なキャッ シュやリクエスト処理に使用できる。キャッシュの効果とは、もし連鎖上に 連なるある一つがそのリクエストに適用できるキャッシュされたレスポンス を持っているなら、リクエスト/レスポンス連鎖を短縮する事である。以下 では、もし B が、UA や A がキャッシュしていないリクエストに対する O からの (C を経由した) 以前のレスポンスのキャッシュされたコピーを持っ ている場合の結果となる連鎖を説明している。 request chain ----------> UA -----v----- A -----v----- B - - - - - - C - - - - - - O <--------- response chain すべてのレスポンスがキャッシュ可能であるわけではなく、いくつかのリク エストではキャッシュの動作への特別な要求を行う修飾子を含む事ができ る。キャッシュの動作やキャッシュ可能なレスポンスに対する HTTP の要求 は section 13 で定義されている。 事実、現在 World Wide Web 上にて実験され、設置されているキャッシュと プロクシには幅広い種類のアーキテクチャやコンフィギュレーションがあ る。これらのシステムには、海を渡るような通信{transoceanic} のバンド幅 を節約するためにプロクシキャッシュを全国的な組織が階層的に管理するも の{national hierarchies} や、エントリしているキャッシュを放送するため のシステムや、CD-ROM を使ってキャッシュされたデータのサブセットを配布 する組織等も含む。HTTP システムは、高バンド幅通信上の社内イントラネッ トでも、そして非力なラジオ通信や断続的な接続を使う PDA 経由でアクセス するためにも使用される。HTTP/1.1 が目指すものは、高い信頼性と、もし失 敗するとしても少なくとも確実な徴候が要求されるウェブアプリケーション を作る人間のニーズに合ったプロトコル構造を取り入れていく一方で、既に 設置されている幅広い多様なコンフィギュレーションをサポートする事であ る。 HTTP 通信は、普通 TCP/IP 接続上で行う。デフォルトポートは TCP 80 であ るが、他のポートを使用する事もできる [19] 。これは、インターネットや 他のネットワーク上の別のプロトコルの最上部として、HTTP を実装する事を 排除しない。HTTP は確実な転送のみを前提し、そのような保証を供給するど んなプロトコルでも使用できる。問題においてプロトコルのデータ転送ユニ ット上の HTTP/1.1 リクエストとレスポンス構造のマッピングはこの仕様書 の範疇を超える。 HTTP/1.0 では、ほとんどのインプリメンテーションはそれぞれのリクエスト /レスポンスを交換するために新しい接続を使用していた。HTTP/1.1 では、 接続は一つ以上のリクエスト/レスポンス交換に使用できるが、レスポンス の種類によっては接続がクローズされるかもしれない (section 8.1 参照)。 2 表記の慣習と一般文法 2.1 拡張 BNF この文書において詳述されるメカニズムのすべては、単調 Backus-Naur Form (BNF) と、RFC 822 [9] で使用されているものに似た拡張 BNF との両方で記 述されている。実装者は、この仕様書を理解するためにこの表記法に精通し ている必要があるだろう。拡張 BNF は以下の構造を含んでいる。 name = definition name とは、("<" と ">"で囲まれているものを除き) 単純にそれ自身の名 前であり、その定義とは等号 "=" 文字によって分割されている。空白 は、二行以上に渡るルール定義を示すために使われる連続行の行頭空白に おいてのみ意味を持つ。特定の基本ルールは SP, LWS, HT, CRLF, DIGIT, ALPHA 等のように大文字である。角括弧は、それらの存在がルール名の使 用の理解を容易にするであろうときに定義の中に使用される。 "literal" クォーテーション記号はリテラルテキストを囲む。もし特に明言されなけ れば、テキストは大文字・小文字を区別しない。 rule1 | rule2 バー ("|") で区切られた要素は二者択一である。例えば "yes | no" は yes か no を受け入れるだろう。 (rule1 rule2) 括弧で囲まれた要素は単一の要素として扱われる。従って、 "(elem (foo | bar) elem)" は、トークンシーケンス "elem foo elem" と "elem bar elem" を認める。 *rule 要素の前にある "*" 文字は繰り返しを意味する。完全な形式は "*element" で、これは element 出現が最低、最大であるこ とを示している。デフォルト値は 0 と無限なので、"*(element)" はゼロ を含むどんな回数も可能であり、"1*element" は最低一つ、"1*2element" は一つか二つが可能である。 [rule] 角括弧は省略可能な要素を囲む。すなわち 、"[foo bar]" は "*1(foo bar)" と同等である。 N rule 具体的な繰り返し。"(element)" は "*(element)" と同等であ る。これは、(element) の出現が確実に 存在する。従って 2DIGIT は二文字の数字であり、3ALPHA は三文字の アルファベット文字の文字列 である。 #rule "#" 構造は、"*" と似て、要素のリストを定義するために定義されてい る。完全な形式は "#element" で、これは element が最低 、 最大 の存在を示していて、それぞれは一つ以上のコンマ (",") と *省略可能な* 連続空白 (LWS) で区切られる。これによって、通常のリス ト形式をとても簡単にできる。例えば、 ( *LWS element *( *LWS "," *LWS element )) のルールは 1#element として表す事ができる。 この構造が使用されているどこでも、null 要素が許されるが、存在する 要素の数に影響しない。つまり、"(element), , (element)" は許される が、二つの要素として数えられる。それゆえに、最低一つの要素が必要な 所では、最低一つの null でない要素が与えられ *なければならない* 。 デフォルト値は 0 と無限であるので、"#element" はゼロを含むどんな数 も認め、"1#element" は最低 1 個を必要とし、"1#2element" は 1 個か 2 個を認めている。 ; comment ルールテキストの右からいくらか距離を置いて始まるセミコロンは、 行 末まで続くコメントの始まりである。これは、この仕様書と共に有益な記 述を含めるための簡単な方法である。 黙示的 *LWS この仕様書によって記述される文法は、単語に基づいている。その他の方 法で明記していなければ、連続した空白(LWS) は、フィールドの解釈を変 える事無く、二つの隣接した言葉 (トークンや引用符で囲まれた文字列) の間や隣接したトークンとデリミタ (LWS かセパレータ) の間に含む事が できる。二つのトークンの間には、最低一つのデリミタ (LWS かセパレー タ) が、それらが単一のトークンとして解釈されないように存在し *なけ ればならない*。 2.2 基本ルール 以下のルールは、基本的な構造概念を記述するためにこの仕様書全体に渡っ て使用される。文字セットとしてコード化された US-ASCII は ANSI X3.4-1986 [21] にて定義されている。 OCTET = <8-bit のデータシーケンス> CHAR = UPALPHA = LOALPHA = ALPHA = UPALPHA | LOALPHA DIGIT = CTL = CR = LF = SP = HT = <"> = HTTP/1.1 は、エンティティボディ以外のすべてのプロトコル要素のための行 末の印として CR LF というシーケンスを定義している (寛容なアプリケーシ ョンのためには、付録 section 19.3 参照)。エンティティボディ内の行末の 印は、section 3.7 で記述されているように、その関連するメディアタイプ によって定義される。 CRLF = CR LF HTTP/1.1 ヘッダフィールドの値は、もし続く行が空白か水平タブで始まって いるならば複数行にまたがって折り返す事ができる。すべての連続空白は、 折り返しているものを含め、SP と同じ意味を持つ。受信者は、フィールドの 値を解釈したり、メッセージを下層{downstream} に流す前に、すべての連続 空白を1つの SP に置きかえた方が *よい* 。 LWS = [CRLF] 1*( SP | HT ) TEXT ルールは、メッセージパーサによって解釈される事を望まないフィール ドの内容と値の説明にのみ使用される。*TEXT の言葉は、RFC 2047 [14] の ルールに従ってエンコードされた時にのみ、ISO-8859-1 [22] 以外の文字セ ットの文字を含む事が *できる* 。 TEXT = CRLF は、ヘッダフィールドの連続行の一部として使う時のみ、TEXT の定義 に含まれる。折り返し LWS は TEXT の値を解釈する前に1つの SP に置きか えるであろう事が予想される。 16 進数文字は様々なプロトコル要素において使用される。 HEX = "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT 多くの HTTP/1.1 ヘッダフィールドの値は、LWS か特別な文字によって区切 られた言葉から成る。これらの特別な文字がパラメータ値内で使用されるた めには (section 3.6 で定義される様に) 引用された文字列内に存在し *な ければならない* 。 token = 1* separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT コメントは、いくつかの HTTP ヘッダ内でコメント文字を括弧で囲む事によ り含む事ができる。コメントは、それらのフィールド値定義の一部として "comment" を含んでいるフィールドにおいてのみ許される。その他のすべて のフィールドにおいては、括弧はフィールド値の一部とみなされる。 comment = "(" *( ctext | quoted-pair | comment ) ")" ctext = <"(" と ")" を除いたあらゆる TEXT> テキストの文字列は、ダブルクォート記号を使って引用されているなら、単 一の言葉として解析される。 quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) qdtext = <<"> を除いたあらゆる TEXT> バックスラッシュ文字 ("\") は、quoted-string と comment 構造内でのみ 単一文字引用メカニズムとして使用する事が *できる*。 quoted-pair = "\" CHAR 3 プロトコルパラメータ 3.1 HTTP のバージョン HTTP では、プロトコルのバージョンを示すために "<メジャーバージョン>. <マイナーバージョン>" と番号づける。プロトコルバージョンのつけ方の方 針としては、その通信で得られたものの特徴を伝えるというよりも、送信者 がメッセージのフォーマットや将来的な HTTP 通信においての理解能力を表 すために使わせようとするものである。通信の振る舞いが影響を受けないメ ッセージの構成要素が追加されたり、拡張可能なフィールドの値が追加され るような場合ではバージョン番号は変更されない。<マイナー> バージョン は、その変更が、一般的なメッセージ解析アルゴリズムを変えるものではな いが、メッセージセマンティクスを付け加え、送信者の機能に追加があった 事を意図する時に、上がる。<メジャー> バージョンは、プロトコル内のメッ セージのフォーマットが変更される時に、上がる。完全なる解説を必要とす る場合は RFC 2145 [36] 参照。 HTTP メッセージのバージョンは、メッセージの最初の行の HTTP-Version フ ィールドで示される。 HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT メジャー番号とマイナー番号は、分割された整数値として扱われ *なければ ならない* ので、メジャー番号とマイナー番号はそれぞれ、一桁以上に増や しても *よい* という事に注意せよ。従って、HTTP/2.4 は HTTP/2.13 より も下のバージョンで、さらにそれらは HTTP/12.3 よりも下となる。先行する ゼロは受け取り側によって無視され *なければならない* し、また送られ *てはならない*。 "HTTP/1.1" という HTTP-Version を含むリクエストやレスポンスメッセージ を送るアプリケーションは、少なくとも条件付きでこの仕様書に準じてい *なければならない* 。少なくとも条件付きでこの仕様書に準じているアプリ ケーションならば、送信するメッセージに "HTTP/1.1" という HTTP-Version を含める *べきであり*、HTTP/1.0 と互換性の無い全てのメッセージには、 必ず含め *なければならない*。 特定の HTTP-Version を送る時についての詳細は、RFC 2145 [36] 参照。 アプリケーションの HTTP バージョンとは、そのアプリケーションが少なく とも条件付きで準じている最も高い HTTP バージョンの事である。 プロクシやゲートウェイなどのアプリケーションは、プロトコルにおけるア プリケーションのバージョンの違うメッセージを転送する時に注意する必要 がある。プロトコルバージョンは送り手のプロトコル能力を示すので、プロ クシ/ゲートウェイは、決して自身の実際のバージョンよりも大きなバージ ョン指標が付いたメッセージを送っ *てはならない*。もし、より高いバージ ョンのリクエストを受けたならば、プロクシ/ゲートウェイはリクエストの バージョンを下げるか、エラーを返すか、トンネル動作にスイッチするかの いずれかを行わ *なければならない*。 RFC 2068 [33] の発行以降に HTTP/1.0 プロクシの通信上の問題が発見され た事を受けて、キャッシュするプロクシは、必ずサポートする最新のバージ ョンにアップグレードし *なければならない*。ゲートウェイは、可能であれ ばアップグレードしても *よい*。またトンネルは、アップグレードし *ては ならない*。そのリクエストのプロクシ/ゲートウェイのレスポンスは、リク エストと同じメジャーバージョンでなければならない。 注意: HTTP のバージョン間の変換は、含まれるバージョンによって要求され る、あるいは禁止されるヘッダフィールドの修正を含んでいてもよい。 3.2 Uniform Resource Identifiers URI とは、既に多くの名前で、例えば WWW address, Universal Document Identifier, Universal Resource Identifier [3], そして、最終的に Universal Resource Locator (URL) [4] と Name (URN) [20] という名で知 られている。HTTP に限って言えば、Uniform Resource Identifier とはリソ ースを名前や場所、その他の特徴で識別する簡潔に書式化された文字列のこ とである。 3.2.1 一般構文 HTTP における URI は、絶対形式か、それが使われている状況に依存する、 ある既知の基底 URI [11] からの相対形式で表される。この二つの形式は、 絶対 URI は常にコロンを後に持つスキーム名から開始しているという事から 区別される。URL 構文やセマンティクスの定義についての情報については、 (RFC 1738 [4] と RFC 1808 [11] を置き換えた) "Uniform Resource Identifiers (URI): Generic Syntax and Semantics," RFC 2396 [42] を参 照。この規格書では、その規格書にある、"URI-reference", "absoluteURI", "relativeURI", "port", "host", "abs_path", "rel_path", "authority" の 定義を採用する。 HTTP プロトコルでは、URI の長さにどんな制限も設けていない。サーバは、 自身が持つどんなリソースの URI も扱え *なければならない* し、もしその ような URI を生成する GET ベースのフォームを用意するなら、無制限の長 さの URI を扱える *べきである*。もし、その URI がサーバが処理できるも のよりも長ければ、サーバは 414 (Request-URI Too Long) ステータスを返 す *べきである* (section 10.4.15 参照)。 注意: いくつかの古いクライアントやプロクシインプリメンテーションは 255 バイトを超える長さを持つ URI を適切にサポートしていないかもし れないので、サーバはそのような URI に頼る場合は注意を払うべきであ る。 3.2.2 http URL "http" スキームは HTTP プロトコル経由でネットワークリソースの位置を指 すために使われる。このセクションでは http URL について、スキーム特有 のシンタックスとセマンティクスを定義する。 http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]] もし、port が空かあるいは与えられていなければ、ポート 80 が仮定され る。そのセマンティクスは、識別されるリソースはそのホストのそのポート で TCP 接続のためのリスニングをしているサーバ上にあり、リソースに対す する Request-URI は、abs_path である (section 5.1.2)。できれば、URL での IP アドレスの使用は避ける *べきである* (RFC 1900 [24] 参照)。も し、abs_path が URL で与えられていなければ、そのリソースへの Request- URI として使われる時に、"/" が与えられなければならない (section 5.1.2)。もし、プロクシが fully qualified domain name ではない ホスト ネームを受けとったならば、プロクシは自分のドメインにそのホストネーム を追加する事が *できる*。もし、プロクシが fully qualified domain name を受けとったならば、プロクシは絶対にホストネームを書き換え *てはなら ない*。 3.2.3 URI の比較 二つの URI が一致しているかどうかを決めるために比較する時、クライアン トは URI 全体で大文字・小文字を区別したオクテット同士の比較をす *べき である* が、以下は例外とする。 - ポートが空、あるいは与えられていない場合は、その URI のデフォル トのポートと等価である。 - ホスト名の比較は、大文字・小文字を区別し *てはならない*。 - スキーム名の比較は、大文字・小文字を区別し *てはならない*。 - 空の abs_path は、"/" という abs_path と等価である。 "reserved" あるいは "unsafe" セット (RFC 2396 [42] 参照) 以外の全ての 文字は、それらを ""%" HEX HEX" エンコーディングしたものと等しい。(※) (※訳注) "unsafe" セットは、RFC 2396 中には存在しない。 例えば、以下の三つの URI は等価である。 http://abc.com:80/~smith/home.html http://ABC.com/%7Esmith/home.html http://ABC.com:/%7esmith/home.html 3.3 日付/時刻フォーマット 3.3.1 完全な日付 HTTP アプリケーションは、歴史的に日付/時刻スタンプの表現のために三つ の異なるフォーマットが許されている。 Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format 最初のフォーマットはインターネット標準としてより好まれ、RFC 1123 [8] (RFC 822 [9] の改定) にて定義される固定長サブセットを表す。第二のフ ォーマットは一般的に使用されているが、時代遅れ{obsolete} な RFC 850 [12] 日付フォーマットに基づいており、四桁年号が欠落している。日付の値 を解析する HTTP/1.1 クライアントとサーバは (HTTP/1.0 との互換性のため に) 三つすべてのフォーマットを受け入れ *なければならない* が、ヘッダ フィールドにおいて HTTP-date 値を表す時は RFC 1123 フォーマットのみを 生成し *なければならない*。更なる情報については、section 19.3 参照。 注意: 日付の値の受取人は、時々 SMTP や NNTP のプロクシ/ゲートウェ イを経由してメッセージが回収されたり送信されたりするような場合の時 に、非 HTTP アプリケーションによって送られるであろう日付の値を受け 入れる程に強固である事が推奨される。 すべての HTTP 日付/時刻スタンプは、例外を除いてグリニッジ標準時刻 (GMT) で表され *なければならない*。HTTP の用途では、GMT は UTC (Coordinated Universal Time) と正確に一致する。これは、タイムゾーンを 表す三文字略として "GMT" の含める事によって最初の二つのフォーマットの 中で示され、asctime フォーマットを解釈する時には仮定され *なければな らない*。HTTP-date は大文字・小文字を区別するが、文法書中の SP のよう に、含まれる特定のもの以上の追加的 LWS を含ん *ではならない*。 HTTP-date = rfc1123-date | rfc850-date | asctime-date rfc1123-date = wkday "," SP date1 SP time SP "GMT" rfc850-date = weekday "," SP date2 SP time SP "GMT" asctime-date = wkday SP date3 SP time SP 4DIGIT date1 = 2DIGIT SP month SP 4DIGIT ; day month year (e.g., 02 Jun 1982) date2 = 2DIGIT "-" month "-" 2DIGIT ; day-month-year (e.g., 02-Jun-82) date3 = month SP ( 2DIGIT | ( SP 1DIGIT )) ; month day (e.g., Jun 2) time = 2DIGIT ":" 2DIGIT ":" 2DIGIT ; 00:00:00 - 23:59:59 wkday = "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun" weekday = "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday" month = "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec" 注意: この日付/時刻スタンプフォーマットの HTTP 的要求は、プロトコ ルストリーム内での使用にのみ適用される。クライアントやサーバは、こ れらのフォーマットをユーザ提示やログイン要求などのために使用する必 要はない。 3.3.2 秒差 ある HTTP ヘッダフィールドでは、メッセージが受信されてからの時間を、 10 進数で表される整数の秒数値で、表す事ができる。 delta-seconds = 1*DIGIT 3.4 文字セット HTTP では、"文字セット" という用語を MIME で表現される場合と同じ定義 で使用する。 この文書中では "文字セット" という用語を、一つ以上のテーブルを使って オクテットシーケンスを文字シーケンスに変換するための方法を述べるため に使う。与えられた文字セットですべての文字が利用できるわけではなかっ たり、文字セットがある特定の文字を表すために二つ以上のオクテットシー ケンスを供給する場合でも、別の指示による無条件な変換が必要でないは事 に注意せよ。この定義は、US-ASCII のような簡単な単一テーブルマッピング から、ISO-2022 の技術を使うような複雑なテーブルをスイッチする方法ま で、さまざまな種類の文字エンコーディングを認めようとするものである。 しかし、MIME 文字セット名に関連したこの定義は、1 オクテットから文字に 行われるマッピングを完全かつ明確に述べ *なければならない*。特に、正確 なマッピングを決定するために外部プロフィール情報を使用する事は許され ない。 注意: ここで使われる "文字セット" という用語は、より一般的には "文 字エンコーディング" という語で述べられる。しかし、HTTP と MIME と で同じ登録を共有しているので、用語もまた共有される事は重要な事であ る。 HTTP 文字セットは大文字・小文字を区別しないトークンによって識別され る。トークンの完全なセットは、IANA の文字セット登録機構 [19] によって 定義される。 charset = token HTTP では、文字セットの値として独自のトークンを使用する事を認めている が、IANA の文字セット登録機構 [19] によって定義済みであるトークンは、 すべてその登録機構で定義された文字セットを表さ *なければならない*。ア プリケーションは、使用する文字セットを IANA の登録機構によって定義さ れたものに制限す *べきである*。 HTTP アプリケーションの開発者は、IETF の文字セット要求を認識す *べき である* [38] [41]。 3.4.1 Charset の誤り いくつかの HTTP/1.0 ソフトウェアは、"受領者が推測すべき"という意図 で、文字セットの無い Content-Type ヘッダを不正確に解釈している。この 振る舞いをやめさせたい送信者は、例え文字セットが ISO-8859-1 の時でも 文字セットパラメータを含む事が *できる* し、受領者が混乱する事が無い であろうという事がわかっていれば、それを含む *べきである*。 不幸な事に、いくつかの古い HTTP/1.0 クライアントでは、明示的文字コー ドパラメータを適切に扱えなかった。HTTP/1.1 の受領者は、送信者によって 供給される文字セットラベルを尊重し *なければならない*。そして、文字コ ードを "推測" する機能を持つユーザエージェントは、もしその文字セット をサポートしていれば、始めに文書を表示する時に、受領者が好むものより も content-type フィールドにある文字セットを使わ *なければならない*。 section 3.7.1 参照。 3.5 内容コーディング 内容コーディング値は、エンティティに適用されている、もしくは適用でき るエンコーディング変換を示す。内容コーディングは、文書をその根本的な メディアタイプのアイデンティティを失ったり、情報の欠落する事が無いよ うに、圧縮したり、他の有用な変換が行われる事を許可するために、主に使 用される。しばしば、エンティティはコード化された形態で保存され、直接 転送され、受け取り側によってのみデコードされる。 content-coding = token すべての content-coding 値は、大文字・小文字を区別しない。HTTP/1.1 で は、content-coding 値を Accept-Encoding (section 14.3) と Content-Encoding (section 14.11) ヘッダフィールドで使用する。その値は content-coding で表されるけれども、そのエンコーディングを解読するため にはどんなデコーディングメカニズムが必要であるかを示す事は、より重要 な事である。 Internet Assigned Numbers Authority (IANA) は、content-coding 値トー クンに対する登録を行なっている。初めに登録されているものには、以下の トークンが含まれる: gzip RFC 1952 [25] に記述されているファイル圧縮プログラム "gzip" (GNU zip) によって作られるエンコーディングフォーマット。このフォーマ ットは32 bit CRC 付きの Lempel-Ziv コーディング (LZ77) である。 compress 一般的な UNIX ファイル圧縮プログラム "compress" で作られるエンコ ーディングフォーマット。このフォーマットは Lempel-Ziv-Welch コー ディング (LZW) に適合している。 エンコーディングフォーマットの確認のためにプログラム名を使用する 事は望ましくなく、将来的なエンコーディングを妨害する。ここでのこ れらの使用は歴史的な慣例であり、決して良い方法ではない。HTTP の 過去のインプリメンテーションへの互換性のため、アプリケーションは "x-gzip" と "x-compress" をそれぞれ "gzip" と "compress" に等価 であるとみなす *べきである*。 deflate RFC 1951 [29] に記述されている "deflate" 圧縮メカニズムと結合し た、RFC 1950 [31] にて定義されている "zlib" フォーマット。 identity デフォルトエンコーディング、つまり圧縮・変形をしない場合に使う。 この content-coding 値は、Accept-Encoding ヘッダでのみ使用し、 Content-Encoding ヘッダでは使用す *べきではない*。 新しい content-coding 値トークンは登録される *べきである*。すなわち、 クライアントとサーバとの間での内部操作性を認めるため、新しい値を実装 する必要のある内容コーディングアルゴリズムの仕様は、広く利用できて、 独立したインプリメンテーションに適し、そしてこの章で定義された内容コ ーディングの目的に従う *べきである*。 3.6 転送コーディング 転送コーディング値は、ネットワークを通して "安全な転送" を保証するた めに、エンティティボディに適用されている、する事のできる、する必要の あるエンコーディング変換を示すために使われる。転送コーディングは、元 のエンティティではなくメッセージの特性である、という点で内容コーディ ングとは異なる。 transfer-coding = "chunked" | transfer-extension transfer-extension = token *( ";" parameter ) パラメータは、attribute/value ペアの形態を為す。 parameter = attribute "=" value attribute = token value = token | quoted-string すべての transfer-encoding 値は、大文字・小文字を区別しない。HTTP/1.1 では、TE ヘッダフィールド (section 14.39) と Transfer-Encoding ヘッダ フィールド (section 14.41) で転送コーディング値を使用している。 接続を閉じる事でメッセージの終了を示す場合以外に、転送コーディングが メッセージボディに適用される時は常に、転送コーディングのセットは "chunked" を含んでい *なければならない*。"chunked" 転送コーディングが 使われた時は、メッセージボディに適用される最後の転送コーディングにし *なければならない*。"chunked" 転送コーディングは、一度メッセージボデ ィに適用したら、それ以上適用し *てはならない*。これらのルールによっ て、受信者はメッセージの転送長さ (section 4.4) を決定できる。 転送エンコーディングは、MIME の Content-Transfer-Encoding 値 [7] と似 ていて、7-bit 転送サービス上でのバイナリデータの安全な転送を可能にす るために設計されている。しかし、完全な 8bit 転送プロトコルにおける安 全な転送とは異なる焦点を持つ。HTTP では、メッセージボディに特有の危険 さは、明確なボディ長 (section 7.2.2) を決定する事が困難な事や、共有さ れた転送経路上でデータの暗号化を望む、という事だけである。 Internet Assigned Numbers Authority (IANA) は、transfer-coding 値トー クンに対する登録を行なっている。初めに登録されているものには、以下の トークンが含まれる: "chunked" (section 3.6.1), "identity" (section 3.6.2), "gzip" (section 3.5), "compress" (section 3.5), "deflate" (section 3.5). (※) (※訳注) section 3.6.2 は、RFC 2616 中には存在しない。 新しい transfer-coding 値トークンは、新しい content-coding 値トークン と同様にして登録される *べきである* (section 3.5)。 理解できない transfer-coding を含むエンティティボディを受信したサーバ は、501 (Unimplemented) を返して接続を閉じる *べきである*。サーバは、 HTTP/1.0 クライアントに転送エンコーディングを送っ *てはならない*。 3.6.1 チャンク形式転送エンコーディング チャンク形式エンコーディングは、それぞれが自身のサイズ指標を持つ、一 連のチャンクと、エンティティヘッダフィールドを含む *オプショナルな* trailer を付加して転送するためにメッセージのボディを書き換える。 これによって、受信者が全メッセージを受信した事を確かめるために必要な 情報を、動的に生成された内容と一緒に転送できるようにする。 Chunked-Body = *chunk last-chunk trailer CRLF chunk = chunk-size [ chunk-extension ] CRLF chunk-data CRLF chunk-size = 1*HEX last-chunk = 1*("0") [ chunk-extension ] CRLF chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) chunk-ext-name = token chunk-ext-val = token | quoted-string chunk-data = chunk-size(OCTET) trailer = *(entity-header CRLF) chunk-size フィールドは、チャンクのサイズを示す 16 進数の数字列であ る。チャンク形式エンコーディングは、サイズが 0 のチャンクで終わり、空 行によって終わる物{trailer} が続く。 trailer では、送信者はメッセージの末尾に HTTP ヘッダフィールドを追加 できる。Trailer ヘッダフィールドは、trailer の中に含まれたヘッダフィ ールドを示すために使う事ができる。 レスポンスでチャンク形式転送コーディングを使うサーバは、以下のどれに も当てはまらなければ、ヘッダフィールドにおいて trailer を使っ *てはな らない*。 a)section 14.39 で示すように、"trailers" を表す TE ヘッダフィールドを 含むリクエストが、レスポンスの転送コーディングで受け入れ可能であ る。 b)そのサーバがレスポンスのオリジンサーバで、trailer フィールド全体が オプショナルなメタデータから成り、受信者はこのメタデータを受け入れ る事無しにその (マナーとしてオリジンサーバは受け入れ可能な) メッセ ージを使う事ができる。言い換えれば、オリジンサーバは、クライアント までの道のりの中で trailer フィールドが黙って廃棄されるかもしれない という可能性を受け入れる事を意図する。 この要求は、HTTP/1.1 (もしくはそれ以降) のプロクシがメッセージを受信 して、それを HTTP/1.0 の受信者に転送する時に、相互通信が失敗しないよ うにする。これは、もしかしたらプロクシに無限のバッファを送る必要があ るような規約を伴う承諾の場面を避ける。 Chunked-Body デコーディングのための例題過程は、付録の 19.4.6 で紹介さ れている。 すべての HTTP/1.1 アプリケーションは、"chunked" 転送コーディングを受 信しデコードでき *なければならない* し、理解できない転送コーディング 拡張は無視し *なければならない*。 3.7 メディアタイプ HTTP は、Content-Type (section 14.17) と Accept (section 14.1) ヘッダ フィールドにおいて、開放・拡張データタイプの決定やタイプネゴシエーシ ョンを供給するために Internet Media Type [17] を使用する。 media-type = type "/" subtype *( ";" parameter ) type = token subtype = token (section 3.6で定義されているように) attribute/value ペアの形態で、タ イプ/サブタイプがあり、その後にパラメータを置く事が *できる*。 タイプ、サブタイプ、パラメータ属性名は、大文字・小文字を区別しない。 しかし、パラメータ値は、パラメータ名のセマンティクスに依存するので、 大文字・小文字は区別されるかもしれない。連続した空白文字 (LWS: Linear white space) は、タイプとサブタイプの間や属性とその値の間で使われ *て はならない*。パラメータのある無しは、メディアタイプの定義に依存するの で、メディアタイプ決定のプロセスに重要なものとなるだろう。 古い HTTP アプリケーションの中には、メディアタイプパラメータを認識し ないものもある事に注意せよ。従って、インプリメンテーションが古い HTTP アプリケーションにデータを送る時は、タイプ/サブタイプ定義を要求した 場合に時のみ、メディアタイプパラメータを使用す *べきである*。 メディアタイプ値は、Internete Assigned Number Authority (IANA [19]) によって登録される。メディアタイプ登録手続きの方法は、RFC 1590 [17] において概説されている。登録されていないメディアタイプの使用は推奨さ れない。 3.7.1 公式化とテキストデフォルト インターネットメディアタイプは、公式の形式で登録される。HTTP メッセー ジ経由で転送されるエンティティボディは、次のパラグラフで定義されるよ うな "text" タイプを除けば、転送する前に、その適切な公式形式で表され *なければならない*。 公式形式では、"text" タイプのメディアサブタイプは、テキストの行末に CRLF を使う。HTTP では、エンティティボディ全体で一貫している場合は、 この要求をゆるめ、行末を表すのに単独の CR や LF をつけたテキストメデ ィアの転送を認めている。HTTP アプリケーションは、HTTP 経由で受信され るテキストメディアの行末表現として、CRLF, CR, LF を受け入れ *なければ ならない*。加えて、もしテキストが、幾つかのマルチバイト文字セットの 場合のように、CR と LF それぞれに対してオクテットの 13 と 10 が使われ ていないような文字セットで表現されているならば、HTTP は、行末の CR や LF と同等の表現をするための、その文字セットで定義されているどんなオク テットシーケンスの使用をも認める。行末に関するこの柔軟性は、エンティ ティボディ内のテキストメディアにのみ適用される。すなわち、(ヘッダフィ ールドやマルチパート境界等の) HTTP 制御構造では、いかなる単独の CR や LF も、CRLF に置き換え *てはならない*。 エンティティボディが内容エンコーディングでエンコードされている場合 は、根底のデータは、エンコードされる前には上で定義される形態をとって い *なければならない*。 "charset" パラメータは、データの文字セット (section 3.4) を定義するた めにいくつかのメディアタイプで使用されている。明示的な charset パラメ ータが送り側から供給されない時に、HTTP 経由で受信される "text" タイプ のメディアサブタイプは、デフォルトの charset である "ISO-8859-1" とい う値を持つと定義される。"ISO-8859-1" やそのサブセット以外の文字セット を使うデータは、適切な charset 値をラベル付け *なければならない*。互 換性の問題については section 3.4.1 参照。 3.7.2 マルチパートタイプ MIME は、一つのメッセージボディの中に複数のエンティティをカプセル化す る "multipart" タイプをいくつか供給する。すべてのマルチパートタイプは RFC 2046 [40] の section 5.1.1 で定義されているように、共通のシンタッ クスを共有し、メディアタイプ値の一部として境界パラメータ{boundary parameter} を含め *なければならない*。メッセージボディは、それ自身プ ロトコル要素の一部であり、それゆえに、body-parts 間の行末を表すために は CRLF のみを使用し *なければならない*。RFC 2046 と異なり、どのマル チパートメッセージのエピローグ{epilogue} も空でなければならない。その ため、HTTP アプリケーションは (たとえ元のマルチパートがエピローグを含 んでいても) エピローグを転送し *てはならない*。これらの制限は、最後の マルチパートの境界線によってメッセージボディの "終端" を示せるよう に、マルチパートのメッセージボディに自己限界性質{the self-delimiting nature} を持たせるために存在する。 一般的に、HTTP はマルチパートメッセージボディを他のメディアタイプとは 区別無く、すなわち単なる付加物{payload} として扱う。ただ一つ例外は、 206 (Partial Content) レスポンス中に現れる時の "multipart/byteranges" タイプ (appendix 19.2) であり、その場合 section 13.5.4 や section 14.16 で表されるような、いくつかの HTTP キャッシュメカニズムによって 解釈されるだろう。その他のすべての場合では、HTTP ユーザエージェント は、MIME ユーザエージェントがマルチパートタイプの受けとる時と同じ、ま たは似たような振る舞いをす *べきである*。マルチパートメッセージボディ の各々のボディ部分中の MIME ヘッダフィールドは、HTTP ではそれらの MIME セマンティクスによる定義以上にどんな意味も持たない。 一般的には、HTTP ユーザエージェントは、MIME ユーザエージェントがマル チパートタイプの受けとる時と同じ、または似たような振る舞いをす *べき である*。アプリケーションが認識できないマルチパートサブタイプを受け取 った場合は、それを "multipart/mixed" に相当するものとして扱わ *なけれ ばならない*。 注意: "multipart/form-data" タイプは、RFC 1867 [15] で表されるよう に、特に POST リクエストメソッド経由で処理するのに合ったフォームデ ータを転送するために特別に定義されている。 3.8 製品トークン 製品トークンは、ソフトウェアの名前とバージョンによってその製品である 事を識別するアプリケーションと通信する事ができるようにするために使わ れる。製品トークンで使用されるほとんどのフィールドは、アプリケーショ ンの重要な部分を形成する部分製品{sub-product} を空白で区切るように列 挙できるようになっている。慣習では、製品はそのアプリケーションを識別 するために重要なものの順に列挙される。 product = token ["/" product-version] product-version = token 例を見よ。 User-Agent: CERN-LineMode/2.15 libwww/2.17b3 Server: Apache/0.8.4 製品トークンは短く要点のみである *べきである*。宣伝や別の本質的でない 情報のために使用し *てはならない*。製品バージョンにはあらゆるトークン 文字を使用 *できる* が、このトークンはバージョン識別子に対してのみ使 われる *べきである*。(例えば、同じ製品の連続したバージョンは、製品値 の製品バージョン部分のみが異なる *べきである*)。 3.9 品質値 HTTP 内容ネゴシエーション (section 12) は、さまざまなネゴシエート可能 なパラメータの相対な重要性 ("ウェイト") を示すために短い "浮動小数点" 数を使う。ウェイトは、0 から 1 までの実数値と標準化され、0 は最小値で 1 は最大値である。もしパラメータが 0 の品質値を持っていたら、そのパラ メータと共にあるものはクライアントは「利用不可能」である。HTTP/1.1 ア プリケーションは、小数点以下で三桁を越える数字を生成し *てはならな い*。これらの値のユーザ設定も、この様式にかぎられる *べきである*。 qvalue = ( "0" [ "." 0*3DIGIT ] ) | ( "1" [ "." 0*3("0") ] ) "品質値" とは、単に要請される特質の相対的な格付けを示すものなので、実 際は誤った表現である。 3.10 言語タグ 言語タグは、他の人間との情報のコミュニケーションのため、人間によって 話され、書かれ、あるいは別の方法で伝えられる自然言語を識別する。コン ピュータ言語は完全に除外される。HTTP では、Accept-Language や Content-Language 各フィールドにおいて言語タグを使用する。 HTTP言語タグのシンタックスや登録は、RFC 1766 [1] で定義されたものと同 じである。要約すると、言語タグは、第1の言語タグと空の可能性のあるサブ タグのいくつかから成る。 language-tag = primary-tag *( "-" subtag ) primary-tag = 1*8ALPHA subtag = 1*8ALPHA ホワイトスペースはタグの中では認められず、すべてのタグで大文字・小文 字を区別しない。言語タグの名前空間は IANA によって管理されている。例 えば、言語タグには以下のような物がは含まれる。 en, en-US, en-cockney, i-cherokee, x-pig-latin 第一タグの二文字は、ISO-639 の言語短縮形であり、サブタグの最初の二文 字は、ISO-3166 カントリーコードである。(上記の後の三タグは登録されて いないタグである。しかし、すべて将来は登録されるかもしれないタグの例 である。) 3.11 エンティティタグ エンティティタグは、同一の要求リソースからの二つ以上のエンティティを 比較するために使用される。HTTP/1.1 では、ETag (section 14.19), If- Match (section 14.24), If-None-Match (section 14.26), If-Range (section 14.27) 各ヘッダフィールドで、エンティティタグを使う。それら がキャッシュバリディタとして、どのよう使われ、比較されるかの定義は、 section 13.3.3 にある。エンティティタグは、引用符で囲まれた opaque 文 字列から成り、weakness インジケータが前方に付く場合もある。 entity-tag = [ weak ] opaque-tag weak = "W/" opaque-tag = quoted-string "strong entity tag" では、もしそれらがオクテット文字によって同等の場 合にのみ、リソースの二つのエンティティが共有 *できる*。 "W/" プレフィクスによって示される "weak entity tag" では、エンティテ ィが等価であり、セマンティクスにおいてそれぞれ重要な変更がなく互いを 代わりに使う事ができる場合のみ、リソースの二つのエンティティが共有 *できる*。weak エンティティタグは、弱い比較の時のみ使用される。 エンティティタグは、特有のリソースと関連付けられたすべてのエンティテ ィのすべてのバージョンの中でユニークで *なければならない*。与えられた エンティティタグの値は、異なる URI へのリクエストから得られたエンティ ティのために使う事が *できる*。異なる URI へのリクエストから得られた エンティティに同じエンティティタグの値を使っているからといって、それ らのエンティティの同等性を暗に意味するものではない。 3.12 レンジ単位 HTTP/1.1 では、クライアントはレスポンス内に含まれるレスポンスエンティ ティの (範囲の) 一部だけを要求できる。HTTP/1.1 は、Range (section 14.35) と Content-Range (section 14.16) 各ヘッダフィールドにおいてレ ンジ単位を使用する。エンティティは、さまざまな構造上の単位に従ったサ ブレンジへと分解されるだろう。 range-unit = bytes-unit | other-range-unit bytes-unit = "bytes" other-range-unit = token HTTP/1.1 で定義されている唯一のレンジ単位は、"bytes" である。HTTP/1.1 インプリメンテーションは、別の単位を使って指定されたレンジは無視する 事が *できる*。 HTTP/1.1 では、アプリケーションの実装がレンジについての知識に依存しな いという事が認められる様に設計されている。 4 HTTP メッセージ 4.1 メッセージタイプ HTTPメッセージは、クライアントからサーバへのリクエストと、サーバから クライアントへのレスポンスから成る。 HTTP-message = Request | Response ; HTTP/1.1 messages リクエスト (section 5) と レスポンス (section 6) 各メッセージは、エン ティティ (メッセージの付加物) を転送するために RFC 822 [9] の一般的な メッセージフォーマットを使用する。両タイプとも、開始行、0 以上のヘッ ダフィールド ("headers"として知られているもの)、ヘッダフィールドの終 了を示す (CRLF の前に何もない行のような) 空行、そして任意のメッセージ ボディからなる。 generic-message = start-line *(message-header CRLF) CRLF [ message-body ] start-line = Request-Line | Status-Line 強い関心を持って、サーバは、Request-Line である事が期待できる位置で受 け取った空行はいかなるものも無視す *べきである*。言いかえれば、サーバ が、メッセージの開始地点からプロトコルストリームで読み出しを行って、 最初に CRLF を受信した場合、その CRLF は無視すべきである。 バグを持つ HTTP/1.0 クライアントインプリメンテーションの中には、POST リクエストの後に余計な CRLF を生成するものもある。BNF によって明示的 に禁止される事を再述すれば、HTTP/1.1 クライアントはリクエストの際に 余計 CRLF を前にも後ろにもつけ *てはならない*。 4.2 メッセージヘッダ 一般ヘッダ (section 4.5)、リクエストヘッダ (section 5.3)、レスポンス ヘッダ (section 6.2)、エンティティヘッダ (section 7.1) 各フィールドを 含む HTTP ヘッダフィールドは、RFC 822 [9] の Section 3.1 で与えられて いるものと同じである共通のフォーマットに従う。それぞれのヘッダフィー ルドは、名前、その後にコロン(":")、そしてフィールド値から成る。フィー ルド名は、大文字・小文字を区別しない。フィールド値には、いくつもの LWS を先行させる事が *できる* が、SP 一つだけが好ましい。ヘッダフィー ルドは、一つ以上の SP や HT をそれぞれの行頭につける事で複数行にまた がる事ができる。アプリケーションが HTTP 構造を生成する時には、"共通形 式" を超えたものは受け入れられないインプリメンテーションがいくつか存 在するであろう事を考慮し、知られている、あるいは示されている "共通形 式"に従うべきである。 message-header = field-name ":" [ field-value ] field-name = token field-value = *( field-content | LWS ) field-content = field-content は、LWS を前にも後ろにも、すなわち field-value の最初の 空白以外の文字の前にも、あるいは field-value の最後の空白以外の文字の 後ろにも、空行を含まない。そのような前後の LWS は、フィールド値のセマ ンティクスを変える事無く削除される *であろう*。field-content の間のい かなる LWS もフィールド値に解釈されたり、下流{downstream} に転送され る前に単なる SP に置き換えられる *であろう*。 異なるフィールド名を持つヘッダフィールドが受信される順序は、重要では ない。しかしながら、最初に一般ヘッダフィールド、その後にリクエストヘ ッダやレスポンスヘッダ、そして最後にエンティティフィールドを送る事が "良い習慣" である。 同じフィールド名を持つ複数のメッセージヘッダフィールドは、そのヘッダ フィールドの全体のフィールド値が [例えば、#(value) のように] コンマで 区切られたリストとして定義される場合にのみ、メッセージに存在 *でき る*。そしてそれら複数のヘッダフィールドは、最初の field-value に、コ ンマによって分けられたそれぞれの field-value を追加する事で、メッセー ジのセマンティクスを変える事無く、一つの "header-name: header-value" ペアに結合でき *なければならない*。それゆえ、同じフィールド名のヘッダ フィールドが受信される順番は、連結されたフィールド値の中間処理のため に重要なので、プロクシはメッセージを転送する時にはそれらのヘッダ値の 順番を変え *てはならない*。 4.3 メッセージボディ HTTPメッセージにメッセージボディがあったとしたら、それはリクエストや レスポンスに関連するエンティティボディを運ぶために使われる。メッセー ジボディは、Transfer-Encoding ヘッダフィールド (section 14.41) によっ て示されるように、転送コーディングが適用された場合のみ、エンティティ ボディとは異なる。 message-body = entity-body | Transfer-Encoding は、メッセージの安全かつ適切な転送を保障するアプリ ケーションによって、適用されるすべての転送コーディングを示すために使 われ *なければならない*。Transfer-Encoding は、メッセージの性質であ り、エンティティの性質ではないので、リクエスト/レスポンス連鎖に関わ るあらゆるアプリケーションによって追加されたり削除されたり *されう る*。(しかしながら、確実に転送コーディングが用いられているであろう時 のために、section 3.6 にて制限を設けている。) メッセージボディがメッセージにおいて認められるルールは、リクエストと レスポンスで異なる。 リクエストにおけるメッセージボディの存在は、リクエスト時にメッセージ ヘッダに Content-Length や Transfer-Encoding 各ヘッダフィールドを含む 事によって伝えられる。リクエスト時に、もし使用するリクエストメソッド (section 5.1.1) の定義で、リクエスト時にエンティティボディを送信する 事を許可していなければ、メッセージボディをリクエストに含ん *ではなら ない*。サーバは、どんなリクエストでもメッセージボディを読んで転送す *べきである*。すなわち、もしリクエストメソッドがエンティティボディに ついて定義されたセマンティクスを含んでいなければ、そのメッセージボデ ィはリクエストを処理した時に無視する *べきである*。 レスポンスメッセージでは、メッセージボディがメッセージに含まれている かどうかは、リクエストメソッドとレスポンスステータスコード (section 6.1.1) の両方に依存する。HEAD リクエストメソッドへのレスポンスは、た とえそこに含まれるエンティティヘッダフィールドがそうするようにあった としても、いかなる場合もメッセージボディを含ん *ではならない*。1xx (Information)、204 (no content)、304 (not modified) レスポンスでは、 すべてメッセージボディを含ん *ではならない*。その他のレスポンスでは、 その長さはゼロである *かもしれない* が、すべてメッセージボディを含ん でいる。 4.4 メッセージの長さ メッセージの転送長さ{transfer-length} は、それがメッセージの中に現れ た時、つまりある転送コーディングが適用された後のメッセージボディの長 さである。メッセージボディがメッセージに含まれる時、そのボディの転送 長さは以下のうちのどれかで決定される (優先順位順)。 1.メッセージボディを含ん "*ではならない*" (1xx, 204, 304 レスポンスや HEAD リクエストに対するすべてのレスポンス) レスポンスメッセージは、 メッセージ中にエンティティヘッダフィールドがあるか無いかに関わら ず、常にヘッダフィールドの後の最初の空行で終了する。 2.もし、Transfer-Encoding ヘッダフィールド (section 14.41) があり、 "identity" 以外の値を持っていて、接続を閉じる事でメッセージが終了し ているのでなければ、転送長さは "chunked" エンコーディング (section 3.6) の使用によって定義される。 3.もし、Content-Length ヘッダフィールド(section 14.14) があれば、その オクテット中の10進数の値は、エンティティ長さ{entity-length} と転送 長さを表す。もしそれら二つの長さが違うのならば、Content-Length ヘッ ダフィールドを送っ *てはならない* (例えば、Transfer-Encoding がある 場合)。もし、メッセージが Transfer-Encoding ヘッダフィールドと Content-Length ヘッダフィールドとを一緒に送ってきたならば、後者は無 視し *なければならない*。 4.もし、メッセージがメディアタイプ "multipart/byteranges" を使い、そ の転送長さが別の方法で特定できなければ、自身で区切りを持つこのメデ ィアタイプは、その転送長さを定義する。送信者は、受信者がこのメディ アタイプを解析できる事という事を知らないのでならば、使っ *てはなら ない*。リクエスト時の複数のバイトレンジを持つ Range ヘッダの存在 は、クライアントが multipart/byterange レスポンスを解析できる事を暗 黙的に意味する。 multipart/byterange を理解しない HTTP/1.0 プロクシは、Range ヘッ ダを転送するだろう。この場合、サーバはこの章で定義されているうち の 1, 3, 5 の項目のいずれかの方法を使って、このメッセージを制御し *なければならない*。 5.接続を閉じるサーバによる。(サーバがレスポンスを送り返す可能性がある 事を捨て置けないので、リクエストボディの終了を示すために接続を閉じ じるという方法は、使えない。) HTTP/1.0 アプリケーションへの互換性のため、メッセージボディを含む HTTP/1.1 リクエストは、もしサーバが HTTP/1.1 に準じている事を知らなけ れば、適した Content-Length ヘッダフィールドを含ま *なければならな い*。もし、リクエストがメッセージボディを含んでいて、Content-Length を含んでいなかったら、サーバは、それによってメッセージの長さが決定で きない場合は 400 (bad request) を、有効な Content-Length を受けとりた い場合は 411 (length required) を、それぞれ返す *べきである*。 エンティティを受け取るすべての HTTP/1.1 アプリケーションは、"chunked" 転送エンコーディング (section 3.6) を受け入れられ *なければならない* ので、メッセージ長が前もって決定できない時には、このメカニズムをメッ セージに対して使う事が認められる。 メッセージには、Content-Length ヘッダフィールドと identity でない転送 コーディングの両方を含ん *ではならない*。メッセージが、identity でな い転送コーディングを含んでいたら、Content-Length は無視され *なければ ならない*。 メッセージボディが認められるメッセージにて Content-Length が与えられ る時には、そのフィールド値はメッセージボディにおけるオクテットの数と 正確に一致し *なければならない*。HTTP/1.1 ユーザエージェントは、不正 な長さが受信されたり検出された時には、それをユーザに通知し *なければ ならない*。 4.5 一般ヘッダフィールド リクエストとレスポンスの両メッセージで、一般的な適用性を持つが、転送 されたエンティティには適用されないヘッダがいくつかある。これらのヘッ ダフィールドは、伝えられているメッセージに対してのみ適用する。 general-header = Cache-Control ; Section 14.9 | Connection ; Section 14.10 | Date ; Section 14.18 | Pragma ; Section 14.32 | Trailer ; Section 14.40 | Transfer-Encoding ; Section 14.41 | Upgrade ; Section 14.42 | Via ; Section 14.45 | Warning ; Section 14.46 一般ヘッダフィールド名は、プロトコルバージョンの変化に伴う連動におい てのみ確実に拡張されうる。しかしながら、新しい、あるいは実験的なヘッ ダフィールドは、もしそのコミュニケーションでのすべてのパーティがそれ らを一般ヘッダフィールドであると認識できるなら、一般的なヘッダフィー ルドのセマンティクスを与えてもよい。認識されないヘッダフィールドは、 エンティティヘッダフィールドとして扱われる。 5 リクエスト クライアントからサーバへのリクエストメッセージには、リソースに適用さ れるメソッド、リソースの識別子、使用するプロトコルのバージョンが最初 の行に含まれる。 Request = Request-Line ; Section 5.1 *(( general-header ; Section 4.5 | request-header ; Section 5.3 | entity-header ) CRLF) ; Section 7.1 CRLF [ message-body ] ; Section 4.3 5.1 リクエストライン リクエストラインは、メソッドトークンに始まり、 Request-URI とプロトコ ルバージョンが後に続き、CRLF で終了する。要素は SP によって分けられ る。最後の CRLF シーケンス以外には、CR も LF も許されない。 Request-Line = Method SP Request-URI SP HTTP-Version CRLF 5.1.1 メソッド メソッドトークンは、 Request-URI により識別されるリソースに働きかける ためのメソッドを示す。メソッドは大文字・小文字を区別する。 Method = "OPTIONS" ; Section 9.2 | "GET" ; Section 9.3 | "HEAD" ; Section 9.4 | "POST" ; Section 9.5 | "PUT" ; Section 9.6 | "DELETE" ; Section 9.7 | "TRACE" ; Section 9.8 | "CONNECT" ; Section 9.9 | extension-method extension-method = token リソースにより認められるメソッドのリストは、Allow ヘッダフィールド (section 14.7) により示される。許されるメソッドのセットは動的に変化で きるため、レスポンスのリターンコードはそのメソッドが現在リソースに許 されているかどうかにかかわらず、常にクライアントに通知される。オリジ ンサーバは、メソッドを理解できても要求されたリソースに対して許されて いない場合は、ステータスコード 405 (Method Not Allowed) を返す *べき であり*、またオリジンサーバがそのメソッドを認識できなかったり実装され ていない場合には 501 (Not Implemented) を返す *べきである*。すべての 一般目的サーバ{general-purpose servers} では、GET とHEAD メソッドは、 サポートしてい *なければならない*。他のすべてのメソッドは *オプショナ ル* であるが、もし上記のメソッドが実装されるなら、それらは section 9 で記述されているものと同じセマンティクスで実装されなければならない。 5.1.2 Request-URI Request-URI は、Uniform Resource Identifier (section 3.2) であり、リ クエストを適用するリソースを識別する。 Request-URI = "*" | absoluteURI | abs_path | authority Request-URI の四つのオプションは、そのリクエストの性質に依存する。ア スタリスク "*" は、そのリクエストが特有のリソースではなく、サーバ自身 に適用するという事を意味し、使われているメソッドがリソースに適用され る必要がないときにのみ許される。一例を挙げる。 OPTIONS * HTTP/1.1 absoluteURI 形式は、リクエストがプロクシに対して生成されている時に *要求される*。プロクシは、そのリクエストを転送するか、有効なキャッシ ュ内から提供する時に呼び出され、レスポンスを返す。プロクシは、そのリ クエストを別のプロクシか、あるいは absoluteURI によって特定されたサー バに直接送る事が *できる* 事に注意せよ。リクエストループを避けるため に、プロクシはそのサーバ名をエイリアス、ローカルバリエーション、数値 IP アドレスまで含め、すべて理解でき *なければならない*。Request-Line の例は以下の様になる。 GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1 HTTP の将来のバージョンにおいてすべてのリクエストが absoluteURI へ移 行する事ができるように、例え HTTP/1.1 クライアントはプロクシへのリク エストとしてのみしか生成しないものであったとしても、全ての HTTP/1.1 サーバはリクエストにおける absoluteURI 形式を受け入れ *なければならな い*。 authority 形式は、CONNECT メソッド (section 9.9) のみで使用する。 Request-URI の最も一般的な形式は、オリジンサーバやゲートウェイ上の リソースを識別するために使用される事である。この場合、URI の絶対パス は Request-URI として通信され *なければならない* (section 3.2.1, abs_path 参照) し、URI のネットワークロケーション(authority) は、Host ヘッダフィールドにおいて転送され *なければならない*。例えば、オリジン サーバから直接上記のリソースを回収する事を望むクライアントは、ホスト "www.w3.org" のポート 80 に TCP 接続を確立し、その行を送る。 GET /pub/WWW/TheProject.html HTTP/1.1 Host: www.w3.org 残りのリクエストをその後に送る。絶対パスは空ではない事に注意せよ。も し、元の URI で何も与えられていなければ、それは "/" (サーバのルート) が与えられ *なければならない*。 Request-URI は、section 3.2.1 に記された形式で送られる。もし、 Request-URI に "% HEX HEX" エンコード [42] が使用されていたら、オリジ ンサーバはそのリクエストを適切に解釈するためにその Request-URI をデコ ードし *なければならない*。サーバは、不正な Request-URI には、適切な ステータスコードをもって応答す *べきである*。 透過的プロクシは、上で記した空の{null} abs_path を "/" に置き換えると いう場合以外は、次のインバウンドサーバに転送する時に、受け取った Request-URI の "abs_path" の一部を書き換え *てはならない*。 注意: "書き換え禁止" という規則は、オリジンサーバが予約された目的 のための予約されていない URL 文字を不適当に使用している時に、プロ クシがリクエストの意味を変えないようにする狙いがある。実装者は、い くつかの HTTP/1.1 以前のプロクシが Request-URI を書き換える事が知 られている、という事を認識すべきである。 5.2 リクエストによって識別されるリソース インターネットリクエストにより識別された正確なリソースは、Request-URI と Host ヘッダフィールドの両方で調べる事で決定される。 HTTP/1.1 リクエストによってリソースを決定する時、リクエストされたホス トによってリソースが異なるという事を認めていないオリジンサーバは、 Host ヘッダフィールド値を無視するで *あろう*。(但し、HTTP/1.1 での Host をサポートする別の必要条件について section 19.6.1.1 参照。) リクエストされたホストに基づいてリソースを区別する (しばしば仮想ホス トや空虚{vanity} なホスト名として参照される) オリジンサーバは、 HTTP/1.1 リクエストで要求されたリソースを決定するために以下のルールを 使わ *なければならない*。 1.もし、Request-URI が absoluteURI ならば、ホストは Request-URI の一 部である。リクエストにおけるどんな Host ヘッダフィールド値も無視さ れ *なければならない*。 2.もし、Request-URI が absoluteURI でなく、リクエストが Host ヘッダフ ィールドを含んでいるならば、ホストは Host ヘッダフィールド値によっ て決定される。 3.もし、規則 1 や 2 で決定されるようなホストがそのサーバで正当なホス トでないならば、レスポンスは 400 (Bad Request) エラーメッセージで *なければならない*。 Host ヘッダフィールドが無い HTTP/1.0 リクエストを受信した者は、要求さ れたリソースがどれほど正確な要求されているかを決定するため (例えば、 特定のホストのユニークな何かに対する URI パスの試験のような) 発見方法 を試す事が *できる*。 5.3 リクエストヘッダフィールド リクエストヘッダフィールドを用いて、クライアントはサーバにリクエスト やクライアント自身に関する追加的な情報を渡す事ができる。これらのフィ ールドは、メソッド発動{invocation} プログラミング言語におけるパラメー タと同等なセマンティクスを持つ、リクエスト修飾子として動作する。 request-header = Accept ; Section 14.1 | Accept-Charset ; Section 14.2 | Accept-Encoding ; Section 14.3 | Accept-Language ; Section 14.4 | Authorization ; Section 14.8 | Expect ; Section 14.20 | From ; Section 14.22 | Host ; Section 14.23 | If-Match ; Section 14.24 | If-Modified-Since ; Section 14.25 | If-None-Match ; Section 14.26 | If-Range ; Section 14.27 | If-Unmodified-Since ; Section 14.28 | Max-Forwards ; Section 14.31 | Proxy-Authorization ; Section 14.34 | Range ; Section 14.35 | Referer ; Section 14.36 | TE ; Section 14.39 | User-Agent ; Section 14.43 リクエストヘッダフィールド名は、プロトコルバージョンの変化に伴っての み確実に拡張されうる。しかしながら、新しい、あるいは実験的なヘッダフ ィールドは、もしそのコミュニケーションでのすべてのパーティがそれらを リクエストヘッダフィールドであると認識できるなら、一般的なヘッダフィ ールドのセマンティクスを与えても *よい*。認識されないヘッダフィールド は、エンティティヘッダフィールドとして扱われる。 6 レスポンス リクエストメッセージを受信・解釈した後、サーバは HTTP レスポンスメッ セージを返す。 Response = Status-Line ; Section 6.1 *(( general-header ; Section 4.5 | response-header ; Section 6.2 | entity-header ) CRLF) ; Section 7.1 CRLF [ message-body ] ; Section 7.2 6.1 ステータスライン レスポンスメッセージの最初の行は、プロトコルのバージョン、ステータス コード番号、それに関連したテキストフレーズからなるステータスライン で、それぞれの要素は、SP によって分けられる。最後の CRLF シーケンス以 外には、CR も LF も許されない。 Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF 6.1.1 ステータスコードと説明句 ステータスコード要素とは、リクエストを理解し満足するための試行につい ての三桁の数字による結果コードである。これらのコードは、section 10 に て完全に定義されている。説明句は、ステータスコードについて短いテキス ト記述を与える目的を持つ。ステータスコードは自動処理によって、また説 明句は人間によってそれぞれ使われる事を意図している。クライアントは、 説明句を調べたり表示したりする必要はない。 ステータスコードの最初の数字はレスポンスのクラスを定義する。後ろの二 つの数字はどんな分類ルールも持たない。最初の数字には五つの値がある。 - 1xx: Informational - リクエストは受け入れられ、処理を続けている - 2xx: Success - 動作は正常に受信され、理解され、受け入れられた - 3xx: Redirection - リクエストを完了するためには、さらに動作を行 わなければならない - 4xx: Client Error - リクエストは間違った構文か、果たす事のできな いものを含んでいる - 5xx: Server Error - サーバは明らかに正当なリクエストを果たすのに 失敗した HTTP/1.1 で定義された個々のステータスコード数値、及びそれに相当する説 明句のセットの例の値を以下に示す。ここでリストされた説明句は推奨に過 ぎない。すなわち、これらはプロトコルに影響が出ないローカルな範囲で、 それに相当するものに置き換えても *よい*。 Status-Code = "100" ; Section 10.1.1: Continue | "101" ; Section 10.1.2: Switching Protocols | "200" ; Section 10.2.1: OK | "201" ; Section 10.2.2: Created | "202" ; Section 10.2.3: Accepted | "203" ; Section 10.2.4: Non-Authoritative Information | "204" ; Section 10.2.5: No Content | "205" ; Section 10.2.6: Reset Content | "206" ; Section 10.2.7: Partial Content | "300" ; Section 10.3.1: Multiple Choices | "301" ; Section 10.3.2: Moved Permanently | "302" ; Section 10.3.3: Found | "303" ; Section 10.3.4: See Other | "304" ; Section 10.3.5: Not Modified | "305" ; Section 10.3.6: Use Proxy | "307" ; Section 10.3.8: Temporary Redirect | "400" ; Section 10.4.1: Bad Request | "401" ; Section 10.4.2: Unauthorized | "402" ; Section 10.4.3: Payment Required | "403" ; Section 10.4.4: Forbidden | "404" ; Section 10.4.5: Not Found | "405" ; Section 10.4.6: Method Not Allowed | "406" ; Section 10.4.7: Not Acceptable | "407" ; Section 10.4.8: Proxy Authentication Required | "408" ; Section 10.4.9: Request Time-out | "409" ; Section 10.4.10: Conflict | "410" ; Section 10.4.11: Gone | "411" ; Section 10.4.12: Length Required | "412" ; Section 10.4.13: Precondition Failed | "413" ; Section 10.4.14: Request Entity Too Large | "414" ; Section 10.4.15: Request-URI Too Large | "415" ; Section 10.4.16: Unsupported Media Type | "416" ; Section 10.4.17: Requested range not satisfiable | "417" ; Section 10.4.18: Expectation Failed | "500" ; Section 10.5.1: Internal Server Error | "501" ; Section 10.5.2: Not Implemented | "502" ; Section 10.5.3: Bad Gateway | "503" ; Section 10.5.4: Service Unavailable | "504" ; Section 10.5.5: Gateway Time-out | "505" ; Section 10.5.6: HTTP Version not supported | extension-code extension-code = 3DIGIT Reason-Phrase = * HTTP ステータスコードは拡張可能である。HTTP アプリケーションは、登録 されたすべてのステータスコードを明確に理解できる事が望ましいが、それ らのすべての意味を理解する必要はない。しかし、アプリケーションは最初 の数字によって示されるステータスコードのクラスはすべて理解し *なけれ ばならない* し、理解できないレスポンスはキャッシュし *てはならない* という例外を除いて、すべての理解できないレスポンスをそのクラスの x00 ステータスコードと同等に扱わ *なければならない*。例えば、431 という 理解できないステータスコードがクライアントに受信されたなら、そのリク エストに何か誤りがあると安全に推測ができ、それが 400 ステータスコード を受信したかのようにレスポンスを扱う事ができる。このような場合、エン ティティはこの異常なステータスを説明しているであろう人間が読める情報 を含んでいると思われるから、ユーザエージェントはレスポンスと共に返さ れたエンティティをユーザに見せる *べきである*。 6.2 レスポンスヘッダフィールド レスポンスヘッダフィールドを用いて、サーバはステータスラインに置けな いレスポンスに関する追加的な情報を渡す事ができる。これらのヘッダフィ ールドは、サーバについてや、Request-URI によって識別されるリソースへ の更なるアクセスに関する情報を与える。 response-header = Accept-Ranges ; Section 14.5 | Age ; Section 14.6 | ETag ; Section 14.19 | Location ; Section 14.30 | Proxy-Authenticate ; Section 14.33 | Retry-After ; Section 14.37 | Server ; Section 14.38 | Vary ; Section 14.44 | WWW-Authenticate ; Section 14.47 レスポンスヘッダフィールド名は、プロトコルバージョンの変化に伴っての み確実に拡張されうる。しかしながら、新しい、あるいは実験的なヘッダフ ィールドは、もしそのコミュニケーションでのすべてのパーティがそれらを レスポンスヘッダフィールドであると認識できるなら、一般的なヘッダフィ ールドのセマンティクスを与えても *よい*。認識されないヘッダフィールド は、エンティティヘッダフィールドとして扱われる。 7 エンティティ リクエストやレスポンスでのメッセージは、リクエストメソッドやレスポン スステータスコードによって規制されていなければ、エンティティを転送す る事が *できる*。エンティティは、エンティティヘッダフィールドとエンテ ィティボディから成るが、エンティティヘッダのみを含むレスポンスもあ る。 この章においては、送信者と受信者の両方がクライアントかサーバのどちら かを表すが、それはエンティティを送信するか受信するかに依存する。 7.1 エンティティヘッダフィールド エンティティヘッダフィールドは、エンティティボディや、もしボディが無 ければリクエストによって識別されたリソースについての外部情報を定義す る。この外部情報は、*オプションナル* なものもあるが、この仕様書の中で *要求している* ものもある。 entity-header = Allow ; Section 14.7 | Content-Encoding ; Section 14.11 | Content-Language ; Section 14.12 | Content-Length ; Section 14.13 | Content-Location ; Section 14.14 | Content-MD5 ; Section 14.15 | Content-Range ; Section 14.16 | Content-Type ; Section 14.17 | Expires ; Section 14.21 | Last-Modified ; Section 14.29 | extension-header extension-header = message-header 拡張ヘッダメカニズムは、プロトコルを変更する事無く追加的エンティティ ヘッダフィールドを定義できるようにしているが、これらのフィールドが受 信者によって認識されるという事は仮定できない。認識されないヘッダフィ ールドは、受信者によって無視される *べきであり*、透過的プロクシによっ て転送され *なければならない*。 7.2 エンティティボディ もし、HTTP リクエストやレスポンスと共にエンティティボディが送られてき たら、それはエンティティヘッダフィールドによって定義されるフォーマッ トをもってエンコーディングされている。 entity-body = *OCTET エンティティボディは、section 4.3 に記されるように、メッセージボディ がある時のみ、メッセージの中に存在する。エンティティボディは、メッセ ージの安全かつ適切な転送を保証するために適用されるであろうあらゆる転 送エンコーディングをデコードする事によってメッセージボディから得られ る。 7.2.1 タイプ エンティティボディがメッセージに含まれる時、このボディのデータタイプ は Content-Type と Content-Encoding 各ヘッダフィールドによって決定さ れる。これらは、2層の順列エンコーディングモデル {ordered encoding model} を定義する。 entity-body := Content-Encoding( Content-Type( data ) ) Content-Type は、元のデータのメディアタイプを示す。Content-Encoding は、要求されたリソースが持つデータを、通常はデータ圧縮という目的のた めに適用されるあらゆる追加的な内容コーディングを示すために使われるで あろう。デフォルトのエンコーディングはない。 エンティティボディを含む HTTP/1.1 メッセージは、いつでもそのボディの メディアタイプを定義するための Content-Type ヘッダフィールドを含む *べきである*。メディアタイプが Content-Type ヘッダによって与えられな い場合に限り、受信者はリソースの内容の検査や、あるいはリソースを識別 するために使用されている URI の名前拡張子を調べる事によってメディアタ イプを推測してみても *よい*。もしメディアタイプが分からないままであっ たら、受信者はそれをタイプ "application/octet-stream" として扱う *べ きである*。 7.2.2 エンティティ長 メッセージのエンティティボディ長は、あらゆる転送エンコーディングが適 用される前のメッセージボディの長さである。section 4.4 では、どのよう にメッセージボディの転送長さが決められているかを定義している。 8 接続 8.1 持続的接続 8.1.1 目的 持続的接続が無い時代には、別々の URL からリソースを取得するために、そ れぞれで TCP 接続を確立していたため、サーバのロードを増加させ、インタ ーネットの混雑を引き起こす原因になっていた。インラインイメージやその 他の関連するデータの使用のために、クライアントはしばしば短時間に同じ サーバへ複数のリクエストを行う必要がある。これらのパフォーマンスの問 題の解析や持続的接続のプロトタイプの実装から得られた結果については、 現在入手可能である [26] [30]。持続的接続を実装する過程で得た経験や、 実際に HTTP/1.1 (RFC 2068) を実装したものを測定した所、良い結果が得ら れた [39]。また一方で、例えば T/TCP [27] のような、違う選択肢も研究さ れてきている。 持続的 HTTP 接続には、いくつかの利点がある。 - TCP コネクションの開閉が少なくなる事で、ルータやホスト (クライア ント、サーバ、プロクシ、ゲートウェイ、トンネル、キャッシュ) にお ける CPU 時間は節約され、TCP プロトコルコントロールブロックのた めに使用されるメモリも節約される。 - HTTP リクエストとレスポンスは、接続上でパイプライン化する事がで きる。パイプライン化によって、クライアントは、各々のレスポンスを 待つ事なく複数のリクエストを行う事ができ、また一つの TCP 接続を より少ない経過時間で、より効果的に使用できる。 - TCP のオープンや、TCP sufficient time にネットワークの混雑状況を 決定させるために使われるパケットの数の減少によって、ネットワーク における混雑は減少される。 - TCP 接続がすでに確立しているので、次回リクエスト時にはそのための 時間が必要無く、リクエストへの反応時間は短縮される。 - TCP 接続を閉じるという罰則無しにエラーを報告できるため、HTTP は より上品に発展する。もし古いサーバと通信するとしても、HTTP の将 来のバージョンを使用するクライアントは、楽天的に新しい機能を試み る事ができ、エラー報告の後には古いセマンティクスが伴う再試行も報 告されるであろう。 HTTP インプリメンテーションは持続的接続を実装す *べきである*。 8.1.2 全体の動作 HTTP/1.1 と HTTP のそれ以前のバージョンとの重要な違いは、すべての HTTP 接続において持続的な接続がデフォルトの動作であるかどうかという事 である。すなわち、何か別の方法が示されない限り、クライアントは、例え サーバからエラーレスポンスが返されても、サーバが持続的接続を維持する であろうと仮定す *べきである*。 持続的接続は、クライアントとサーバが TCP 接続を閉じる時に合図を行える というメカニズムを提供する。この合図は、Connection ヘッダフィールド (section 14.10) を用いて示す。一度接続を閉じる事が示されたら、クライ アントはその接続でそれ以上のリクエストを送っ *てはならない*。 8.1.2.1 ネゴシエーション HTTP/1.1 サーバは、HTTP/1.1 クライアントがリクエスト中に "close" とい う connection-token を含んでいる Connection ヘッダを送られなければ、 持続的接続を維持するつもりである事を想定しても *よい*。もし、サーバが レスポンスを送信した後すぐに接続を閉じる事を選ぶのであれば、 connection-token に close を含んでいる Connection ヘッダを送信す *べ きである*。 HTTP/1.1 クライアントは、接続が開いたままである事を期待しても *よい* が、サーバからのレスポンスが connection-token が close である Connection ヘッダを含んでいるかどうかに基づいて回線の維持についてを決 めるであろう。クライアントがそのリクエスト以上に接続を維持する事を望 まない場合は、connection-token に close を含む Connection ヘッダを送 る *べきである*。 もし、クライアントかサーバのどちらかが、Connection ヘッダにおいて close トークンを送ったならば、そのリクエストはその接続に対する最後の ものとなる。 クライアントやサーバは、それが明確に合図された場合以外は、1.1 よりも 低い HTTP のバージョンにおいては、持続的接続が維持されていると仮定す *べきではない*。HTTP/1.0 クライアントとの下位互換性に必要な情報につい ては section 19.6.2 参照。 持続性を維持するために、接続上のすべてのメッセージは section 4.4 で定 義されているように、自身で定義した (例えばそれが接続の閉鎖によって定 義されるようなものではない) メッセージ長さを持た *なければならない*。 8.1.2.2 パイプライン化 持続的接続をサポートするクライアントは、そのリクエストを "パイプライ ン" する事が *できる* (例えば、複数のレスポンスを待つ事無く、複数のリ クエストを送る)。サーバは、リクエストが受信されたのと同じ順番で、それ らのリクエストのレスポンスを返さ *なければならない*。 持続的接続を想定し、接続確立の後にすぐパイプラインを行うクライアント は、もし最初のパイプライン化への試行が失敗した場合は、それらの接続を 再試行する準備をす *べきである*。クライアントがそのような再試行を行う 場合は、その接続が持続的であると分かるまではパイプラインを行っ *ては ならない*。もし、サーバがすべての通信のレスポンスを返す前に接続を閉 じてしまったら、クライアントはそれらのリクエストを再送信する準備をし *なければならない*。 クライアントは、等冪でない{non-idempotent} メソッド、あるいはメソッド のシーケンスを使ったリクエストをパイプラインす *べきではない* (section 9.1.2 参照)。そうでなければ、転送接続の早過ぎる終了が不確定 な結果を招く事になるだろう。等冪でないリクエストを送ろうとするクライ アントは、前のリクエストのレスポンスステータスを受け取るまでリクエス トを送る事を待つ *べきである*。 8.1.3 プロクシサーバ プロクシが section 14.10 で指定されるように Connection ヘッダの機能を 正確に実装する事は特に重要である。 プロクシサーバは、自身が接続しているクライアントとオリジンサーバ (あ るいは別のプロクシサーバ) のそれぞれに持続的接続を知らせ *なければな らない*。それぞれの持続的接続は、一つの転送リンクのみで適用される。 プロクシサーバは、HTTP/1.0 クライアントと HTTP/1.1 の持続的接続を確立 し *てはならない* (但し、多くの HTTP/1.0 クライアントに実装されている Keep-Alive ヘッダを使った問題の情報と議論については RFC 2068 [33] 参 照)。 8.1.4 現実的な考察 多くのサーバは、もはや接続を維持しないとするタイムアウト値を持ってい るであろう。クライアントはたぶん同じサーバへとより多くの接続を持とう とするはずなので、プロクシサーバはサーバが設定するタイムアウト値より も大きな値にしたほうがよい。持続的接続の使用は、クライアントやサーバ のためのこのタイムアウト値の長さ (あるいは存在) に必要性を置かない。 クライアントやサーバがタイムアウトを望む時は、転送接続上礼儀正しい閉 鎖を発行す *べきである*。クライアントもサーバも、他方の転送の閉鎖を絶 えず監視し、適切にそれに応じる *べきである*。もし、クライアントやサー バが、相手側の閉鎖を即座に検出しなければ、それはネットワーク上の不必 要なリソース消耗を引き起こすかもしれない。 クライアント、サーバ、あるいはプロクシは、どんな時でも転送接続を閉鎖 する事が *できる*。例えば、サーバが "アイドル" 状態の接続を閉鎖しよう と決めたのと同時に、クライアントは新しいリクエストを送り始めるかもし れない。サーバ側から見れば接続はアイドルである間に閉鎖されているが、 クライアント側から見ればリクエストは進行中である。 これは、クライアント、サーバ、プロクシが、非同期のクローズイベントか ら回復でき *なければならない* という事を意味する。クライアントソフト ウェアは転送接続を再度オープンし、リクエストシーケンスが等冪 {idempotent} (section 9.1.2 参照) である限り、ユーザインタラクション なしに中止されたリクエストのシーケンスを再送信す *べきである*。そうで ないメソッドやシーケンスは自動的に再試行し *てはならない* が、ユーザ エージェントは人間のオペレータにリクエストの再試行についての選択を尋 ねても *よい*。アプリケーションが意味を理解した上で、ユーザ自身の確認 の代わりにユーザエージェントソフトウェアが確認しても *よい*。この自動 再試行は、もし二回目のリクエストシーケンスが失敗したなら繰り返す *べ きではない*。 サーバは、もし完全に可能なら、常に一つの接続につき少なくとも一つのリ クエストにレスポンスす *べきである*。サーバは、ネットワークやクライア ントの失敗を疑う場合以外は、レスポンスの転送中に接続をクローズす *べ きではない*。 持続的接続を使用するクライアントは、サーバへ維持する同時接続の数を制 限す *べきである*。シングルユーザクライアントは、どんなサーバやプロク シへも 2 接続より多く維持す *べきではない*。プロクシは、N は同時のア クティブユーザの数として、別のサーバやプロクシへの 2*N 接続以上を使用 す *べきである*。これらのガイドラインは HTTP レスポンスタイムを改善 し、ネットワークの混雑を避けようとするものである。 8.2 メッセージ転送の必要条件 8.2.1 持続的接続とフローコントロール HTTP/1.1 サーバは、一時的な過負荷を解消するためには、持続的接続を維持 し、TCP フローコントロールメカニズムを使う *べきであり*、クライアント が再試行するであろうという期待を持って接続を終了させるよりもよい。後 者の方法ではネットワークの混雑はよりひどくなるであろう。 8.2.2 エラーステータスメッセージのための接続のモニタリング メッセージボディを送る HTTP/1.1 (あるいはそれ以降) のクライアントは、 リクエストを送っている間、エラーステータスのためにネットワークの接続 をモニタリングす *べきである*。エラーステータスを発見した場合、すぐに ボディの転送を止める *べきである*。もしボディに "chunked" エンコーデ ィング (section 3.6) を施していたら、早過ぎるメッセージの終わりを表す ために 0 サイズのチャンクと空の trailer を使う事が *できる*。もしボデ ィより Content-Length ヘッダが先に送られていたら、クライアントは接続 を閉じ *なければならない*。 8.2.3 100 (Continue) ステータスの使用 100 (Continue) ステータス (section 10.1.1 参照) は、オリジンサーバが クライアントがリクエストボディを送る前に (リクエストヘッダに基づいた) リクエストを受け入れようとする場合に、リクエストボディを伴ったリクエ ストメッセージを送る事をクライアントに決めさせるという目的を持つ。い くつかのケースでは、サーバがボディを見る事も無くメッセージを受けつけ ていない場合にクライアントがボディを送る事は、不適切でひどく効率が悪 くなる事がある。 HTTP/1.1 クライアントの必要条件は、以下の通りである。 - もしクライアントがリクエストボディを送る前に 100 (Continue) レス ポンスのために待とうとするならば、"100-continue" という expectation を持った Expect リクエストヘッダフィールド(section 14.20) を送ら *なければならない*。 - もしリクエストボディを送るつもりが無いならば、"100-continue" と いう expectation を持った Expect リクエストヘッダフィールド (section 14.20) を送っ *てはならない*。 未だに古いインプリメンテーションが存在するため、プロトコルではクライ アントが 417 (Expectation Failed) ステータスや 100 (Continue) ステー タスを受け取る前に、"Expect: 100-continue" を送ってしまうかもしれない ようなあいまいな場面を認めている。それ故に、クライアントが 100 (Continue) ステータスを見た事が無いようなオリジンサーバ (あるいは経由 するプロクシ) にこれを送るような時でも、リクエストボディを送る前に無 期限で待つような事はす *べきではない*。 HTTP/1.1 オリジンサーバの必要条件は、以下の通りである。 - "100-continue" という expectation を持つ Expect リクエストヘッダ フィールドを含むリクエストを受け取った時は、100 (Continue) ステ ータスを応答し引き続き入力ストリームを読み続けるか、最終ステータ スコードを応答するか、どちらかを実行し *なければならない*。オリ ジンサーバは、100 (Continue) レスポンスを送る前にリクエストボデ ィを待ってい *てはならない*。最終ステータスコードを応答した場合 は、転送接続を切断しても *よい* し、引き続き読みこんで残りのリク エストを破棄しても *よい*。最終ステータスコードを返した場合は、 そのリクエストメソッドを実行し *てはならない*。 - オリジンサーバは、リクエストメッセージが "100-continue" という expectation を持つ Expect リクエストヘッダを含んでいなければ 100 (Continue) レスポンスを送る *べきではなく*、リクエストが HTTP/1.0 (あるいはそれ以前) のクライアントからのものであったら、 100 (Continue) レスポンスを送っ *てはならない*。この規則には拡張 がある。すなわち、RFC 2068 との互換性のため、サーバは "100-continue" という expectation を持つ Expect リクエストヘッダ を含んでいない HTTP/1.1 PUT あるいは POST リクエストへのレスポン スに 100 (Continue) を送る事が *できる*。クライアントのプロセス が 100 (Continue) ステータスのために宣言されない待機によって遅れ る事を最小限にするという目的を持つこの拡張は、HTTP/1.1 リクエス トにのみ適用され、他の HTTP バージョン値を持つリクエストには適用 されない。 - オリジンサーバは、すでにそのリクエストに関する一部、あるいは全部 のリクエストボディを既に受け取っている場合、100 (Continue) レス ポンスを省略する事が *できる*。 - 100 (Continue) レスポンスを送るオリジンサーバは、先に転送接続が 切られているので無ければ、一度リクエストボディが受け取られ、処理 され、最終的には最終ステータスコードを送ら *なければならない*。 - オリジンサーバが "100-continue" という expectation を持つ Expect リクエストヘッダフィールドを含まないリクエストを受け取ったなら ば、リクエストはリクエストボディを含んでいるので、サーバはその転 送接続からのリクエストボディ全体を読みきる前に最終ステータスコー ドを返すが、リクエスト全体を読みきるまで、あるいはクライアントが その接続を切断するまでは、サーバは、その転送接続を切断す *べきで はない*。そうしなければ、クライアントは確実にレスポンスメッセー ジを受け取れないかもしれない。しかし、この必要条件はサーバがサー ビス不能攻撃{denial-of-service attacks} やひどく破綻したクライア ントインプリメンテーションから、己の身を守る事を妨げるようには作 作られてはいない。 HTTP/1.1 プロクシの必要条件は、以下の通りである。 - プロクシが "100-continue" という expectation を持つ Expect リク エストヘッダフィールドを含むリクエストを受け取った時に、プロクシ が次に接続する{next-hop} サーバが HTTP/1.1 以上に従っている事を 知っている、あるいは次に接続するサーバの HTTP バージョンを知らな い場合には、Expect ヘッダフィールドを含めて、リクエストを転送し *なければならない*。 - プロクシが、次に接続するサーバが HTTP/1.0 以下のバージョンである 事を知っていたら、そのリクエストは転送せずに、417 (Expectation Failed) ステータスを返さ *なければならない*。 - プロクシは、最近参照したネクストホップサーバから受け取った HTTP バージョン番号をキャッシュに記録し保管す *べきである*。 - プロクシは、HTTP/1.0 (あるいはそれ以前) のクライアントから受け取 り、そこに "100-continue" という expectation を持つ Expect リク エストヘッダフィールドを含んでいないリクエストメッセージは、100 (Continue) レスポンスを転送し *てはならない*。この必要条件は、 1xx レスポンス (section 10.1 参照) を転送するという一般規則を上 書きする。 8.2.4 サーバが早まって接続を閉じた場合のクライアントの振る舞い もし、HTTP/1.1 クライアントがリクエストボディを持つが、"100-continue" という expectation を持つ Expect リクエストヘッダフィールドを含んでい ないリクエストメッセージを送り、しかもクライアントは HTTP/1.1 オリジ ンサーバには直接接続はしておらず、そこでクライアントがサーバからのど んなステータスをも受け取る前に接続の切断を知った場合は、クライアント はリクエストを再試行す *べきである*。クライアントがこのリクエストを再 試行する時は、確実なレスポンスの獲得を保証させるため、以下の "binary exponential backoff" アルゴリズムを使用 *できる*。 1. サーバへの接続を初期化する 2. リクエストヘッダを転送する 3. サーバへと見積もった round-trip time (つまり、その接続を確立す るためにかかった時間に基づいているもの) か、あるいは round-trip time が利用できい場合は定数値である 5 秒で変数 R を初期化する。 4. T = R * (2**N) を計算する。この時、N はこのリクエストの前までの 試行回数である。 5. サーバからのエラーレスポンスが来るか、もしくは T 秒 (どちらかが 来るまで) 待つ 6. エラーレスポンスが受信されなければ、T 秒後にリクエストのボディ を転送する。 7. クライアントは、コネクションが早まって切断されたのを知ったなら ば、リクエストが受け入れられ、エラーレスポンスを受け取るか、ユ ーザが待ちかねて再試行プロセスを終了するまで、ステップ 1 から繰 り返す。 上のどの時点でも、エラーステータスを受けとったら、クライアントは - 続ける *べきではない* し - もしリクエストメッセージを完全に送信していなければ、接続を切断す *べきである*。 9 メソッド定義 HTTP/1.1 のための一般的なメソッドのセットは以下に定義される。このセッ トは拡張可能であるが、追加されるメソッドは別々に拡張されたクライアン トとサーバに対して同じセマンティクスを共有する事を仮定できない。 Host リクエストヘッダフィールド(section 14.23) は、すべての HTTP/1.1 リクエストに付加され *なければならない*。 9.1 安全なメソッドと等冪{idempotent} なメソッド 9.1.1 安全なメソッド 実装者は、インターネット上における相互動作においてはソフトウェアがユ ーザを表しているという事を認識すべきであり、ユーザがそれら自身や他の ものに対して予測しない意図を持つようなあらゆる動作に気がつく事ができ るように注意すべきである。 特に、GET と HEAD メソッドはその動作にリソースの回収以上の意味を持つ *べきではない* という慣習が確立されている。これらのメソッドは、"安全" だと考えるべきである。これによって、ユーザエージェントがそれ以外の、 例えば POST, PUT, DELETE のようなメソッドを特別な方法で表す事ができる ようになり、ユーザにひょっとしたら安全でない動作が要求されているかも しれないという事実を認識させる。 本質的に、サーバが GET リクエストを実行した結果として副作用を起こさな いという事を保証するのは不可能であり、事実、いくつかの動的なリソース はそれが特徴であると考えている。ここで特に区別すべきなのは、ユーザが 副作用を要求しなかったという事であり、それゆえにそれらに対しては責任 をもてない。 9.1.2 等冪{idempotent} なメソッド メソッドは、(エラーや期限切れ発行とは別に) 同一のリクエストの N > 0 の副作用が単一のリクエストにおけるものと同じであるような際には "等冪{idempotence}" の性質を持つ事もできる。GET, HEAD, PUT, DELETE 各 メソッドはこの性質を共有する。また、OPTIONS と TRACE 各メソッドは副作 用を持つ *べきではない* し、本来等冪であるものである。 しかしながら、たとえその順序にて実行される全てのメソッドが等冪であっ たとしても、いくつかのリクエストの順番は等冪ではない。(もし全体の順序 中のある一つを実行しても、その順序の全体、または一部分を再実行した際 に結果は常に変わらないという事になるのであれば、順序は等冪である。) 例えば、同じ順序でもその結果が後に修正される値に依存するのであれば、 順序は等冪ではない。 副作用を持たない順序は、(同時に起こる動作は同じリソースの一組{set} 上 に実行されている事は無い、との条件で) 定義によって等冪である。 9.2 OPTIONS OPTIONS メソッドは、Request-URI によって識別されるリクエスト/レスポ ンス連鎖上で利用可能な通信オプションについての情報のためのリクエスト を表す。クライアントは、このメソッドはを使ってリソースアクションを暗 に意味したりリソース回収を初期化する事なしに、リソースやサーバの能力 に関するオプションや必要条件を決定する事ができる。 このメソッドへのレスポンスはキャッシュ可能ではない。 もし OPTIONS リクエストが (Content-Length や Transfer-Encoding の存在 によって指し示される様な) エンティティボディを含むならば、そのメディ アタイプは Content-Type フィールドによって指し示され *なければならな い*。この特性は、そのようなエンティティボディのいかなる使用方法も決定 しないが、HTTP の将来的な拡張によってそのサーバについてのより詳細な情 報文字列を作るために OPTIONS のボディを使うかもしれない。そのような拡 張機能をサポートしていないサーバでは、リクエストボディを廃棄する *か もしれない*。 もし、Request-URI がアスタリスク ("*") なら、OPTIONS リクエストは特定 のリソースへというよりも全体としてサーバへ適用する意思を示す。サーバ のコミュニケーションオプションは典型的にリソースに依存するので、"*" リクエストは、まるで "ping" や "no-op" のように使われるのみで、すなわ ちサーバの能力をテストするする事をクライアントに許可する以上には意味 を持たない。例えば、これはプロクシに HTTP/1.1 に従っているか (あるい はその機能が欠けているか) をテストするために使われる。 もし、Request-URI が アスタリスクでなければ、OPTIONS リクエストはその リソースと通信する時に利用可能なオプションのみを尋ねる。 200 レスポンスには、サーバによって実装され、そのリソースに適用できる オプション的な機能を示す (例えば、Allow のような) ヘッダフィールド や、可能であればこの仕様書で定義されていないような拡張も含む *べきで ある*。もしレスポンスボディがあれば、それはコミュニケーションオプショ ンについての情報も含む *べきである*。そのようなボディのフォーマットは この仕様書では定義しないが、HTTP の将来の拡張によって定義されるであろ う。適切なレスポンストを選択するために、フォーマッコンテントネゴシエ ーションを使われる *かもしれない*。もしレスポンスボディが含まれていな ければ、そのレスポンスは "0" というフィールド値を持つ Content-Length フィールドを含ま *なければならない*。 Max-Forwards リクエストヘッダフィールドは、リクエスト連鎖中で特定のプ ロクシを目標に使われるで *あろう*。プロクシは、転送が許可されたリクエ ストのための absoluteURI と共に OPTIONS リクエストを受けとった時に は、Max-Forwards フィールドをチェックし *なければならない*。もし、 Max-Forwards フィールドの値がゼロ("0") ならば、プロクシはそのメッセー ジを転送し *てはならない*。その代わりに、プロクシ自身のコミュニケーシ ョンオプションを返す *べきである*。もし、Max-Forwards フィールドの値 がゼロより大きな整数値ならば、プロクシはリクエストを転送する際にその 値を一つ減らさ *なければならない*。リクエストの中に Max-Forwards フィ ールドが存在していなければ、転送するリクエストに Max-Forwards フィー ルドを含め *てはならない*。 9.3 GET GET メソッドは、Request-URI で識別される (エンティティ形式の) 情報な らなんでも回収する事を意味する。もし、Request-URI がデータ生産プロセ ス{data-producing process} を参照するのであれば、それはレスポンスのエ ンティティとして返されるであろうとして生産されるデータであり、もしそ のテキストがプロセスの出力として生じるのでなければ、プロセスのソース テキストではない。 リクエストメッセージに If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, If-Range のいずれかのヘッダフィールドを含ん でいる場合、GET メソッドのセマンティクスは条件付き GET に変わる。条件 付き GET メソッドは、エンティティがその条件付きヘッダフィールドによっ て表される状況下でのみ転送されるようにリクエストする。条件付き GET メ ソッドは、キャッシュされるエンティティに複数のリクエストを要求する事 や、クライアントによってすでに保持されているデータを転送する事無く清 新できるようにする事で、不必要なネットワークの使用を減らそうというも のである。 リクエストメッセージに Range ヘッダフィールドを含んでいる場合、GET メ ソッドのセマンティクスは "部分的 GET" に変わる。部分的 GET は、 section 14.35 で示されるように、転送されるエンティティの一部のみを要 求する。部分的 GET メソッドは、クライアントによって既に保持されている データを転送する事無くエンティティを部分的に取得させ、完全なものにで きるようにする事で、不必要なネットワークの使用を減らそうというもので ある。 GET リクエストへのレスポンスは、section 13 に示されるような HTTP キャ ッシングのための必要条件がそろった場合にのみ、キャッシュ可能となる。 フォームを使った場合のセキュリティの考察については、section 15.1.3 を 見よ。 9.4 HEAD HEAD メソッドは、サーバがレスポンスにおいてメッセージボディを返し *て はならない* 事を除けば GET と同一である。HEAD リクエストへのレスポン スにおける HTTP ヘッダに含まれる外部情報は、GET リクエストへのレスポ ンスで送られる情報と同一である *べきである*。このメソッドは、エンティ ティボディ自身を転送する事なしにリクエストによって意味されるエンティ ティに付いての外部情報を得るために使用される。このメソッドは、ハイパ ーテキストリンクの正当性、アクセス可能性、最近の修正のテストのため に、しばしば使用される。 HEAD リクエストへのレスポンスは、そのレスポンスに含まれる情報はリソー スから前もってキャッシュされたエンティティを更新するために使う事が *できる* 、という意味でキャッシュ可能である *かもしれない*。もし、新 しいフィールド値がキャッシュされたエンティティは (Content-Length, Content-MD5, ETag, Last-Modified 各値の変更によって示されるように) 現 在のエンティティと違うという事を示すならば、キャッシュはそのキャッシ ュエンティティを新鮮でないものとして扱わ *なければならない*。 9.5 POST POST メソッドは、サーバがリクエストライン内の Request-URI により識別 されるリソースへの新しい従属{subordinate} として、リクエストに同封さ れるエンティティを受け入れる事を要求するために使用される。POST は以下 の機能のカバーするための画一的メソッドとして設計されている。 - 既存リソースの注釈 - 掲示板、ニュースグループ、メーリングリスト、あるいはその類の記事 グループへのメッセージの投稿 - フォーム提出の結果のような、データ処理プロセス {data-handling process} へのデータブロックの供給 - 追加動作を通したデータベースの拡張 POST メソッドによって実行される実際の機能はサーバによって決定され、通 常は Request-URI に依存する。ポストされたエンティティは、ファイルが ディレクトリに従属し、ニュース記事がそれがポストされたニュースグルー プに従属し、レコードがそのデータベースに従属しているという事と同じ形 で、その URI に従属する。 POST メソッドによって実行される動作は、URI によって識別されうるリソー スという結果にはならないかもしれない。この場合、200 (OK) か 204 (No Content) が適切なレスポンスステータスであり、それはレスポンスが結果を 記述したエンティティを含んでいるかどうかに依存する。 リソースがオリジンサーバで既に生成されている場合、レスポンスは 201 (Created) であり、リクエストのステータス、新しいリソースへの参照、 Location ヘッダ (section 14.30) を記述したエンティティを含む *べきで ある*。 レスポンスが適切な Cache-Control や Expires ヘッダフィールドを含んで いなければ、このメソッドのレスポンスはキャッシュ可能ではない。しかし ながら、303 (See Other) レスポンスは、ユーザエージェントにキャッシュ 可能なリソースの検索を指示するために使用される。 POST リクエストは、section 8.2 にあるメッセージ転送要求に従わ *なけれ ばならない*。 セキュリティの考察については、section 15.1.3 参照。 9.6 PUT PUT メソッドは、同封されたエンティティを供給される Request-URI の元に 保存するように要求する。Request-URI が既に存在するリソースを参照して いる場合は、同封されるエンティティはオリジンサーバにあるそれの修正版 とみなされる *べきである*。Request-URI が既存のリソースを指していない 場合に、その URI がリクエストしているユーザエージェントによって新しい リソースとして定義する事ができる時は、オリジンサーバはその URI にリソ ースを作成できる。新しいリソースが作成された場合、オリジンサーバは 201 (Created) レスポンスをもってユーザエージェントに知らせ *なければ ならない*。既存のリソースが更新された場合は、リクエストが成功し終了し た事を示すために 200 (OK) か 204 (No Content) のいずれかのレスポンス コードを送る *べきである*。もし、リソースがその Request-URI に作成、 あるいは更新されなかった時は、問題の本質を反映する適切なエラーレスポ ンスが与えられる *べきである*。エンティティを受ける側は、理解できなか ったり実装していないようないかなる Content-* ヘッダ (例えば Content-Range 等) も無視してはならず、そのような場合には 501 (Not Implemented) レスポンスを返さ *なければならない*。 リクエストがキャッシュを通り抜けたり、Request-URI が現在キャッシュさ れている一つ以上のエンティティを識別する場合、これらのエンティティは 新鮮でないものとして扱われる *べきである*。このメソッドのレスポンスは キャッシュできない。 リクエスト POST と PUT とでの根本的な違いは、Request-URI の意味の違い をもたらす。POST リクエストにおける URI は、同封されたエンティティを 処理するであろうリソースを識別する。リソースは、データ受諾プロセス {data-accepting process} か、ある別のプロトコルへのゲートウェイ、ある いは注釈を受け入れる分割されたエンティティであろう。それに対して、PUT リクエストにおける URI は、リクエストとともに同封されたエンティティを 識別する。しかし、ユーザエージェントがリソースにその URI を割り当てる つもりであっても、サーバはそのリクエストをある別のリソースへと割り当 てようとし *てはならない*。そのリクエストを別の URI に申しこむように 要求する時は、サーバは 301 (Moved Permanently) レスポンスを返さ *なけ ればならない*。この時、ユーザエージェントはそのリクエストをリダイレク トするかどうかに関して決める事が *できる*。 単一のリソースが、多くの異なった URI によって識別される *かもしれな い*。例えば、ある記事が各々のバージョンを識別する URI とは別に、"最新 のバージョン" を識別するための URI を持っているかもしれない。この場 合、一般の URI への PUT リクエストは、オリジンサーバによって定義され ているいくつかの他の URI へと行われるはずである。 HTTP/1.1 では、PUT メソッドがオリジンサーバの状態にどのように影響を及 ぼすかは定義しない。 PUT リクエストは、section 8.2 にあるメッセージ転送要求に従わ *なけれ ばならない*。 特定のエンティティヘッダが別の方法では指定できない場合、PUT リクエス トにおけるエンティティヘッダは、PUT によって作成、あるいは修正された リソースに適用される *べきである*。 9.7 DELETE DELETE メソッドは、オリジンサーバが Request-URI により識別されるリソ ースを削除する事を要求する。このメソッドは、オリジンサーバにおいて人 間の手 (あるいは別の方法) によって上書きされている *かもしれない*。例 えオリジンサーバから返されたステータスコードは動作がうまく完了したと いう事を示していたとしても、クライアントはその操作が実行された事は保 証されない。しかしそのレスポンスが与えられた場合に、サーバがそのリソ ースを削除したり、アクセスできない場所へ移動したりしようとしていない のであれば、成功を示す *べきではない*。 成功したレスポンスは、もしレスポンスがステータスで表しているエンティ ティを含んでいるなら 200 (OK)、もし動作がまだ行われていないなら 202 (Accepted)、もし動作は行われたが、レスポンスにエンティティを含んでい ないなら 204 (No Content) である *べきである*。 もし、リクエストがキャッシュを通り抜けたり、Request-URI が現在キャッ シュされている一つ以上のエンティティとして識別されるなら、これらのエ ンティティは新鮮でないものとして扱われる *べきである*。このメソッドの レスポンスはキャッシュできない。 9.8 TRACE TRACE メソッドは、リクエストメッセージのアプリケーション層のループバ ックを遠隔的に発動するために使用される。リクエストの最後の受信者は、 200 (OK) レスポンスのエンティティボディとして、そのメッセージをクライ アントにそのまま送り返す *べきである*。最後の受信者とは、オリジンサー バ、もしくはリクエストで Max-Forwards (section 14.31) 値がゼロ (0) で あったものを受け取った最初のプロクシかゲートウェイである。TRACE リク エストはエンティティを含ん *ではならない*。 TRACE を使って、クライアントはリクエスト連鎖の反対側では何が受け取ら れているのかを見る事や、テストや診断情報のためのデータを使用する事が できる。これはリクエスト連鎖のトレースとして動作するので、Via ヘッダ フィールド (section 14.45) の値が特に重要である。Max-Forwards ヘッダ フィールドを使用する事で、クライアントにリクエスト連鎖の大きさに制限 を与える事ができ、これは無限ループ上でメッセージを転送するプロクシ連 鎖をテストするために有用である。 もしリクエストが妥当ならば、レスポンスは "message/http" という Content-Type と一緒に、エンティティボディとしてリクエストメッセージの 全体を含む *べきである*。このメソッドのレスポンスはキャッシュされ *て はならない*。 9.9 CONNECT この仕様書では、(例えば SSLトンネリング [44] 等の) トンネルとなるよう に動的に切り換える事ができるプロクシが使用する時のために CONNECT とい うメソッド名を予約する。 10 ステータスコード定義 各々のステータスコードについて、レスポンス時に後に従える事のできるメ ソッドと必要とされるすべての外部情報の記述と共に、以下に記述する。 10.1 Informational 1xx このステータスコードのクラスは一時的なレスポンスを示し、ステータスラ インとオプション的なヘッダからのみなり、空行で終了する。このステータ スコードのクラスのための必要なリクエストヘッダは無い。HTTP/1.0 では、 どんな 1xx ステータスコードも定義していないので、サーバは実験的な状況 下以外では HTTP/1.0 クライアントに 1xx レスポンスを送っ *てはならな い*。 クライアントは、例え 100 (Continue) ステータスメッセージを期待してい なかったとしても、通常のレスポンスの前の一つ以上の 1xx レスポンスを受 け入れるよう準備されてい *なければならない*。ユーザエージェントは、期 待していない 1xx レスポンスを無視する事が *できる*。 プロクシは、もしプロクシとクライアント間の接続が切断されている、ある いはプロクシ自身が 1xx レスポンスの生成を要求したという場合以外は、 1xx レスポンスを転送しなければならない。 (例えば、プロクシがリクエス トを転送する時に "Expect: 100-continue" というフィールドを付け加えた 時には、それに相当する 100 (Continue) レスポンスを転送する必要はな い。) 10.1.1 100 Continue クライアントは、そのリクエストを続ける *べきである*。この暫定的レスポ ンスは、リクエストの始めの部分は受け取られ、サーバによって拒否された ものではないという事をクライアントに知らせるために使用される。クライ アントは、リクエストの残りを送り続けるか、もし既にリクエストが完了し ていれば、このレスポンスを無視す *べきである*。サーバは、リクエストが 完了した後に最終的なレスポンスを送ら *なければならない*。このステータ スコードの使用・処理の詳細な議論のために section 8.2.3 参照。 10.1.2 101 Switching Protocols サーバは理解し、Upgrade メッセージヘッダフィールド (section 14.42) を 使って、この接続で使用されているアプリケーションプロトコルを変更する 事でクライアントのリクエストに従おうとしている。サーバは 101 レスポン スを終了する空行のあと、すぐにレスポンスの Upgrade ヘッダフィールドに よって定義されたプロトコルに変更するだろう。 プロトコルは、変更した方が有益な場合にのみ変更される *べきである*。例 えば、HTTP のより新しいバージョンに変更するという事は、古いバージョン 以上に有益だし、リアルタイムに、同期するプロトコルを変更する事はその ような機能を使うリソースを配布するときに都合が良いだろう。 10.2 Successful 2xx このステータスコードのクラスは、クライアントのリクエストがうまく受信 され、理解され、そして受け入れられた事を示す。 10.2.1 200 OK リクエストは成功した。レスポンスと共に返される情報はリクエストに使用 されたメソッドに依存し、例えば以下の様になる。 GET リクエストされたリソースに対応するエンティティがレスポンスとし て送られる。 HEAD リクエストされたリソースに対応するエンティティヘッダフィールド がメッセージボディを伴わずにレスポンスとして送信される。 POST 動作の結果を記述もしくは含んでいるエンティティ TRACE 端末サーバによって受信されたリクエストメッセージを含んでいるエ ンティティ 10.2.2 201 Created リクエストは果たされ、結果として新しいリソースが作成された。新しく作 成されたリソースは Location ヘッダにより与えられるリソースに対する最 も明確な URI を伴って、レスポンスのエンティティにおいて返される URI によって参照される。レスポンスは、ユーザあるいはユーザエージェントが 最も適切なものを選択するために、リソースの特徴と場所のリストをエンテ ィティとして含む *べきである*。エンティティのフォーマットは、 Content-Type ヘッダフィールドにて与えられるメディアタイプによって指定 される。オリジンサーバは、201 ステータスコードを返す前にリソースを作 成し *なければならない*。もし動作がすぐに実行できないのであれば、サー バは代わりに 202 (Accepted) レスポンスを返す *べきである*。 201 レスポンスは、作成されたばかりのリクエストされたバリアントのため に、現在のエンティティタグの値を示す ETag レスポンスヘッダフィールド を含む事が *できる*。section 14.19 参照。 10.2.3 202 Accepted リクエストは処理のために受け入れられたが、処理は完了されていない。こ のリクエストは、実際に処理される時に拒否されるかもしれないので、最終 的に動作されるかどうかは不明である。このような非同期操作からステータ スコードを再送信するための機能は存在しない。 202 レスポンスは、意図的に責任を持たない{non-committal}。これはサーバ が、プロセスが完了されるまでユーザエージェントとの接続を持続させる事 無く、他のいくつかのプロセス (多分一日に一度しか実行されないバッチ志 向プロセス{batch-oriented process}) のためのリクエストを受け入れる事 を可能にするという目的を持つ。このレスポンスによって返されるエンティ ティは、リクエストの現在の状態を表すものと、状態モニタへのポインタ、 あるいはそのリクエストがいつ果たされるかをユーザが予期できる見積もり のどちらかを含む *べきである*。 10.2.4 203 Non-Authoritative Information エンティティヘッダにおいて返された外部情報は、オリジンサーバから利用 できるような決定的なセットではなく、ローカルもしくはサードパーティコ ピーから集められたものである。提示されたセットは元のバージョンのサブ セットかスーパーセットで *あろう*。例えば、リソースについてのローカル な注釈情報を含む事はオリジンサーバによって知らされる外部情報のスーパ ーセットとなるかもしれない。そのレスポンスが 200 (OK) とは別の方法で 示したい場合、このレスポンスコードを使用する必要はないが、そのような 場合にのみ適切である。 10.2.5 204 No Content サーバはリクエストを受け入れたが、エンティティボディを送り返す必要は 無く、更新された外部情報を返す事を望むだろう。レスポンスは、エンティ ティヘッダ形式の中に、新規あるいは更新された外部情報を含む事が *でき*、もしあればリクエストされたバリアントが関連付けられる *べきで ある*。 もしクライアントがユーザエージェントなら、リクエストの送信をもたらし た状態からその文書画面{view} を変える *べきではない*。このレスポンス は主に、ユーザエージェントの現在の{active} 文書画面を変える事無く、動 作を起こすための入力をさせる意図を持つが、どんな新規あるいは更新され た外部情報もユーザエージェントの現在の画面中にある現在の文書に適用さ れる *べきである*。 204 レスポンスは メッセージボディを含ん *ではならない* ので、常にヘッ ダフィールドの後の最初の空行で終了する。 10.2.6 205 Reset Content サーバはリクエストを受け入れたので、ユーザエージェントは送信されたリ クエストをもたらした現在の画面をリセットす *べきである*。このレスポン スは主に、ユーザが別の入力動作を簡単に始められるように、入力が与えら れたフォームをクリアして、ユーザの入力経由で動作を起こすための入力を させる意図を持つ。レスポンスはエンティティを含ん *ではならない*。 10.2.7 206 Partial Content サーバはリソースに対する部分的 GET リクエストを受け入れた。リクエスト は、望む範囲を示すための Range ヘッダフィールド (section 14.35) を含 め *なければならない* し、またリクエストを条件付きにしたいければ If- Range ヘッダフィールド (section 14.27) を含んだ方が *よい*。 レスポンスは、以下のヘッダフィールドを含め *なければならない*。 - このレスポンスに含まれる範囲を示す Content-Range ヘッダフィール ド (section 14.16) か、それぞれの部分に Content-Range フィールド を含む multipart/byteranges という Content-Type のどちらか。この レスポンスにて Content-Length ヘッダフィールドが送られた場合、そ の値はメッセージボディで転送される OCTET の実際の数と一致し *な ければならない*。 - Date - もしそのヘッダが、同じリクエストに対して 200 レスポンス を返すで あろう場合は ETag, Content-Location のうち一つ以上 - もしフィールド値が、同じバリアントのための以前のレスポンスで送ら れたものと異なるならば、Expires, Cache-Control, Vary のうち一つ 以上 もし 206 レスポンスが、強いキャッシュバリディタ (section 13.3.3 参照) を使った If-Range リクエストの結果ならば、レスポンスは他のエンティテ ィヘッダを含める *べきではない*。もし、レスポンスが弱いバリディタを使 った If-Range リクエストの結果がとしたら、レスポンスは他のエンティテ ィヘッダを含め *てはならない*。これはキャッシュされたエンティティボデ ィと更新されたエンティティヘッダとの不一致を避ける為である。そうで無 ければ、レスポンスは同じリクエストに対して 200 (OK) レスポンスと共に 返されたであろうすべてのエンティティヘッダを含め *なければならない*。 もし ETag か Last-Modified ヘッダが正確に一致しなければ、キャッシュは 他の以前キャッシュされた要素と 206 レスポンスとを結びつけ *てはならな い*。section 13.5.4 参照。 Range や Content-Range ヘッダをサポートしていないキャッシュは、206 (Partial) レスポンスをキャッシュし *てはならない*。 10.3 Redirection 3xx このステータスコードのクラスは、リクエストを果たすためにはユーザエー ジェントによって更なる動作が行われる必要がある事を示す。二番目のリク エストで使われたメソッドが GET か HEAD である場合にのみ、ユーザとの相 互動作無しに、ユーザエージェントによって要求された動作を実行する事が *できる*。リダイレクションループによって各々のリダイレクションはネッ トワーク渋滞を生み出す事になるので、クライアントは無限リダイレクショ ンループを発見す *べきである*。 注意: この仕様書の前のバージョンでは、5 回のリダイレクションを最大 として推奨している。内容開発者{Content developers} は、そのような 修正された制限を実装したクライアントがあるであろう事を意識すべきで ある。 10.3.1 300 Multiple Choices リクエストされたリソースは、表現セットの一つに対応し、各々が特有の場 所にあり、エージェント駆動型ネゴシエーション情報 (section 12) が、ユ ーザ (あるいはユーザエージェント) が望む表現を選択でき、その位置にリ クエストをリダイレクトできるように供給されている。 もし HEAD リクエストでなければ、レスポンスはエンティティにユーザかユ ーザエージェントが最も適切なものを選択するためのリソースの特徴と場所 のリストを含む *べきである*。エンティティのフォーマットは、Content- Type ヘッダフィールドにて与えられるメディアタイプによって指定される。 データフォーマットやユーザエージェントの能力に依存する事なので、最も 適切な選択は自動的に行われる *かもしれない*。しかし、この仕様書ではそ のような自動選択に対してどのような標準も定義しない。 サーバが選択された表現を持っているのであれば、Location フィールド内に その表現のための具体的な URI を含む *べきである*。ユーザエージェント は、自動リダイレクションのためにその Location フィールドの値を使うこ とが *できる*。このレスポンスは、別のものを示しているのでなければキャ ッシュ可能である。 10.3.2 301 Moved Permanently リクエストされたリソースは新しい恒久的な URI に割り当てられたので、以 降そのリソースへの参照は返された URI の一つを使用す *べきである*。リ ンク編集機能を持つクライアントは、可能であればサーバにより返された新 しい参照の一つ以上の Request-URI を参照するように自動的に再リンクすべ きである。このレスポンスは、別のものを示しているのでなければキャッシ ュ可能である。 新しい恒久的 URI は、レスポンス内の Location フィールドによって与えら れる *べきである*。リクエストメソッドが HEAD でなければ、レスポンスの エンティティは新しい URI へのハイパーリンクを持った短いハイパーテキス トの注釈を含む *べきである*。 もし 301 ステータスコードが GET や HEAD 以外のリクエストのレスポンス として受信されたら、リクエストが発行された時点の条件から変わっている かもしれないため、ユーザエージェントはユーザに確認せずに、リクエスト を自動的にリダイレクトし *てはならない*。 注意: 301 ステータスコードを受信した後 POST リクエストを自動的にリ ダイレクトする時、既存の HTTP/1.0 ユーザエージェントの中には誤って それを GET リクエストに変えるものがある。 10.3.3 302 Found リクエストされたリソースは、一時的に別の URI に属している。このリダイ レクションは場合によって変更されるかもしれないので、クライアントは将 来のリクエストではその Request-URI を使い続ける *べきである*。このレ スポンスは Cache-Control か Expires のどちらかのヘッダフィールドによ って期限が示されている場合にのみキャッシュ可能である。 一時的 URI は、レスポンス内の Location フィールドによって与えられる *べきである*。リクエストメソッドが HEAD でなければ、レスポンスのエン ティティは新しい URI へのハイパーリンクを持った短いハイパーテキストの 注釈を含む *べきである*。 もし 302 ステータスコードが GET や HEAD 以外のリクエストのレスポンス として受信されたら、リクエストが発行された時点の条件から変わっている かもしれないため、ユーザエージェントはユーザに確認せずに、リクエスト を自動的にリダイレクトし *てはならない*。 注意: RFC 1945 や RFC 2068 では、クライアントはリダイレクトするリ クエストのメソッドを変えてはならないと明確に述べられている。しかし ながら、多くの既存ユーザエージェントは 302 レスポンスをまるで 303 レスポンスのようにみなし、元々のリクエストメソッドにかかわらず Location フィールド値へと GET を行う。ステータスコード 303 と 307 は、クライアントが期待する反応の種類を明確にしたいというサーバのた めに加えられた。 10.3.4 303 See Other リクエストに対するレスポンスは別の URI の元から発見でき、このリソース を GET メソッドを使用して回収す *べきである*。このメソッドは、主に POST によって活性化される {POST-activated} スクリプトの出力が選択され たリソースへユーザエージェントをリダイレクトできるようにするために存 在する。新しい URI は元々リクエストされたリソースに対する代わりの参照 ではない。303 レスポンスはキャッシュ可能し *てはならない* が、二番目 の (リダイレクトされた) リクエストへのレスポンスはキャッシュ可能であ る。 異なる URI は、レスポンス内の Location フィールドによって与えられる *べきである*。リクエストメソッドが HEAD でなければ、レスポンスのエン ティティは新しい URI へのハイパーリンクを持った短いハイパーテキストの 注釈を含む *べきである*。 注意: 多くの HTTP/1.1 以前のユーザエージェントは 303 ステータスを 理解できない。そのようなクライアントと相互通信する時、ほとんどのユ ーザエージェントは 302 レスポンスを 303 レスポンスのように扱うの で、302 レスポンスコードが代わりに使われるであろう。 10.3.5 304 Not Modified クライアントが条件付き GET リクエストを実行し、アクセスは許可されたが その文書は更新されていなかった場合、サーバはこのステータスコードもっ て応答す *べきである*。304 レスポンスはレスポンスボディを含ん *ではな らない* ので、いつもヘッダフィールドの後の最初の空行で終了する。 レスポンスは以下のヘッダフィールドを含ま *なければならない*。 - その省略が section 14.18.1 によって要求されていなければ、Date 時計の無いオリジンサーバがこのルールに従っている場合、プロクシやクラ イアントは ([RFC 2068] の section 14.19 にて既に記されているように) 受信した Date ヘッダを持たないいかなるレスポンスにも自身の Date を付 け加える事で、キャッシュは正常に作動するであろう。 - もしそのヘッダが、同じリクエストに対して 200 レスポンス を返すで あろう場合は ETag, Content-Location のうち一つ以上 - もしフィールド値が、同じバリアントのための以前のレスポンスで送ら れたものと異なるならば、Expires, Cache-Control, Vary のうち一つ 以上 条件付き GET に、強いキャッシュバリディタ (section 13.3.3 参照) を使 う場合、レスポンスは他のエンティティヘッダを含める *べきではない*。そ うでない (例えば条件付き GET が弱いバリディタを使う) 場合、レスポンス は他のエンティティヘッダを含め *てはならない*。これは、キャッシュされ たエンティティボディと更新されたエンティティヘッダとの不一致を避ける 為である。 304 レスポンスが現在キャッシュされていないエンティティを示すならば、 キャッシュはレスポンスを無視し、条件なしのリクエストを反復しなければ *ならない*。 キャッシュが受信された 304 レスポンスをキャッシュエントリを更新するた めに使用する場合、キャッシュはレスポンスで与えられたあらゆる新しいフ ィールド値をも反映させるため、エントリを更新し *なければならない*。 10.3.6 305 Use Proxy リクエストされたリソースは Location フィールドによって与えられるプロ クシを通してアクセスされ *なければならない*。Location フィールドはプ ロクシの URI を与える。受信側はプロクシ経由で単一のリクエストを再送信 する事を期待する。305 レスポンスはオリジンサーバによってのみ生成され *なければならない*。 注意: RFC 2068 では、305 は単一リクエストをリダイレクトさせようと する事、またオリジンサーバによってのみ生成される事は明確にしていな い。これらの制限がセキュリティの上で重要な意味を持つという事を認識 していなかったためである。 10.3.7 306 (Unused) 306 ステータスコードは前のバージョンの仕様書では使われていたが、もは や使われておらず、将来のために予約されている。 10.3.8 307 Temporary Redirect リクエストされたリソースは、一時的に別の URI に属している。このリダイ レクションは場合によって変更されるかもしれないので、クライアントは将 来のリクエストではその Request-URI を使い続ける *べきである*。このレ スポンスは Cache-Control か Expires のどちらかのヘッダフィールドによ って期限が示されている場合にのみキャッシュ可能である。 一時的 URI は、レスポンス内の Location フィールドによって与えられる *べきである*。多くの HTTP/1.1 以前のユーザエージェントは 307 ステータ スを理解できないので、リクエストメソッドが HEAD でなければ、レスポン スのエンティティは新しい URI へのハイパーリンクを持った短いハイパーテ キストの注釈を含む *べきである*。それゆえ、その注釈にはユーザが新しい URI に元々のリクエストを繰り返すのに必要な情報を含む *べきである*。 もし 302 ステータスコードが GET や HEAD 以外のリクエストのレスポンス として受信されたら、リクエストが発行された時点の条件から変わっている かもしれないため、ユーザエージェントはユーザに確認せずに、リクエスト を自動的にリダイレクトし *てはならない*。 10.4 Client Error 4xx ステータスコードの 4xx クラスは、クライアントが間違えているような場合 を示す。HEAD リクエストへのレスポンスを除き、サーバはエラー状況が一時 的か恒久的かに拘わらず、エラー状況の説明を含むエンティティを返す *べ きである*。これらのステータスコードは、あらゆるリクエストメソッドに適 用されうる。ユーザエージェントは、含まれるエンティティすべてをユーザ に表示す *べきである*。 もしクライアントがデータを送信している最中ならば、TCP を使用している サーバインプリメンテーションは、サーバが入力接続を切断する前に、レス ポンスを含んでいるパケットの受領をクライアントが認識できる事を保証す るために気を配る *べきである*。もし切断後にもクライアントがサーバにデ ータを送信し続けていたら、サーバの TCP スタックはクライアントにリセッ トパケットを送り、これによって、HTTP アプリケーションがリクエストを読 み出して中間処理する前に、クライアントの認識されない入力バッファを消 去するだろう。 10.4.1 400 Bad Request リクエストは、不正なシンタックスのためサーバに理解されなかった。クラ イアントは、修正しないままでそのリクエストを再送信す *べきではない*。 10.4.2 401 Unauthorized リクエストはユーザ認証を必要とする。レスポンスは、リクエストされたリ ソースに適用できる challenge を含む WWW-Authenticate ヘッダフィールド (section 14.47) を含ま *なければならない*。クライアントは、適切な Authorization ヘッダフィールド (section 14.8) を伴うリクエストを繰り 返す事が *できる*。もしリクエストがすでに Authorization credentials を含んでいるのであれば、この 401 レスポンスは認証がそれらの credentials に対して拒否された事を示す。もし 401 レスポンスが前のレス ポンス時と同じ challenge を含み、ユーザエージェントが既に最低一回認証 を試みているならば、そのエンティティに関連する診断情報を含んでいるで あろうから、ユーザエージェントはレスポンスで与えられたエンティティを 表示す *べきである*。HTTP アクセス認証は、"HTTP Authentication: Basic and Digest Access Authentication" において説明されている。 10.4.3 402 Payment Required このコードは、将来の使用のため予約されている。 10.4.4 403 Forbidden サーバはリクエストを理解したが、それを実行する事を拒否した。認証は役 に立たないであろうから、リクエストは繰り返される *べきではない*。リク エストメソッドが HEAD で無い時に、サーバはなぜリクエストが実行されな かったかを公にしたいならば、エンティティにおいて拒否の理由を記す *べ きである*。サーバはこの情報をクライアントに利用されたくないならば、ス テータスコードとして 404 (Not Found) を代わりに使う事ができる。 10.4.5 404 Not Found サーバが、Request-URI に一致するものを見つけられなかった。その状態が 一時的か恒久的かに拘わらず、与えられる指示はない。もしサーバが、ある 内部に組み込まれているメカニズムを通して、古いリソースが恒久的に利用 できず、それを転送するためのアドレスも無いという事を知っていたら、410 (Gone) ステータスコードが使用される *べきである*。このステータスコー ドは一般に、サーバが何故リクエストが拒否したかを正確には表したく無い 時、あるいは他に適切なレスポンスが無い時に使われる。 10.4.6 405 Method Not Allowed リクエストラインに記述されたメソッドは、Request-URI によって識別され るリソースに許可されていない。レスポンスは、リクエストされたリソース へ適用できるメソッドのリストを含む Allow ヘッダを含ま *なければならな い*。 10.4.7 406 Not Acceptable リクエストによって識別されるリソースは、リクエスト中に送られた Accept ヘッダによれば、受け入れられない内容特性を持つレスポンスエンティティ を生成する事ができるのみである。 もし HEAD リクエストでなければ、レスポンスはエンティティにユーザかユ ーザエージェントが最も適切なものを選択するためのリソースの特徴と場所 のリストを含む *べきである*。エンティティのフォーマットは、Content- Type ヘッダフィールドにて与えられるメディアタイプによって指定される。 データフォーマットやユーザエージェントの能力に依存する事なので、最も 適切な選択は自動的に行われる *かもしれない*。しかし、この仕様書ではそ のような自動選択に対してどのような標準も定義しない。 注意: HTTP/1.1 サーバは、リクエスト中に送られた Accept ヘッダによ れば受け入れる事ができないとされるレスポンスを返す事を許されてい る。そのような場合、406 レスポンスを送る事が望ましい。ユーザエージ ェントは、もしそれを受け入れられるなら、それを決定するために送られ てきたレスポンスのヘッダを詳しく調べる事が推奨される。 もしレスポンスが受け入れる事ができなければ、ユーザエージェントはそれ 以上のデータの受信を一時的に中止し、それ以降の動作を決定するためユー ザに尋ねる *べきである*。 10.4.8 407 Proxy Authentication Required このコードは、401 (Unauthorized) と似ているが、クライアントが最初にプ ロクシに認証されなければならない事を示す。プロクシは、リクエストされ たリソースのためのプロクシに適用できる challenge を含んだ Proxy- Authenticate ヘッダフィールド (section 14.33) を返さ *なければならな い*。クライアントは、適切な Proxy-Authorization ヘッダフィールド (section 14.34) を伴うリクエストを繰り返す事ができる。HTTP アクセス認 証は、"HTTP Authentication: Basic and Digest Access Authentication" [43] において説明されている。 10.4.9 408 Request Timeout クライアントは、サーバの待ち時間内にリクエストを発行しなかった。クラ イアントは、それ以降に修正しないでリクエストを繰り返しても *よい*。 10.4.10 409 Conflict リクエストは、リソースの現在の状態との矛盾のため完了できなかった。こ のコードは、ユーザが矛盾を解決し、リクエストを再提出できる事が期待で きる状況のみに許される。レスポンスボディには、ユーザが矛盾の原因を認 識するための十分な情報を含む *べきである*。理論的には、そのレスポンス エンティティはユーザやユーザエージェントが問題を修正するための十分な 情報を含んでいるであろうが、実際それは不可能だろうしその必要もない。 矛盾は、PUT リクエストへのレスポンス時に最も発生しやすい。例えば、も しバージョン処理{versioning} が使用され、PUT されているエンティティが 初期 (サードパーティ) のリクエストによって作られたものと矛盾している リソースに変わるものを含んでいるならば、サーバはリクエストが完了でき ない事を示す 409 レスポンスを使用できる。この場合、レスポンスエンティ ティにはおそらく、レスポンスの Content-Type によって定義されるフォー マット中で二つのバージョンの違いについてのリストを含むであろう。 10.4.11 410 Gone リクエストされたリソースは、もはやそのサーバでは利用できないし、転送 先のアドレスも分からない。この状況は、恒久的なものとみなされるであろ う。リンク編集機能を持つクライアントは、ユーザから承認を得た後に Request-URI の参照を削除す *べきである*。サーバがその状況が恒久的なも のかどうかを、知らないか、あるいはそれを決定するための能力が無いので あれば、代わりにステータスコード 404 (Not Found) が使用される *べき である*。別の方法が示されなければ、このレスポンスはキャッシュできる。 410 レスポンスは主に、リソースが故意に利用不可能であったり、サーバの オーナーがリソースへのリモートリンクを削除したい事を受信者に通知する 事でウェブメンテナンスの作業を補助する意図を持つ。そのような事は、期 間限定の宣伝サービスや、サーバのサイト内でもはや働いていない個人が所 有していたリソースに対して一般的である。"無くなった{gone}" ような恒久 的に利用できないすべてのリソースをマークしたり、いつまでもそのマーク を維持しておく必要はないが、これをいつ破棄するかはサーバオーナーの判 断にまかされる。 10.4.12 411 Length Required サーバは、定義された Content-Length の無いリクエストを受け入れる事を 拒否した。リクエストメッセージにメッセージボディの長さを含んでいる妥 当な Content-Length ヘッダフィールドを追加すれば、クライアントはリク エストを繰り返す事が *できる*。 10.4.13 412 Precondition Failed 一つ以上のリクエストヘッダフィールドで与えられた前提条件は、それがサ ーバでテストされたときに偽であると評価された。このレスポンスコードは クライアントが現在のリソースの外部情報 (ヘッダフィールドデータ) を前 提条件として置けるようにし、それによってリクエストされたメソッドを目 的以外のリソースに適用されないようにする。 10.4.14 413 Request Entity Too Large リクエストエンティティがサーバが想定、あるいは処理可能なものより大き いため、サーバはリクエストの処理を拒否している。サーバは、クライアン トにリクエストを続けさせないため接続を閉じて *よい*。 もしその状態が一時的なものであれば、サーバはそれが一時的であるという 事と、クライアントが再試行しても *よい* 経過時間を示す Retry-After ヘ ッダフィールドを含む *べきである*。 10.4.15 414 Request-URI Too Long サーバが中間処理をするために想定している Request-URI より長いため、サ ーバはリクエストのサービスを拒否している。このまれな状態は、クライア ントが長いクエリ情報を伴った POST リクエストを GET リクエストに不適当 に変換した時、クライアントがリダイレクションの URI "ブラックホール" (例えば、リダイレクトされた URI が自身の末尾を指すようなものを自身の 前に置いてしまうような状態) に陥った時、あるいはサーバが Request-URI の読み出しや操作のために固定長バッファを使用しているいくつかのサーバ に存在する当面のセキュリティホールを利用しようとしているクライアント からアタックを受けている時にのみ起こる傾向がある。 10.4.16 415 Unsupported Media Type リクエストのエンティティは、リクエストされたメソッドに対してリクエス トされたリソースがサポートしていないフォーマットであるため、サーバは リクエストのサービスを拒否している。 10.4.17 416 Requested Range Not Satisfiable リクエストが Range ヘッダフィールド (section 14.35) を含み、このフィ ールドの範囲指定値が選ばれたリソースの現在の範囲に重なっていなくて、 リクエストに If-Range リクエストヘッダフィールドを含んでいなかった ら、サーバはこのステータスコードを含むレスポンスを返す *べきである*。 (バイトレンジの場合、これはすべての byte-range-spec 値での first- bytes-pos が、現在選択されているリソースの長さを超えている事を意味す る。) このステータスコードをバイトレンジのリクエストで返す場合、レスポンス には選ばれたリソースの現在のサイズを特定するために Content-Range ヘッ ダフィールドを含む *べきである* (section 14.16 参照)。このレスポンス は、コンテントタイプが multipart/byteranges のものに使用し *てはなら ない*。 10.4.18 417 Expectation Failed Expect リクエストヘッダフィールド (section 14.20 参照) によって与えら れるこの拡張は、このサーバでは受け入れる事はできないし、あるいはサー バがプロクシであったなら、次に到達するサーバがそのリクエストを受け入 れる事ができないという明白な証拠を持っている。 10.5 Server Error 5xx 数字 "5" で始まるレスポンスステータスコードは、サーバがエラー状態にあ るか、リクエストを実行する能力が無いと気づいた場合を表す。HEAD リクエ ストに応答する場合以外は、サーバはそのエラー状況と、それが一時的か恒 久的なのかの説明を含むエンティティを返す *べきである*。ユーザエージェ ントは、ユーザに返されたあらゆるエンティティを表示す *べきである*。こ れらのレスポンスコードは、あらゆるリクエストメソッドにも適用できる。 10.5.1 500 Internal Server Error サーバは、リクエストの実行を妨げる予測しない状態に遭遇した。 10.5.2 501 Not Implemented サーバは、リクエストを実行するのに必要な機能をサポートしていない。こ れは、サーバがリクエストメソッドを認識できない時の適切なレスポンスで あり、どんなリソースに対してもそれをサポートする能力がない。 10.5.3 502 Bad Gateway ゲートウェイやプロクシとして動作しているようなサーバが、リクエストを 実行しようと呼び出しているアップストリームサーバから不正なレスポンス を受け取った。 10.5.4 503 Service Unavailable サーバは、一時的な過負荷かあるいはサーバのメンテナンスのため、現在リ クエストを扱う事ができない。これは、いくらか遅延された後に軽減される であろうという一時的な状態も含む。もし分かるなら、遅延時間の長さを Retry-After ヘッダで示す事が *できる*。もし Retry-After が与えられな ければ、クライアントはそれを 500 レスポンスと同様に処理すべきである。 注意: 503 ステータスコードの存在は、サーバが過負荷状態になった時に は常にそれを使わなければならないという事を暗黙的に意味するものでは ない。単に接続の拒否を望むサーバもあるだろう。 10.5.5 504 Gateway Timeout ゲートウェイやプロクシとして動作するサーバは、URI によって特定される アップストリームサーバ (例えば HTTP, FTP, LDAP) や、リクエストを完了 させようとするためにアクセスに必要な他の補助のサーバ (例えば DNS) か ら適時のレスポンスを受信しなかった。 注意: 実装者向け: 設置されたプロクシの中には、DNS lookup がタイム アウトした時に 400 あるいは 500 を返すものがあるという事が知られて いる。 10.5.6 505 HTTP Version Not Supported サーバは、リクエストメッセージで使用された HTTP プロトコルバージョン をサポートしていない、あるいはサポートを拒否している。サーバは、この エラーメッセージ以外は、section 3.1 で表されるように、クライアントと 同じメジャーバージョンを使用してリクエストを完了させる事は不可能、 あ るいはそれを望んでいないという事を示している。レスポンスは、何故この バージョンがサポートされていないか、どんな別のプロトコルがこのサーバ によってサポートされているかを記述したエンティティを含む *べきであ る*。 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) に強制的に訴える事ができるように考慮されている。 14 ヘッダフィールド定義 この章では、すべての標準 HTTP/1.1 ヘッダフィールドのシンタックスとセ マンティクスを定義する。エンティティヘッダフィールドに対して、送信者 と受信者の両方は、クライアントかサーバのどちらかを参照するが、それは エンティティを誰が送信し誰が受信するかに依存する。 14.1 Accept Accept リクエストヘッダフィールドは、レスポンスで受け入れ可能なメディ アタイプを指定するために使われる。Accept ヘッダでは、インラインイメー ジを要求する場合などに、希望するタイプの小セット{small set} を特に限 定して指定するために使われる。 Accept = "Accept" ":" #( media-range [ accept-params ] ) media-range = ( "*/*" | ( type "/" "*" ) | ( type "/" subtype ) ) *( ";" parameter ) accept-params = ";" "q" "=" qvalue *( accept-extension ) accept-extension = ";" token [ "=" ( token | quoted-string ) ] アスタリスク "*" という文字は、ある範囲のメディアタイプをグループ化す るために使われ、"*/*" ではすべてのメディアタイプを表し、"type/*" はそ のメディアタイプに含まれるすべてのサブタイプを表す。media-range は、 その範囲に適用できるメディアタイプパラメータを含む事が *できる*。 それぞれの media-range では、相対的な品質係数を示すため "q" で始まる パラメータを、一つ以上 accept-params として付加する事が *できる*。 もし "q" パラメータがあれば、最初の "q" パラメータが media-range と accept-params を分けるものとなる。品質係数によって、ユーザやユーザエ ージェントは 0 から 1 までの qvalue 尺度 (section 3.9) を使って、その メディアタイプの相対的な優先度を示す事ができる。デフォルトの値は、q=1 である。 注意: メディアタイプパラメータと Accept 拡張パラメータとを分けるた めに "q" パラメータの名前を使用するのは、歴史的慣例によるものであ る。これによって、メディアレンジとして "q" という名前のパラメータ を使用する事が妨げられるが、IANA メディアタイプ登録機関には "q" パ ラメータは無く、Accept でメディアタイプパラメータを使う事はまれな ので、そのような状況が問題となる事はないと思われる。将来的に、メデ ィアタイプに "q" という名前を持つパラメータが登録される事は推奨さ れない。 次の例を見よ。 Accept: audio/*; q=0.2, audio/basic この例では、「私は audio/basic を望むが、もし品質を 80% 下げても最も 有効に利用できるのであれば、どんな audio タイプでもかまわない」と解釈 される *べきである*。 Accept ヘッダフィールドが無い場合は、クライアントはすべてのメディアタ イプを受けつけるとみなされる。Accept ヘッダフィールドがある場合に、サ ーバが Accpet フィールド値に適したレスポンスを送る事ができなければ、 サーバは 406 (not acceptable) レスポンスを返す *べきである*。 より複雑な例を示す。 Accept: text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c これを文字通りに解釈すると、「text/html と text/x-c が望むメディアタ イプであるが、もし存在しないのであれば text/x-dvi エンティティを、そ れも無ければ、text/plain エンティティを送信せよ。」となる。 メディアレンジでは、より特定されるメディアレンジやメディアタイプが優 先される。あるメディアタイプに複数のメディアレンジが当てはまる場合、 最も特定される指示を優先される。例を見よ。 Accept: text/*, text/html, text/html;level=1, */* この優先順位は以下の様になる。 1) text/html;level=1 2) text/html 3) text/* 4) */* あるメディアタイプに関連付けられる品質係数は、そのメディアタイプにマ ッチする最も高い優先度を持つメディアレンジを発見する事によって決定さ れる。例を見よ。 Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5 品質係数は以下の様になる。 text/html;level=1 = 1 text/html = 0.7 text/plain = 0.3 image/jpeg = 0.5 text/html;level=2 = 0.4 text/html;level=3 = 0.7 注意: ユーザエージェントは、あるメディアレンジに対してデフォルトの 品質値を供給するかもしれない。しかし、ユーザエージェントが他のレン ダリングエージェントと相互作用できないクローズドなシステムで無いの であれば、このデフォルト値はユーザが設定できるようにすべきである。 14.2 Accept-Charset Accept-Charset リクエストヘッダフィールドは、レスポンスで受け入れ可能 な文字セットを示すのに使われる。このフィールドは、一般的な文字セット や、特殊な目的を持つ文字セットを理解できるクライアントがそれらの文字 セットの中で文書を表現する能力を持つサーバに対して、利用できる文字セ ットを通知する事を可能にする。 Accept-Charset = "Accept-Charset" ":" 1#( ( charset | "*" )[ ";" "q" "=" qvalue ] ) 文字セット値は、section 3.4 で記されている。それぞれの文字セットに、 ユーザの望む文字セットの優先度を表す関連付けられた品質値を付ける事が *できる*。デフォルト値は 1 である。次の例を見よ。 Accept-Charset: iso-8859-5, unicode-1-1;q=0.8 特別な値である "*" が Accept-Charset フィールド中にある場合、その Accept-Charset フィールドにて指定されていないすべての文字セット (ISO-8859-1を含む) に合致する。もし、"*" が Accept-Charset フィールド で与えられていなければ、明示されていないすべての文字セットの品質値は 0 である。ただし、ISO-8859-1 が明示されていない場合は、その品質値は 1 である。 Accept-Charset ヘッダが無い場合、デフォルトではどんな文字セットも受け 入れ可能である。Accept-Charset ヘッダがあっても、サーバが Accept- Charset ヘッダによって受け入れ可能なレスポンスを返せない場合、サーバ は、クライアントが扱えないレスポンスを返す事もできるが、406 (not acceptable) エラーレスポンスを返す *べきである*。 14.3 Accept-Encoding Accept-Encoding リクエストヘッダフィールドは、Accept ヘッダに似ている が、レスポンスで受け入れ可能な内容コーディング (section 3.5) を制限す る。 Accept-Encoding = "Accept-Encoding" ":" 1#( codings [ ";" "q" "=" qvalue ] ) codings = ( content-coding | "*" ) 使用例は以下の様になる。 Accept-Encoding: compress, gzip Accept-Encoding: Accept-Encoding: * Accept-Encoding: compress;q=0.5, gzip;q=1.0 Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0 サーバは、Accept-Encoding フィールドに従って、以下のルールを使い内容 コーディングが受け入れ可能かどうかを試す。 1. その内容コーディングが Accept-Encoding フィールドに列挙されてい るうちの一つで、その qvalue が0で無ければ、受け入れ可能である。 (section 3.9 で定義されているように、qvalue が 0 であるという 事は "受け入れ不可能" を意味する。) 2. Accept-Encoding フィールド中の特別な "*" 記号は、ヘッダフィール ド内に明示的に列挙されていないどんな内容コーディングも受け入れ 可能とみなす。 3. もし複数の内容コーディングが受け入れ可能ならば、最も大きな 0 以 外の qvalue を持つ受け入れ可能な内容コーディングが優先される。 4. "identity" 内容コーディングは、もし Accept-Encoding フィールド が "identity;q=0" を含む、あるいは "*;q=0" を含み明示的に "identity" 内容コーディングを含まない事で、特に否定していなけれ ば、常に受け入れ可能である。もし、Accept-Encodingフィールドが空 であれば、"identity" 内容コーディングのみが受け入れ可能である。 リクエストに Accept-Encoding ヘッダがある時に、サーバが Accept- Encoding ヘッダによって受け入れ可能なレスポンスを返せない場合、406 (not acceptable) エラーレスポンスを返す *べきである*。 リクエストに Accept-Encoding フィールドが無い場合は、サーバはどんな内 容エンコーディングも受け入れると仮定する事が *できる*。この場合、もし "identity" が利用可能な内容コーディングの一つで、その他の内容コーディ ングを使う事がクライアントにとって意味のある追加情報となるわけでなけ れば、サーバは "identity" 内容コーディングを使う *べきである*。 注意: リクエストが Accept-Encoding フィールドを含まず、"identity" が利用不可能である場合、古いクライアントの中には他の内容コーディン グと共に送られるメッセージを不適当に表示するものがあるので、 HTTP/1.0 クライアントが一般に理解する内容コーディング (例えば "gzip" や "compress") を使う事が好まれる。サーバは、また特定のユー ザエージェント、あるいはクライアントについての情報に基づく決定を行 ってもよい。 注意: 多くの HTTP/1.0 アプリケーションは、内容コーディングに関連付 けられた qvalue を理解しないし、従わない。これは、qvalue は x-gzip あるいは x-compress については作動しないし許可しない事を意味する。 14.4 Accept-Language Accept-Language リクエストヘッダフィールドは、Accept に似ているが、リ クエストへのレスポンスとして望む自然言語のセットを限定する。言語タグ は、section 3.10 にて定義されている。 Accept-Language = "Accept-Language" ":" 1#( language-range [ ";" "q" "=" qvalue ] ) language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" ) それぞれの languege-range では、そのレンジで指定する言語に対するユー ザの優先度を示す品質値をつける事が *できる*。品質値のデフォルトは、 "q=1" である。例を見よ。 Accept-Language: da, en-gb;q=0.8, en;q=0.7 これは、"私はデンマーク語を望むが、イギリス英語か、他の英語でも受け入 れる。" という事を意味する。もし languege-range が、タグに一致する 時、あるいはタグの接頭辞に等しくてそれに続く文字が "-" である時には、 言語タグに一致する。Accept-Languege フィールドに特別なレンジである "*" がある場合は、その Accept-Languege フィールド内に無いあらゆるタグ に一致する。 注意: この接頭辞一致規則を使うのは、もしユーザがあるタグを持った言 語を理解できるのであれば、そのユーザはこのタグを接頭辞に持つすべて の言語を理解できるはずなので、言語タグをそのような方法で割り当て る、という事を暗に意味するものではない。この接頭辞規則は単に、その ような状況になれば、接頭辞タグを使ってもよいという事である。 Accept-Language フィールドによって言語タグに割り当てられる言語品質係 数は、言語タグに一致するフィールドの中で最も長い languege-range の品 質値である。もしフィールド内に一致するタグが無ければ、割り当てられる 言語品質係数は 0 である。もしリクエストヘッダ内に Accept-Language が 無ければ、サーバはすべての言語が同等に利用可能であるとみなす *べきで ある*。Accept-Language がある場合は、0 以上の品質係数が割り当てられて いるすべての言語が利用可能である。 ユーザが、すべてのリクエストに完全な言語優先度を伴った Accept- Language ヘッダを送信する事は、プライバシー保護の立場とは逆のものとな るかもしれない。この問題の議論について、section 15.1.4 参照。 理解度はそれぞれのユーザへの依存度が高いので、クライアントアプリケー ションはユーザが利用できる言語優先度の選択肢を作る事が薦められる。も しその選択が利用できないように作られているならば、Accept-Language ヘ ッダフィールドをリクエストで与え *てはならない*。 注意: ユーザが利用可能な言語優先度の選択肢を作る時、開発者は、ユー ザは上で記述されているようなものに一致する言語の詳細に精通していな いし、それについて適切な解説を示すべきである、という事を認識すべき である。例えば、"en-gb" を選択したユーザは、もしイギリス英語が利用 できない時は、その他の英語文書が送られて来ると考えるであろう。ユー ザエージェントは、このような場合に最高の一致状態を得るために "en" を加える事を提案できる。 14.5 Accept-Ranges Accept-Ranges レスポンスヘッダフィールドは、サーバにリソースへの範囲 リクエストの受け入れを示させる。 Accept-Ranges = "Accept-Ranges" ":" acceptable-ranges acceptable-ranges = 1#range-unit | "none" バイトレンジリクエストを受け入れるオリジンサーバは、以下のものを送る 事が *できる*。 Accept-Ranges: bytes しかし、これは必ずとも必要ではない。クライアントは、必要とするリソー スに関してこのヘッダを受けなくても、バイトレンジリクエストを生成する 事が *できる*。レンジ単位は、section 3.12 にて定義されている。 リソースへのいかなる範囲リクエストも受け入れないサーバは、以下のもの を送る事が *できる*。 Accept-Ranges: none これは、クライアントに範囲リクエストをしないように忠告する。 14.6 Age Age レスポンスヘッダは、オリジンサーバがレスポンスを生成した (あるい は再検証した) 時点からの送信者の推定経過時間を示す。キャッシュされた レスポンスは、経過時間{age} がその使用有効期限{freshness lifetime} を 過ぎていなければ、新鮮である。Age 値は、section 13.2.3 で記述されたよ うに計算される。 Age = "Age" ":" age-value age-value = delta-seconds Age 値は、負でない整数値であり、秒数を表す。 もしキャッシュが表現できる以上の正の整数値を持っていたり、その経過時 間計算でオーバーフローしたら、2147483648 (2^31) という値の Age ヘッダ を送ら *なければならない*。キャッシュを持っている HTTP/1.1 サーバは、 自身のキャッシュからのすべてのレスポンスにおいて、Age ヘッダフィール ドを含ま *なければならない*。キャッシュは、少なくても 31bit の範囲は ある計算型を使う *べきである*。 14.7 Allow Allow エンティティヘッダフィールドは、Request-URI によって識別される リソースがサポートするメソッドの一覧を示す。このフィールドは、リソー スに関する有効なメソッドを受信者に厳密に知らせる事を目的にする。Allow ヘッダフィールドは、405 (Method Not Allowed) レスポンス中に存在し *な ければならない*。 Allow = "Allow" ":" #Method 使用例を見よ。 Allow: GET, HEAD, PUT このフィールドを使っても、クライアントが他のメソッドを試す事を妨げる 事はできない。しかし、クライアントは Allow ヘッダフィールドにて示され た値には従う *べきである*。実際に許可されるメソッドのセットは、各々の リクエストの度にオリジンサーバによって定義される。 PUT リクエスト時に、Allow ヘッダフィールドを使って、新規、あるいは更 新されるリソースによってサポートされる事が推奨されるメソッドを提供す る事が *できる*。サーバはこれらのメソッドをサポートする事は要求されな いが、レスポンスには実際にサポートされるメソッドを与えた Allow ヘッダ を含める *べきである*。 プロクシは、例えそこに書かれたすべてのメソッドが理解できなくても、ユ ーザエージェントがオリジンサーバと通信するための別の意味を持っている かもしれないので、Allow ヘッダフィールドを書き換え *てはならない*。 14.8 Authorization サーバに認証を受けようとするユーザエージェントは、必ずというわけでは ないが、通常は 401 レスポンスの後、リクエストに Authorization リクエ ストヘッダフィールドを含める。Authorization フィールド値は、リクエス トされたリソースのある領域へのユーザエージェントの認証情報を含む credentials からなる。 Authorization = "Authorization" ":" credentials HTTP アクセス認証については、"HTTP Authentication: Basic and Digest Access Authentication" [43] にて記述されている。もしリクエスト認証さ れ、領域が指定されれば、その領域内への他のすべてのリクエストへも同じ credentials は有効である *べきである* (認証スキーム自身は、例えば challenge 値や使用中の同期した時計によって変更した credentials のよう に、他の場合を要求しない事を仮定する)。 共有キャッシュ (section 13.7 参照) が Authorization フィールドを含む リクエストを受けた時、以下の例外のどれにも当てはまらなければ、他のど んなリクエストへの応答としても対応するレスポンスを返し *てはならな い*。 1. レスポンスが "s-maxage" という cache-control 指示が含んでいる場合 は、キャッシュは、その後のリクエストへの応答にそのレスポンスを使用 して *よい*。しかし (もし指定された最大有効期限が過ぎてしまってい たら) プロクシキャッシュは、オリジンサーバに新しいリクエストを認証 させるために新しいリクエストのリクエストヘッダを使って、始めにオリ ジンサーバで再検証し *なければならない*。 (これは s-maxage のため に定義されている動作である。) レスポンスが "s-maxage=0" を含んでい る場合は、プロクシは (レスポンスのキャッシュを) 再利用する前に常に 再検証し *なければならない*。 2. レスポンスが "must-revalidate" という cache-control 指示を含んでい る場合は、キャッシュはその後のリクエストへの応答にそのレスポンスを 使用して *よい*。しかし、レスポンスが新鮮で無い場合は、すべてのキ ャッシュは、オリジンサーバに新しいリクエストを認証させるために新し いリクエストのリクエストヘッダを使って、始めにオリジンサーバで再確 認し *なければならない*。 3. レスポンスが "public" という cache-control 指示を含んでいる場合 は、キャッシュはその後のどんなリクエストへの応答にもそのレスポンス を使用して *よい*。 14.9 Cache-Control Cache-Control 一般ヘッダフィールドは、リクエスト/レスポンス連鎖上の すべてのキャッシングメカニズムが従わ *なければならない* 指示を記述す るために使用される。キャッシュがリクエストやレスポンスに不利になるよ うに干渉させないような振る舞いを指定する。これらの指示は、常にデフォ ルトのキャッシングアルゴリズムを上書きするものである。キャッシュ指示 は、リクエスト中にある指示があっても、それと同じ指示がレスポンスで与 えられるという事を暗に意味しない、という意味において単向性である。 HTTP/1.0 キャッシュは、Cache-Control を実装してせず、Pragma: no-cache (section 14.32 参照) しか実装していないかもしれない事に 注意せよ。 キャッシュ指示は、リクエスト/レスポンス連鎖上のすべての受信者に適用 できるため、プロクシやゲートウェイアプリケーションを、そのアプリケー ションの重要性に関係なく通り抜け *なければならない*。特定のキャッシュ のために cache-directive を記述するのは不可能である。 Cache-Control = "Cache-Control" ":" 1#cache-directive cache-directive = cache-request-directive | cache-response-directive cache-request-directive = "no-cache" ; Section 14.9.1 | "no-store" ; Section 14.9.2 | "max-age" "=" delta-seconds ; Section 14.9.3, 14.9.4 | "max-stale" [ "=" delta-seconds ] ; Section 14.9.3 | "min-fresh" "=" delta-seconds ; Section 14.9.3 | "no-transform" ; Section 14.9.5 | "only-if-cached" ; Section 14.9.4 | cache-extension ; Section 14.9.6 cache-response-directive = "public" ; Section 14.9.1 | "private" [ "=" <"> 1#field-name <"> ] ; Section 14.9.1 | "no-cache" [ "=" <"> 1#field-name <"> ]; Section 14.9.1 | "no-store" ; Section 14.9.2 | "no-transform" ; Section 14.9.5 | "must-revalidate" ; Section 14.9.4 | "proxy-revalidate" ; Section 14.9.4 | "max-age" "=" delta-seconds ; Section 14.9.3 | "s-maxage" "=" delta-seconds ; Section 14.9.3 | cache-extension ; Section 14.9.6 cache-extension = token [ "=" ( token | quoted-string ) ] ある指示子がどんな 1#field-name パラメータも無く現れた時、その指令は リクエストやレスポンス全体に適用される。ある指示子が 1#field-name パ ラメータを伴って現れたら、指定されたフィールド (群) のみに適用され、 リクエストやレスポンスの残りの部分には適用されない。このメカニズムは 拡張性を持っている。HTTP プロトコルの将来のバージョンのインプリメンテ ーションは、これらの指示子に HTTP/1.1 で定義されていないヘッダフィー ルドを適用する事ができる。 cache-control 指示子は、これらの一般的なカテゴリの中に分類する事がで きる。 - キャッシュ可能なものを制限; これらはオリジンサーバのみが課す事が できる。 - キャッシュによって保存できるものを制限; これらはオリジンサーバか ユーザエージェントのどちらかによって課す事ができる。 - 基本的な満期メカニズムの修正; これらはオリジンサーバかユーザエー ジェントのどちらかによって課す事ができる。 - キャッシュの再検証と再読み込みの制御; これらはユーザエージェント のみが課す事ができる。 - エンティティの変形についての制御。 - キャッシングシステムの拡張。 14.9.1 キャッシュ可能とは何か リクエストメソッド、リクエストヘッダフィールド、レスポンスステータス がキャッシュ可能である事を要求している場合、デフォルトではレスポンス はキャッシュ可能である。section 13.4 では、キャッシュ可能性のためのこ れらのデフォルトを要約している。以下の Cache-Control レスポンス指示子 を使うと、オリジンサーバはレスポンスのデフォルトのキャッシュ可能性を 上書きする事ができる。 public たとえそれが通常はキャッシュ可能でなかったり、非共有キャッシュ内で のみキャッシュ可能であったとしても、レスポンスがすべてのキャッシュ によってキャッシュ可能に *できる* 事を示す。 (追加される詳細のた め、section 14.8 の Authorization も見よ。) private レスポンスメッセージのすべてもしくは一部は、単一のユーザのために用 意された物であり、共有キャッシュによってキャッシュされ *てはならな い* 事を示す。これによって、オリジンサーバは、そのレスポンスの指定 された部分ががあるユーザにのみ向けられたもので、別のユーザによるリ クエストにとっては正当なレスポンスではない事を述べる事ができるよう にする。プライベート (非共有) キャッシュは、そのレスポンスをキャッ シュ *できる*。 注意: この private と言う指示子の使用は、レスポンスがキャッシュで きるところのみを制御するもので、メッセージ内容のプライバシーは保 証できない。 no-cache もし no-cache 指示子がフィールド名を指定していなければ、オリジンサ ーバへの再検証が成功するまで、以降のリクエストを満足させるためにそ のレスポンスを使っ *てはならない*。これによって、オリジンサーバは リクエストするクライアント古くなったレスポンスを返すよう設定されて いるキャッシュによるキャッシングさえ行えなくする事ができる。 もし no-cache 指示子が一つ以上のフィールド名を指定していたら、キャ ッシュはキャッシングにおける他の制約の元で、以降のリクエストを満足 するためにそのレスポンスを使う事が *できる*。しかし、指定されたフ ィールド名はオリジンサーバへの再検証が成功するまで、以降のリクエス トを満足させるためにそのレスポンスを使っ *てはならない*。これによ って、オリジンサーバはレスポンスの残りをキャッシングできる間、レス ポンス中のあるヘッダフィールドの再使用を行えなくする事ができる。 注意: 多くの HTTP/1.0 キャッシュは、この指示子を理解できず、従う 事はないだろう。 14.9.2 キャッシュによって保存できるものは何か no-store no-store 指示子の目的は、取り扱いが慎重な (例えばバックアップテー プ上の) 情報の不注意な漏洩や保留を防ぐ事である。no-store 指示子は メッセージ全体に適用され、レスポンスかリクエストのどちらかで送るこ とが *できる*。リクエストで送られる場合、キャッシュはそのリクエス トやそれへのいかなるレスポンスの一部分を保存し *てはならない*。レ スポンスで送られる場合、キャッシュはそのレスポンスやそれを引き起こ したリクエストの一部分を保存し *てはならない*。この指示は、非共有 ・共有キャッシュのどちらにも当てはまる。この状況下での "保存しては *ならない*" は、キャッシュを一時的なものではない保存場所{non- volatile storage} にその情報を故意に保存し *てはならない* し、一時 的な保存場所{volatile storage} であってもそれを転送した後にできる だけ早くそこから情報の削除するために最善を尽くさ *なければならな い*、という事を意味する。 その指示がレスポンスに関連している時でも、ユーザはキャッシングシス テムの外側にそのようなレスポンスを明白に (例えば、"Save As" ダイア ログを伴って) 保存できる。履歴バッファは、これらの通常操作の一部と してこのようなレスポンスを保存する事が *できる*。 この指示の目的は、キャッシュデータ構造への予期しないアクセスを経て 情報の偶発的な漏洩を心配するユーザやサービス著者達が前もって示した 必要条件に見合うようにするためである。この指示子を使う事でいくつか の場合でプライバシーを改善できるであろうが、これはプライバシーを保 証するための信頼できる、もしくは十分なメカニズムのどのような方法に おけるものでは *無い* 事を警告しておく。特に、悪意のあるキャッシュ や一部の機能のみが実装された{compromised} キャッシュはこの命令を認 識しなかったり従わなかったりするかもしれないし、あるいは通信ネット ワーク自体が盗聴に対して無防備であるかもしれない。 14.9.3 基本的な期限のメカニズムの修正 エンティティの有効期限は、Expires ヘッダ (section 14.21 参照) を使っ てオリジンサーバにより記述する事が *できる*。あるいは、レスポンスで max-age 指示子を使って記述する事が *できる*。max-age cache-control 指 示子がキャッシュされたレスポンス中にあった時に、現在まで経過した時間 {age} がそのリソースへ新しいリクエストがなされてからの (秒数で) 与え られた時間を過ぎていたら、そのレスポンスは新鮮では無い。レスポンス中 の max-age 指示子があり、その他にキャッシュに制限を与えるような指示子 が無ければ、レスポンスはキャッシュ可能 (すなわち、"共有キャッシュ") であるという事を暗黙的に意味する。 もしレスポンスに Expires ヘッダと max-age 指示子の両方が含まれたいた ら、たとえ Expires ヘッダがより制限的なものであっても、max-age 指示子 は Expires ヘッダを上書きする。このルールによって、オリジンサーバは与 えられたレスポンスに対して HTTP/1.0 キャッシュよりも HTTP/1.1 (及びそ れ以降の) キャッシュに長い有効期限を提供できるようになる。これは、あ る HTTP/1.0 キャッシュがおそらく同期していない時計のために不適当に経 過時間や有効期限を計算してしまうような場合に有用であろう。 多くの HTTP/1.0 キャッシュインプリメンテーションは、Cache-Control レ スポンス指示子が "no-cache" と同等であるようなレスポンスの Date 値以 下として Expires 値を扱うであろう。もし HTTP/1.1 キャッシュがそのよう なレスポンスを受けとり、そのレスポンスが Cache-Control ヘッダフィール ドを含んでいなければ、そのレスポンスは HTTP/1.0 サーバとの互換性を保 つためにキャッシュ可能ではないとみなす *べきである*。 注意: オリジンサーバは、例えば "private" 指示子のような、比較的新 しい HTTP キャッシュコントロール機能を、その機能を理解しない古い キャッシュを含むネットワーク上で使いたいとするかもしれない。オリ ジンサーバは、その値が Date 値以下になるような Expires フィールド を新しい機能を結合する必要があるであろう。これによって、古いキャ ッシュにレスポンスを不適当にキャッシングさせないようにするであろ う。 s-maxage レスポンスが s-maxage 指示子を含んでいる場合、共有キャッシュにつ いて (非共有キャッシュについてではない) 、この指示子で指定された 最大使用期限は max-age 指示子や Expires ヘッダによって指定された 最大使用期限を上書きする。また s-maxage 指示子は proxy-revalidate 指示子 (section 14.9.4 参照) のセマンティクス、すなわち、共有され たキャッシュはオリジンサーバに最初の再検証をせずにその後のリクエ ストへのレスポンスとしてそれが新鮮で無くなってしまったエントリを 使ってはならない、という事も暗黙的に意味する。s-maxage 指示子は、 非共有キャッシュには常に無視される。 多くの古い、この仕様書に従わないようなキャッシュは、いかなる cache- control 指示子も実装していない事に注意せよ。HTTP/1.1 に従順なキャッシ ュによるキャッシングを制限し、同時にそれを邪魔しない、cache-control 指示子を使いたいオリジンサーバは、max-age 指示子は Expires ヘッダを上 書きするという条件と、HTTP/1.1 に従順なキャッシュ以前のものは max-age 指示子に気付かないという事実を利用する事が *できる*。 他の指示子は、ユーザエージェントが基本的な期限メカニズムを修正できる ようにする。これらの指示は、リクエストにおいて記述 *できる*。 max-age クライアントは、ここで記述した秒時間よりも大きな経過時間を持たない ようなレスポンスを受け入れる意図を持つ事を表す。そこに max-stale 指示子が含まれていなければ、クライアントは古くなったレスポンスを受 け入れようとはしていない。 min-fresh クライアントは、それが新鮮であるような残り時間がここで指定した秒時 間に現在の経過時間を足した物より小さくなるようなレスポンスを受け入 れる意図を持つ事を表す。これは、クライアントが少なくとも指定した秒 数の間はまだ新鮮であるようなレスポンスを望んでいるという事である。 max-stale クライアントは、期限を超えたようなレスポンスを受け入れる意図を持つ 事を表す。max-stale に値を割り当てられている場合、クライアントは指 定した秒数だけ有効期限を過ぎてしまったようなレスポンスを受け入れよ うとしている。max-stale に値が割り当てられていない場合は、クライア ントはどれだけ時間が経過しような新鮮で無いレスポンスも受け入れよう としている。 リクエスト中の max-stale 指示子、あるいはキャッシュがレスポンスの有効 期限を上書きするように形成されているかのどちらかの理由で、キャッシュ が新鮮でないレスポンスを返す場合、キャッシュは Warning 110 (Response is stale) を使って、新鮮ではないレスポンスに Warning ヘッダを追加し *なければならない*。 キャッシュは、キャッシュの再検証に関しての "MUST" レベルの必要条件 (例えば "must-revalidate" cache-control 指示子) とは矛盾を起こさない ようにする場合のみ、再検証せずに新鮮で無いレスポンスを返すように構成 する事が *できる*。 もし新しいリクエストとキャッシュされたエントリの両方に "max-age" 指示 子が含まれていたら、そのリクエストのためのキャッシュされるエントリの 残り時間の決定には、二つの値の小さい方が使われる。 14.9.4 キャッシュの再検証とリロードコントロール 時々ユーザエージェントは、キャッシュがオリジンサーバ (オリジンサーバ への経路上の次のキャッシュではなく) にキャッシュエントリの再検証を行 う事を要求したり、オリジンサーバからそのキャッシュエントリをリロード する事を望みあるいは必要とするかもしれない。エンドトゥエンド{end-to- end} 再検証は、キャッシュかオリジンサーバのどちらかがキャッシュされた レスポンスの有効期限を過大評価している場合に必要とあろう。エンドトゥ エンド・リロードは、キャッシュエントリがある理由のため古く使えなくな った場合に必要とあろう。 エンドトゥエンドの再検証は、クライアントが自身のローカルにキャッシュ されたコピーを持っていないような、我々が "未指定性エンドトゥエンド再 検証{Unspecified end-to-end revalidation}" と呼ぶような場合か、クライ アントがローカルにキャッシュされたコピーを持っているような、我々が "指定性エンドトゥエンド再検証{Specific end-to-end revalidation}" と呼 ぶような場合の、どちらかの場合で要求されるであろう。 クライアントは、Cache-Control リクエスト指示子を使って以下の三種類の 動作を指定する事ができる。 エンドトゥエンド・リロード リクエストは、"no-cache" Cache-Control 指示子や、HTTP/1.0 クライア ントとの互換性のための "Pragma: no-cache" を含んでいる。リクエスト 中には、no-cache 指示子を伴うどんなフィールド名も含ん *ではならな い*。サーバは、そのようなリクエストに応答する時にはキャッシュされ たコピーを使っ *てはならない*。 指定性エンドトゥエンド再検証 リクエストは、"max-age=0" Cache-Control 指示子を含み、これは強制的 に自身のエントリの正当性をオリジンサーバや、もしあればオリジンサー バへの経路上のそれぞれのキャッシュに再検証させる。最初のリクエスト では、クライアントの現在のバリディタを伴うキャッシュの正当性検証条 件{cache-validating conditional} を含んでいる。 未指定性エンドトゥエンド再検証 リクエストは、"max-age=0" Cache-Control 指示子を含み、これは強制的 に自身のエントリの正当性をオリジンサーバや、もしあればオリジンサー バへの経路上のそれぞれのキャッシュに再検証させる。最初のリクエスト では、クライアントの現在のバリディタを伴うキャッシュの正当性検証条 件を含んでいない。このリソースのキャッシュエントリを持っている経路 上の最初のキャッシュ (もしあれば) は、現在のバリディタを伴うキャッ シュの正当性検証条件を含んでいる。 max-age 中間キャッシュが max-age=0 によって、そのキャッシュエントリの再確 認を強制され、クライアントがそのリクエスト中に自身のバリディタを 供給するような場合、供給されたバリディタは現在キャッシュエントリに 保存されているバリディタとは異なるかもしれない。この場合、キャッシ ュは意味的透過性の影響を考える事無くそれ自身のリクエストを作成する 際にはどちらのバリディタでも使う事が *できる*。 しかし、バリディタの選択によってパフォーマンスに影響が出るかもしれ ない。中間キャッシュがリクエストを作成する際の最良のアプローチは、 自身の確証子を使う事である。サーバが 304 (Not Modified) を返した場 合は、キャッシュはクライアントに 200 (OK) レスポンスと現在の検証さ れたコピーを返す事ができる。しかし、もしサーバが新しいエンティティ とキャッシュバリディタを返したら、中間キャッシュは返されたバリディ タとクライアントのリクエストから与えられたものとを強い比較機能を使 使用して比較する事ができる。クライアントのバリディタがオリジンサー バのものと等しければ、中間キャッシュは単純に 304 (Not Modified) を 返す。そうでなければ、200 (OK) レスポンスと新しいエンティティを返 す。 リクエストが no-cache 指示子を含む場合は、min-fresh, max-stale, max-age を含む *べきではない*。 only-if-cached 例えばネットワーク接続が極めて貧弱である等、いくつかの場合では、ク ライアントはキャッシュが現在保存しているレスポンスのみを返し、オリ ジンサーバにリロードや再検証を行わないように望むだろう。これを行う ため、クライアントはリクエスト中に only-if-cached 指示子を含む事が できる。この指示子を受け取った場合、キャッシュはそのリクエストの別 の条件を満たすようなキャッシュエントリを使って返すか、504 (Gateway Timeout) ステータスを返すか、どちらかを行う *べきである*。しかし、 もしあるキャッシュのグループが内部の接続性が良い統合システムとして 運用されているなら、そのようなリクエストはそのようなキャッシュのグ ループ内に転送しても *よい*。 must-revalidate キャッシュはサーバの指定する有効期限を無視するように形成する事が *でき*、またクライアントのリクエストでは max-stale 指示子を含む事 が *できる* (これは似たような効果がある) ので、プロトコルはオリジ ンサーバがそれ以降に使われるあらゆるキャッシュエントリの再検証を要 求するようなメカニズムを含む。must-revalidate 指示子がキャッシュに よって受信されたレスポンス中にあった時は、キャッシュはオリジンサー バに最初にそれを再検証せずに以降のリクエストに応答するために新鮮で 無いエントリを使っ *てはならない*。 (すなわち、キャッシュは毎回エ ンドトゥエンドの再検証をし *なければならない* し、もし、単にオリジ ンサーバの Expires か max-age 値に基づいているなら、キャッシュされ たレスポンスは新鮮なものではない。) must-revalidate 指示子は、特定のプロトコル機能の信頼できる操作をサ ポートするために必要である。いかなる状況においても HTTP/1.1 キャッ シュは must-revalidate 指示子には従わ *なければならない* が、特別 に、もしキャッシュが何らかの理由でオリジンサーバに到達できない場合 は、504 (Gateway Timeout) レスポンスを生成し *なければならない*。 例えば黙って履行されていない財務的処理{silently unexecuted financial transaction} のように、エンティティの再検証が失敗するこ とでリクエストが不適当な操作というような結果になる場合にのみ、サー バは must-revalidate 指示子を送る *べきである*。受信者は、この指示 を破るような自動的動作は行っ *てはならない* し、もし再検証に失敗し たらエンティティの検証が行われていないコピーを自動的に供給し *ては ならない*。 これは奨励されないが、厳しい接続制約の元で操作されているユーザエー ジェントはこの指示を破る事が *できる* が、そのような場合でも、検証 されていないレスポンスが供給された事をユーザに明確に警告し *なけれ ばならない*。この警告は、検証されていないアクセス毎に供給され *な ければならない* し、ユーザによる明確な検証を必要とす *べきであ る*。 proxy-revalidate proxy-revalidate 指示子は、非共有ユーザエージェントキャッシュには 適用されない事を除けば、must-revalidate 指示子と同じ意味を持つ。こ れは、多くのユーザにサービスしているプロクシは毎回再検証する事を必 要とする (それぞれのユーザが認証されている事を保証するため) 一方 で、ユーザのキャッシュにそれを再検証する必要が無いレスポンス (ユー ザによって既に一度認証されているので) を保存し、後に返すような事を 許すような認証リクエストへのレスポンスとして使用できる。 そのような認証されたレスポンスも、それらがすべてキャッシュされるよ うにするためには public キャッシュコントロール指示子を必要とする事 に注意せよ。 14.9.5 no-transform 指示子 no-transform 中間キャッシュ (プロクシ) の実装者は、あるエンティティボディのメデ ィアタイプを変換する事が有用である事を知っている。例えば、透過的プ ロクシはキャッシュスペースを節約したり、遅い通信路上のトラフィック の量を減らすために画像フォーマットの変換を行う事ができる。 しかし、これらの変換がある種のアプリケーションのために作られたエン ティティボディに適用される時に、深刻な操作上の問題が起こる事があ る。例えば、医療用の映像処理、科学的なデータ分析、およびエンドトゥ エンド認証を使うようなアプリケーションは、すべて元々のエンティティ ボディと bit 単位で同一のエンティティボディを受け取る事を前提にし ている。 それ故に、もしメッセージが no-transform 指示子を含んでいたら、中間 キャッシュやプロクシは no-transform 指示に従うものとして section 13.5.2 で列挙されているようなヘッダを変更し *てはならない*。これ は、キャッシュやプロクシがこれらのヘッダによって指定されたエンティ ティボディの、エンティティボディ自身の値を含め、いかなる部分も変更 し *てはならない* 事を意味する。 14.9.6 キャッシュコントロールの拡張 Cache-Control ヘッダフィールドは、それぞれにオプション的に割り当てら れる値を伴う、一つ以上の cache-extension トークンを使う事によって拡張 可能である。情報的拡張 (キャッシュの振る舞いにおける変更を必要としな いもの) は、他の指示子のセマンティクスを変更せずに追加 *できる*。振る 舞いの拡張は、既存のキャッシュ指示子のベースへの修飾子として動作する 事により機能するために設計されている。新しい指示子と標準の指示子が与 えられる場合、新しい指示子を理解しないアプリケーションは標準の指示子 によって指定される振る舞いをデフォルトとし、新しい指示子を理解するよ うなアプリケーションは標準命令に関連する要求点を修正するようにそれを 認識する。このようにして、Cache-Control 指示子はその基底のプロトコル を変更する必要なく拡張する事ができる。 この拡張メカニズムは、それに元々の HTTP バージョンによって定義される すべての cache-control 指示子に従い、ある特定の拡張にも従い、理解でき ない指示子はすべて無視するような HTTP キャッシュに依存する。 例えば、ここで private 指示子の修飾子として動作する "community" と呼 ばれる新しいレスポンス指示子を仮定する。この新しい指示子を、あらゆる 非共有キャッシュに加えて、この値で名前付けされたコミュニティのメンバ によってのみ共有されるあらゆるキャッシュはそのレスポンスをキャッシュ できる、と定義する。UCI というコミュニティに元々プライベートレスポン スであるものを共有キャッシュとして使わせようとするオリジンサーバは、 以下のものを含む事でそうする事ができる。 Cache-Control: private, community="UCI" このヘッダフィールドを認識するキャッシュは、例え community というキャ ッシュ拡張を理解しなくても、private 指示子を見つけ理解する事で、安全 な振る舞いをデフォルトとするので正しく動作するだろう。 認識できないキャッシュ指示子は、無視され *なければならない*。つまり、 HTTP/1.1 キャッシュには理解されないであろうあらゆるキャッシュ指示子は 例えキャッシュが拡張を理解できないとしてもキャッシュの振る舞いが最小 限正しいものであるように、標準の指示子 (やレスポンスのデフォルトのキ ャッシュ能力) と結合され送られるという事が仮定される。 14.10 Connection Connection 一般ヘッダフィールドは、送信者が特定の接続のために望むオプ ションを指定する事を可能にするが、介在するプロクシとの接続を超えて伝 達し *てはならない*。 Connectionヘッダは、以下の様な文法を持つ。 Connection = "Connection" ":" 1#(connection-token) connection-token = token HTTP/1.1 プロクシは、メッセージが転送される前に Connection ヘッダフィ ールドを解析し、フィールド内の各 connection-token ごとに、connection- token と同じ名前を持つメッセージからヘッダフィールドを削除し *なけれ ばならない*。接続オプションは、その接続オプションに関するパラメータが 無ければ、追加的ヘッダフィールドは送信されないかもしれないので、対応 する追加的ヘッダフィールドによってではなく、Connection ヘッダフィール ド内の connection-token によって表される。 Connection ヘッダ内に列挙されるメッセージヘッダは、Cache-Control のよ うなエンドトゥエンドヘッダを含め *てはならない*。 HTTP/1.1 では、送信者がレスポンスを完了した後に接続を切断するというこ とを合図する "close" 接続オプションを定義する。次の例を見よ。 Connection: close この場合、リクエスト・レスポンスのどちらかのヘッダフィールドの場合で も、その接続は現在のリクエスト/レスポンスが完了したら、「持続的」 (section 8.1) であるとみなす *べきではない*。 持続的接続をサポートしていない HTTP/1.1 アプリケーションは、すべての メッセージに "close" 接続オプションを含め *なければならない*。 Connection ヘッダを含む HTTP/1.0 (あるいはそれ以前の) メッセージを受 けとったシステムは、このフィールド内の各 connection-token ごとに、 connection-token と同じ名前を持つメッセージからヘッダフィールドを削除 し、無視し *なければならない*。これは、HTTP/1.1 以前のプロクシによっ てそのようなヘッダフィールドを転送するような誤りを起こさないようにす るものである。section 19.6.2 参照。 14.11 Content-Encoding Content-Encoding エンティティヘッダフィールドは、メディアタイプの修飾 子として使われる。この値があれば、それはエンティティボディに適用され ている内容コーディングを示し、すなわち Content-Type ヘッダフィールド にあるメディアタイプを得るために適用しなければならないデコード方法を 示している。内容コーディングは、主にその根底のメディアタイプの特性を 失わせる事無く文書を圧縮するために使われる。 Content-Encoding = "Content-Encoding" ":" 1#content-coding 内容コーディングは、section 3.5 にて定義されている。使用例を見よ。 Content-Encoding: gzip 内容コーディングは、Request-URI によって識別されるエンティティの特性 である。一般に、エンティティボディは、このエンコーディング状態のまま 保存され、レンダリングやそれに類似した使用の直前にのみデコードされ る。しかし、透過的でないプロクシは、受信者がそれ以外のコーディングが 利用可能であると知っていて、かつメッセージ中に "no-transform" cache- control 指示子が無い時は、内容コーディングを修正する事が *できる*。 エンティティの内容コーディングが "identity" で無い場合、レスポンスは 現在使用されている identity で無い内容コーディング (複数可) を列挙し た、Content-Encoding エンティティヘッダ (section 14.11) を含め *なけ ればならない*。 もしリクエストメッセージ中のエンティティの内容コーディングをオリジン サーバが利用できなければ、サーバは 415 (Unsupported Media Type) のス テータスコードを持つレスポンスを返す *べきである*。 エンティティに複数のエンコーディングが適用されている場合は、それが適 用された順に列挙され *なければならない*。エンコーディングパラメータに ついての追加情報は、この仕様書では定義されない他のエンティティヘッダ フィールドによって与える事が *できる*。 14.12 Content-Language Content-Language エンティティヘッダフィールドは、それと共に送られるエ ンティティの読者の自然言語を表す。ただし、エンティティボディで使われ ている言語のすべてとは一致しないかもしれない事に注意せよ。 Content-Language = "Content-Language" ":" 1#language-tag 言語タグは、section 3.10 にて定義されている。Content-Language の主な 目的は、ユーザ自身が望む言語に応じて、エンティティを識別したり区別し たりできるようにするためである。そのため、もしボディの内容がデンマー ク語を理解できる人のみを対象にしているのならば、それに合ったフィール ドは次のようになる。 Content-Language: da Content-Language が特定されていない場合、デフォルトではその内容は全て の言語読者に向けられている、という事になる。これは、送信者はそれがい ずれかの自然言語に特有のものであるとは考えていないか、あるいは送信者 自身がどの言語を意図しているかがわからないか、のどちらかを意味するで あろう。 複数の言語の読者を対象とした内容では、複数の言語を列挙する事が *でき る*。例えば、オリジナルのマオリ語版と英語版が同時に表現される "ワイタ ンギ条約" の翻訳では、以下の様に表されるだろう。 Content-Language: mi, en しかし、エンティティ内に複数の言語があるという事が、すなわち複数の言 語の読者を対象にしているとは限らない。例えば、"初めてのラテン語" のよ うなその言語の初心者向け読み物がその例で、これは明らかに英語を理解す る読者に向けられている。この場合、Content-Language は適切に "en" のみ を含めるべきである。 Content-Language は、テキスト文書だけでなく、あらゆるメディアタイプに 適用する事が *できる*。 14.13 Content-Length Content-Length エンティティヘッダフィールドは、受信者に送られるエンテ ィティボディのサイズを、HEAD メソッドの場合は GET リクエストがなされ た場合に送られるエンティティボディのサイズを、10 進数のオクテットで表 す。 Content-Length = "Content-Length" ":" 1*DIGIT 例を見よ。 Content-Length: 3495 アプリケーションは、section 4.4 にある規則で禁じられていなければ、こ のフィールドをメッセージボディの転送長さを示すのに使う *べきである*。 0 以上の値を持つ Content-Length は、すべて有効値である。section 4.4 では、Content-Length が与えられていない場合のメッセージボディの長さを 決定する方法を記している。 このフィールドの意味は、MIME にて対応する定義、すなわち "message/external-body" という content-type の中で使われるオプショナ ルなフィールドとは全く異なっている事に注意せよ。HTTP では、section 4.4 にある規則で禁じられていなければ、メッセージを転送する前にその長 さを決定できる時は常にそれを送る *べきである*。 14.14 Content-Location Content-Location エンティティヘッダフィールドは、エンティティがリクエ ストされたリソースの URI とは別の場所から取得可能である時に、そのメッ セージに含まれるエンティティに対するリソースの場所を与える時に使う事 が *できる*。サーバは、そのレスポンスエンティティに対応する、別種のも の{variant} のための Content-Location を返す *べきである*。特に、それ に関連するリソースが複数あり、それぞれのエンティティが実際に別々の場 所で別々にアクセスされるような場合は、サーバは返される特定の別リソー ス{variant} について、Content-Locationを返す *べきである*。 Content-Location = "Content-Location" ":" ( absoluteURI | relativeURI ) Content-Location の値は、エンティティの基底 URI をも定義する。 Content-Location 値は、本来の Request-URI の代わりとはならない。すな わち、リクエストの時点でのこの特定のエンティティに対応するリソースの 場所を示しているだけである。もしその特定のエンティティの源を明らかに したければ、将来のリクエストでは Request-URI として Content-Location の URI を指定する事が *できる*。 キャッシュは、再利用するために使った URI とは異なる Content-Location を持つエンティティを、その後のその Content-Location URI へのリクエス トへのレスポンスとして使ってもよいとは仮定できない。しかし、section 13.6 に記されているように、Content-Location は単一のリクエストされた リソースから再利用するための複数のエンティティを区別するために使う事 ができる。 Content-Location が相対 URI であれば、その相対 URI は Request-URI か ら相対的に解釈される。 PUT リクエストや POST リクエストでの Content-Location の意味は定義さ れていないので、この場合サーバはそれを無視してもかまわない。 14.15 Content-MD5 Content-MD5 エンティティヘッダフィールドは、RFC 1864 [23] にて定義さ れるように、エンティティボディのメッセージ状態チェック{message integrity check} (MIC) をエンティトゥエンドで提供するという目的を持つ エンティティボディの MD5 ダイジェストである。 (注意: MIC は転送時にお ける偶発的変化を発見するには有効であるが、故意的攻撃においては十分に 対抗はできない。) Content-MD5 = "Content-MD5" ":" md5-digest md5-digest = Content-MD5 ヘッダフィールドは、オリジンサーバやクライアントがエンテ ィティボディの状態チェックをするために生成する事が *できる*。オリジン サーバやクライアントのみが Content-MD5 ヘッダフィールドを生成する事が *でき*、プロクシやゲートウェイはエンドトゥエンドでの状態チェックとい う価値が失われてしまうので、これを生成し *てはならない*。ゲートウェイ やプロクシを含むあらゆるエンティティボディの受信者は、このヘッダフィ ールド内のダイジェスト値が受信したエンティティボディのものと一致する かどうかをチェックする事が *できる*。 MD5 ダイジェストは、エンティティボディの内容に基づいて計算されるが、 これは適用される内容コーディングは含むが、メッセージボディに適用され る転送コーディングは含めない。メッセージに転送コーディングがなされて いる場合、そのエンコーディングは受け取ったエンティティについての Content-MD5 値をチェックする前に取り除かれ *なければならない*。 これによって、もし転送コーディングが適用されずに送信された場合でも、 ダイジェストを正確にエンティティボディのオクテットに基づいて計算する 事ができる。 HTTP は、MIME 複合メディアタイプのダイジェスト (例えば、multipart/* や message/rfc822) を計算できるように RFC 1864 を拡張したが、前の段落 で定義したようなダイジェストの計算方法は変わらない。 ここにいくつか重要な点がある。複合型のエンティティボディは、それぞれ が MIME や HTTP ヘッダ (Content-MD5, Content-Transfer-Encoding, Content-Encoding 各ヘッダを含む) を持つような、複数のボディ部分{body- part} を持つ事が *できる*。もしボディ部分に Content-Transfer-Encoding か Content-Encoding のどちらかのヘッダがあれば、そのボディ部分の内容 はエンコーディングが適用されているとみなされ、Content-MD5 ダイジェス トにはそのまま、すなわちエンコーディングが適用された後のボディ部分で ある、とみなされる。Transfer-Encoding ヘッダフィールドは、ボディ部分 に含む事は許されない。 ダイジェストを計算、あるいはチェックする前には、どんな改行も CRLF に 変換し *てはならない*。すなわち、実際に送信されたテキストで使われた改 行規定は、ダイジェストを計算する時までそのままにしておか *なければな らない*。 注意: HTTP における Content-MD5 の定義は、RFC 1864 での MIME エンティ ティボディについてのものと全く同一であるが、HTTP エンティティボディへ の Content-MD5 の適用とMIMEエンティティボディへのものとを区別する方法 がいくつかある。まず一つは HTTP は、MIME とは違い、Content-Transfer- Encoding を使わずに、Transfer-Encoding や Content-Encoding を使う。次 に、HTTP は MIME よりも頻繁にバイナリ内容タイプを使うが、その場合は、 ダイジェストを計算するのに使ったバイトオーダーが、そのタイプで定義さ れた伝送バイトオーダーであるという事に注意する必要がある。最後に、 HTTP では正当な形式である CRLF 以外の改行規定を持つテキストタイプの伝 送を許している。 14.16 Content-Range Content-Range エンティティヘッダフィールドは、共に送られるエンティテ ィボディの一部が、エンティティボディ全体のうちどこに当たるものかを示 すために送られる。レンジ単位は、section 3.12 にて定義されている。 Content-Range = "Content-Range" ":" content-range-spec content-range-spec = byte-content-range-spec byte-content-range-spec = bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" ) byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*" instance-length = 1*DIGIT エンティティボディ全体の長さがわからない、あるいはそれを決定するのが 難しいというので無ければ、このヘッダにはその全体の長さを含む *べきで ある*。アスタリクス "*" という文字があった場合、そのレスポンスが生成 された時点では instance-length はわからないという事を意味する。 byte-ranges-specifier 値 (section 14.35.1 参照) とは違い、byte-range- resp-spec では、範囲は一つのみ、そしてその範囲の最初と最後のバイトを 絶対バイト位置で指定し *なければならない*。 last-byte-pos 値が first-byte-pos 値より小さかったり、instanse-length 値が last-byte-pos 値以下であるような byte-range-resp-spec を持った byte-content-range-spec は不正である。不正な byte-content-range-spec を受信しても、その値、そしてそれと共に送られてきた内容は無視し *なけ ればならない*。 レスポンスと共に 416 (Requested range not satisfiable) というステータ スコードを送るサーバは、byte-range-resp-spec が "*" である Content- Range フィールドを含む *べきである*。instance-length は、選択されたリ ソースの現在の長さを示す。206 (Partial Content) というステータスコー ドのレスポンスには、byte-range-resp-spec が "*" である Content-Range フィールドを含ん *ではならない*。 byte-content-range-spec 値の例として、エンティティが全体で 1234 バイ ト持っていると仮定する。 . 最初の 500 バイト: bytes 0-499/1234 . 次の 500 バイト: bytes 500-999/1234 . 最初の 500 バイト以外すべて: bytes 500-1233/1234 . 最後の 500 バイト: bytes 734-1233/1234 HTTP メッセージが単一のレンジ (例えば、単一のレンジへのリクエスト、あ るいは複数レンジであっても隙間無く重なるようなセットへのリクエスト等 へのレスポンス) の内容を含んでいる場合、この内容は Content-Range ヘッ ダと、実際に転送されるバイト数を示した Content-Length ヘッダを伴う。 例を見よ。 HTTP/1.1 206 Partial content Date: Wed, 15 Nov 1995 06:25:24 GMT Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT Content-Range: bytes 21010-47021/47022 Content-Length: 26012 Content-Type: image/gif HTTP メッセージが複数のレンジ (例えば、その範囲が重ならないような複数 レンジへのリクエストのレスポンス) の内容を含んでいる場合、それらはマ ルチパートメッセージとして転送される。この目的で使われるマルチパート メディアタイプは、付録 19.2 にて定義される "multipart/byteranges" で ある。互換性の問題に付いては、付録 19.6.3 参照。 単一レンジへのリクエストのレスポンスには、multipart/byteranges メディ アタイプを使って送っ *てはならない*。結果的に単一レンジになるような、 複数レンジへのリクエストのレスポンスには、その部分を送るのに multipart/byteranges メディアタイプを使っても *よい*。 multipart/byteranges メッセージをデコードできないクライアントは、一つ のリクエストで複数のバイトレンジを要求し *てはならない*。 クライアントが1つのリクエストで複数のバイトレンジを要求した時、サー バはリクエストされた順にバイトレンジを返す *べきである*。 サーバがシンタックス上不正だという理由で byte-range-spec を無視した場 合、サーバはその不正な Range ヘッダフィールドが存在しない時と同様にそ のリクエストを扱う *べきである*。 (通常、それはエンティティ全体を含ん だ 200 レスポンスを返す事を意味する。) もし、サーバが満足できない Range リクエストヘッダフィールド (つまり、 その byte-range-spec 値のすべてにおいて、first-byte-pos の値が選択さ れたリソースの現在の長さを越えているようなもの) を含んだ (If-Range リ クエストヘッダフィールドを含む場合以外の) リクエストを受けたならば、 416 (Requested range not satisfiable) というレスポンスコードを返す *べきである* (section 10.4.17)。 注意: すべてのサーバがこのリクエストヘッダを実装しているわけではない ので、クライアントは満足できない Range リクエストヘッダフィールドへの レスポンスとして、サーバが 200 (OK) レスポンスの代わりに 416 (Requested range not satisfiable) レスポンスを送るであろうという事を 当てにはできない。 14.17 Content-Type Content-Type エンティティヘッダフィールドは、受信者に送られるエンティ ティボディのメディアタイプを示し、HEAD メソッドの場合は、GET リクエス トがなされた場合に送られるエンティティボディのメディアタイプを示す。 Content-Type = "Content-Type" ":" media-type メディアタイプは section 3.7 にて定義されている。このフィールドの使用 例を見よ。 Content-Type: text/html; charset=ISO-8859-4 エンティティのメディアタイプを識別するための方法については、section 7.2.1 にて更に詳しく記述されている。 14.18 Date Date 一般ヘッダフィールドは、メッセージが生成された日付・時刻を表し、 RFC 822 の orig-date と同じセマンティクスを持つ。フィールド値は、 section 3.3.1 にて示される HTTP-date であり、RFC 1123 [8] の時刻フォ ーマットが送られ *なければならない*。 Date = "Date" ":" HTTP-date 例を見よ。 Date: Tue, 15 Nov 1994 08:12:31 GMT オリジンサーバは、以下の場合を除き、すべてのレスポンスに Date ヘッダ フィールドを含め *なければならない*。 1. もし、レスポンスステータスコードが 100 (Continue) か 101 (Switching Protocols) ならば、レスポンスはサーバのオプションと して、Date ヘッダフィールドを含める事が *できる*。 2. もし、レスポンスステータスコードが、例えば 500 (Internal Server Error) や 503 (Service Unavailable) 等のサーバエラーを表せば、 有効な Date ヘッダを生成する事は、不便であり不可能である。 3. もし、サーバが有効な現在時刻を表せる時計を持っていなければ、レ スポンスは Date ヘッダフィールドを含め *てはならない*。この場 合、section 14.18.1 にある規則に従わ *なければならない*。 Date ヘッダフィールドを持たないメッセージが、メッセージが受信者によっ てキャッシュされたり、Date ヘッダが要求されるプロトコルによって経由さ れていれば、受信者がそれを割り当て *なければならない*。時計を持たない HTTP インプリメンテーションは、使うたびにその有効性を再検証しない限り はレスポンスをキャッシュし *てはならない*。HTTP キャッシュ、特に共有 キャッシュは、NTP [28] のような、信頼できる外部の標準の時計と同期する ためのメカニズムを使う *べきである*。 クライアントは、PUT リクエストや POST リクエストのように、エンティテ ィボディを含むようなメッセージにのみ Date ヘッダフィールドを送る *べ きである* が、省略してもよい。時計を持たないクライアントは、リクエス トに Date ヘッダフィールドを送っ *てはならない*。 Date ヘッダ中に送られる HTTP-date は、メッセージ生成後の日付・時刻を 表す *べきではない*。もし、インプリメンテーションがかなり正確な日付・ 時刻を生成できるというので無ければ、メッセージの生成時刻として最も利 用可能な近似値を表す *べきである*。理論上は、日付はエンティティを生成 する直前の時刻を表すべきである。しかし実用上は、メッセージの生成中な らば、その意味上の値に影響を及ぼす事無く、いつでも生成できる。 14.18.1 時計の無いサーバの動作 オリジンサーバインプリメンテーションの中には、利用可能な時計を持って いないものがあるかもしれない。時計の無いオリジンサーバは、信頼ある時 計を持つシステムやユーザによるリソースに関連付けられた値で無ければ、 Expires や Last-Modified 値を割り当て *てはならない*。しかし、そのサ ーバが設置される時刻以前の、それが過去であるとわかっている Expires 値 は割り当てる事が *できる* (これは、各々のリソースの Expires 値を分け て保存する事無く、レスポンスの "pre-expiration" を許す) 。 14.19 ETag ETag レスポンスヘッダフィールドは、リクエストされたバリアントのエンテ ィティタグの現在の値を示す。エンティティタグと共に使われるヘッダは、 section 14.24, 14.26, section 14.44 にて記されている。エンティティタ グは、同じリソースからの他のエンティティとの比較に使う事が *できる* (section 13.3.3 参照)。 ETag = "ETag" ":" entity-tag 例を見よ。 ETag: "xyzzy" ETag: W/"xyzzy" ETag: "" 14.20 Expect Expect リクエストヘッダフィールドは、特定のサーバの振る舞いがクライア ントによって要求されている事を示すために使われる。 Expect = "Expect" ":" 1#expectation expectation = "100-continue" | expectation-extension expectation-extension = token [ "=" ( token | quoted-string ) *expect-params ] expect-params = ";" token [ "=" ( token | quoted-string ) ] リクエスト中の Expect フィールドにある期待値{expectation values} を理 解できない、あるいはそれに従えないサーバは、適切なエラーステータスを 返さ *なければならない*。サーバは、その期待{expectations} に一つでも 添えない場合は、417 (Expectation Failed) ステータスを返さ *なければな らない* が、そのリクエストが他に問題を持つような場合などは、他の 4xx ステータスを返してもよい。 このヘッダフィールドは、将来の拡張によって許される拡張されたシンタッ クスによって定義される。もし、サーバがサポートしていない expectation- extension を含んだ Expect フィールドを持つリクエストを受けた時は、417 (Expectation Failed) ステータスを返さ *なければならない*。 期待値の比較では、" " にて括られていないトークン (100-continue トーク ンも含む) においては大文字・小文字を区別しないが、" " にて括られた expectation-extensions においては区別される。 Expect のメカニズムはホップバイホップである。すなわち、HTTP/1.1 プロ クシは、もし叶えられない期待を持つリクエスト受けた時には 417 (Expectation Failed) ステータスを返さ *なければならない*。しかし、 Expect リクエストヘッダフィールド自体はエンドトゥエンドである。すなわ ち、もしリクエストが転送される場合には、このヘッダも転送されなければ *ならない*。 多くの古い HTTP/1.0 や HTTP/1.1 各アプリケーションは、Expect ヘッダを 理解できない。 100 (continue) ステータスの使い方については、section 8.2.3 参照。 14.21 Expires Expires エンティティヘッダフィールドは、レスポンスが新鮮で無くなる {stale} と考えられる時点の日付/時刻を表す。通常、キャッシュ (プロク シのキャッシュかユーザエージェントのキャッシュ) は、最初にオリジンサ ーバ (かエンティティの新鮮なコピーを持つ中間キャッシュ) にその有効性 を検証{validated} するまでは、新鮮で無いキャッシュエントリを返さない であろう。期限切れモデルについて、更に詳しくはsection 13.2 参照。 Expires フィールドがあっても、オリジナルリソースがその期限前、あるい は期限後に更新されたり、削除されたりするという事を暗黙的に意味するも のではない。 Expires フィールドのフォーマットは、section 3.3.1 にて定義される絶対 日時であり、RFC 1123 の日付フォーマットで *なければならない*。 Expires = "Expires" ":" HTTP-date その使用例は以下のようになる。 Expires: Thu, 01 Dec 1994 16:00:00 GMT 注意: もしレスポンスに max-age 指示子を持つ Cache-Control フィール ドを含んでいたら (section 14.9.3 参照) 、その指示は Expires フィー ルドを上書きする。 HTTP/1.1 のクライアントとキャッシュは、今までのように、この他の、特に "0" という値 (すなわち "期限切れ" ) を含む不正な日付フォーマットも扱 わ *なければならない*。 レスポンスが "期限切れ" というる事を表すためには、オリジンサーバは Date ヘッダの値と同じである Expires の日付を送る (期限の計算方法につ いては、section 13.2.4 参照)。 レスポンスが "期限切れではない" という事を表すためには、オリジンサー バはレスポンスが送られる時点からおよそ1年後の時刻の日付を持つ Expires を送る。HTTP/1.1 サーバは、Expires の日付に1年後以上未来の日付を送る *べきではない*。 デフォルトではキャッシュできないレスポンスにおいて、ある未来の日付を 持つ Expires ヘッダフィールドがあって、それに Cache-Control ヘッダフ ィールド (section 14.9) にて何らかの指示がなされていなければ、そのレ スポンスはキャッシュ可能である。 14.22 From もし From リクエストヘッダフィールドが与えられていれば、そこにはリク エストしているユーザエージェントを操っている人間のインターネット e-mail アドレスが含められている *べきである*。そのアドレスは、RFC 1123 [8] によってアップデートされた RFC 822 [9] の中で定義されている ような、マシンが使えるものである *べきである*。 From = "From" ":" mailbox 例を見よ。 From: webmaster@w3.org このヘッダフィールドは、ログを取るという目的や不正なあるいは望まない リクエストの原因を究明するために使う事が *できる*。アクセス保護の安全 性が確保できない形態では使う *べきではない*。このフィールドは、このリ クエストがそのメソッドを実行する責任を持つ者に代わって実行された、と いう事を意味する。特に、ロボットエージェントは、受信後に問題が起きた 場合にロボットを操作している責任者に連絡を取るために、このヘッダを含 める *べきである*。 このフィールドのインターネット e-mail アドレスは、リクエストを発行す るインターネットホストとは異なるものを使う事が *できる*。例えば、リク エストがプロクシを通して送られた場合、元々のリクエスト者のアドレスが 使われる *べきである*。 クライアントは、それがユーザのプライバシーへの関心やそのサイトのセキ ュリティポリシーにそぐわないかもしれないので、From ヘッダフィールドを ユーザの承認無しには送る *べきではない*。ユーザが、リクエストの前にこ のフィールドの値を使用不可にしたり、使用可能にしたり、修正したりでき るようする事を強く推奨する。 14.23 Host Host リクエストヘッダフィールドは、リクエストされたリソースのインター ネットホストとポート番号を、ユーザや参照されるリソースによって与えら れるオリジナル URI (一般には section 3.2.2 にて表されるような HTTP URL) から得るために、指定する。Host フィールド値は、オリジンサーバや オリジナルURL によって与えられているゲートウェイによって名付けられる authority を表さ *なければならない*。これによって、オリジンサーバやゲ ートウェイは、単一のIPアドレス上で複数のホスト名を持つサーバのルート URL "/" のような、内部的に曖昧な{internally-ambiguous} URL を区別する 事ができる。 Host = "Host" ":" host [ ":" port ] ; Section 3.2.2 "host" の後にポートの情報が無ければ、暗黙的にリクエストされるサービス のデフォルトポート (すなわち HTTP URL の場合は "80") を使用する事を意 味する。例えば、 のオリジンサーバへのリク エストは、厳密には以下のものを含んでいるであろう。 GET /pub/WWW/ HTTP/1.1 Host: www.w3.org クライアントは、すべての HTTP/1.1 リクエストメッセージに Host ヘッダ フィールドを含め *なければならない*。もし、リクエストされた URI がリ クエストされているサービスのインターネットホスト名を含んでいなけれ ば、Host ヘッダフィールドの値は空にし *なければならない*。HTTP/1.1 プ ロクシは、どんな転送するリクエストメッセージにも、プロクシによってリ クエストされているサービスを識別する適切な Host ヘッダフィールドを含 んでいるようにし *なければならない*。すべてのインターネットベースの HTTP/1.1 サーバは、Host ヘッダフィールドが無い HTTP/1.1 リクエストメ ッセージには、400 (Bad Request) ステータスコードを返さ *なければなら ない*。 Host に関するその他の必要条件については、section 5.2 及び 19.6.1.1 を 見よ。 14.24 If-Match If-Match リクエストヘッダフィールドは、メソッドを条件付きにするために 使われる。以前にそのリソースから一つ以上のエンティティを取得している クライアントは、If-Match ヘッダフィールド中に関連するエンティティタグ のリストを含める事によって、それらのエンティティの一つが現在使用され ているものかどうかを確かめる事ができる。エンティティタグは、section 3.11 にて定義されている。この機能は、トランザクションのオーバーヘッド を最小量にするようにキャッシュされた情報を能率的に更新する事を目的と している。また、間違ったバージョンのリソースを不注意に更新させないた めに、更新リクエストにも使用される。特別な場合として、"*" という値 は、そのリソースの現在のあらゆるエンティティに一致する。 If-Match = "If-Match" ":" ( "*" | 1#entity-tag ) もし、いずれかのエンティティタグがそのリソースへの類似した (If-Match ヘッダが無い) GETリクエストのレスポンスとして返されるであろうエンティ ティのエンティティタグに一致する場合か、"*" が与えられている場合にそ のリソースとして現在使用できるエンティティが存在する場合には、サーバ はそのリクエストに If-Match ヘッダが無い場合と同じようにリクエストさ れた動作を行う事が *できる*。 サーバが If-Match にあるエンティティタグを比較するためには強い比較関 数 (section 13.3.3 参照) を使わ *なければならない*。 エンティティタグに一致するものが無かったり、"*" が与えられていてもそ のリソースとして現在使用できるエンティティが存在しない場合には、サー バはリクエストされた動作を実行し *てはならない* 代わりに、412 (Precondition Failed) レスポンスを返さ *なければならない*。この振る舞 いは、クライアントが、ある時点に取得してから更新されたリソースを、例 えば PUT のような更新メソッドによって、更新されないようにしたい場合に 最も有用である。 If-Match を持たないリクエストが 2xx や 412 以外の結果を返す時は、If- Match ヘッダは無視され *なければならない*。 "If-Match: *" とは、オリジンサーバ (あるいは Vary メカニズムを使う事 ができるようなキャッシュ、section 14.44 参照) によって選択された表現 がある時にはそのメソッドは実行される *べきであり*、その表現が無い時に はそのメソッドは実行され *てはならない* という事を意味する。 リソースを更新しようとするリクエスト (例えば PUT) は、もし If-Match の値 (単一のエンティティタグ) に対応するエンティティが、もはやそのリ ソースの表現で無い場合にはそのリクエストメソッドを適用し *てはならな い* という事を表すために If-Match ヘッダフィールドを含める事が *でき る*。これによってユーザは、リソースが知らないうちに更新されていた場合 にリクエストを成功させないようにしたいという事を示す事ができる。例を 見よ。 If-Match: "xyzzy" If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz" If-Match: * If-Match ヘッダフィールドと同時に If-None-Match か If-Modified-Since ヘッダフィールドを使用しているようなリクエストについては、この仕様書 ではその結果についてを定義しない。 14.25 If-Modified-Since If-Modified-Since リクエストヘッダフィールドは、メソッドを条件付きに するために使われる。もしリクエストされたバリアントがこのフィールドに て指定された時刻以降に更新されていなければ、サーバはエンティティを返 す代わりに、304 (not modified) レスポンスをメッセージボディ無しで返す であろう。 If-Modified-Since = "If-Modified-Since" ":" HTTP-date このフィールドの例を見よ。 If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT If-Modified-Since ヘッダを持っていて且つ Range ヘッダを持たない GET メソッドは、If-Modified-Since ヘッダによって与えられる時刻以降に更新 された場合のみ指定したエンティティを転送する事を要求する。これを決定 するためのアルゴリズムには、以下のようなものを含む。 a) リクエストが 200 (OK) ステータス以外の結果を返すか、あるいは渡 された If-Modified-Since の日付が不正なものであるような場合、レ スポンスは通常の GET 時と全く同じものとなる。サーバの現在時刻よ り未来の時刻は無効である。 b) バリアントが If-Modified-Since にある時刻以降に更新されている場 合、レスポンスは通常の GET 時と全く同じものとなる。 c) バリアントが有効な If-Modified-Since にある時刻以降に更新されて いない場合、サーバは 304 (not modified) レスポンスを返す *べき である*。 この機能は、トランザクションのオーバーヘッドを最小量にするようにキャ ッシュされた情報を能率的に更新する事を目的にしている。 注意: Range リクエストヘッダフィールドは、If-Modified-Since の意味を 変更する。詳細については section 14.35 参照。 注意: If-Modified-Since の時刻はサーバによって解釈されるが、この時計 はクライアントのものとは同期していないかもしれない。 注意: If-Modified-Since ヘッダフィールドを扱う時、いくつかのサーバは 304 (not modified) レスポンスを返すかどうかを決定する際に、それ以下で あるかを見る関数{less-than function} よりも、正確に時刻を比較する関数 {comparison function} を使うであろう。キャッシュの妥当性{validation} のために If-Modified-Since ヘッダフィールドを送った時に最良な結果を得 るためには、クライアントは可能であればいつでも直前の Last-Modified ヘ ッダフィールドにて受けたそのままの時刻文字列を使う事を提案する。 注意: クライアントが同じリクエストから取得した Last-Modified ヘッダか ら得られた時刻の代わりに If-Modified-Since ヘッダに任意の時刻を使った としたら、クライアントはこの日付がサーバが決めている時刻の取り決めに 従って解釈されるという事に注意すべきである。クライアントは、クライア ントとサーバ間の時計のズレや異なるエンコーディングの使用による丸めの 問題を考慮するべきである。これは、もし最初にリクエストした時刻からそ の後の If-Modified-Since にある時刻までに文書が変化した場合に競合状態 が起こる可能性や、If-Modified-Since の日付がサーバの時計による修正無 しにクライアントの時計から導出された場合に {clock-skew-related} 問題 がおこる可能性を示している。クライアントとサーバ間の時計のズレの修正 は、ネットワーク間での待ち時間があるので、全く同じにする事はできな い。 If-Modified-Since ヘッダフィールドと同時に If-Match か If-Unmodified- Since ヘッダフィールドを使用しているようなリクエストについては、この 仕様書ではその結果についてを定義しない。 14.26 If-None-Match If-None-Match リクエストヘッダフィールドは、メソッドを条件付きにする 場合に使われる。以前にそのリソースから一つ以上のエンティティを取得し ているクライアントは、If-None-Match ヘッダフィールド中にそれに対応す るエンティティタグのリストを含める事によって、それらのエンティティの 中に現在使用できるものがないかどうかを確かめる事ができる。この機能 は、トランザクションのオーバーヘッドを最小量にするようにキャッシュさ れた情報を能率的に更新する事を目的にしている。また (例えば PUT 等の) メソッドを使う場合に、既にあるリソースをクライアントがそのリソースが 無いと考えている場合に不注意に更新してしまわないようにするためにも使 われる。 特別な場合として、"*" という値は、そのリソースの現在のあらゆるエンテ ィティに一致する。 If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag ) いずれかのエンティティタグがそのリソースにされる類似した (If-None- Match ヘッダが無い) GET リクエストのレスポンスとして返されるエンティ ティのエンティティタグに一致する場合か、"*" が与えられる場合にそのリ ソースに現在使用できるエンティティが存在する場合において、サーバはリ ソースの更新時刻とリクエストの中の If-Modified-Since ヘッダフィールド にて与えられた時刻が一致しなかった場合以外は、リクエストされた動作を 行っ *てはならない*。その代わり、もしリクエストメソッドが GET か HEAD であれば、サーバは 304 (Not Modified) レスポンスを、一致したエンティ ティのうちの一つのキャッシュに関連するヘッダフィールド (特に ETag) を 付けて返す *べきである*。その他のメソッドの場合はすべて、サーバは 412 (Precondition Failed) というステータスを返さ *なければならない*。 二つのエンティティタグが一致しているかどうかを決定する方法についての 決まりについては、section 13.3.3 参照。GET や HEAD リクエストの場合に は、弱い比較関数のみを使う事ができる。 エンティティタグが一致するものが無ければ、サーバはそのリクエストに If-None-Match ヘッダが無い場合と同じようにリクエストされた動作を行う 事が *できる* が、同時にリクエスト中のすべての If-Modified-Since ヘッ ダフィールドは無視され *なければならない*。すなわち、エンティティタグ が一致するものが無ければ、サーバは 304 (Not Modified) レスポンスを返 し *てはならない*。 もし If-None-Match を持たないリクエストが、2xx や 304 各ステータス以 外の結果を返すならば、If-None-Match ヘッダは無視され *なければならな い*。 (あるリクエスト中に If-Modified-Since と If-None-Match が同時に 存在する場合のサーバの振る舞いについての議論は section 13.3.4 を見 よ。) "If-None-Match: *" とは、オリジンサーバ (あるいは Vary メカニズムを使 う事ができるようなキャッシュ、section 14.44 参照) によって選択された 表現がある時には、そのメソッドは実行し *てはならない* が、その表現が 無い時には、そのメソッドは実行する *べきである* という事を意味する。 この機能は、ある二つの PUT 作業中に競合が起こらないようにする場合に有 に有用である。 例を見よ。 If-None-Match: "xyzzy" If-None-Match: W/"xyzzy" If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz" If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz" If-None-Match: * If-None-Match ヘッダフィールドと同時に If-Match か If-Unmodified- Since ヘッダフィールドを使用しているようなリクエストについては、この 仕様書ではその結果についてを定義しない。 14.27 If-Range もしクライアントがキャッシュとしてあるエンティティのコピーの一部を保 持していて、そのエンティティ全体の最新のコピーが欲しい場合、 (If- Unmodified-Since か If-Match、あるいは両方を使った) 条件付き GET とし て Range リクエストヘッダを使う事ができる。しかし、もしエンティティが 更新されたために条件が成立しなければ、クライアントは最新のエンティテ ィボディ全体を取得するために次なるリクエストをしなければならない。 If-Range ヘッダは、クライアントの次なるリクエストを "短略化{short- circuit}" する事ができる。一般的に、これは「もしエンティティが更新さ れていなかったら、私が持っていない部分を送信してくれ。そうでなけれ ば、新しいエンティティ全体を送信してくれ。」のように解釈される。 If-Range = "If-Range" ":" ( entity-tag | HTTP-date ) クライアントがそのエンティティのエンティティタグは持っていないが、 Last-Modified の日付を持っている場合、クライアントは If-Range ヘッダ としてその日付を使う事が *できる*。 (サーバは、多くても 2 文字を調べ るだけで、正確な HTTP 日付と任意の形式のエンティティタグとを区別する 事ができる。) If-Range ヘッダは Range ヘッダと共にのみ使う *べきであ り*、リクエストが Range ヘッダを含んでいない場合や、サーバが sub- range 操作をサポートしない場合には、これは無視され *なければならな い*。 If-Range ヘッダにて与えられたエンティティタグがそのエンティティの現在 のエンティティタグに一致した場合、サーバは 206 (Partial content) レス ポンスを使って、そのエンティティの指定される sub-range を供給す *べき である*。もしエンティティタグが一致しなければ、サーバは 200 (OK) レス ポンスを使って、そのエンティティ全体を返す *べきである*。 14.28 If-Unmodified-Since If-Unmodified-Since リクエストヘッダフィールドは、メソッドを条件付き にするために使われる。もし、リクエストされたリソースがこのフィールド 内に記された時刻以降に更新されていなければ、サーバはそのリクエストに If-Unmodified-Since ヘッダが無い場合と同じようにリクエストされた動作 を行う *べきである*。 リクエストされたバリアントが指定された時刻以降に更新されている場合、 サーバはリクエストされた動作を行っ *てはならない* 代わりに、412 (Precondition Failed) を返さ *なければならない*。 If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date このフィールドの使用例は、次のようになる。 If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT 通常のリクエスト (すなわち If-Unmodified-Since が無いリクエスト) が、 2xx や 412 以外の結果を返す場合、If-Unmodified-Since ヘッダは無視す *べきである*。 指定された時刻が不正であれば、このヘッダは無視される。 If-Unmodified-Since ヘッダフィールドと同時に If-None-Match か If- Modified-Since ヘッダフィールドを使用しているようなリクエストについて は、この仕様書ではその結果についてを定義しない。 14.29 Last-Modified Last-Modified エンティティヘッダフィールドは、オリジンサーバがバリア ントが最後に更新されたと考える日付を表す。 Last-Modified = "Last-Modified" ":" HTTP-date 使用例は以下のようになる。 Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT このヘッダフィールドの正確な意味は、オリジンサーバのインプリメンテー ションとオリジナルリソースの性質による。それがファイルである場合、そ のファイルシステムの最終更新時刻になるであろう。動的に取りこまれる部 分を持つエンティティの場合、その各構成要素の最終更新時刻の中で最も最 新の物になるであろう。データベースゲートウェイの場合、レコードの最終 更新時刻のタイムスタンプになるであろう。仮想オブジェクトの場合、内部 状態が変化した最終時刻になるであろう。 オリジンサーバは、Last-Modified にメッセージを生成した時刻よりも後の 日付を送っ *てはならない*。リソースの最終更新時刻がある未来の時点を示 すような場合は、サーバはその日付をメッセージ生成時点のものに置き換え *なければならない*。 オリジンサーバは、レスポンスの Date 値を生成する時刻にできるだけ近い エンティティの Last-Modified 値を得る *べきである*。これによって受信 者は、特にもしエンティティの更新がレスポンスが生成される時刻と近い場 合に、エンティティの更新時刻について正確な評価ができる。 HTTP/1.1 サーバは、可能であればいつでも Last-Modified を送る *べきで ある*。 14.30 Location Location レスポンスヘッダフィールドは、リクエストを完了するため、ある いは新しいリソースを識別するため、受信者を Request-URI 以外の場所にリ ダイレクトするのに使われる。201 (Created) レスポンスの場合、Location はリクエストによって作られた新しいリソースの場所である。3xx レスポン スの場合、Location はリソースへ自動でリダイレクションさせるためにサー バが望む URI を示す *べきである*。このフィールド値は、単一の絶対 URI から成る。 Location = "Location" ":" absoluteURI 例を見よ。 Location: http://www.w3.org/pub/WWW/People.html 注意: Content-Location ヘッダフィールド (section 14.14) は、リクエ ストと共に送られるエンティティのオリジナルの場所を指すという点で、 Location ヘッダとは異なる。それ故に、レスポンスは Location と Content-Location の両ヘッダフィールドを含む事は可能である。いくつ つかのメソッドでのキャッシュの必要条件については、section 13.10 も 合わせて見よ。 14.31 Max-Forwards Max-Forwards リクエストヘッダフィールドは、TRACE (section 9.8) や OPTIONS (section 9.2) の各メソッドに、次のインバウンドサーバにリクエ ストを転送できるプロクシやゲートウェイの数を制限するというメカニズム を提供する。これは、クライアントが、その中間で失敗したりループしたり しているリクエスト連鎖を追跡しようとする場合に有用である。 Max-Forwards = "Max-Forwards" ":" 1*DIGIT Max-Forwards 値は、このリクエストメッセージが残り何回転送できるかとい う回数を表す 10 進数の整数値である。 Max-Forwards ヘッダフィールドを含む TRACE あるいは OPTION リクエスト を受けたプロクシやゲートウェイは、リクエストを転送する前にその値を調 べ、更新し *なければならない*。もし、受けとった Max-Forwards の値が 0 であれば、受信者はそのリクエストを転送し *てはならない* 代わりに、最 後の受信者として応答し *なければならない*。受けとった Max-Forwards の 値が 0 以上であれば、転送されるメッセージにはその値から 1 を引いた値 に更新した Max-Forwards フィールドを含め *なければならない*。 Max-Forwards ヘッダフィールドは、その仕様書で定義された他のすべてのメ ソッドや、そのメソッド定義の部分で明確に述べられていない拡張メソッド 中では無視しても *よい*。 14.32 Pragma Pragma 一般ヘッダフィールドは、リクエスト/レスポンス連鎖中のあらゆる 受信者にも適用されるであろうインプリメンテーションの特別な指示を示す ために使われる。すべての pragma 指示子は、プロトコルの視点から見れば オプショナルな振るまいを指定するが、その振るまいが指示子と一致してい る事を要求するシステムがある *かもしれない*。 Pragma = "Pragma" ":" 1#pragma-directive pragma-directive = "no-cache" | extension-pragma extension-pragma = token [ "=" ( token | quoted-string ) ] no-cache 指示子がリクエストメッセージ中にある時は、アプリケーション はリクエストされたもののキャッシュコピーを持ってたとしても、オリジン サーバに向けてリクエストを転送す *べきである*。この pragma 指示子は、 no-cache キャッシュ指示子 (section 14.9 参照) 同じセマンティクスを持 ち、HTTP/1.0 との後方互換のためにここで定義される。クライアントは、 HTTP/1.1 に従っているかどうかを知らないサーバに no-cache リクエストを 送る際には、両方のヘッダフィールドを含める *べきである*。 pragma 指示子は、そのアプリケーションにとってどんな意味を持つかに関わ らず、その指示がそのリクエスト/レスポンス連鎖に関わるすべての受信者 に適用されるかもしれないので、プロクシやゲートウェイアプリケーション はそれを無加工で通さ *なければならない*。特定の受信者のために pragma を指定する可能性は無いけれども、受信者にとって適切で無いあらゆる pragma 指示子は、受信者によって無視される *べきである*。 HTTP/1.1 キャッシュは "Pragma: no-cache" を "Cache-Control: no-cache" が送られた時と同様に扱う *べきである*。HTTP では、新しい Pragma 指示 子は定義されないであろう。 注意: レスポンスヘッダフィールドでの "Pragma: no-cache" は、実際に は定義されていないので、レスポンスでの "Cache-Control: no-cache" の確実な代用とはならない。 14.33 Proxy-Authenticate Proxy-Authenticate レスポンスヘッダフィールドは、407 (Proxy Authentication Required) レスポンスの一部として含め *なければならな い*。このフィールド値は、この Request-URI のプロクシに適用される認証 スキームとパラメータを含む challenge から成る。 Proxy-Authenticate = "Proxy-Authenticate" ":" 1#challenge HTTP アクセス認証処理方法については、"HTTP Authentication: Basic and Digest Access Authentication" [43] にて記述されている。WWW- Authenticate とは違い、Proxy-Authenticate ヘッダフィールドは現在の接 続にのみ適用され、またダウンストリームのクライアントに通す *べきでは ない*。しかし、中間のプロクシがダウンストリームのクライアントからリク エストされる事によって自身の credentials を得る必要がある可能性があ り、そのような場合はまるでプロクシが Proxy-Authenticate ヘッダフィー ルドを転送しているように見える事がある。 14.34 Proxy-Authorization Proxy-Authorization リクエストヘッダフィールドを使って、クライアント は認証を要求するプロクシに自身 (やそのユーザ) を識別させる。Proxy- Authorization のフィールド値は、プロクシやリクエストされたリソースの ある領域へのユーザエージェントの認証情報を含む credentials から成る。 Proxy-Authorization = "Proxy-Authorization" ":" credentials HTTP アクセス認証処理方法については、"HTTP Authentication: Basic and Digest Access Authentication" [43] にて記述されている。Authorization とは違い、Proxy-Authorization ヘッダフィールドは Proxy-Authorization を使って認証を要求する次のアウトバウンドプロクシにのみ適用される。連 鎖内に複数のプロクシがある時は、Proxy-Authorization ヘッダフィールド は、credentials を受け取ろうとしている最初のアウトバウンドプロクシに よって消去される。もしプロクシが与えられたリクエストを協同で認証する ようなメカニズムならば、プロクシはリクエストから次のプロクシへとクラ イアントの credentials を取り次ぐ事が *できる*。 14.35 Range 14.35.1 バイトレンジ HTTP メッセージ中では、すべての HTTP エンティティがバイトシーケンスで 表せるので、バイトレンジの概念はあらゆる HTTP エンティティにとって意 義のあるものである。 (しかしながら、すべてのクライアントとサーバがバ イトレンジ操作をサポートする必要は無い。) HTTP でのバイトレンジ指定は、エンティティボディ (それがメッセージボデ ィと同一で無くてもよい) 中のバイトシーケンスに適用される。 バイトレンジ操作では、単一のバイトレンジ、または一つのエンティティ中 で複数のレンジセットを指定する事が *できる*。 ranges-specifier = byte-ranges-specifier byte-ranges-specifier = bytes-unit "=" byte-range-set byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec ) byte-range-spec = first-byte-pos "-" [last-byte-pos] first-byte-pos = 1*DIGIT last-byte-pos = 1*DIGIT byte-range-spec 中の first-byte-pos 値には、その範囲の最初のバイトの byte-offset を与える。last-byte-pos 値には、その範囲の最後のバイトの byte-offset を与える。つまり、指定されるバイトの位置も含まれる。バイ トオフセットは 0 から始まる。 last-byte-pos 値がある場合、その値は byte-range-spec での first-byte- pos 以上のものにし *なければならない* が、そうで無い場合はシンタック ス上不正となる。一つ以上のシンタックス上不正な byte-range-spec 値を含 む byte-range-set を受信しても、その byte-range-set を含むヘッダフィ ールドは無視し *なければならない*。 last-byte-pos 値が無い、あるいはその値が現在のエンティティボディの大 きさ以上であったら、last-byte-pos はエンティティボディの現在のバイト 長から 1 を引いた値になる。 クライアントは、自身が指定する last-byte-pos によって、エンティティの サイズを知らなくても受け取るバイト数を制限する事ができる。 suffix-byte-range-spec = "-" suffix-length suffix-length = 1*DIGIT suffix-byte-range-spec は、エンティティボディの、suffix-length 値によ って与えられる長さの末尾を指定するのに使われる。 (すなわち、この形式 ではエンティティボディの最後の N バイトを指定する。) もしエンティティ が指定された suffix-length 以下の長さしかなければ、エンティティ全体が 使われる。 シンタックス上不正な byte-range-set が、first-byte-pos が現在のエンテ ィティボディ長よりも小さいような byte-range-spec、あるいは 0 でない suffix-length を持つ suffix-byte-range-spec を一つでも含んでいたら、 その byte-range-set はシンタックスを満足する。そうでない byte-range- set は不正値である。byte-range-set が不正値である場合、サーバは 416 (Requested range not satisfiable) というステータスを持ったレスポンス を返す *べきである*。そうで無ければ、サーバはエンティティボディのうち 指定された範囲と 206 (Partial Content) というステータスを持ったレスポ ンスを返す *べきである*。 byte-ranges-specifier 値の例を示す (エンティティボディの大きさを 10000 と仮定する)。 - 最初の 500 バイト (バイトオフセットは始点・終点を含めて、0-499) : bytes=0-499 - 次の 500 バイト (バイトオフセットは始点・終点を含めて、500-999) : bytes=500-999 - 最後の 500 バイト (バイトオフセットは始点・終点を含めて、9500- 9999) : bytes=-500 - あるいは bytes=9500- - 最初と最後の 1 バイト (バイトオフセットは 0 と 9999) : bytes=0-0,-1 - 間違いではないが一般的ではない次の 500 バイトの指定方法 (バイト オフセットは始点・終点を含めて、500-999) : bytes=500-600,601-999 bytes=500-700,601-999 14.35.2 レンジ更新リクエスト 条件付き、あるいは条件の付かない GET メソッドを使った HTTP 検索リクエ ストは Range リクエストヘッダを使って、エンティティ全体の代わりに、エ ンティティの一つ以上の sub-range を要求 *でき*、リクエストの結果とし て返されるエンティティに当たる。 Range = "Range" ":" ranges-specifier サーバは、Range ヘッダを無視 *できる*。しかし、Range をサポートするこ とで転送に失敗した部分の再取得や、大きなサイズのエンティティの部分的 な検索を効果的にサポートするので、HTTP/1.1 のオリジンサーバや中間キャ ッシュは、可能であればバイトレンジをサポートすべきである。 もし、サーバが Range ヘッダをサポートし、指定される範囲 (群) がそのエ ンティティに適切であれば、以下の様になる。 - 条件の付かない GET に Range ヘッダがあった場合、その GET が他の 点で成功していれば、返る値が修正される。言いかえると、レスポンス は 200 (OK) の代わりに 206 (Partial Content) というステータスコ ードを返す。 - 条件付きの GET (If-Modified-Since と If-None-Match のどちらかあ るいは両方、もしくは If-Unmodified-Since と If-Match のどちらか あるいは両方を使ったリクエスト) に Range ヘッダがあった場合、そ の GET が他の点で成功していて、条件が真であったら、返る値が修正 される。もし条件が偽であれば、304 (Not Modified) レスポンスには 影響ない。 場合によっては、Range ヘッダに加えて If-Range ヘッダ (section 14.27 参照) を使う方が適切であるかもしれない。 もし、レンジをサポートするプロクシが Range リクエストを受け、そのリク エストをインバウンドサーバに転送し、その返答としてエンティティ全体を 受け取ったとしたら、プロクシはクライアントが要求した範囲のみを返す *べきである*。もしそれがキャッシュの割り当て方針にあったものであれ ば、キャッシュには受け取ったレスポンス全体を保存す *べきである*。 14.36 Referer Referer[原文ママ] リクエストヘッダフィールド ("referrer" であるはずな のに綴りは間違っているが) は、サーバの利益のために、Request-URI が得 られたリソースのアドレス (URI) をクライアントに示させる。Referer リク エストヘッダは、サーバが興味やログの取得、キャッシュの活用等のため に、そのリソースへの逆リンクのリストを作成できるようにする。また、メ ンテナンスのために、既に使用していない{obsolete} リンクやミスタイプの リンクを追跡できるようにもする。もし Request-URI が、例えばユーザのキ ーボードからの入力など、それ自身の URI を持たないソースから得られた場 合は、Refererフィールドを送っ *てはならない*。 Referer = "Referer" ":" ( absoluteURI | relativeURI ) 例を示す。 Referer: http://www.w3.org/hypertext/DataSources/Overview.html もしこのフィールド値が相対 URI ならば、Request-URI からの相対的なもの と解釈す *べきである*。URI にはフラグメントを含め *てはならない*。セ キュリティ上の考察については、section 15.1.3 参照。 14.37 Retry-After Retry-After レスポンスヘッダフィールドは、リクエストしているクライア ントにそのサービスがどのくらいの時間利用不可能なのかを示すために、503 (Service Unavailable) レスポンスと共に使われる。また、このフィールド はリダイレクトされたリクエストが発行される前にユーザエージェントが待 たなければならない最小の時間を示すために 3xx (Redirection) レスポンス で使う事も *できる*。このフィールドの値は、HTTP-date か、あるいはレス ポンス時以降の整数の (10進数の) 秒数である。 Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds ) 次の二つの使用例を見よ。 Retry-After: Fri, 31 Dec 1999 23:59:59 GMT Retry-After: 120 後者の場合、その遅れは2分である。 14.38 Server Server レスポンスヘッダフィールドは、リクエストを処理するオリジンサー バが使っているソフトウェアについての情報を含んでいる。このフィールド には、複数の製品トークン (section 3.8) や、サーバとその他の重要な付属 製品を識別するためのコメントを含める事ができる。製品トークンは、アプ リケーションを識別するために重要な順に列挙される。 Server = "Server" ":" 1*( product | comment ) 例を見よ。 Server: CERN/3.0 libwww/2.17 レスポンスがプロクシを通して送られた場合、プロクシアプリケーションは Server レスポンスヘッダを書き換え *てはならない*。代わりに、 (section 14.45 に記述されている) Via フィールドを使う *べきである*。 注意: サーバのソフトウェアバージョンを明らかにする事で、セキュリテ ィホールを持っている事がわかっているソフトウェアを使うサーバのマシ ンは攻撃を受けやすくなるかもしれない。サーバの開発者は、このフィー ルドをオプションとして設定を変更できるようにする事が推奨される。 14.39 TE TE リクエストヘッダフィールドは、レスポンスとしてどんな拡張転送コーデ ィングを受け入れられるか、またチャンク形式転送コーディング内の trailer フィールドを受け入れられるかどうかを示す。この値は、 "trailers" というキーワードや、 (section 3.6 にて定義される) 拡張転送 コーディングの名前と省略可能な受け入れパラメータをコンマで区切ったリ ストからなるだろう。 TE = "TE" ":" #( t-codings ) t-codings = "trailers" | ( transfer-extension [ accept-params ] ) "trailers" というキーワードがあれば、section 3.6.1 にて定義されるよう に、クライアントはチャンク形式転送コーディング内の trailer フィールド を受け入れられる、という事を表す。このキーワードは、たとえクライアン トが転送コーディングを表せないとしても、転送コーディング値を使うため に予約される。 その使用例は以下のようになる。 TE: deflate TE: TE: trailers, deflate;q=0.5 TE ヘッダフィールドは、直接の接続にのみ適用される。それゆえ、TE が HTTP/1.1 メッセージに存在する時は常に、このキーワードを Connection ヘ ッダフィールド (section 14.10) の中に与え *なければならない*。 サーバは、TE フィールドによって与えられた転送コーディングが受け入れ可 能かを試すために、以下の規則を使う事ができる。 1. "chunked" 転送コーディングは常に受け入れ可能である。"trailers" というキーワードが列挙されていれば、クライアントは、自身やダウ ンストリームのクライアントがチャンク形式のレスポンス中の trailer フィールドを受け入れ可能である、という事を示す。このフ ィールドが与えられた場合、クライアントは、すべてのダウンストリ ームクライアントは転送されるレスポンス中の trailer フィールドを 受け入れ可能であるか、あるいはダウンストリームの受信者のために レスポンスをバッファしようとしているか、のどちらかを示している 事を意味する。 注意: HTTP/1.1 は、クライアントがレスポンス全体のバッファリング を保証できるようなチャンク形式レスポンスのサイズの制限するため の手段を定義しない。 2. 現在試している転送コーディングが TE フィールド内に列挙されてい る転送コーディングの一つで、その qvalue が 0 でなければ、受け入 れ可能である。 (section 3.9 にて定義されるように、qvalue が 0 であるという事は、"受け入れ不可能" を意味する。) 3. 複数の転送コーディングが受け入れ可能である時は、qvalue が 0 以 上で最も大きい値を持つ転送コーディングが優先される。"chunked" 転送コーディングの qvalue は常に 1 である。 TE フィールド値が空か、あるいは TE フィールドが与えられていなければ、 使用できる転送コーディングは "chunked" のみとなる。転送コーディングが なされていないメッセージは、常に受け入れ可能である。 14.40 Trailer Trailer 一般フィールドの値は、その中で与えられたヘッダフィールドのセ ットがチャンク形式転送コーディングにてエンコードされたメッセージの後 につけられるもの{trailer} の中に含まれている事を表す。 Trailer = "Trailer" ":" 1#field-name HTTP/1.1 のメッセージは、チャンク形式転送コーディングされ空ではない trailer を持っているメッセージ中では Trailer ヘッダフィールドを含む *べきである*。そうする事で、受信者は trailer の中にどんなヘッダフィー ルドがあるかを知る事ができる。 Trailer ヘッダフィールドがなければ、trailer はいかなるヘッダフィール ドも含む *べきではない*。"chunked" 転送コーディング中の trailer フィ ールドの使用の制限については、section 3.6.1 参照。 Trailer ヘッダフィールド中に列挙されるメッセージヘッダフィールドには 以下のヘッダフィールドを含め *てはならない*。 . Transfer-Encoding . Content-Length . Trailer 14.41 Transfer-Encoding Tranfer-Encoding 一般ヘッダフィールドは、 (もし変形がなされていれば) 送信者と受信者の間でメッセージボディを安全に転送するために、適用され ている変形の形を示す。転送コーディングというのは、メッセージの特性で あり、エンティティの特性では無い、という点で内容コーディングとは異な る。 Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer-coding 転送コーディングは section 3.6 にて定義される。例を見よ。 Transfer-Encoding: chunked もしエンティティに複数のエンコーディングが適用されていたら、適用され ている順番に列挙し *なければならない*。エンコーディングパラメータにつ いての追加的情報は、この仕様書に定義されていない他のエンティティヘッ ダフィールドによって与える事が *できる*。 多くの古い HTTP/1.0 アプリケーションは、Transfer-Encoding ヘッダを理 解しない。 14.42 Upgrade Upgrade 一般ヘッダは、クライアントが他にどんな通信プロトコルをサポー トするかを表し、サーバがプロトコルを切り換えた方がいいと判断した場合 に使わせたいものを指定させる。サーバは、Upgrade ヘッダフィールドをプ ロトコルが切り換えられた事を示す 101 (Switching Protocols) レスポンス の中で使わ *なければならない*。 Upgrade = "Upgrade" ":" 1#product 例を見よ。 Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 Upgrade ヘッダフィールドは、HTTP/1.1 からある他の、互換性が無いプロト コルへの変換のための単純なメカニズムを提供する事を目的としている。こ れは、クライアントがたとえ現在のリクエストが HTTP/1.1 を使って作られ たものであっても、例えばより大きなメジャーバージョン番号を持つ新しい バージョンの HTTP のような、他のプロトコルを使いたいという要求をした 場合に変換が行われる。これは、クライアントがもしそれが利用できれば "よりよい" プロトコルを使用したいという事をサーバに示している間に、よ り一般的にサポートされるプロトコルでリクエストを開始させる事で、互換 性の無い互いのプロトコル間の難しい変換を簡単にする (ここでの "よりよ い" とは、リクエストされているメソッドやリソースの性質に応じて、サー バが決定する)。 Upgrade ヘッダフィールドは、現在のトランスポート層にある接続上のアプ リケーション層プロトコルの切り替えにのみ適用される。Upgrade は、プロ トコルの変換を強要する事はできない。すなわち、サーバがこのフィールド を受け入れるか、それをどう使うかはサーバによる。プロトコル変換後の最 初の動作は Upgrade ヘッダフィールドを含む最初の HTTP リクエストへのレ スポンスで *なければならない* が、プロトコルの変換後のアプリケーショ ン層の通信能力とその性質は完全に選択された新しいプロトコルに依存す る。 Upgrade ヘッダフィールドは、直接の接続にのみ適用される。それゆえ、 Upgrade が HTTP/1.1 メッセージに存在する時は常に、upgrade というキー ワードを Connection ヘッダフィールド (section 14.10) の中に与え *なけ ればならない*。 Upgrade ヘッダフィールドは、異なる接続でプロトコルを変換するために使 う事はできない。この場合、301, 302, 303, 305 のいずれかのリダイレクシ ョンレスポンスを使う方が適切である。 この仕様書では、section 3.1 の HTTP バーションの規則と将来更新される この仕様書に定義されるように、ハイパーテキスト転送プロトコルのファミ リーとして使用するための "HTTP" というプロトコル名のみを定義する。プ ロトコル名としてはあらゆるトークンが使用できるが、クライアントとサー バの両方がその名前で同じプロトコルを関連付けている場合のみそれが有効 となるであろう。 14.43 User-Agent User-Agent リクエストヘッダフィールドは、リクエストを生成したユーザエ ージェントについての情報を含む。これは、統計目的、プロトコル違反の追 跡、特定のユーザエージェントの制限を回避するようなレスポンスを作成す るためのユーザエージェントの自動認識のために使う。ユーザエージェント は、リクエストの際にこのヘッダを含む *べきである*。このフィールドに は、複数の製品トークン (section 3.8) や、エージェントやユーザエージェ ントの重要な付属製品を識別するためのコメントを含める事ができる。慣習 によれば、製品トークンはアプリケーションを識別するために重要な順に列 挙される。 User-Agent = "User-Agent" ":" 1*( product | comment ) 例を見よ。 User-Agent: CERN-LineMode/2.15 libwww/2.17b3 14.44 Vary Vary フィールド値は、そのレスポンスが新鮮である{fresh} 間、キャッシュ が再検証無しにそれに続くリクエストに対するレスポンスとして使ってよい かどうかを、完全に決定するためのリクエストヘッダフィールドのセットを 示す。キャッシュできない、あるいは新鮮でなくなった{stale} レスポンス の場合、Vary フィールド値はユーザエージェントにその表現を選択するた めに使われた基準{criteria} について通知するために使われる。"*" という Vary フィールド値は、キャッシュはこのレスポンスが適切な表現であるかど うかをそれに続くのリクエストのリクエストヘッダからは決定できない、と いう事を意味する。キャッシュにおける Vary ヘッダフィールドの使い方に ついては section 13.6 参照。 Vary = "Vary" ":" ( "*" | 1#field-name ) HTTP/1.1 サーバは、サーバ駆動型ネゴシエーションを受けるあらゆるキャッ シュ可能なレスポンスに Vary ヘッダフィールド値を含む *べきである*。そ うする事で、キャッシュはそのリソースへの将来のリクエストを適切に解釈 する事ができ、ユーザエージェントにそのリソースへのネゴシエーションの 存在について知らせる事ができる。サーバは、サーバ駆動型ネゴシエーショ ンを受けるキャッシュ不可能なレスポンスにも、ユーザエージェントにその レスポンス時には変化してしまうレスポンスの規模{dimensions} についての 有益な情報を提供するであろうから、Vary ヘッダフィールド値を含む事が *できる*。 Vary フィールド値は、最もふさわしい表現を選択するために列挙されたリク エストヘッダフィールド値 *のみ* を考慮する選択アルゴリズムに従ってレ スポンスとして選択された表現を知らせる field-name の列挙から成る。キ ャッシュは、そのレスポンスが新鮮である間は、列挙されるフィールド名に 同じフィールド値を取るような将来のリクエストでも同じ選択がなされるで あろう、と仮定する事が *できる*。 与えられる field-name は、この仕様書にて定義されている標準のリクエス トヘッダフィールドに制限されない。フィールド名は、大文字・小文字を区 別しない。 "*" という Vary フィールド値は、指定されていないパラメータはリクエス トヘッダに制限されないという事を示し (例えば、クライアントのネットワ ークアドレス) 、レスポンスの表現の選択において役割を果たす。プロクシ サーバは、"*" という値を生成し *てはならない*。それは生成できるのはオ リジンサーバのみである。 14.45 Via Via 一般ヘッダフィールドは、リクエスト時におけるユーザエージェントか らサーバ間の、またレスポンス時におけるオリジンサーバからユーザエージ ェント間の、中間のプロトコルと受信者を示すためにゲートウェイやプロク シによって使われ *なければならない*。これは、RFC 822 [9] での "Received" フィールドに類似しており、転送されるメッセージを追跡した り、リクエストループを回避したり、リクエスト/レスポンス連鎖上のすべ ての送信者のプロトコル能力を識別したりする意図を持つ。 Via = "Via" ":" 1#( received-protocol received-by [ comment ] ) received-protocol = [ protocol-name "/" ] protocol-version protocol-name = token protocol-version = token received-by = ( host [ ":" port ] ) | pseudonym pseudonym = token received-protocol は、リクエスト/レスポンス連鎖上の各セグメントでサ ーバやクライアントから受けたメッセージのプロトコルバージョンを表す。 received-protocol のバージョンは、アップストリームのアプリケーション のプロトコル能力についての情報がすべての受信者に見えるようにするため に、メッセージの転送時に Via フィールドに添えられる。 protocol-name は、"HTTP" である場合のみ省略可能となる。received-by フ ィールドは通常、その後メッセージを転送した受信サーバやクライアントの ホストと省略可能なポート番号である。しかし、本当のホスト名が取り扱い に慎重を要する情報であるとみなされるのであれば、偽名に置き換える事が *できる*。ポート名が与えられなければ、received-protocol のデフォルト ポートであるとみなして *よい*。 複数の Via フィールド値は、それぞれがメッセージを転送したプロクシやゲ ートウェイを表す。それぞれの受信者は、その結果がアプリケーションを転 送する順序になるように末尾に自身の情報を付加し *なければならない*。 コメントは、User-Agent や Server 各ヘッダフィールドと同様に、受信プロ クシやゲートウェイソフトウェアを識別するために Via ヘッダフィールド内 で使う事が *できる*。しかし、Via フィールド内のすべてのコメントは省略 可能であり、他の受信者はそのメッセージを転送する前にそれを削除する事 が *できる*。 例えば、リクエストメッセージが HTTP/1.0 ユーザエージェントから "fred" というコードネームの内部プロクシに送られ、これが HTTP/1.1 を使って nowhere.com にある公衆プロクシにリクエストを転送し、最後に www.ics.uci.edu というオリジンサーバにリクエストを転送する事で完了す る場合を考える。www.ics.uci.edu が受けるリクエストは、次のような Via ヘッダフィールドを持っているだろう。 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) ネットワークファイアウォールへの入り口として使われるプロクシやゲート ウェイは、デフォルトでは、ファイアウォール域内部のホスト名やポート番 号を転送す *べきではない*。この情報は、明示的に許可された場合にのみ伝 えられる *べきである*。許可されなければ、ファイアウォール内のあらゆる ホストの received-by は、適当な偽名に置き換えられる *べきである*。 内部構造の守秘に関して強いプライバシー要求を持つ組織では、プロクシは 同一の received-protocol 値を持つ連続した Via ヘッダフィールドエント リを一つのエントリに連結する事が *できる*。次の例を見よ。 Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy これは次のようにまとめられる。 Via: 1.0 ricky, 1.1 mertz, 1.0 lucy アプリケーションは、それらがすべて同じ組織コントロール化にあって、ホ スト名が既に偽名に置き換えられている場合以外には、複数のエントリを連 結す *べきではない*。アプリケーションは、異なる received-protocol 値 を持つエントリを連結し *てはならない*。 14.46 Warning Warning 一般ヘッダフィールドは、そのメッセージ中には反映されないであ ろうステータスやメッセージの変化についての付加的情報を伝えるために使 われる。この情報は、キャッシュの処理やメッセージのエンティティボディ に適用される変化から意味的透過性が欠けている可能性がある事を警告する ために定型的に使われる。 Warning ヘッダは、以下のような形式を使ってレスポンスと共に送られる。 Warning = "Warning" ":" 1#warning-value warning-value = warn-code SP warn-agent SP warn-text [SP warn-date] warn-code = 3DIGIT warn-agent = ( host [ ":" port ] ) | pseudonym ; the name or pseudonym of the server adding ; the Warning header, for use in debugging warn-text = quoted-string warn-date = <"> HTTP-date <"> レスポンスでは、複数の Warning ヘッダを転送する事が *できる*。 warn-text は、レスポンスを受けとる人間ユーザが最も理解できそうな自然 言語と文字セットである *べきである*。これはあらゆる利用できる情報、例 えばキャッシュやユーザの場所、リクエスト中の Accept-Language フィール ド、レスポンス中の Content-Language フィールド等に基づいて決定するこ とが *できる*。デフォルトの言語は英語であり、文字セットは ISO-8859-1 である。 ISO-8859-1 以外の文字セットが使われる場合は、RFC 2047 [14] にて記述さ れる方法を用いて warn-text 内でエンコードし *なければならない*。 Warning ヘッダは一般にどんなメッセージにも適用する事ができるが、中に は特定のキャッシュについて言及している warn-code もあり、それについて はレスポンスメッセージにのみ適用できる。新しい Warning ヘッダは、既存 の Warning ヘッダの後に追加される *べきである*。キャッシュは、メッセ ージと共に受け取ったどんな Warning ヘッダも消去し *てはならない*。し かし、キャッシュがキャッシュエントリの検証に成功した場合、特定の Warning コードに指定されているもので無ければ、前もってエントリに付加 されていた Warning ヘッダを消去す *べきである*。そして、そこに検証し た時のレスポンスで受け取ったあらゆる Warning ヘッダを付け加え *なけれ ばならない*。言い換えれば、Warning ヘッダは最新の適切なレスポンスに加 えられるものなのである。 レスポンスに複数の Warning ヘッダが付加されている時は、ユーザエージェ ントは、レスポンス中に現れた順序に従って、できるだけたくさんユーザに 表示すべきである。すべての警告を表示できない場合、ユーザエージェント は以下の規則に従う *べきである*。 - レスポンス中に先に現れた Warning は、後に現れたものよりも優先さ れる。 - ユーザが指定した文字セットの Warning は、同一の warn-code や warn-agent で無ければ他の文字セットのものよりも優先される。 複数の Warning ヘッダを生成するシステムでは、このユーザエージェントの 振る舞いに気をつけて、ヘッダを並べる *べきである*。 Warning を尊重するキャッシュの振る舞いの必要条件は、section 13.1.2 に て述べられている。 以下は、現在定義されている warn-code の一覧と、それぞれに英語での推奨 される warn-text をつけて、その意味について記述したものである。 110 Response is stale 返されるレスポンスが新鮮で無い場合は常にこれを含ま *なければならな い*。 111 Revalidation failed キャッシュがサーバに到達できないという理由で、レスポンスの再検証に 失敗して古いレスポンスを返すという場合はこれを含ま *なければならな い*。 112 Disconnected operation キャッシュが一定の期間にネットワークから故意に切断される場合はこれ を含む *べきである*。 113 Heuristic expiration キャッシュが有効期限を 24 時間以上に設定している時にそのレスポンス の経過時間が 24 時間以上である場合はこれを含ま *なければならない*。 199 Miscellaneous warning この警告文には、それを人間ユーザに表示、記録させるために独自の情報 を含む事が *できる*。この警告を受けたシステムは、警告をユーザに表示 する以外には、どんな自動的なアクションも起こし *てはならない*。 214 Transformation applied (Content-Encoding ヘッダにて指定されるような) 内容コーディング、レ スポンスの (Content-Type ヘッダにて指定されるような) メディアタイ プ、あるいはレスポンスのエンティティボディになんらかの変形が施され る時に、すでにそのレスポンスにこの Wanring コードが与えられている場 合以外は、これが中間のキャッシュかプロクシによって追加されなければ *ならない*。 299 Miscellaneous persistent warning この警告文には、それを人間ユーザに表示、記録させるために独自の情報 を含む事が *できる*。この警告を受けたシステムは、どんな自動的なアク ションも起こし *てはならない*。 もしインプリメンテーションが HTTP/1.0 以下のバージョンの一つ以上の Warning ヘッダを持ったメッセージを送ったならば、送信者はそれぞれの warning-value にレスポンスの時刻に一致する warn-date を含ま *なければ ならない*。 もしインプリメンテーションが warn-date 付きの warning-value を持つメ ッセージを受け取り、その warn-date がレスポンス中の Date 値と異なって いたとしたら、それを保存、転送、使用する前にメッセージからその warning-value を消去し *なければならない*。 (これは、無用心なキャッシ ュが Warning ヘッダフィールドを処理した時に好ましくない結果を引き起こ す事を防止する。) この理由によりすべての warning-value が消去されたな らば、同様にして Waning ヘッダも消去され *なければならない*。 14.47 WWW-Authenticate WWW-Authenticate レスポンスヘッダフィールドは、401 (Unauthorized) レ スポンスメッセージ中に含まれてい *なければならない*。このフィールド値 は、その Request-URI に適用できる認証スキームとパラメータを示す最低一 つの challenge から成る。 WWW-Authenticate = "WWW-Authenticate" ":" 1#challenge HTTP アクセス認証処理方法については、"HTTP Authentication: Basic and Digest Access Authentication" [43] にて記述されている。ユーザエージェ ントは、それが複数の challenge を含んでいる、あるいは複数の WWW- Authenticate ヘッダフィールドを含んでいても、challenge の内容にコンマ で分けられた認証パラメータのリストを含んでいるかもしれないので、WWW- Authenticate フィールド値を解析するのには特別な注意を払うべきである。 15 セキュリティについての考察 この章はアプリケーション開発者、情報提供者、そしてユーザにこの文書で 記述されているような HTTP/1.1 のセキュリティ限界を知らせるという意図 を持つ。このディスカッションでは明示される問題の決定的な解決方法を含 んでいないが、セキュリティリスクを減らすためのいくつかの提案を行って いる。 15.1 個人情報 HTTP クライアントはしばしば多くの量の個人情報 (例えばユーザの名前、場 所、メールアドレス、パスワード、暗号キー、等々) を管理しているので、 この情報を HTTP プロトコル経由で他のリソースへと知らないうちに漏洩し ていないように特に気をつける *べきである*。我々は、ユーザがそのような 情報の公開についてを制御するための便利なインタフェースが提供される事 と、設計者や実装者はこの部分を特に注意する事を特に強く推奨する。歴史 的に、この部分のエラーがしばしば深刻なセキュリティやプライバシー問題 を引き起こし、その結果実装者の会社に対して不利な評判を高めている。 15.1.1 サーバログ情報の乱用 サーバは、読み込みの傾向や興味の対象で識別されるであろうユーザのリク エストについての個人情報を保存する立場にある。この情報は本質的に明ら かに秘密であり、その扱いは国によっては法によって統制されているであろ う。データを供給するために HTTP プロトコルを使用している人々は、その ようなデータは発行された結果、身元がわかってしまうその個人の許可無し には配布されないという事を保証しなければならない。 15.1.2 機密性の高い情報の転送 一般的なデータ転送プロトコルと同様に、HTTP は転送されるデータの内容を 規制する事はできないし、与えられるリクエストの状況の中でその情報の特 定の部分の機密性を決定するためのどんな優先的方法もない。それ故に、ア プリケーションはこの情報の供給者にできるだけ多くこの情報の制御機能を 供給す *べきである*。この状況において特に言及の価値がある四つのヘッダ フィールドが Server, Via, Referer, From である。 サーバの具体的なソフトウェアのバージョンを示す事によって、サーバマシ ンはあるセキュリティホールが知られているソフトウェアに対するアタック を受けやすくなるかもしれない。実装者は、Server ヘッダフィールドを設定 可能なオプションとす *べきである*。 ネットワークファイアウォールの入口の役割を果たすプロクシは、ファイア ウォールの内側にあるホストを識別するヘッダ情報の転送について特に用心 す *べきである*。特に、ファイアウォールの内側で生成されたすべての Via フィールドは削除するか安全なものに置き換える *べきである*。 Referer ヘッダは、読み込み傾向を調査したりやリンクの逆引きをできるよ うにさせる。これはとても有用であるが、もしユーザの詳細が Referer に含 まれる情報から分けられていなければ、その力は悪用されうる。さらに個人 情報が既に削除されていても、Referer ヘッダは公表が不適当であろうプラ イベート文書の URI を示すかもしれない。 From フィールドで送られる情報はユーザのプライバシー観念やサイトのセキ ュリティポリシーに反するかもしれないので、ユーザがそのフィールドの値 を無効、有効、変更ができないのであれば転送される *べきではない*。ユー ザは、ユーザ設定やアプリケーションの初期設定においてこのフィールドの 内容をセットでき *なければならない*。 必ずというわけではないが、我々はユーザが From と Referer 情報の送信を 有効、無効にできるようにする便利なトグルインターフェースを提案する。 User-Agent (section 14.43) や Server (section 14.38) ヘッダフィールド は、時々そのクライアントやサーバが搾取{exploit} 可能な特定のセキュリ ティホールを持っているという事を判別するために使われる。不幸な事に、 この同じ情報は現在の HTTP ではそれ以上の仕組みを持たない他の貴重な目 的にもしばしば使われる。 15.1.3 URI での機密性の高い情報のエンコード リンクのソースがプライベートな情報、あるいは他のプライベートな情報の ソースを明らかにしてしまうかもしれないので、ユーザが Referer フィール ドを送信するかどうかを選択できるようにする事を強く推奨する。例えば、 ブラウザクライアントは公然に/匿名にブラウジングするためのトグルスイ ッチを持ち、Referer や From の各情報の送信をそれぞれ有効/無効とでき る。 クライアントは、参照されるページがセキュアプロトコルで転送された場合 は、(セキュアで無い) HTTP リクエストにReferer ヘッダフィールドを含む *べきではない*。 HTTP プロトコルを使うサービスの作者は、その Request-URI にエンコード されたデータが現れるので、機密性の高いデータの提出に GET を使ったフォ ームを使う *べきではない*。多くの現存のサーバやプロクシ、ユーザエージ ェントは、第三者が見るかもしれない場所にその Request-URI を記録するで あろう。サーバは、代わりに POST を使ったフォームを使うべきである。 15.1.4 Accept ヘッダに関連するプライバシーの問題 Accept リクエストヘッダは、アクセスされたすべてのサーバにユーザに関す る情報を表す事ができる。特に Accept-Language ヘッダは、特定の言語を理 解するという事がしばしば特定の民族グループの一員である事と強く関連付 けられているため、個人的な性質であるとみなすであろう情報を表す。リク エスト毎に送られる Accept-Language ヘッダの内容を設定するためのオプシ ョンを提供するユーザエージェントは、設定のプロセス中にそれがユーザの プライバシーの損失になるという事に気づかせるようなメッセージを含むよ うにする事が強く推奨される。 プライバシーの損失をより制限するためには、ユーザエージェントがデフォ ルトでは Accept-Language ヘッダを送信しないようにし、サーバによって生 成された Vary レスポンスヘッダフィールドを見つけ、その送信によってサ ービスの品質を向上できるとわかった場合に、サーバに Accept-Language ヘ ッダを送る事を開始するどうかをユーザに尋ねるようにする。 ユーザによって設定された詳細な Accept ヘッダフィールドがリクエストご とに送られ、特にそれらが品質値を含んでいたら、比較的信頼でき長い間住 んでいる{long-lived} ユーザを識別するものとしてサーバによって使われう る。そのようなユーザを識別するものは、内容供給者がクリックの追跡 {click-trail tracking} をできるようにし、共同で作業する内容供給者が個 々のユーザのサーバ越しのクリックの追跡{cross-server click-trail} やフ ォーム提出と一致できるようにする。プロクシの内側でない多くのユーザに とって、ユーザエージェントが実行されているホストのネットワークアドレ スも長く住んでいる{long-lived} ユーザを識別するものとして役に立つとい う事に注意せよ。プロクシがプライバシーを高めるために使用されている環 境においては、ユーザエージェントはエンドユーザに accept ヘッダコンフ ィギュレーションオプションを提供する事には保守的であるべきである。極 端なプライバシー手段として、プロクシは中継されたリクエストにおける accept ヘッダをフィルタできる。高いヘッダ設定機能を供給する一般的な目 的のユーザエージェントは、伴う可能性のあるプライバシーの損失に関して ユーザに警告す *べきである*。 15.2 ファイル名やパス名に基づく攻撃 HTTP オリジンサーバの実装は、HTTP リクエストによって返される文書はサ ーバ管理者によって意図されたものだけに制限するように注意す *べきであ る*。HTTP サーバがファイルシステムコールを含む HTTP URI を直接解釈す る場合、サーバは HTTP クライアントへの配信を意図しないファイルを送信 しないように特に注意を払わ *なければならない*。例えば、UNIX や Microsoft Windows や他のオペレーティングシステムはカレントディレクト リの上の階層のディレクトリを表すパス要素として ".." を使う。そのよう なシステムにおいては、HTTP サーバ経由でアクセス可能である事が意図され ている外部リソースへのアクセスが別の方法で許されている場合、HTTP サー バは Request-URI 中にそのような構造のものを許し *てはならない*。同様 に、サーバ内部でのみでの参照が意図されたファイル (アクセス制御ファイ ル、設定ファイル、スクリプトコード等) は、機密性の高い情報を含んでい るので、不適当な検索から保護され *なければならない*。経験的に、そのよ うな HTTP サーバインプリメンテーションの小さなバグがセキュリティリス クになっている。 15.3 DNS スプーフィング HTTP を使用しているクライアントは Domain Name Service に非常に頼って おり、従って一般的に IP アドレスと DNS 名の故意なる間違った組み合わせ をベースとしたセキュリティアタックが行われる傾向にある。クライアント は、IP アドレス/DNS 名の組み合わせの正当性の連続についての仮定にて注 意深くある必要がある。 特に、HTTP クライアントは前回のホスト名 lookup の結果のキャッシュより も、IP アドレス/DNS 名組み合わせの確認についてはそのネームリゾルバを 頼る *べきである*。多くのプラットフォームは適切な時期に既にローカルに ホスト名 lookup をキャッシュできるので、そうするように設定す *べきで ある*。しかし、これらの lookup はネームサーバによって報告された TTL (Time To Live) 情報がキャッシュされた情報がおそらく有効であるであろう とした時にのみキャッシュされるのが適切である。 もし HTTP クライアントがパフォーマンスを改善させるためにホスト名 lookup の結果をキャッシュするなら、DNS によって報告される TTL 情報を 監視し *なければならない*。 もし HTTP クライアントがこのルールを守らないと、それらは直前にアクセ スしたサーバの IP アドレスが変更された時にだまされる。ネットワークの 数値再割り当てがますます一般的になってくる事が予想されるため [24]、こ の形式のアタックの可能性は高くなる。従って、この要求を監視する事によ ってこの潜在的なセキュリティの弱さを減らす。 また、この要求は同じ DNS 名を使用している複製されたサーバに対してクラ イアントのロードバランシング{load-balancing} 動作を改善し、この作戦を 使うサイトをアクセスした場合にユーザが直面する失敗の可能性を減らす。 15.4 Location ヘッダとスプーフィング もし単一のサーバがお互いを信頼していない複数の組織をサポートするなら ば、権限を持っていないところでリソースを無効にしないようにと気をつけ るため、示された組織の制御の元で生成されたレスポンスの Location ヘッ ダと Content-Location ヘッダの値をチェックし *なければならない*。 15.5 Content-Disposition 問題 RFC 1806 [35] は、HTTP ではしばしば実装されている Content-Disposition ヘッダについてのものだが、これはいくつかの深刻なセキュリティ上の問題 を抱えている。Content-Disposition は HTTP 標準では無いが、広く実装さ れているので、我々は実装者にその使用法とリスクについて記述している。 詳細については (RFC 1806 を更新した) RFC 2183 [49] を参照。 15.6 認証用証明書と無配慮なクライアント 現存の HTTP クライアントやユーザエージェントは、典型的に認証情報を無 期限に保持している。HTTP/1.1 では、サーバがクライアントこれらのキャッ シュされた証明書を破棄させるようにするための方法は提供していない。こ れは、HTTP の将来の拡張で要求される重大な欠点である。そのような証明書 がキャッシュされた状況ではアプリケーションのセキュリティモデルに従っ て干渉する事ができるが、以下については制限がない。 - サーバがクライアントにユーザの証明書の再提出を望んだ後に延長され た期間アイドル状態であるクライアント - サーバサイドのアプリケーションがクライアントがこれ以上証明書を保 持する理由がないと `知った' 後にセッションの終了を示すもの (例え ばページの下にある `logout' や `commit' ボタン) を受けたアプリケ ーション これは現在切り離され研究されている。この問題に一部にまつわるものがい くつかあるが、我々はスクリーンセーバへのパスワードプロテクト、アイド ル時のタイムアウト、その他この問題が本来持っているセキュリティ問題を 軽減するための方法を使用する事を推奨する。特に、証明書をキャッシュす るユーザエージェントにはユーザが簡単にキャッシュされた証明書を破棄を 指示できるようなメカニズムを提供する事を推奨する。 15.7 プロクシとキャッシング その性質から必然的に、HTTP プロクシは人と人の間に入り{men-in-the- middle}、中継人による攻撃{man-in-the-middle attacks} の機会が与えられ る。プロクシが運転されているシステムの妥協{compromise} が深刻なセキュ リティとプライバシーの問題を引き起こす。プロクシはセキュリティに関係 した情報、ユーザ個人やその団体についての個別の情報、ユーザやそのプロ バイダが所有する所有者情報にアクセスする。妥協したプロクシや、セキュ リティやプライバシーの問題に無関心に実装、形成されたプロクシは、様々 な可能性を持つ攻撃に使われる。 プロクシのオペレータは、機密性の高い情報を含み、また転送するシステム を守るように、プロクシが運転しているシステムを守るべきである。特に、 プロクシによって集められたログ情報はしばしば特に機密性の高い個人情報 や組織情報を含んでいる。ログ情報は注意深く監視すべきであり、改善や更 新のための使用にも適切なガイドラインを設けるべきである。(section 15.1.1) キャッシングプロクシは、キャッシュの内容が悪意ある利用には魅力的なタ ーゲットを表しているので、潜在的な弱点が付け加えられる。キャッシュの 内容が HTTP リクエストが完了した後もずっと残っているので、キャッシュ へのアタックでユーザがその情報はネットワークからは既に削除されたと信 じているずっと後にその情報を見る事ができる。それ故に、キャッシュの内 容は機密性の高い情報として守られるべきである。 プロクシの実装者は、その設計やコーディングの決定、そしてプロクシオペ レータへ提供する設定オプション (特にデフォルトの設定) がプライバシー やセキュリティに関わるという事を考慮すべきである。 プロクシのユーザは、プロクシを運転する人間しか信頼する価値のある人は いないという事を知っておく必要がある。HTTP 自身はこの問題を解決できな い。 暗号を適切な時に適切に使う事は、広い範囲のセキュリティや個人への攻撃 に対しての防御に十分なものとなろう。このような暗号については HTTP/1.1 の仕様書の範囲を超える。 15.7.1 プロクシを使ったサービス拒否攻撃 この攻撃は存在する。この攻撃を防御する事は難しい。調査を続けよ。用心 せよ。 16 謝辞 この仕様書では、RFC 822 [9] で David H. Crocker によって定義された拡 張 BNF と共通概念を多数使用している。同様に、MIME [7] で Nathaniel Borenstein と Ned Freed によって提供された多くの定義を再利用してい る。我々は、この仕様書内に含まれる事柄が過去に HTTP とインターネット メールメッセージフォーマットとの間にあった混乱を減らす助けとなって欲 しいと願っている。 HTTP プロトコルは、1年でかなり発展した。これは、大きな、そして活発な www-talk メーリングリストに参加している多くの人々から成る開発者コミュ ニティのおかげであり、そしてそコミュニティは一般に HTTP や World-Wide Web を成功させるために最も責任のあるコミュニティである。Marc Andreessen, Robert Cailliau, Daniel W. Connolly, Bob Denny, John Franks, Jean-Francois Groff, Phillip M. Hallam-Baker, Hakon W. Lie, Ari Luotonen, Rob McCool, Lou Montulli, Dave Raggett, Tony Sanders, Marc VanHeyningen 各氏は、このプロトコルの初期の概観を定義したという 努力に対して特に評価されるに値する。 この文書は、おおいに HTTP-WG に参加するすべての人のコメントのおかげで ある。既に述べた人達の他に、以下の方々がこの仕様書に貢献してくれた。 Gary Adams Ross Patterson Harald Tveit Alvestrand Albert Lunde Keith Ball John C. Mallery Brian Behlendorf Jean-Philippe Martin-Flatin Paul Burchard Mitra Maurizio Codogno David Morris Mike Cowlishaw Gavin Nicol Roman Czyborra Bill Perry Michael A. Dolan Jeffrey Perry David J. Fiander Scott Powers Alan Freier Owen Rees Marc Hedlund Luigi Rizzo Greg Herlihy David Robinson Koen Holtman Marc Salomon Alex Hopmann Rich Salz Bob Jernigan Allan M. Schiffman Shel Kaphan Jim Seidman Rohit Khare Chuck Shotton John Klensin Eric W. Sink Martijn Koster Simon E. Spero Alexei Kosut Richard N. Taylor David M. Kristol Robert S. Thau Daniel LaLiberte Bill (BearHeart) Weinman Ben Laurie Francois Yergeau Paul J. Leach Mary Ellen Zurko Daniel DuBois Josh Cohen キャッシングのデザインの内容と表現の多くは、以下の方々からの提案とコ メントのおかげである: Shel Kaphan, Paul Leach, Koen Holtman, David Morris, Larry Masinter. レンジの仕様の多くは、元々は Ari Luotonen と John Franks によって行わ れていたものに基づいており、それに Steve Zilles がいくらか追加したも のである。 Palo Alto の "洞穴男" に感謝する。本人ならそれが誰だかわかるはずだ。 Jim Gettys (この文書の現在の筆者) は、この文書の前の筆者達である John Klensin, Jeff Mogul, Paul Leach, Dave Kristol, Koen Holtman, John Franks, Josh Cohen, Alex Hopmann, Scott Lawrence, Larry Masinter, 及 び彼らを助けた人達、そして特に Roy Fielding に感謝する。そして "MUST/MAY/SHOULD" の審査をしてくれた Jeff Mogul と Scott Lawrence も 特に感謝する。 The Apache Group, Anselm Baird-Smith, Jigsaw の作者, Henrik Frystyk は、RFC 2068 以前のものを実装した。我々はそれによってこの文書が正そう としていた多くの問題を発見する事ができたという事を彼らに感謝したい。 17 参考文献 [1] Alvestrand, H., "Tags for the Identification of Languages", RFC 1766, March 1995. [2] Anklesaria, F., McCahill, M., Lindner, P., Johnson, D., Torrey, D. and B. Alberti, "The Internet Gopher Protocol (a distributed document search and retrieval protocol)", RFC 1436, March 1993. [3] Berners-Lee, T., "Universal Resource Identifiers in WWW", RFC 1630, June 1994. [4] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform Resource Locators (URL)", RFC 1738, December 1994. [5] Berners-Lee, T. and D. Connolly, "Hypertext Markup Language - 2.0", RFC 1866, November 1995. [6] Berners-Lee, T., Fielding, R. and H. Frystyk, "Hypertext Transfer Protocol -- HTTP/1.0", RFC 1945, May 1996. [7] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, November 1996. [8] Braden, R., "Requirements for Internet Hosts -- Communication Layers", STD 3, RFC 1123, October 1989. [9] Crocker, D., "Standard for The Format of ARPA Internet Text Messages", STD 11, RFC 822, August 1982. [10] Davis, F., Kahle, B., Morris, H., Salem, J., Shen, T., Wang, R., Sui, J., and M. Grinbaum, "WAIS Interface Protocol Prototype Functional Specification," (v1.5), Thinking Machines Corporation, April 1990. [11] Fielding, R., "Relative Uniform Resource Locators", RFC 1808, June 1995. [12] Horton, M. and R. Adams, "Standard for Interchange of USENET Messages", RFC 1036, December 1987. [13] Kantor, B. and P. Lapsley, "Network News Transfer Protocol", RFC 977, February 1986. [14] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, November 1996. [15] Nebel, E. and L. Masinter, "Form-based File Upload in HTML", RFC 1867, November 1995. [16] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821, August 1982. [17] Postel, J., "Media Type Registration Procedure", RFC 1590, November 1996. [18] Postel, J. and J. Reynolds, "File Transfer Protocol", STD 9, RFC 959, October 1985. [19] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC 1700, October 1994. [20] Sollins, K. and L. Masinter, "Functional Requirements for Uniform Resource Names", RFC 1737, December 1994. [21] US-ASCII. Coded Character Set - 7-Bit American Standard Code for Information Interchange. Standard ANSI X3.4-1986, ANSI, 1986. [22] ISO-8859. International Standard -- Information Processing -- 8-bit Single-Byte Coded Graphic Character Sets -- Part 1: Latin alphabet No. 1, ISO-8859-1:1987. Part 2: Latin alphabet No. 2, ISO-8859-2, 1987. Part 3: Latin alphabet No. 3, ISO-8859-3, 1988. Part 4: Latin alphabet No. 4, ISO-8859-4, 1988. Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988. Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987. Part 7: Latin/Greek alphabet, ISO-8859-7, 1987. Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988. Part 9: Latin alphabet No. 5, ISO-8859-9, 1990. [23] Meyers, J. and M. Rose, "The Content-MD5 Header Field", RFC 1864, October 1995. [24] Carpenter, B. and Y. Rekhter, "Renumbering Needs Work", RFC 1900, February 1996. [25] Deutsch, P., "GZIP file format specification version 4.3", RFC 1952, May 1996. [26] Venkata N. Padmanabhan, and Jeffrey C. Mogul. "Improving HTTP Latency", Computer Networks and ISDN Systems, v. 28, pp. 25-35, Dec. 1995. Slightly revised version of paper in Proc. 2nd International WWW Conference '94: Mosaic and the Web, Oct. 1994, which is available at http://www.ncsa.uiuc.edu/SDG/IT94/Proceedings/DDay/mogul/HTTPLat ency.html. [27] Joe Touch, John Heidemann, and Katia Obraczka. "Analysis of HTTP Performance", , ISI Research Report ISI/RR-98-463, (original report dated Aug. 1996), USC/Information Sciences Institute, August 1998. [28] Mills, D., "Network Time Protocol (Version 3) Specification, Implementation and Analysis", RFC 1305, March 1992. [29] Deutsch, P., "DEFLATE Compressed Data Format Specification version 1.3", RFC 1951, May 1996. [30] S. Spero, "Analysis of HTTP Performance Problems," http://sunsite.unc.edu/mdma-release/http-prob.html. [31] Deutsch, P. and J. Gailly, "ZLIB Compressed Data Format Specification version 3.3", RFC 1950, May 1996. [32] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P., Luotonen, A., Sink, E. and L. Stewart, "An Extension to HTTP: Digest Access Authentication", RFC 2069, January 1997. [33] Fielding, R., Gettys, J., Mogul, J., Frystyk, H. and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2068, January 1997. [34] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. [35] Troost, R. and Dorner, S., "Communicating Presentation Information in Internet Messages: The Content-Disposition Header", RFC 1806, June 1995. [36] Mogul, J., Fielding, R., Gettys, J. and H. Frystyk, "Use and Interpretation of HTTP Version Numbers", RFC 2145, May 1997. [jg639] [37] Palme, J., "Common Internet Message Headers", RFC 2076, February 1997. [jg640] [38] Yergeau, F., "UTF-8, a transformation format of Unicode and ISO-10646", RFC 2279, January 1998. [jg641] [39] Nielsen, H.F., Gettys, J., Baird-Smith, A., Prud'hommeaux, E., Lie, H., and C. Lilley. "Network Performance Effects of HTTP/1.1, CSS1, and PNG," Proceedings of ACM SIGCOMM '97, Cannes France, September 1997.[jg642] [40] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, November 1996. [jg643] [41] Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 18, RFC 2277, January 1998. [jg644] [42] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax and Semantics", RFC 2396, August 1998. [jg645] [43] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., Leach, P., Luotonen, A., Sink, E. and L. Stewart, "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, June 1999. [jg646] [44] Luotonen, A., "Tunneling TCP based protocols through Web proxy servers," Work in Progress. [jg647] [45] Palme, J. and A. Hopmann, "MIME E-mail Encapsulation of Aggregate Documents, such as HTML (MHTML)", RFC 2110, March 1997. [46] Bradner, S., "The Internet Standards Process -- Revision 3", BCP 9, RFC 2026, October 1996. [47] Masinter, L., "Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)", RFC 2324, 1 April 1998. [48] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples", RFC 2049, November 1996. [49] Troost, R., Dorner, S. and K. Moore, "Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field", RFC 2183, August 1997. 18 筆者のアドレス Roy T. Fielding Information and Computer Science University of California, Irvine Irvine, CA 92697-3425, USA Fax: +1 (949) 824-1715 EMail: fielding@ics.uci.edu James Gettys World Wide Web Consortium MIT Laboratory for Computer Science 545 Technology Square Cambridge, MA 02139, USA Fax: +1 (617) 258 8682 EMail: jg@w3.org Jeffrey C. Mogul Western Research Laboratory Compaq Computer Corporation 250 University Avenue Palo Alto, California, 94305, USA EMail: mogul@wrl.dec.com Henrik Frystyk Nielsen World Wide Web Consortium MIT Laboratory for Computer Science 545 Technology Square Cambridge, MA 02139, USA Fax: +1 (617) 258 8682 EMail: frystyk@w3.org Larry Masinter Xerox Corporation 3333 Coyote Hill Road Palo Alto, CA 94034, USA EMail: masinter@parc.xerox.com Paul J. Leach Microsoft Corporation 1 Microsoft Way Redmond, WA 98052, USA EMail: paulle@microsoft.com Tim Berners-Lee Director, World Wide Web Consortium MIT Laboratory for Computer Science 545 Technology Square Cambridge, MA 02139, USA Fax: +1 (617) 258 8682 EMail: timbl@w3.org 19 付録 19.1 インターネットメディアタイプ message/http と application/http HTTP/1.1 プロトコルの定義に追加して、この文書ではインターネットメディ アタイプ "message/http" と "application/http" についての仕様を示す。 message/http タイプは単一の HTTP リクエストやレスポンスメッセージを含 むために使う事ができ、行長さやエンコーディングに関するすべての "message" タイプが受ける MIME 制限 に従う。application/http タイプは 一つ以上の HTTP リクエストやレスポンスメッセージ(混合されてはいない もの)のパイプラインを含むために使う事ができる。以下のものが IANA に て登録されている。 メディアタイプ名: message メディアサブタイプ名: http 必要なパラメータ: 無し 省略可能なパラメータ: version, msgtype version: メッセージに同封された HTTP-Version 番号 (例えば "1.1" 等) 。もしが与えられていなければ、ボディの最初の行から 決定する事ができる。 msgtype: メッセージタイプ、すなわち "request" か "response"。も し与えられていなければ、ボディの最初の行で決定する事が できる。 Encoding についての考察: "7bit", "8bit", "バイナリ" のみが許され る。 Security についての考察: 無し メディアタイプ名: application メディアサブタイプ名: http 必要なパラメータ: 無し 省略可能なパラメータ: version, msgtype version: メッセージに同封された HTTP-Version 番号 (例えば "1.1" 等) 。もしが与えられていなければ、ボディの最初の行から 決定する事ができる。 msgtype: メッセージタイプ、すなわち "request" か "response"。も し与えられていなければ、ボディの最初の行で決定する事が できる。 Encoding についての考察:このタイプに含まれる HTTP メッセージは "バイナリ" フォーマットである。すなわち、転送が E-mail 経由で行われる時には、適切な Content-Transfer-Encoding が使われる必要となる。 Security についての考察: 無し 19.2 インターネットメディアタイプ multipart/byteranges HTTP 206 (Partial Content) レスポンスメッセージが複数の範囲の内容 (複 数の重ならない範囲のリクエストへのレスポンス) を含む時、これらはマル チパートメッセージボディとして転送される。この目的のためのメディアタ イプは "multipart/byteranges" と呼ばれる。 multipart/byteranges メディアタイプは二つ以上の部分を含み、それぞれに 自身の Content-Type と Content-Range フィールドを持つ。要求される境界 パラメータはそれぞれのボディ部分を分けるために使われる境界文字列を指 定する。 メディアタイプ名: multipart メディアサブタイプ名: byteranges 必要なパラメータ: boundary 省略可能なパラメータ: 無し Encoding についての考察: "7bit", "8bit", "バイナリ" のみが許され る。 Security についての考察: 無し 例を見よ。 HTTP/1.1 206 Partial Content Date: Wed, 15 Nov 1995 06:25:24 GMT Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT Content-type: multipart/byteranges; boundary=THIS_STRING_SEPARATES --THIS_STRING_SEPARATES Content-type: application/pdf Content-range: bytes 500-999/8000 ...最初の範囲... --THIS_STRING_SEPARATES Content-type: application/pdf Content-range: bytes 7000-7999/8000 ...次の範囲 --THIS_STRING_SEPARATES-- 注意 1) エンティティの最初の境界文字列の前に追加の CRLF を置く事ができ る。 2) RFC 2046 [40] ではクォートされた境界文字列を認めているが、既存 のインプリメンテーションの中にはクォートされた文字列を不適切に 扱うものがある。 3) いくつかのブラウザやサーバは multipart/x-byteranges というメデ ィアタイプを使用するバイト範囲の仕様の初期ドラフトに基づいてコ ーディングされているが、それは HTTP/1.1 にて記述されるバージョ ンとは、ほぼ互換性はあるものの、完全互換ではない。 19.3 寛容なアプリケーション この文書は HTTP/1.1 メッセージの生成についての要求を表しているもので あるが、すべてのアプリケーションが正しくそれらを実装しているわけでは 無いであろう。故に、我々は作業アプリケーションはもし実装から逸脱する 部分があってもそれが明確に中間処理できる時は、逸脱に対して寛容である 事を推奨する。 クライアントはステータスラインの解析において、またサーバはリクエスト ラインの解析時においてそれぞれ寛容である *べきである*。特に、例えそこ には単一の SP のみが必要だったとしても、フィールド間のいかなる量の SP や HT 各文字列を受け入れる *べきである*。 message-header フィールドについての行末は CRLF シーケンスである。しか し我々は、アプリケーションがそのようなヘッダを解析する時には、単一の LF を行末として認識しその前の CR を無視する事を推奨する。 エンティティボディの文字セットは、US-ASCII や ISO-8859-1 ラベルをもっ てエンティティをラベル付けされるという事以上に好まれるラベル付けは無 いという例外を除けば、そのボディで使用されている文字コードの共通点が 最も低い特徴としてラベル付けされる *べきである*。section 3.7.1 や 3.4.1 参照。 日付の解析やエンコーディング上の要求や日付エンコーディングに伴うその 他の潜在的な問題に対する追加的規則には以下が含まれる。 - HTTP/1.1 クライアントやキャッシュは、将来において 50 年を越えて 現れると思われる RFC-850 日付は実際過去のものであると仮定す *べ きである* (これは "2000年" 問題を解決する助けとなる)。 - HTTP/1.1 インプリメンテーションは解析された Expires 日付を適切な 値よりも早いように内部的に表す事が *できる* が、解析された Expires を適切な値よりも遅いように内部的に表し *てはならない*。 - 有効期限に関連するすべての計算は、GMT で行われ *なければならな い*。ローカルタイムゾーンは経過時間や有効期限の計算や比較に影響 を及ぼし *てはならない*。 - HTTP ヘッダが誤って GMT 以外のタイムゾーンの日付値を転送してしま った場合、最も可能な限り保守的な変換を使って GMT へと変換され *なければならない*。 19.4 HTTP のエンティティ と RFC2045 のエンティティとの違い HTTP/1.1 は、エンティティが公開されている様々な表現や拡張可能なメカニ ズムによって転送できるようにするためにインターネットメール (RFC 822 [9]) や Multipurpose Internet Mail Extensions (MIME [7]) のために定義 されている多くの構造を使用する。しかし、RFC 2045 ではメールについて議 論し、HTTP は RFC 2045 中に表されているものとは違ういくつかの特徴を持 っている。これらの違いはバイナリ接続以上にパフォーマンスを最適化する ために、新しいメディアタイプをより自由に使用できるために、日付の比較 を容易にするために、そしていくつかの初期の HTTP サーバやクライアント の実行を認めるために注意深く選ばれた。 この付録では HTTP が RFC 2045 と異なる具体的な部分を表す。厳密な MIME 環境へのプロクシやゲートウェイはこの違いを知る *べきであり* 必要な部 分での適切な変換を提供す *べきである*。また MIME 環境から HTTP へのプ ロクシやゲートウェイもいくつか変換が必要であるのでこの違いを知る必要 がある。 19.4.1 MIME-Version HTTP は MIME 準拠のプロトコルではない。しかし、HTTP/1.1 メッセージは そのメッセージを構成するためにどんな MIME プロトコルのバージョンが使 用されたかを示すために単一の MIME-Version 一般ヘッダフィールドを含む 事が *できる*。MIME-Version ヘッダフィールドの使用は (RFC 2045[7] に て定義されるように) そのメッセージが MIME プロトコルの完全に追従して いる事を示す。プロクシ/ゲートウェイは HTTP メッセージを厳密な MIME 環境にエクスポートする時に (それが可能であれば) 完全に追従している事 を保証する責任を持つ。 MIME-Version = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT MIME バージョン "1.0" は HTTP/1.1 で使うデフォルトである。しかしなが ら、HTTP/1.1 メッセージの解析やセマンティクスはこの文書によって定義さ れ MIME の仕様ではない。 19.4.2 公式形式への変換 RFC 2045 [7] は、RFC 2049 [48] の section 4 にて記述される様に、イン ターネットメールエンティティが転送される前に公式形式に変換される事を 要求する。この文書の section 3.7.1 では HTTP 上を転送される時の "text" メディアタイプのサブタイプについて認められる形式を記述してい る。RFC 2046 は、"text" タイプを伴う内容は CRLF をもって行末を表し、 行末シーケンス以外の CR や LF の使用を禁止する事を要求する。HTTP では メッセージが HTTP 上を転送される時にはテキスト内容の行末を示すために CRLF、単独の CR、単独の LF を認めている。 可能であれば、HTTP から厳密な MIME 環境へのプロクシやゲートウェイはこ の文書の section 3.7.1 にて記述されたテキストメディアタイプに含まれる すべての行末を RFC 2049 の公式形式である CRLF に変換す *べきである*。 しかし、HTTP がいくつかのマルチバイト文字セットのための場合として、 Content-Encoding がある事や、CR と LF を表すためにオクテットの 13 と 10 を使わないいくつかの文字セットの使用を認めているという事実によって これが複雑になっているかもしれない事に注意せよ。 実装者は、もし元の内容が既に公式形式であるので無ければ、変換は元の内 容に適用されている暗号チェックサムを壊してしまうであろう事に注意せ よ。故に、公式形式は HTTP 中にてチェックサムを使うあらゆる内容に対し て推奨される。 19.4.3 日付フォーマットの変換 HTTP/1.1 は日付比較の処理を簡単にするために制限された日付フォーマット (section 3.3.1) のセットを使用する。他のプロトコルからのプロクシやゲ ートウェイは、確実にメッセージ中に与えられるあらゆる Date ヘッダも HTTP/1.1 フォーマットの一つに従い必要であれば日付を書き換える *べきで ある*。 19.4.4 内容コーディングの導入 RFC 2045 は HTTP/1.1 の Content-Encoding ヘッダフィールドに相当するど んな概念も含んでいない。これはメディアタイプを修正子のように動作する ので、HTTP から MIME 準拠のプロトコルへのプロクシやゲートウェイは Content-Type ヘッダフィールドの値を変更するか、あるいはメッセージを転 送する前にエンティティボディをデコードするかし *なければならない*。 (インターネットメールについての Content-Type のいくつかの実験的なアプ リケーションは既に Content-Encoding と等価な機能を行う ";conversions=" のメディアタイプパラメータを使用して いる。しかし、このパラメータは RFC 2045 の一部ではない。) 19.4.5 No Content-Transfer-Encoding HTTP は RFC 2045 の Content-Transfer-Encoding (CTE) フィールドを使用 していない。MIME 準拠のプロトコルから HTTP へのプロクシやゲートウェイ は HTTP クライアントへとレスポンスメッセージを配信する前にあらゆる identify で無い CTE ("quoted-printable" や "base64") エンコーディング を取り除か *なければならない*。 HTTP から MIME 準拠のプロトコルへのプロクシやゲートウェイはメッセージ がそのプロトコル上で安全に転送されるための正しいフォーマットとエンコ ーディングがなされる事を保証する責任を持つが、ここでの "安全な転送" とは使用されているプロトコルの制限によって定義される。そのようなプロ クシやゲートウェイは、もしそうする事が目的のプロトコル上での安全な転 送の可能性を高めるのであれば、適切な Content-Transfer-Encoding を持っ たデータをラベル付けす *べきである*。 19.4.6 転送エンコーディングの導入 HTTP/1.1 は Transfer-Encoding ヘッダフィールド (section 14.41) を導入 する。プロクシ/ゲートウェイは MIME 準拠のプロトコル経由でメッセージ を転送する前にあらゆる転送コーディングを削除し *なければならない*。 "chunked" 転送コーディング (section 3.6) をデコードするための処理は以 下の疑似コードによって表される: length := 0 read chunk-size, chunk-extension (if any) and CRLF while (chunk-size > 0) { read chunk-data and CRLF append chunk-data to entity-body length := length + chunk-size read chunk-size and CRLF } read entity-header while (entity-header not empty) { append entity-header to existing header fields read entity-header } Content-Length := length Remove "chunked" from Transfer-Encoding 19.4.7 MHTML と行末制限 MHTML [45] インプリメンテーションに伴うコードを共有する HTTP インプリ メンテーションは、MIME 行末制限に気をつける必要がある。HTTP にはその ような制限は無いので、HTTP は長い行を折り返さない。HTTP によって転送 されている MHTML メッセージは、HTTP はすべてのメッセージボディを付加 物{payload} として転送し、その中に含まれるであろう内容や MIME ヘッダ ラインを解釈しないので、行末制限、折り返し、公式化などを含んだ、すべ ての MHTML の慣習に従う。 19.5 追加機能 RFC 1945 や RFC 2068 ではいくつかの既存の HTTP インプリメンテーション によって使われているプロトコル要素について記述したが、これらは多くの HTTP/1.1 アプリケーションを通じて一貫していなく、また正確ではない。実 装者はこれらの機能を知っておいたほうがよいが、他の HTTP/1.1 アプリケ ーションにおいてそれらの存在や通信協力{interoperability} を当てにはで きない。これらの内のいくつかは実験的な機能として提案されるものを示 し、またいくつかは基本の HTTP/1.1 仕様書中に現在表された欠如を実験的 な配置が見つける機能を記述する。 Content-Disposition や Title のような、SMTP や MIME からのいくつかの 他のヘッダもまたしばしば実装される (RFC 2076 [37] 参照)。 19.5.1 Content-Disposition Content-Disposition レスポンスヘッダフィールドは、ユーザがその内容を ファイルに保存したい場合にオリジンサーバがデフォルトのファイル名を提 案する事を意味するように勧告されている。この使用法は RFC 1806 [35] 中 の Content-Disposition の定義に由来する。 content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm ) disposition-type = "attachment" | disp-extension-token disposition-parm = filename-parm | disp-extension-parm filename-parm = "filename" "=" quoted-string disp-extension-token = token disp-extension-parm = token "=" ( token | quoted-string ) 例を見よ。 Content-Disposition: attachment; filename="fname.ext" 受信するユーザエージェントは filename-parm パラメータ中に表されている ディレクトリパス情報を尊重す *べきではない*。その時 HTTP インプリメン テーションに適用されるために信じられる唯一の情報だからである。ファイ ル名は端末構成部品としてのみ扱われる *べきである*。 もしこのヘッダが application/octet-stream コンテントタイプを伴ったレ スポンス中で使われるのであれば、ユーザエージェントはレスポンスを表示 すべきではなく、直接「レスポンスを名前を付けて保存」ダイアログを記入 する事が暗黙的に提案される。 Content-Disposition のセキュリティ上の問題については section 15.5 参 照。 19.6 前バージョンとの互換性 前のバージョンに従うように指示する事はプロトコル仕様書としての範疇を 超える。HTTP/1.1 は慎重に設計されたものではあるが、前のバージョンをサ ポートする事は簡単である。この仕様書を作った時 (1996) に、我々が HTTP/1.1 サーバに以下を期待していたであろう事に注目する価値はある。 - HTTP/0.9, 1.0, 1.1 それぞれのリクエストラインのフォーマットを認 識する - HTTP/0.9, 1.0, 1.1 それぞれのフォーマットのあらゆる有効なリクエ ストを理解する - クライアントが使ったものと同じメジャーバージョンのメッセージを伴 い適切に応答する また、我々は HTTP/1.1 クライアントには以下を期待していたであろう事に 注目する価値はある。 - HTTP/0.9, 1.0, 1.1 それぞれのステータスラインのフォーマットを認 識する - HTTP/0.9, 1.0, 1.1 それぞれのフォーマットのあらゆる有効なレスポ ンスを理解する 多くの HTTP/1.0 インプリメンテーションでは、それぞれの接続はリクエス トの前にクライアントによって確立され、レスポンスを送った後にサーバに よって切断される。インプリメンテーションの中には RFC 2068 [33] の section 19.7.1 中に記される Keep-Alive バージョンの持続的接続を実装し ているものがある。 19.6.1 HTTP/1.0 からの変更点 この章では HTTP/1.0 と HTTP/1.1 との間での主な違いを簡単に述べる。 19.6.1.1 複数割当{Multi-homed} Web サーバを簡単化し IP アドレスを保護す るための変更 クライアントとサーバは Host リクエストヘッダをサポートし、HTTP/1.1 リ クエストに Host リクエストヘッダ (section 14.23) が欠落していた場合は エラーを知らせ、絶対 URI (section 5.1.2) を受け入れる、という必要条件 はこの仕様書にて定義されている最も重要な変更の一つである。 古い HTTP/1.0 クライアントは IP アドレスとサーバの一対一の関係を仮定 していたので、そのリクエストが向けられた IP アドレスとは他にリクエス トの意図されたサーバを区別するための別の確立されたメカニズムが存在し なかった。上に概説された変更によって、インターネットは、かつての古い HTTP クライアントはもはや一般的では無い、単一の IP アドレスで複数の Web サイトをサポートできるようになり、単一のホストへの多くの IP アド レスの割り当てが深刻な問題を引き起こしているような、大きな作業上の Web サーバをより簡略化する事ができる。また、インターネットもルートレ ベルの HTTP URL 中で使われる特別な目的のドメイン名の唯一の目的に割り 当てられていた IP アドレスを取り返す事ができる。Web の成長率と既に設 置されたサーバの数を考慮に入れると、すべての HTTP インプリメンテーシ ョン (既存の HTTP/1.0 アプリケーションをアップデートしたものを含む) がこれらの要求を正しく実装する事は非常に重要である。 - HTTP/1.1 リクエストを送るクライアントは Host ヘッダを送ら *なけ ればならない*。 - クライアントとサーバ共に、Host リクエストヘッダをサポートし *な ければならない*。 - サーバは、HTTP/1.1 リクエストが Host リクエストヘッダを含んでい なければエラー 400 (Bad Request) を知らせ *なければならない*。 - サーバは 絶対 URI を受け入れ *なければならない*。 19.6.2 HTTP/1.0 持続的接続との互換性 クライアントやサーバの中には HTTP/1.0 のクライアントやサーバ中におけ る持続的接続についてある以前のインプリメンテーションと互換性を持たせ たいと思うかもしれない。HTTP/1.0 における持続的接続はそれらがデフォル トの振る舞いでは無いとして明確にネゴシエートされる。HTTP/1.0 の持続的 接続の実験的な実装には欠点があり、HTTP/1.1 における新しい機能はこれら の問題を改善するために設計されている。問題はある既存の 1.0 クライアン トが Connection を理解できないプロクシサーバへ Keep-Alive が送ってい るかもしれず、さらにインバウンドサーバに誤ってそれを転送するかもしれ ず、そうなると Keep-Alive 接続が確立され、その結果レスポンスでの切断 を待っている HTTP/1.0 プロクシのハングアップを引き起こす事になるであ ろう。これは HTTP/1.0 クライアントがプロクシと通信する時に Keep-Alive を使用する事を防がなければならないという事である。 しかし、プロクシとの通信は持続的接続の最も重要な使い方であり、その禁 止は明らかに受け入れる事はできない。故に、我々は Connection を無視す る古いプロクシと通信する時に使用しても安全な、持続的接続が望まれてい る事を示すための他のメカニズムを必要とする。持続的接続は HTTP/1.1 メ ッセージのデフォルトであり、我々は非持続性を宣言するための新しいキー ワード (Connection: close) を導入する。section 14.10 参照。 持続的接続の元の HTTP/1.0 の形式 (Connection:Keep-Alive や Keep-Alive ヘッダ) は RFC 2068 [33] 中に記述されている。 19.6.3 RFC 2068 からの変更点 この仕様書はキーワードの仕様について正しくまた曖昧で無い様に慎重に検 査された。RFC 2068 は RFC 2119 [34] 中に置かれた約定について多くの問 題を抱えていた。 インバウンドサーバの失敗のために使われるべきエラーコードは明らかにさ れる (例. DNS の失敗)。(Section 10.5.5) CREATE はリソースが最初に生成された時に送られる ETag を要求する種類を 持つ。(Section 10.2.2) Content-Base は仕様書から削除された。これは広くは実装されてはおらず、 また、逞しい{robust} 拡張メカニズム無しにこれを導入する事は単純なもの でも安全なものでも無い。加えて、これは MHTML [45] 中では似たようなも のが使われているが、同一のやり方ではない。 (自己分割できない転送コーディングを考慮に入れるために) チャンクエンコ ーディングが使用される場合、Transfer-coding とメッセージ長は全て正確 なる固定が要求される方法において相互動作する; どのようにメッセージ長 が計算されるかを正確に決定しておく事は重要であった。(Sections 3.6, 4.4, 7.2.2, 13.5.2, 14.13, 14.16) キャッシング中に発見される問題を解決するために、内容コーディングに "identity" が導入された。(Section 3.5) 0 という品質値は、クライアントが表現を拒否できるように "それを望まな い" という事を示すべきである。(Section 3.9) HTTP のバージョン番号の使用とその説明については RFC 2145 にて明示され た。プロクシは HTTP/1.0 インプリメンテーションに見られる問題を扱う事 をサポートするために最も高いプロトコルバージョンにアップグレードする 必要がある。(Section 3.1) Accept ヘッダ中の文字セット名の急激な増加を避けるために文字セットの ワイルドカード{Charset wildcarding} が導入された。(Section 14.2) ある事例が HTTP/1.1 の Cache-Control モデル中に入れ損なわれていた。よ って、s-maxage がこの抜けた事例を加えるために導入された。(Sections 13.4, 14.8, 14.9, 14.9.3) レスポンスの場合の Cache-Control: max-age 指示子が適切に定義されてい なかった。(Section 14.9.3) サーバ(特にプロクシ)がレスポンスの全長は知らないが、バイト範囲リク エストをする能力はあるという場合がある。故に、我々はメッセージの全長 を示さない content-range を伴ったバイト範囲を許すメカニズムを必要とす る。(Section 14.16) レンジリクエストは、既に全ての外部データが返されていた場合には、ひど く冗長になるであろう。しかし、サーバが 206 レスポンス中に必要なヘッダ のみを送る事ができるようにする事によって、この問題は解決できる。 (Section 10.2.7, 13.5.3, 14.27) 満足できないレンジリクエストに修正について。これには二つの場合があっ て、シンタックス上の問題と、その範囲が文書に存在しない場合とがある。 416 ステータスコードは、文書の実際の内容以外の点について失敗したバイ ト範囲リクエストのエラーを示すために、その曖昧さを解決するために必要 である。(Section 10.4.17, 14.16) ここにあるエラーの結果はインターネットに重要な影響を及ぼしうるので、 実装者が状況をこれ以上悪くする事を、また実装者が以下の問題を扱う事を 避けるためのメッセージ転送の必要条件の書き直し: 1. その部分が将来の HTTP/1.x バージョンの実装の振る舞いにおける必 要条件を不正確に示している文脈において、"HTTP/1.1 以降" を "HTTP/1.1" に変える 2. ユーザエージェントはリクエストを繰り返すべきであるが、一般に "クライアント" はそうすべきではない、という事を明らかにさせる。 3. クライアントは予期しない 100 (Continue) レスポンスを無視せよ、 またプロクシは 100 レスポンスを転送せよ、という必要条件を 1xx レスポンスに対する一般的な必要条件に変える。 4. いくつかの TCP に特定した言語を修正し、HTTP のためには TCP では ない転送でも可能であるという事をより明らかにする。 5. オリジンサーバは自身が要求された 100 (Continue) レスポンスを送 る前には、リクエストボディを待っ *てはならない* という事を必要 とする。 6. サーバはリクエストボディの一部を既に取得している場合は 100 (Continue) レスポンスを省略する事を、必要とするよりもむしろ、そ れを見込んでいる。 7. サーバはサービス不能攻撃や故障したクライアントから身を守る事が できる。 この変更により Expect ヘッダと 417 ステータスコードが付け加えられた。 メッセージ転送の必要条件は sections 8.2, 10.4.18, 8.1.2.2, 13.11, 14.20 の各セクションにて修正される。 プロクシは適切な時点で Content-Length を付け加える事ができるべきであ る。(Section 13.5.2) 403 と 404 の各レスポンスの区別を明らかにせよ。(Section 10.4.4, 10.4.5, 10.4.11) Warning が不正確にキャッシュされたリ、適切に更新されなかったりした。 (Section 13.1.2, 13.2.4, 13.5.2, 13.5.3, 14.9.3, 14.46) また Warning は一般ヘッダである必要があり、よって PUT や他のメソッドではリクエスト 中にそれが必要となるであろう。 転送コーディングは、特にチャンク形式エンコーディングで相互作用する時 に、重要な問題を持っていた。これは転送コーディングが内容コーディング のように完全なものとなる事で解決する。これには転送コーディング (内容 コーディングとは別に) や新しいヘッダフィールド (TE) が IANA レジスト リに登録され、将来的に trailer ヘッダが使用可能になる事が必要となる。 転送エンコーディングはパフォーマンス上に大きな利益があるので、修正す る価値はある [39]。TE はその他の、チャンク形式にエンコーディングされ た認証用のもの{authentication trailers} と HTTP/1.0 クライアントとの 間の相互作用によって起こったはっきりしない下方の相互運用上の問題を解 決する。(Section 3.6, 3.6.1, 14.39) この仕様書の前のバージョンでは PATCH, LINK, UNLINK 各メソッドが定義さ れていたが、これは一般には実装されていない。 RFC 2068 [33] 参照。 この仕様書の前のバージョンでは Alternates, Content-Version, Derived- From, Link, URI, Public, Content-Base 各ヘッダフィールドが定義されて いたが、これは一般には実装されていない。 RFC 2068 [33] 参照。 20 索引 索引についてはこの RFC の PostScript 版を見ていただきたい。 21. 完全なる著作権宣言 Copyright (C) The Internet Society (1999). All Rights Reserved. この文章とその翻訳は、複製し他人に配布する事ができ、またその実装につ いてのコメント、その他の方法を用いた説明、その補助となるような派生的 作業はそれらの中に上の著作権表示とこの段落を含む事によって、その全て 又は一部を、いかなる制約も受けずに、作成、複製、発表、及び配布する事 ができる。しかしながら、インターネット標準化プロセスにて定義されてい る著作権のための手続きに従わなければならないような場合の中でインター ネット標準を開発するという目的に必要である、あるいは英語以外の言語に 翻訳する必要があるという場合を除いて、この文章自体を、その著作権表示 や、インターネット学会あるいは他のインターネット団体への参照を削除す るような、いかなる変更もできない。 上で認めた制限された許諾は永続的なものであり、インターネット学会及び その継承者や譲渡者によって取り消される事は無い。 この文章とここに含まれた情報は、"そのまま {AS IS}" である事を基に提供 され、*インターネット学会、及び IETF は、この中の情報の使用が、商用利 用及び特定用途においていかなる権利もいかなる暗黙的保障も侵害していな いという保障への制限を含め、明示的に又は暗黙的に、全ての保障を放棄す る*。 謝辞 RFC Editer 機構の資金は、現在インターネット学会から提供されている。