この文書は、 R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee: Hypertext Transfer Protocol -- HTTP/1.1 (RFC 2616), June 1999. を 橋本英彦 が日本語訳した物です。 この文書の取り扱いについては、[Studying HTTP] の RFC 日本語訳を利用するにあたってに従って下さい。
Network Working Group Request for Comments: 2616 Obsoletes: 2068 Category: Standards Track
R. Fielding UC Irvine J. Gettys Compaq/W3C J. Mogul Compaq H. Frystyk W3C/MIT L. Masinter Xerox P. Leach Microsoft T. Berners-Lee W3C/MIT June 1999
この文書は、インターネットコミュニティにおけるインターネット標準化過程プロトコルを規定し、改良のために議論と提案を求めるものである。 このプロトコルの標準化状態と状況については、"Internet Official Protocol Standards" (STD 1) の最新版を参照していただきたい。 この文書の配布に制限は無い。
Copyright © The Internet Society (1999). All Rights Reserved.
ハイパーテキスト転送プロトコル (HTTP) は、分散・共同体ハイパーメディア情報システムのアプリケーションレベルプロトコルである。 このプロトコルは、リクエストメソッド、エラーコード、ヘッダ等の拡張を経て、ネームサーバや分散オブジェクト管理システム等、ハイパーテキストのために使う以上に多くの作業のために用いる事ができる、一般的でステートレスなプロトコルである [47]。 HTTP の特徴として、データ表現のタイプ付け、及びネゴシエーションがあり、これによって転送されるデータの独立性が確立されるようなシステムが構築できる。
HTTP は、World-Wide Web グローバル情報利用の先進として、1990 年から使われている。 この仕様書は、"HTTP/1.1" と呼ばれるプロトコルを定義し、RFC 2068 [33] を更新するものである。
ハイパーテキスト転送プロトコル (HTTP) は、分散・共同体ハイパーメディア情報システムのアプリケーションレベルプロトコルである。 HTTP は、World-Wide Web グローバル情報利用の先進として、1990 年から使われている。 HTTP の最初のバージョンは、HTTP/0.9 と呼ばれ、インターネットを通じて未加工のデータを転送するための単純なプロトコルであった。 HTTP/1.0 は、RFC 1945 [6] にて定義され、転送されるデータに関する外部情報とリクエスト/レスポンス意味論{semantics} の修飾子を含んだ MIME のようなメッセージ形式のメッセージを付加する事によってプロトコルを改良した。 しかし、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 は様々なアプリケーションから利用できるリソースへの基本的なハイパーメディアアクセスを可能にする。
この文書中における "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL" という各キーワードは、RFC 2119 [34]にて記述されるように解釈される。
もし、ある実装が、そのプロトコルの MUST あるいは REQUIRED レベルの要求の一つ以上を満足できないのならば、その実装は従順なものではない。 もし、ある実装がそのプロトコルのすべての MUST あるいは REQUIRED レベルと、すべての SHOULD レベルの要求を満足していれば、その実装は "無条件に従順" と呼ぶ。 そして、すべての MUST レベルの要求は満たしているが、一つでも SHOULD 要求を満たしていないものは "条件付きで従順" と呼ばれる。
この仕様書では、HTTP 通信に参加する人間、あるいは物を参照するための専門用語をいくつか使用する。
HTTP プロトコルはリクエスト/レスポンスプロトコルである。 クライアントは、サーバへの接続上で、リクエストメソッド、URI、そしてプロトコルバージョン、その後にリクエスト修飾子、クライアント情報、可能であれば内容本体を含んだ MIME のようなメッセージ形式をサーバにリクエストとして送る。 サーバは、メッセージのプロトコルバージョンと成功か失敗を表すコードを含むステータス行に続き、サーバ情報、エンティティメタ情報、可能であればエンティティボディの内容を含む MIME のようなメッセージで応答する。 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 参照)。
この文書において詳述されるメカニズムのすべては、単調 Backus-Naur Form (BNF) と、RFC 822 [9] で使用されているものに似た拡張 BNF との両方で記述されている。 実装者は、この仕様書を理解するためにこの表記法に精通している必要があるだろう。 拡張 BNF は以下の構造を含んでいる。
以下の規定は、基本的な構造概念を記述するためにこの仕様書全体に渡って使用される。 文字セットとしてコード化された US-ASCII は ANSI X3.4-1986 [21] にて定義されている。
OCTET = <8-bit のデータシーケンス> CHAR = <US-ASCII 文字 (0 - 127 オクテット)> UPALPHA = <US-ASCII 大文字 "A".."Z"> LOALPHA = <US-ASCII 小文字 "a".."z"> ALPHA = UPALPHA | LOALPHA DIGIT = <US-ASCII 数字 "0".."9"> CTL = <US-ASCII 制御文字 (0 - 31 オクテット) と DEL (127)> CR = <US-ASCII CR, キャリッジリターン (13)> LF = <US-ASCII LF, ラインフィード (10)> SP = <US-ASCII SP, スペース (32)> HT = <US-ASCII HT, 水平タブ (9)> <"> = <US-ASCII ダブルクォート記号 (34)>
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 = <CTL を除き、LWS を含むすべての OCTET>
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*<CTL や separators を除いたあらゆる CHAR> 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
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 のバージョン間の変換は、含まれるバージョンによって要求される、あるいは禁止されるヘッダフィールドの修正を含んでいてもよい。
URIとは、既に多くの名前で、例えば WWW address, Universal Document Identifier, Universal Resource Identifier [3], そして、最終的に Universal Resource Locator (URL) [4] と Name (URN) [20] という名で知られている。 HTTP に限って言えば、Uniform Resource Identifier とはリソースを名前や場所、その他の特徴で識別する簡潔に書式化された文字列の事である。
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 に頼る場合は注意を払うべきである。
"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 を受けとったならば、プロクシは絶対にホストネームを書き換えてはならない。
二つの URI が一致しているかどうかを決めるために比較する時、クライアントは URI 全体で大文字・小文字を区別したオクテット同士の比較をすべきであるが、以下は例外とする。
"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
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 的要求は、プロトコルストリーム内での使用にのみ適用される。 クライアントやサーバは、これらのフォーマットをユーザ提示やログイン要求などのために使用する必要はない。
ある HTTP ヘッダフィールドでは、メッセージが受信されてからの時間を、10 進数で表される整数の秒数値で、表す事が出来る。
delta-seconds = 1*DIGIT
HTTP では、"文字セット" という用語を MIME で表現される場合と同じ定義で使用する。
この文書中では "文字セット" という用語を、一つ以上のテーブルを使ってオクテットシーケンスを文字シーケンスに変換するための方法を述べるために使う。 与えられた文字セットですべての文字が利用できるわけではなかったり、文字セットがある特定の文字を表すために二つ以上のオクテットシーケンスを供給する場合でも、別の指示による無条件な変換が必要でないは事に注意せよ。 この定義は、US-ASCII のような簡単な単一テーブルマッピングから、ISO-2022 の技術を使うような複雑なテーブルをスイッチする 方法まで、さまざまな種類の文字エンコーディングを認めようとするものである。 しかし、MIME 文字セット名に関係付けられる定義は、1 オクテットから文字へと実行される写像{mapping} を完全に規定しなければならない。 特に、正確な写像を決定するために外部プロフィール情報を使用する事は許されない。
注: ここで使われる "文字セット" という用語は、より一般的には "文字エンコーディング" という語で述べられる。 しかし、HTTP と MIME とで同じ登録を共有しているので、用語もまた共有される事は重要な事である。
HTTP 文字セットは大文字・小文字を区別しないトークンによって識別される。 トークンの完全なセットは、IANA の文字セット登録機構 [19] によって定義される。
charset = token
HTTP では、文字セットの値として独自のトークンを使用する事を認めているが、IANA の文字セット登録機構 [19] によって定義済みであるトークンは、すべてその登録機構で定義された文字セットを表さなければならない。 アプリケーションは、使用する文字セットを IANA の登録機構によって定義されたものに制限すべきである。
HTTP アプリケーションの開発者は、IETF の文字セット要求を認識すべきである [38] [41]。
いくつかの HTTP/1.0 ソフトウェアは、"受信者が推測すべき" という意図で、文字セットの無い Content-Type ヘッダを不正確に解釈している。 この振る舞いをやめさせたい送信者は、例え文字セットが ISO-8859-1 の時でも文字セットパラメータを含む事ができるし、受信者が混乱する事が無いであろうという事がわかっていれば、それを含むべきである。
不幸な事に、いくつかの古い HTTP/1.0 クライアントでは、明示的文字コードパラメータを適切に扱えなかった。 HTTP/1.1 の受信者は、送信者によって供給される文字セットラベルを尊重しなければならない。 そして、文字コードを "推測" する機能を持つユーザエージェントは、もしその文字セットをサポートしていれば、始めに文書を表示する時に、受信者が好むものよりも content-type フィールドにある文字セットを使わなければならない。 section 3.7.1 参照。
内容コーディング値は、エンティティに適用されている、もしくは適用できるエンコーディング変換を示す。 内容コーディングは、文書をその根本的なメディアタイプのアイデンティティを失ったり、情報の欠落する事が無いように、圧縮したり、他の有用な変換が行われる事を許可するために、主に使用される。 しばしば、エンティティはコード化された形態で保存され、直接転送され、受け取り側によってのみデコードされる。
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 値トークンに対する登録を行なっている。 初めに登録されているものには、以下のトークンが含まれる:
新しい content-coding 値トークンは登録されるべきである。 すなわち、クライアントとサーバとの間での内部操作性を認めるため、新しい値を実装する必要のある内容コーディングアルゴリズムの仕様は、広く利用できて、独立した実装に適し、そしてこの章で定義された内容コーディングの目的に従うべきである。
転送コーディング値は、ネットワークを通して "安全な転送" を保証するために、エンティティボディに適用されている、する事のできる、する必要のあるエンコーディング変換を示すために使われる。 転送コーディングは、元のエンティティではなくメッセージの特性である、という点で内容コーディングとは異なる。
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 クライアントに転送エンコーディングを送ってはならない。
チャンク形式エンコーディングは、それぞれが自身のサイズ指標を持つ、一連のチャンクと、エンティティヘッダフィールドを含むオプショナルな 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 の中に含まれたヘッダフィールドを示すために使う事ができる (section 14.40 参照)。
レスポンスでチャンク形式転送コーディングを使うサーバは、以下のどれにも当てはまらなければ、ヘッダフィールドにおいて trailer を使ってはならない。
この要求は、HTTP/1.1 (もしくはそれ以降) のプロクシがメッセージを受信して、それを HTTP/1.0 の受信者に転送する時に、相互通信が失敗しないようにする。 これは、もしかしたらプロクシに無限のバッファを送る必要があるような規約を伴う承諾の場面を避ける。
Chunked-Body デコーディングのための例題過程は、付録の 19.4.6 で紹介されている。
すべての HTTP/1.1 アプリケーションは、"chunked" 転送コーディングを受信しデコードできなければならないし、理解できない転送コーディング拡張は無視しなければならない。
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] において概説されている。 登録されていないメディアタイプの使用は推奨されない。
インターネットメディアタイプは、公式の形式で登録される。 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 参照。
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 リクエストメソッド経由で処理するのに合ったフォームデータを転送するために特別に定義されている。
製品トークンは、ソフトウェアの名前とバージョンによってその製品である事を識別するアプリケーションと通信する事ができるようにするために使われる。 製品トークンで使用されるほとんどのフィールドは、アプリケーションの重要な部分を形成する部分製品{sub-product} を空白で区切るように列挙できるようになっている。 慣習では、製品はそのアプリケーションを識別するために重要なものの順に列挙される。
product = token ["/" product-version] product-version = token
例を見よ。
User-Agent: CERN-LineMode/2.15 libwww/2.17b3 Server: Apache/0.8.4
製品トークンは短く要点のみであるべきである。 宣伝や別の本質的でない情報のために使用してはならない。 製品バージョンにはあらゆるトークン文字を使用できるが、このトークンはバージョン識別子に対してのみ使われるべきである。 (例えば、同じ製品の連続したバージョンは、製品値の製品バージョン部分のみが異なるべきである)。
HTTP 内容ネゴシエーション (section 12) は、さまざまなネゴシエート可能なパラメータの相対な重要性 ("ウェイト") を示すために短い "浮動小数点" 数を使う。 ウェイトは、0 から 1 までの実数値と標準化され、0 は最小値で 1 は最大値である。 もしパラメータが 0 の品質値を持っていたら、そのパラメータと共にあるものはクライアントは「利用不可能」である。 HTTP/1.1 アプリケーションは、小数点以下で三桁を越える数字を生成してはならない。 これらの値のユーザ設定も、この様式にかぎられるべきである。
qvalue = ( "0" [ "." 0*3DIGIT ] ) | ( "1" [ "." 0*3("0") ] )
"品質値" とは、単に要請される特質の相対的な格付けを示すものなので、実際は誤った表現である。
言語タグは、他の人間との情報のコミュニケーションのため、人間によって話され、書かれ、あるいは別の方法で伝えられる自然言語を識別する。 コンピュータ言語は完全に除外される。HTTP では、Accept-Language や Content-Language 各フィールドにおいて言語タグを使用する。
HTTP 言語タグの構文や登録は、RFC 1766 [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 カントリーコードである。 (上記の後ろ三つのタグは登録されていないタグである; しかし、全て将来に登録されるかもしれないタグの例である。)
エンティティタグは、同一の要求リソースからの二つ以上のエンティティを比較するために使用される。 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" では、もしそれらがオクテット文字によって同等の場合にのみ、リソースの2つのエンティティが共有できる。
"W/" プレフィクスによって示される "weak entity tag" では、エンティティが等価であり、意味論においてそれぞれ重要な変更がなく互いを代わりに使う事が出来る場合のみ、リソースの2つのエンティティが共有できる。 weak エンティティタグは、弱い比較の時のみ使用される。
エンティティタグは、特有のリソースと関連付けられた全てのエンティティの全てのバージョンの中で一意{unique} でなければならない。 与えられたエンティティタグの値は、異なる URI へのリクエストから得られたエンティティのために使う事ができる。 異なる URI へのリクエストから得られたエンティティに同じエンティティタグの値を使っているからといって、それらのエンティティの同等性を暗に意味するものではない。
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 では、アプリケーションの実装がレンジについての知識に依存しないという事が認められる様に設計されている。
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 を前にも後ろにもつけてはならない。
一般ヘッダ (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-value を構成し、*TEXT あるいは token, separators, quoted-string を連結 したものから成る OCTET>
field-content は、LWS を前にも後ろにも、すなわち field-value の最初の空白以外の文字の前にも、あるいは field-value の最後の空白以外の文字の後ろにも、含まない。 そのような前後の LWS は、フィールド値の意味論を変える事無く削除されるであろう。 field-content の間のいかなる LWS もフィールド値に解釈されたり、下流{downstream} に転送される前に単なる SP に置き換えられるであろう。
異なるフィールド名を持つヘッダフィールドが受信される順序は、重要ではない。 しかしながら、最初に一般ヘッダフィールド、その後にリクエストヘッダやレスポンスヘッダ、そして最後にエンティティフィールドを送る事が "良い習慣" である。
同じフィールド名を持つ複数のメッセージヘッダフィールドは、そのヘッダフィールドの全体のフィールド値が [例えば、#(value) のように] コンマで区切られたリストとして定義される場合にのみ、メッセージに存在できる。 そしてそれら複数のヘッダフィールドは、最初の field-value に、コンマによって分けられたそれぞれの field-value を追加する事で、メッセージの意味論を変える事無しに、一つの "header-name: header-value" ペアに結合できなければならない。 それゆえ、同じフィールド名のヘッダフィールドが受信される順番は、連結されたフィールド値の中間処理のために重要なので、プロクシはメッセージを転送する時にはそれらのヘッダ値の順番を変えてはならない。
HTTP メッセージにメッセージボディがあったとしたら、それはリクエストやレスポンスに関連するエンティティボディを運ぶために使われる。 メッセージボディは、Transfer-Encoding ヘッダフィールド (section 14.41) によって示されるように、転送コーディングが適用された場合のみ、エンティティボディとは異なる。
message-body = entity-body | <Transfer-Encoding にてエンコードされた 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) レスポンスでは、すべてメッセージボディを含んではならない。 その他のレスポンスでは、その長さはゼロであるかもしれないが、すべてメッセージボディを含んでいる。
メッセージの転送長さ{transfer-length} は、それがメッセージの中に現れた時、つまりある転送コーディングが適用された後のメッセージボディの長さである。 メッセージボディがメッセージに含まれる時、そのボディの転送長さは以下のうちのどれかで決定される(優先順位順)。
multipart/byterange を理解しない HTTP/1.0 プロクシは、Range ヘッダを転送するだろう。 この場合、サーバはこの章で定義されているうちの 1, 3, 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 ユーザエージェントは、不正な長さが受信されたり検出された時には、それをユーザに通知しなければならない。
リクエストとレスポンスの両メッセージで、一般的な適用性を持つが、転送されたエンティティには適用されないヘッダがいくつかある。 これらのヘッダフィールドは、伝えられているメッセージに対してのみ適用する。
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
一般ヘッダフィールド名は、プロトコルバージョンの変化に伴う連動においてのみ確実に拡張されうる。 しかしながら、新しい、あるいは実験的なヘッダフィールドは、もしそのコミュニケーションでのすべてのパーティがそれらを一般ヘッダフィールドであると認識できるなら、一般的なヘッダフィールドの意味論を与えてもよい。 認識されないヘッダフィールドは、エンティティヘッダフィールドとして扱われる。
クライアントからサーバへのリクエストメッセージには、リソースに適用されるメソッド、リソースの識別子、使用するプロトコルのバージョンが最初の行に含まれる。
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
リクエストラインは、メソッドトークンに始まり、 Request-URI とプロトコルバージョンが後に続き、CRLF で終了する。 要素は SP によって分けられる。 最後の CRLF シーケンス以外には、CR も LF も許されない。
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
メソッドトークンは、 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 で記述されているものと同じ意味論で実装されなければならない。
Request-URI は、Uniform Resource Identifier (section 3.2) であり、リクエストを適用するリソースを識別する。
Request-URI = "*" | absoluteURI | abs_path | authority
Request-URI の 4 つのオプションは、そのリクエストの性質に依存する。 アスタリスク "*" は、そのリクエストが特定のリソースではなく、サーバ自身に適用するという事を意味し、使用されるメソッドがリソースに適用される必要がない時にのみ許される。 一例を挙げる。
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 を書き換える事が知られている、という事を認識すべきである。
インターネットリクエストにより識別された正確なリソースは、 Request-URI と Host ヘッダフィールドの両方で調べる事で決定される。
HTTP/1.1 リクエストによってリソースを決定する時、リクエストされたホストによってリソースが異なるという事を認めていないオリジンサーバは、Host ヘッダフィールド値を無視するであろう。(但し、HTTP/1.1 での Host をサポートする別の必要条件について section 19.6.1.1 参照。)
リクエストされたホストに基づいてリソースを区別する (しばしば仮想ホストや空虚{vanity} なホスト名として参照される) オリジンサーバは、HTTP/1.1 リクエストで要求されたリソースを決定するために以下の規定を使わなければならない。
Host ヘッダフィールドが無い HTTP/1.0 リクエストを受信した者は、要求されたリソースがどれほど正確な要求されているかを決定するため (例えば、特定のホストのユニークな何かに対する URI パスの試験のような) 発見方法を試す事ができる。
リクエストヘッダフィールドを用いて、クライアントはサーバにリクエストやクライアント自身に関する追加的な情報を渡す事ができる。 これらのフィールドは、メソッド発動{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
リクエストヘッダフィールド名は、プロトコルバージョンの変化に伴ってのみ確実に拡張されうる。 しかしながら、新しい、あるいは実験的なヘッダフィールドは、もしそのコミュニケーションでのすべてのパーティがそれらをリクエストヘッダフィールドであると認識できるなら、一般的なヘッダフィールドの意味論を与えてもよい。 認識されないヘッダフィールドは、エンティティヘッダフィールドとして扱われる。
リクエストメッセージを受信・解釈した後、サーバは 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
レスポンスメッセージの最初の行は、プロトコルのバージョン、ステータスコード番号、それに関連したテキストフレーズからなるステータスラインで、それぞれの要素は、SP によって分けられる。 最後の CRLF シーケンス以外には、CR も LF も許されない。
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
ステータスコード要素とは、リクエストを理解し満足するための試行についての三桁の数字による結果コードである。 これらのコードは、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 = *<CR, LF を含まない TEXT>
HTTP ステータスコードは拡張可能である。 HTTP アプリケーションは、登録されたすべてのステータスコードを明確に理解できる事が望ましいが、それらのすべての意味を理解する必要はない。 しかし、アプリケーションは最初の数字によって示されるステータスコードのクラスはすべて理解しなければならないし、理解できないレスポンスはキャッシュしてはならないという例外を除いて、すべての理解できないレスポンスをそのクラスの x00 ステータスコードと同等に扱わなければならない。 例えば、431 という理解できないステータスコードがクライアントに受信されたなら、そのリクエストに何か誤りがあると安全に推測ができ、それが 400 ステータスコードを受信したかのようにレスポンスを扱う事ができる。このような場合、エンティティはこの異常なステータスを説明しているであろう人間が読める情報を含んでいると思われるから、ユーザエージェントはレスポンスと共に返されたエンティティをユーザに見せるべきである。
レスポンスヘッダフィールドを用いて、サーバはステータスラインに置けないレスポンスに関する追加的な情報を渡す事ができる。 これらのヘッダフィールドは、サーバについてや、 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
レスポンスヘッダフィールド名は、プロトコルバージョンの変化に伴ってのみ確実に拡張されうる。 しかしながら、新しい、あるいは実験的なヘッダフィールドは、もしそのコミュニケーションでのすべてのパーティがそれらをレスポンスヘッダフィールドであると認識できるなら、一般的なヘッダフィールドの意味論を与えてもよい。 認識されないヘッダフィールドは、エンティティヘッダフィールドとして扱われる。
リクエストやレスポンスでのメッセージは、リクエストメソッドやレスポンスステータスコードによって規制されていなければ、エンティティを転送する事ができる。 エンティティは、エンティティヘッダフィールドとエンティティボディから成るが、エンティティヘッダのみを含むレスポンスもあ る。
この章においては、送信者と受信者の両方がクライアントかサーバのどちらかを表すが、それはエンティティを送信するか受信するかに依存する。
エンティティヘッダフィールドは、エンティティボディや、もしボディが無ければリクエストによって識別されたリソースについての外部情報を定義する。この外部情報は、オプションナルなものもあるが、この仕様書の中で要求しているものもある。
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
拡張ヘッダメカニズムは、プロトコルを変更する事無く追加的エンティティヘッダフィールドを定義できるようにしているが、これらのフィールドが受信者によって認識されるという事は仮定できない。 認識されないヘッダフィールドは、受信者によって無視されるべきであり、透過的プロクシによって転送されなければならない。
もし、HTTP リクエストやレスポンスと共にエンティティボディが送られてきたら、それはエンティティヘッダフィールドによって定義されるフォーマットをもってエンコーディングされている。
entity-body = *OCTET
エンティティボディは、section 4.3 に記されるように、メッセージボディがある時のみ、メッセージの中に存在する。 エンティティボディは、メッセージの安全かつ適切な転送を保証するために適用されるであろうあらゆる転送エンコーディングをデコードする事によってメッセージボディから得られる。
エンティティボディがメッセージに含まれる時、このボディのデータタイプは 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" として扱うべきである。
メッセージのエンティティボディ長は、あらゆる転送エンコーディングが適用される前のメッセージボディの長さである。 section 4.4 では、どのようにメッセージボディの転送長さが決められているかを定義している。
持続的接続が無い時代には、別々の URL からリソースを取得するために、それぞれで TCP 接続を確立していたため、サーバのロードを増加させ、インターネットの混雑を引き起こす原因になっていた。 インラインイメージやその他の関連するデータの使用のために、クライアントはしばしば短時間に同じサーバへ複数のリクエストを行う必要がある。 これらのパフォーマンスの問題の解析や持続的接続のプロトタイプの実装から得られた結果については、現在入手可能である [26] [30]。 持続的接続を実装する過程で得た経験や、実際に HTTP/1.1 (RFC 2068) を実装したものを測定した所、良い結果が得られた [39]。 また一方で、例えば T/TCP [27] のような、違う選択肢も研究されてきている。
持続的 HTTP 接続には、いくつかの利点がある。
HTTP 実装は持続的接続を実装すべきである。
HTTP/1.1 と HTTP のそれ以前のバージョンとの重要な違いは、すべての HTTP 接続において持続的な接続が既定の動作であるかどうかという事である。 すなわち、何か別の方法が示されない限り、クライアントは、例えサーバからエラーレスポンスが返されても、サーバが持続的接続を維持するであろうと仮定すべきである。
持続的接続は、クライアントとサーバが TCP 接続を閉じる時に合図を行えるというメカニズムを提供する。 この合図は、Connection ヘッダフィールド (section 14.10) を用いて示す。 一度接続を閉じる事が示されたら、クライアントはその接続でそれ以上のリクエストを送ってはならない。
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 で定義されているように、自身で定義した (例えばそれが接続の切断によって定義されるようなものではない) メッセージ長さを持たなければならない。
持続的接続をサポートするクライアントは、そのリクエストを "パイプライン" する事ができる (例えば、複数のレスポンスを待つ事無く、複数のリクエストを送る)。 サーバは、リクエストが受信されたのと同じ順番で、それらのリクエストのレスポンスを返さなければならない。
持続的接続を想定し、接続確立の後にすぐパイプラインを行うクライアントは、もし最初のパイプライン化への試行が失敗した場合は、それらの接続を再試行する準備をすべきである。 クライアントがそのような再試行を行う場合は、その接続が持続的であると分かるまではパイプラインを行ってはならない。 もし、サーバがすべての通信のレスポンスを返す前に接続を閉じてしまったら、クライアントはそれらのリクエストを再送信する準備をしなければならない。
クライアントは、冪等でない{non-idempotent} メソッド、あるいはメソッドのシーケンスを使ったリクエストをパイプラインすべきではない (section 9.1.2 参照)。 そうでなければ、転送接続の早期異常終了が不確定な結果を招く事になるだろう。 冪等でない{non-idempotent} リクエストを送ろうとするクライアントは、前のリクエストのレスポンスステータスを受け取るまでリクエストを送る事を待つべきである。
プロクシが section 14.10 で指定されるように Connection ヘッダの機能を 正確に実装する事は特に重要である。
プロクシサーバは、自身が接続しているクライアントとオリジンサーバ (あるいは別のプロクシサーバ) のそれぞれに持続的接続を知らせなければならない。 それぞれの持続的接続は、一つの転送リンクのみで適用される。
プロクシサーバは、HTTP/1.0 クライアントと HTTP/1.1 の持続的接続を確立してはならない (但し、多くの HTTP/1.0 クライアントに実装されている Keep-Alive ヘッダを使った問題の情報と議論については RFC 2068 [33] 参照)。
多くのサーバは、もはや接続を維持しないとするタイムアウト値を持っているであろう。 クライアントはたぶん同じサーバへとより多くの接続を持とうとするはずなので、プロクシサーバはサーバが設定するタイムアウト値よりも大きな値にしたほうがよい。 持続的接続の使用は、クライアントやサーバのためのこのタイムアウト値の長さ (あるいは存在) に必要性を置かない。
クライアントやサーバがタイムアウトを望む時は、転送接続上礼儀正しい切断を発行すべきである。 クライアントもサーバも、他方の転送の切断を絶えず監視し、適切にそれに応じるべきである。 もし、クライアントやサーバが、相手側の切断を即座に検出しなければ、それはネットワーク上の不必要なリソース消耗を引き起こすかもしれない。
クライアント、サーバ、あるいはプロクシは、どんな時でも転送接続を切断する事ができる。 例えば、サーバが "アイドル" 状態の接続を切断しようと決めたのと同時に、クライアントは新しいリクエストを送り始めるかもしれない。 サーバ側から見れば接続はアイドルである間に切断されているが、クライアント側から見ればリクエストは進行中である。
これは、クライアント、サーバ、プロクシが、非同期の切断状態{event} から回復できなければならないという事を意味する。 クライアントソフトウェアは転送接続を再度オープンし、リクエストシーケンスが冪等{idempotent} (section 9.1.2 参照) である限り、ユーザインタラクションなしに中止されたリクエストのシーケンスを再送信すべきである。 そうでないメソッドやシーケンスは自動的に再試行してはならないが、ユーザエージェントは人間のオペレータにリクエストの再試行についての選択を尋ねてもよい。 アプリケーションが意味を理解した上で、ユーザ自身の確認の代わりにユーザエージェントソフトウェアが確認してもよい。 この自動再試行は、もし二回目のリクエストシーケンスが失敗したなら繰り返すべきではない。
サーバは、もし完全に可能なら、常に一つの接続につき少なくとも一つのリクエストにレスポンスすべきである。 サーバは、ネットワークやクライアントの失敗を疑う場合以外は、レスポンスの転送中に接続を切断すべきではない。
持続的接続を使用するクライアントは、サーバへ維持する同時接続の数を制限すべきである。 シングルユーザクライアントは、どんなサーバやプロクシへも 2 接続より多く維持すべきではない。 プロクシは、N は同時のアクティブユーザの数として、別のサーバやプロクシへの接続使用数を多くても 2*N までとすべきである。 これらのガイドラインは HTTP レスポンスタイムを改善し、ネットワークの混雑を避けようとするものである。
HTTP/1.1 サーバは、一時的な過負荷を解消するためには、持続的接続を維持し、TCP フローコントロールメカニズムを使うべきであり、クライアントが再試行するであろうという期待を持って接続を終了させるよりもよい。 後者の方法ではネットワークの混雑はよりひどくなるであろう。
メッセージボディを送る HTTP/1.1 (あるいはそれ以降) のクライアントは、リクエストを送っている間、エラーステータスのためにネットワークの接続をモニタリングすべきである。 エラーステータスを発見した場合、すぐにボディの転送を止めるべきである。 もしボディに "chunked" エンコーディング (section 3.6) を施していたら、早過ぎるメッセージの終わりを表すために 0 サイズのチャンクと空の trailer を使う事ができる。 もしボディより Content-Length ヘッダが先に送られていたら、クライアントは接続を閉じなければならない。
100 (Continue) ステータス (section 10.1.1 参照) は、オリジンサーバがクライアントがリクエストボディを送る前に (リクエストヘッダに基づいた) リクエストを受け入れようとする場合に、リクエストボディを伴ったリクエストメッセージを送る事をクライアントに決めさせるという目的を持つ。 いくつかのケースでは、サーバがボディを見る事も無くメッセージを受けつけていない場合にクライアントがボディを送る事は、不適切でひどく効率が悪くなる事がある。
HTTP/1.1 クライアントの必要条件は、以下の通りである。
未だに古い実装が存在するため、プロトコルではクライアントが 417 (Expectation Failed) ステータスや 100 (Continue) ステータスを受け取る前に、"Expect: 100-continue" を送ってしまうかもしれないようなあいまいな場面を認めている。 それ故に、クライアントが 100 (Continue) ステータスを見た事が無いようなオリジンサーバ (あるいは経由するプロクシ) にこれを送るような時でも、リクエストボディを送る前に無期限で待つような事はすべきではない。
HTTP/1.1 オリジンサーバの必要条件は、以下の通りである。
HTTP/1.1 プロクシの必要条件は、以下の通りである。
もし、HTTP/1.1 クライアントがリクエストボディを持つが、"100-continue" という expectation を持つ Expect リクエストヘッダフィールドを含んでいないリクエストメッセージを送り、しかもクライアントは HTTP/1.1 オリジンサーバには直接接続はしておらず、そこでクライアントがサーバからのどんなステータスをも受け取る前に接続の切断を知った場合は、クライアントはリクエストを再試行すべきである。 クライアントがこのリクエストを再試行する時は、確実なレスポンスの獲得を保証させるため、以下の "binary exponential backoff" アルゴリズムを使用できる。
上のどの時点でも、エラーステータスを受けとったら、クライアントは
HTTP/1.1 のための一般的なメソッドのセットは以下に定義される。 このセットは拡張可能であるが、追加されるメソッドは別々に拡張されたクライアントとサーバに対して同じ意味論を共有する事を仮定できない。
Host リクエストヘッダフィールド(section 14.23) は、すべての HTTP/1.1 リクエストに付加されなければならない。
実装者は、インターネット上における相互動作においてはソフトウェアがユーザを表しているという事を認識すべきであり、ユーザがそれら自身や他のものに対して予測しない意図を持つようなあらゆる動作に気がつく事ができるように注意すべきである。
特に、GET と HEAD メソッドはその動作にリソースの回収以上の意味を持つべきではないという慣習が確立されている。 これらのメソッドは、"安全{safe}" だと考えるべきである。 これによって、ユーザエージェントがそれ以外の、例えば POST, PUT, DELETE のようなメソッドを特別な方法で表す事ができるようになり、ユーザにひょっとしたら安全でない動作が要求されているかもしれないという事実を認識させる。
本質的に、サーバが GET リクエストを実行した結果として副作用を起こさないという事を保証するのは不可能であり、事実、いくつかの動的なリソースはそれが特徴であると考えている。 ここで特に区別すべきなのは、ユーザが副作用を要求しなかったという事であり、それゆえにそれらに対しては責任をもてない。
メソッドは、(エラーや期限切れ発行とは別に) 同一のリクエストの N > 0 の副作用が単一のリクエストにおけるものと同じであるような際には "冪等{idempotence}" の性質を持つ事もできる。 GET, HEAD, PUT, DELETE 各メソッドはこの性質を共有する。 また、OPTIONS と TRACE 各メソッドは副作用を持つべきではないし、本来冪等であるものである。
しかしながら、たとえその順序にて実行される全てのメソッドが冪等であったとしても、いくつかのリクエストの順番は冪等ではない。 (もし全体の順序中のある一つを実行しても、その順序の全体、または一部分を再実行した際に結果は常に変わらないという事になるのであれば、順序は冪等である。) 例えば、同じ順序でもその結果が後に修正される値に依存するのであれば、順序は冪等ではない。
副作用を持たない順序は、(同時に起こる動作は同じリソースの一組{set} 上に実行されている事は無い、との条件で) 定義によって冪等である。
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" という field-value を持つ Content-Length フィールドを含まなければならない。
Max-Forwards リクエストヘッダフィールドは、リクエスト連鎖中で特定のプロクシを目標に使われるであろう。 プロクシは、転送が許可されたリクエストのための absoluteURI と共に OPTIONS リクエストを受けとった時には、Max-Forwards フィールドをチェックしなければならない。 もし、Max-Forwards フィールドの値がゼロ ("0") ならば、プロクシはそのメッセージを転送してはならない。 その代わりに、プロクシ自身のコミュニケーションオプションを返すべきである。 もし、Max-Forwards フィールドの値がゼロより大きな整数値ならば、プロクシはリクエストを転送する際にその値を一つ減らさなければならない。 リクエストの中に Max-Forwards フィールドが存在していなければ、転送するリクエストに Max-Forwards フィールドを含めてはならない。
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 を見よ。
HEAD メソッドは、サーバがレスポンスにおいてメッセージボディを返してはならない事を除けば GET と同一である。 HEAD リクエストへのレスポンスにおける HTTP ヘッダに含まれる外部情報は、GET リクエストへのレスポンスで送られる情報と同一であるべきである。 このメソッドは、エンティティボディ自身を転送する事なしにリクエストによって意味されるエンティティに付いての外部情報を得るために使用される。 このメソッドは、ハイパーテキストリンクの正当性、アクセス可能性、最近の修正のテストのために、しばしば使用される。
HEAD リクエストへのレスポンスは、そのレスポンスに含まれる情報はリソースから前もってキャッシュされたエンティティを更新するために使う事ができる、という意味でキャッシュ可能であるかもしれない。 もし、新しいフィールド値がキャッシュされたエンティティは (Content-Length, Content-MD5, ETag, Last-Modified 各値の変更によって示されるように) 現在のエンティティと違うという事を示すならば、キャッシュはそのキャッシュエンティティを新鮮でないものとして扱わなければならない。
POST メソッドは、サーバがリクエストライン内の Request-URI により識別されるリソースへの新しい従属{subordinate} として、リクエストに同封されるエンティティを受け入れる事を要求するために使用される。 POST は以下の機能のカバーするための画一的メソッドとして設計されている。
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 参照。
PUT メソッドは、同封されたエンティティを供給される Request-URI の元に保存するように要求する。 Request-URI が既に存在するリソースを参照している場合は、同封されるエンティティはオリジンサーバにあるそれの修正版とみなされるべきである。 Request-URI が既存のリソースを指していない場合に、その URI がリクエストしているユーザエージェントによって新しいリソースとして定義する事ができる時は、オリジンサーバはその URI にリソースを作成できる。 新しいリソースが作成された場合、オリジンサーバは 201 (Created) レスポンスをもってユーザエージェントに知らせなければならない。 既存のリソースが更新された場合は、リクエストが成功し終了した事を示すために 200 (OK) か 204 (No Content) のいずれかのレスポンスコードを送るべきである。 もし、リソースがそのリクエスト 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 によって作成、あるいは修正されたリソースに適用されるべきである。
DELETE メソッドは、オリジンサーバが Request-URI により識別されるリソースを削除する事を要求する。 このメソッドは、オリジンサーバにおいて人間の手 (あるいは別の方法) によって上書きされているかもしれない。 例えオリジンサーバから返されたステータスコードは動作がうまく完了したという事を示していたとしても、クライアントはその操作が実行された事は保証されない。 しかしそのレスポンスが与えられた場合に、サーバがそのリソースを削除したり、アクセスできない場所へ移動したりしようとしていないのであれば、成功を示すべきではない。
成功したレスポンスは、もしレスポンスがステータスで表しているエンティティを含んでいるなら 200 (OK)、もし動作がまだ行われていないなら 202 (Accepted)、もし動作は行われたが、レスポンスにエンティティを含んでいないなら 204 (No Content) であるべきである。
もし、リクエストがキャッシュを通り抜けたり、 Request-URI が現在キャッシュされている一つ以上のエンティティとして識別されるなら、これらのエンティティは新鮮でないものとして扱われるべきである。 このメソッドのレスポンスはキャッシュできない。
TRACE メソッドは、リクエストメッセージのアプリケーション層のループバックを遠隔的に発動するために使用される。 リクエストの最後の受信者は、200 (OK) レスポンスのエンティティボディとして、そのメッセージをクライアントにそのまま送り返すべきである。 最後の受信者とは、オリジンサーバ、もしくはリクエストで Max-Forwards (section 14.31) 値がゼロ (0) であったものを受け取った最初のプロクシかゲートウェイである。 TRACE リクエストはエンティティを含んではならない。
TRACE を使って、クライアントはリクエスト連鎖の反対側では何が受け取られているのかを見る事や、テストや診断情報のためのデータを使用する事ができる。 これはリクエスト連鎖のトレースとして動作するので、Via ヘッダフィールド (section 14.45) の値が特に重要である。 Max-Forwards ヘッダフィールドを使用する事で、クライアントにリクエスト連鎖の大きさに制限を与える事ができ、これは無限ループ上でメッセージを転送するプロクシ連鎖をテストするために有用である。
もしリクエストが妥当ならば、レスポンスは "message/http" という Content-Type と一緒に、エンティティボディとしてリクエストメッセージの全体を含むべきである。 このメソッドのレスポンスはキャッシュされてはならない。
この仕様書では、(例えば SSL トンネリング [44] 等の) トンネルとなるように動的に切り換える事ができるプロクシが使用する時のために CONNECT というメソッド名を予約する。
各々のステータスコードについて、レスポンス時に後に従える事の出来るメソッドと必要とされるすべての外部情報の記述と共に、以下に記述する。
このステータスコードのクラスは一時的なレスポンスを示し、ステータスラインとオプション的なヘッダからのみなり、空行で終了する。 このステータスコードのクラスのための必要なリクエストヘッダは無い。 HTTP/1.0 では、どんな 1xx ステータスコードも定義していないので、サーバは実験的な状況下以外では HTTP/1.0 クライアントに 1xx レスポンスを送ってはならない。
クライアントは、例え 100 (Continue) ステータスメッセージを期待していなかったとしても、通常のレスポンスの前の一つ以上の 1xx レスポンスを受け入れるよう準備されていなければならない。 ユーザエージェントは、期待していない 1xx レスポンスを無視する事ができる。
プロクシは、もしプロクシとクライアント間の接続が切断されている、あるいはプロクシ自身が 1xx レスポンスの生成を要求したという場合以外は、1xx レスポンスを転送しなければならない。 (例えば、プロクシがリクエストを転送する時に "Expect: 100-continue" というフィールドを付け加えた時には、それに相当する 100 (Continue) レスポンスを転送する必要はない。)
クライアントは、そのリクエストを続けるべきである。 この暫定的レスポンスは、リクエストの始めの部分は受け取られ、サーバによって拒否されたものではないという事をクライアントに知らせるために使用される。 クライアントは、リクエストの残りを送り続けるか、もし既にリクエストが完了していれば、このレスポンスを無視すべきである。 サーバは、リクエストが完了した後に最終的なレスポンスを送らなければならない。 このステータスコードの使用・処理の詳細な議論のために section 8.2.3 参照。
サーバはクライアントのリクエストを理解し、Upgrade メッセージヘッダフィールド (section 14.42) を使って、この接続で使用されているアプリケーションプロトコルを変更する事でこのリクエストに従おうとしている。 サーバは 101 レスポンスを終了する空行のあと、直ちにレスポンスの Upgrade ヘッダフィールドによって定義されたプロトコルに変更するだろう。
プロトコルは、変更した方が有益な場合にのみ変更されるべきである。 例えば、HTTP のより新しいバージョンに変更するという事は、古いバージョン以上に有益だし、リアルタイムに、同期するプロトコルを変更する事はそのような機能を使うリソースを配布するときに都合が良いだろう。
このステータスコードのクラスは、クライアントのリクエストがうまく受信され、理解され、そして受け入れられた事を示す。
リクエストは成功した。 レスポンスと共に返される情報はリクエストに使用されたメソッドに依存し、例えば以下の様になる。
リクエストは果たされ、結果として新しいリソースが作成された。 新しく作成されたリソースは Location ヘッダにより与えられるリソースに対する最も明確な URI を伴って、レスポンスのエンティティにおいて返される URI によって参照される。 レスポンスは、ユーザあるいはユーザエージェントが最も適切なものを選択するために、リソースの特徴と場所のリストをエンティティとして含むべきである。 エンティティのフォーマットは、Content-Type ヘッダフィールドにて与えられるメディアタイプによって指定される。 オリジンサーバは、201 ステータスコードを返す前にリソースを作成しなければならない。 もし動作がすぐに実行できないのであれば、サーバは代わりに 202 (Accepted) レスポンスを返すべきである。
201 レスポンスは、作成されたばかりのリクエストされたバリアントのために、現在のエンティティタグの値を示す ETag レスポンスヘッダフィールドを含む事ができる。 section 14.19 参照。
リクエストは処理のために受け入れられたが、処理は完了されていない。 このリクエストは、実際に処理される時に拒否されるかもしれないので、最終的に動作されるかどうかは不明である。 このような非同期操作からステータスコードを再送信するための機能は存在しない。
202 レスポンスは、意図的に責任を持たない{non-committal}。 これはサーバが、プロセスが完了されるまでユーザエージェントとの接続を持続させる事無く、他のいくつかのプロセス (多分一日に一度しか実行されないバッチ指向プロセス{batch-oriented process}) のためのリクエストを受け入れる事を可能にするという目的を持つ。 このレスポンスによって返されるエンティティは、リクエストの現在の状態を表すものと、状態モニタへのポインタ、あるいはそのリクエストがいつ果たされるかをユーザが予期できる見積もりのどちらかを含むべきである。
エンティティヘッダにおいて返された外部情報は、オリジンサーバから利用できるような決定的なセットではなく、ローカルもしくはサードパーティコピーから集められたものである。 提示されたセットは元のバージョンのサブセットかスーパーセットであろう。 例えば、リソースについてのローカルな注釈情報を含む事はオリジンサーバによって知らされる外部情報のスーパーセットとなるかもしれない。 そのレスポンスが 200 (OK) とは別の方法で示したい場合、このレスポンスコードを使用する必要はないが、そのような場合にのみ適切である。
サーバはリクエストを受け入れたが、エンティティボディを送り返す必要は無く、更新された外部情報を返す事を望むだろう。 レスポンスは、エンティティヘッダ形式の中に、新規あるいは更新された外部情報を含む事ができ、もしあればリクエストされたバリアントが関連付けられるべきである。
もしクライアントがユーザエージェントなら、リクエストの送信をもたらした状態からその文書画面{view} を変えるべきではない。 このレスポンスは主に、ユーザエージェントの現在の{active} 文書画面ビューを変える事無く、動作を起こすための入力をさせる意図を持つが、どんな新規あるいは更新された外部情報もユーザエージェントの現在の画面中にある現在の文書に適用されるべきである。
204 レスポンスは メッセージボディを含んではならない ので、常にヘッダフィールドの後の最初の空行で終了する。
サーバはリクエストを受け入れたので、ユーザエージェントは送信されたリクエストをもたらした現在の画面をリセットすべきである。 このレスポンスは主に、ユーザが別の入力動作を簡単に始められるように、入力が与えられたフォームをクリアして、ユーザの入力経由で動作を起こすための入力をさせる意図を持つ。 レスポンスはエンティティを含んではならない。
サーバはリソースに対する部分的 GET リクエストを受け入れた。 リクエストは、望む範囲を示すための Range ヘッダフィールド (section 14.35) を含めなければならないし、またリクエストを条件付きにしたいければ If-Range ヘッダフィールド (section 14.27) を含んだ方がよい。
レスポンスは、以下のヘッダフィールドを含めなければならない。
もし 206 レスポンスが、強いキャッシュバリディタ (section 13.3.3 参照) を使った If-Range リクエストの結果ならば、レスポンスは他のエンティティヘッダを含めるべきではない。 もし、レスポンスが弱いバリディタを使った If-Range リクエストの結果がとしたら、レスポンスは他のエンティティヘッダを含めてはならない。 これはキャッシュされたエンティティボディと更新されたエンティティヘッダとの不一致を避ける為である。 そうで無ければ、レスポンスは同じリクエストに対して 200 (OK) レスポンスと共に返されたであろうすべてのエンティティヘッダを含めなければならない。
もし ETag か Last-Modified ヘッダが正確に一致しなければ、キャッシュは他の以前キャッシュされた要素と 206 レスポンスとを結びつけてはならない。 section 13.5.4 参照。
Range や Content-Range ヘッダをサポートしていないキャッシュは、206 (Partial) レスポンスをキャッシュしてはならない。
このステータスコードのクラスは、リクエストを果たすためにはユーザエージェントによって更なる動作が行われる必要がある事を示す。 二番目のリクエストで使われたメソッドが GET か HEAD である場合にのみ、ユーザとの相互動作無しに、ユーザエージェントによって要求された動作を実行する事ができる。 リダイレクションループによって各々のリダイレクションはネットワーク渋滞を生み出す事になるので、クライアントは無限リダイレクションループを発見すべきである。
注: この仕様書の前のバージョンでは、5 回のリダイレクションを最大として推奨している。 内容開発者{Content developers} は、そのような修正された制限を実装したクライアントがあるであろう事を意識すべきである。
リクエストされたリソースは、表現セットの一つに対応し、各々が特有の場所にあり、エージェント駆動型ネゴシエーション情報 (section 12) が、ユーザ (あるいはユーザエージェント) が望む表現を選択でき、その位置にリクエストをリダイレクトできるように供給されている。
もし HEAD リクエストでなければ、レスポンスはエンティティにユーザかユーザエージェントが最も適切なものを選択するためのリソースの特徴と場所のリストを含むべきである。 エンティティのフォーマットは、Content-Type ヘッダフィールドにて与えられるメディアタイプによって指定される。 データフォーマットやユーザエージェントの能力に依存する事なので、最も適切な選択は自動的に行われるかもしれない。 しかし、この仕様書ではそのような自動選択に対してどのような標準も定義しない。
サーバが選択された表現を持っているのであれば、Location フィールド内にその表現のための具体的な URI を含むべきである。 ユーザエージェントは、自動リダイレクションのためにその Location フィールドの値を使う事ができる。 このレスポンスは、別のものを示しているのでなければキャッシュ可能である。
リクエストされたリソースは新しい恒久的な URI に割り当てられたので、以降そのリソースへの参照は返された URI の一つを使用すべきである。 リンク編集機能を持つクライアントは、可能であればサーバにより返された新しい参照の一つ以上の Request-URI を参照するように自動的に再リンクすべきである。 このレスポンスは、別のものを示しているのでなければキャッシュ可能である。
新しい恒久的 URI は、レスポンス内の Location フィールドによって与えられるべきである。 リクエストメソッドが HEAD でなければ、レスポンスのエンティティは新しい URI へのハイパーリンクを持った短いハイパーテキス トの注釈を含むべきである。
もし 301 ステータスコードが GET や HEAD 以外のリクエストのレスポンスとして受信されたら、リクエストが発行された時点の条件から変わっているかもしれないため、ユーザエージェントはユーザに確認せずに、リクエストを自動的にリダイレクトしてはならない。
注: 301 ステータスコードを受信した後 POST リクエストを自動的にリダイレクトする時、既存の HTTP/1.0 ユーザエージェントの中には誤ってそれを GET リクエストに変えるものがある。
リクエストされたリソースは、一時的に別の URI に属している。このリダイレクションは場合によって変更されるかもしれないので、クライアントは将来のリクエストではその Request-URI を使い続けるべきである。 このレスポンスは Cache-Control か Expires のどちらかのヘッダフィールドによって期限が示されている場合にのみキャッシュ可能である。
一時的 URI は、レスポンス内の Location フィールドによって与えられるべきである。 リクエストメソッドが HEAD でなければ、レスポンスのエンティティは新しい URI へのハイパーリンクを持った短いハイパーテキストの注釈を含むべきである。
もし 302 ステータスコードが GET や HEAD 以外のリクエストのレスポンスとして受信されたら、リクエストが発行された時点の条件から変わっているかもしれないため、ユーザエージェントはユーザに確認されなければ、リクエストを自動的にリダイレクトしてはならない。
注: RFC 1945 や RFC 2068 では、クライアントはリダイレクトするリクエストのメソッドを変えてはならないと明確に述べられている。 しかしながら、多くの既存ユーザエージェントは 302 レスポンスをまるで 303 レスポンスのようにみなし、元々のリクエストメソッドにかかわらず Location フィールド値へと GET を行う。 ステータスコード 303 と 307 は、クライアントが期待する反応の種類を明確にしたいというサーバのために加えられた。
リクエストに対するレスポンスは別の URI の元から発見でき、このリソースを GET メソッドを使用して回収すべきである。 このメソッドは、主に POST によって活性化される {POST-activated} スクリプトの出力が選択されたリソースへユーザエージェントをリダイレクトできるようにするために存在する。 新しい URI は元々リクエストされたリソースに対する代わりの参照ではない。 303 レスポンスはキャッシュ可能してはならない が、二番目の (リダイレクトされた) リクエストへのレスポンスはキャッシュ可能である。
異なる URI は、レスポンス内の Location フィールドによって与えられるべきである。 リクエストメソッドが HEAD でなければ、レスポンスのエンティティは新しい URI へのハイパーリンクを持った短いハイパーテキストの注釈を含むべきである。
注: 多くの HTTP/1.1 以前のユーザエージェントは 303 ステータスを理解できない。 そのようなクライアントと相互通信する時、ほとんどのユーザエージェントは 302 レスポンスを 303 レスポンスのように扱うので、302 レスポンスコードが代わりに使われるであろう。
クライアントが条件付き GET リクエストを実行し、アクセスは許可されたがその文書は更新されていなかった場合、サーバはこのステータスコードもって応答すべきである。 304 レスポンスはレスポンスボディを含んではならないので、いつもヘッダフィールドの後の最初の空行で終了する。
レスポンスは以下のヘッダフィールドを含まなければならない。
時計の無いオリジンサーバがこの規定に従っている場合、プロクシやクラ イアントは ([RFC 2068] の section 14.19 にて既に記されているように) 受信した Date ヘッダを持たないいかなるレスポンスにも自身の Date を付 け加える事で、キャッシュは正常に作動するであろう。
条件付き GET に、強いキャッシュバリディタ (section 13.3.3 参照) を使う場合、レスポンスは他のエンティティヘッダを含めるべきではない。 そうでない (例えば条件付き GET が弱いバリディタを使う) 場合、レスポンスは他のエンティティヘッダを含めてはならない。 これは、キャッシュされたエンティティボディと更新されたエンティティヘッダとの不一致を避ける為である。
304 レスポンスが現在キャッシュされていないエンティティを示すならば、キャッシュはレスポンスを無視し、条件なしのリクエストを反復しなければならない。
キャッシュが受信された 304 レスポンスをキャッシュエントリを更新するために使用する場合、キャッシュはレスポンスで与えられたあらゆる新しいフィールド値をも反映させるため、エントリを更新しなければならない。
リクエストされたリソースは Location フィールドによって与えられるプロクシを通してアクセスされなければならない。 Location フィールドはプロクシの URI を与える。 受信側はプロクシ経由で単一のリクエストを再送信する事を期待する。 305 レスポンスはオリジンサーバによってのみ生成されなければならない。
注: RFC 2068 では、305 は単一リクエストをリダイレクトさせようとする事、またオリジンサーバによってのみ生成される事は明確にしていない。 これらの制限がセキュリティの上で重要な意味を持つという事を認識していなかったためである。
306 ステータスコードは前のバージョンの仕様書では使われていたが、もはや使われておらず、将来のために予約されている。
リクエストされたリソースは、一時的に別の URI に属している。 このリダイレクションは場合によって変更する事ができるので、クライアントは将来のリクエストではその Request-URI を使い続けるべきである。 このレスポンスは Cache-Control か Expires のヘッダフィールドによって期限が示される場合にのみキャッシュ可能である。
一時的 URI は、レスポンス内の Location フィールドによって与えられるべきである。 多くの HTTP/1.1 以前のユーザエージェントは 307 ステータスを理解できないので、リクエストメソッドが HEAD でなければ、レスポンスのエンティティは新しい URI へのハイパーリンクを持った短いハイパーテキストの注釈を含むべきである。 それ故に、その注釈にはユーザが新しい URI に元々のリクエストを繰り返すために必要な情報を含むべきである。
もし 307 ステータスコードが GET や HEAD 以外のリクエストのレスポンスとして受信されたら、リクエストが発行された時点の条件から変わっているかもしれないため、ユーザエージェントはユーザに確認されなければ、リクエストを自動的にリダイレクトしてはならない。
ステータスコードの 4xx クラスは、クライアントが間違えているような場合を示す。 HEAD リクエストへのレスポンスを除き、サーバはエラー状況が一時的か恒久的かに拘わらず、エラー状況の説明を含むエンティティを返すべきである。 これらのステータスコードは、あらゆるリクエストメソッドに適用されうる。 ユーザエージェントは、含まれるエンティティすべてをユーザに表示すべきである。
もしクライアントがデータを送信している最中ならば、TCP を使用しているサーバ実装は、サーバが入力接続を切断する前に、レスポンスを含んでいるパケットの受領をクライアントが認識できる事を保証するために気を配るべきである。 もし切断後にもクライアントがサーバにデータを送信し続けていたら、サーバの TCP スタックはクライアントにリセットパケットを送り、これによって、HTTP アプリケーションがリクエストを読み出して中間処理する前に、クライアントの認識されない入力バッファを消去するだろう。
リクエストは、不正な構文のためサーバに理解されなかった。 クライアントは、修正しないままでそのリクエストを再送信すべきではない。
リクエストはユーザ認証を必要とする。レスポンスは、リクエストされたリソースに適用できる challenge を含む WWW-Authenticate ヘッダフィールド (section 14.47) を含まなければならない。 クライアントは、適切な Authorization ヘッダフィールド (section 14.8) を伴うリクエストを繰り返す事ができる。 もしリクエストがすでに Authorization credentials を含んでいるのであれば、この 401 レスポンスは認証がそれらの credentials に対して拒否された事を示す。 もし 401 レスポンスが前のレスポンス時と同じ challenge を含み、ユーザエージェントが既に最低一回認証を試みているならば、そのエンティティに関連する診断情報を含んでいるであろうから、ユーザエージェントはレスポンスで与えられたエンティティを表示すべきである。 HTTP アクセス認証は、"HTTP Authentication: Basic and Digest Access Authentication" において説明されている。
このコードは、将来の使用のため予約されている。
サーバはリクエストを理解したが、それを実行する事を拒否した。 認証は役に立たないであろうから、リクエストは繰り返されるべきではない。 リクエストメソッドが HEAD で無い時に、サーバはなぜリクエストが実行されなかったかを公にしたいならば、エンティティにおいて拒否の理由を記すべきである。 サーバはこの情報をクライアントに利用されたくないならば、ステータスコードとして 404 (Not Found) を代わりに使う事が出来る。
サーバが、 Request-URI に一致するものを見つけられなかった。 その状態が一時的か恒久的かに拘わらず、与えられる指示はない。 もしサーバが、ある内部に組み込まれているメカニズムを通して、古いリソースが恒久的に利用できず、それを転送するためのアドレスも無いという事を知っていたら、410 (Gone) ステータスコードが使用されるべきである。 このステータスコードは一般に、サーバが何故リクエストが拒否したかを正確には表したく無い時、あるいは他に適切なレスポンスが無い時に使われる。
リクエストラインに記述されたメソッドは、 Request-URI によって識別されるリソースに許可されていない。 レスポンスは、リクエストされたリソースへ適用できるメソッドのリストを含む Allow ヘッダを含まなければならない。
リクエストによって識別されるリソースは、リクエスト中に送られた Accept ヘッダによれば、受け入れられない内容特性を持つレスポンスエンティティを生成する事ができるのみである。
もし HEAD リクエストでなければ、レスポンスはエンティティにユーザかユーザエージェントが最も適切なものを選択するためのリソースの特徴と場所のリストを含むべきである。 エンティティのフォーマットは、Content-Type ヘッダフィールドにて与えられるメディアタイプによって指定される。 データフォーマットやユーザエージェントの能力に依存する事なので、最も適切な選択は自動的に行われるかもしれない。 しかし、この仕様書ではそのような自動選択に対してどのような標準も定義しない。
注: HTTP/1.1 サーバは、リクエスト中に送られた Accept ヘッダによれば受け入れる事ができないとされるレスポンスを返す事を許されている。 そのような場合、406 レスポンスを送る事が望ましい。 ユーザエージェントは、もしそれを受け入れられるなら、それを決定するために送られてきたレスポンスのヘッダを詳しく調べる事が推奨される。
もしレスポンスが受け入れる事ができなければ、ユーザエージェントはそれ以上のデータの受信を一時的に中止し、それ以降の動作を決定するためユーザに尋ねるべきである。
このコードは、401 (Unauthorized) と似ているが、クライアントが最初にプロクシに認証されなければならない事を示す。 プロクシは、リクエストされたリソースのためのプロクシに適用できる challenge を含んだ Proxy-Authenticate ヘッダフィールド (section 14.33) を返さなければならない。 クライアントは、適切な Proxy-Authorization ヘッダフィールド (section 14.34) を伴うリクエストを繰り返す事ができる。 HTTP アクセス認証は、"HTTP Authentication: Basic and Digest Access Authentication" [43] において説明されている。
クライアントは、サーバの待ち時間内にリクエストを発行しなかった。 クライアントは、それ以降に修正しないでリクエストを繰り返してもよい。
リクエストは、リソースの現在の状態との矛盾のため完了できなかった。 このコードは、ユーザが矛盾を解決し、リクエストを再提出できる事が期待できる状況のみに許される。 レスポンスボディには、ユーザが矛盾の原因を認識するための十分な情報を含むべきである。 理論的には、そのレスポンスエンティティはユーザやユーザエージェントが問題を修正するための十分な情報を含んでいるであろうが、実際それは不可能だろうしその必要もない。
矛盾は、PUT リクエストへのレスポンス時に最も発生しやすい。 例えば、もしバージョン処理{versioning} が使用され、PUT されているエンティティが初期 (サードパーティ) のリクエストによって作られたものと矛盾しているリソースに変わるものを含んでいるならば、サーバはリクエストが完了できない事を示す 409 レスポンスを使用できる。 この場合、レスポンスエンティティにはおそらく、レスポンスの Content-Type によって定義されるフォーマット中で二つのバージョンの違いについてのリストを含むであろう。
リクエストされたリソースは、もはやそのサーバでは利用できないし、転送先のアドレスも分からない。 この状況は、恒久的なものとみなされるであろう。 リンク編集機能を持つクライアントは、ユーザから承認を得た後にリクエスト URI の参照を削除すべきである。 サーバがその状況が恒久的なものかどうかを、知らないか、あるいはそれを決定するための能力が無いのであれば、代わりにステータスコード 404 (Not Found) が使用されるべきである。 別の方法が示されなければ、このレスポンスはキャッシュできる。
410 レスポンスは主に、リソースが故意に利用不可能であったり、サーバのオーナーがリソースへのリモートリンクを削除したい事を受信者に通知する事でウェブメンテナンスの作業を補助する意図を持つ。 そのような事は、期間限定の宣伝サービスや、サーバのサイト内でもはや働いていない個人が所有していたリソースに対して一般的である。 "無くなった{gone}" ような恒久的に利用できないすべてのリソースをマークしたり、いつまでもそのマークを維持しておく必要はないが、これをいつ破棄するかはサーバオーナーの判断にまかされる。
サーバは、定義された Content-Length の無いリクエストを受け入れる事を拒否した。 リクエストメッセージにメッセージボディの長さを含んでいる妥当な Content-Length ヘッダフィールドを追加すれば、クライアントはリクエストを繰り返す事ができる。
一つ以上のリクエストヘッダフィールドで与えられた前提条件は、それがサーバでテストされたときに偽であると評価された。このレスポンスコードはクライアントが現在のリソースの外部情報 (ヘッダフィールドデータ) を前提条件として置けるようにし、それによってリクエストされたメソッドを目的以外のリソースに適用されないようにする。
リクエストエンティティがサーバが想定、あるいは処理可能なものより大きいため、サーバはリクエストの処理を拒否している。 サーバは、クライアントにリクエストを続けさせないため接続を閉じてよい。
もしその状態が一時的なものであれば、サーバはそれが一時的であるという事と、クライアントが再試行してもよい経過時間を示す Retry-After ヘッダフィールドを含むべきである。
サーバが中間処理をするために想定している Request-URI より長いため、サーバはリクエストのサービスを拒否している。 このまれな状態は、クライアントが長いクエリ情報を伴った POST リクエストを GET リクエストに不適当に変換した時、クライアントがリダイレクションの URI "ブラックホール" (例えば、リダイレクトされた URI が自身の末尾を指すようなものを自身の前に置いてしまうような状態) に陥った時、あるいはサーバが Request-URI の読み出しや操作のために固定長バッファを使用しているいくつかのサーバに存在する当面のセキュリティホールを利用しようとしているクライアントからアタックを受けている時にのみ起こる傾向がある。
リクエストのエンティティは、リクエストされたメソッドに対してリクエストされたリソースがサポートしていないフォーマットであるため、サーバはリクエストのサービスを拒否している。
リクエストが Range ヘッダフィールド (section 14.35) を含み、このフィールドの範囲指定値が選ばれたリソースの現在の範囲に重なっていなくて、リクエストに If-Range リクエストヘッダフィールドを含んでいなかったら、サーバはこのステータスコードを含むレスポンスを返すべきである。 (バイトレンジの場合、これはすべての byte-range-spec 値での first-bytes-pos が、現在選択されているリソースの長さを超えている事を意味する。)
このステータスコードをバイトレンジのリクエストで返す場合、レスポンスには選ばれたリソースの現在のサイズを特定するために Content-Range ヘッダフィールドを含むべきである (section 14.16 参照)。 このレスポンスは、content-type が multipart/byteranges のものに使用してはならない。
Expect リクエストヘッダフィールド (section 14.20 参照) によって与えられるこの拡張は、このサーバでは受け入れる事は出来ないし、あるいはサーバがプロクシであったなら、次に到達するサーバがそのリクエストを受け入れる事ができないという明白な証拠を持っている。
数字 "5" で始まるレスポンスステータスコードは、サーバがエラー状態にあるか、リクエストを実行する能力が無いと気づいた場合を表す。 HEAD リクエストに応答する場合以外は、サーバはそのエラー状況と、それが一時的か恒久的なのかの説明を含むエンティティを返すべきである。 ユーザエージェントは、ユーザに返されたあらゆるエンティティを表示すべきである。 これらのレスポンスコードは、あらゆるリクエストメソッドにも適用できる。
サーバは、リクエストの実行を妨げる予測しない状態に遭遇した。
サーバは、リクエストを実行するのに必要な機能をサポートしていない。 これは、サーバがリクエストメソッドを認識できない時の適切なレスポンスであり、どんなリソースに対してもそれをサポートする能力がない。
ゲートウェイやプロクシとして動作しているようなサーバが、リクエストを実行しようと呼び出しているアップストリームサーバから不正なレスポンスを受け取った。
サーバは、一時的な過負荷かあるいはサーバのメンテナンスのため、現在リクエストを扱う事ができない。これは、いくらか遅延された後に軽減されるであろうという一時的な状態も含む。もし分かるなら、遅延時間の長さを Retry-After ヘッダで示す事ができる。 もし Retry-After が与えられなければ、クライアントはそれを 500 レスポンスと同様に処理すべきである。
注: 503 ステータスコードの存在は、サーバが過負荷状態になった時には常にそれを使わなければならないという事を暗黙的に意味するものではない。 単に接続の拒否を望むサーバもあるだろう。
ゲートウェイやプロクシとして動作するサーバは、URI によって特定されるアップストリームサーバ (例えば HTTP, FTP, LDAP) や、リクエストを完了させようとするためにアクセスに必要な他の補助のサーバ (例えば DNS) から適時のレスポンスを受信しなかった。
注: 実装者向け: 設置されたプロクシの中には、DNS lookup がタイムアウトした時に 400 あるいは 500 を返すものがあるという事が知られている。
サーバは、リクエストメッセージで使用された HTTP プロトコルバージョンをサポートしていない、あるいはサポートを拒否している。 サーバは、このエラーメッセージ以外は、section 3.1 で表されるように、クライアントと同じメジャーバージョンを使用してリクエストを完了させる事は不可能、 あるいはそれを望んでいないという事を示している。 レスポンスは、何故このバージョンがサポートされていないか、どんな別のプロトコルがこのサーバによってサポートされているかを記述したエンティティを含むべきである。
HTTP は、サーバがクライアントにリクエストを誰何{challenge} するため、あるいはクライアントが認証情報を提供するために使用する事ができる、いくつかのオプショナルな誰何-応答{challenge-response} 認証メカニズムを提供する。 アクセス認証の全体の枠組、そして "基本" 及び "ダイジェスト" 認証の仕様については、"HTTP Authentication: Basic and Digest Access Authentication" [43] にて記述されている。 この仕様書では、その仕様書にある "challenge" と "credentials" の定義を採用する。
多くの HTTP レスポンスは、人間ユーザによって解釈される情報から成るエンティティを含む。 当然、リクエストに対応した "最も利用できる" エンティティをユーザに供給するのが望ましい。 サーバやキャッシュにとって不幸な事は、すべてのユーザが "最上" なものについて同じ優先度を持たせているわけではないし、すべてのユーザエージェントがすべてのエンティティタイプを等しく表現できるわけではないという事である。 この理由により、HTTP は "内容ネゴシエーション"、すなわち複数の利用可能な表現がある時に与えられたレスポンスにとって最上の表現を選択するための処理のためのいくつかのメカニズムを持っている。
注: これは、ある別の表現として、メディアタイプは同じであるが使用言語が異っている等、そのタイプとは異なる能力{capabilities} を使用するかもしれないので、"フォーマットネゴシエーション" とは呼ばれない。
エンティティボディを含むあらゆるレスポンスは、エラーレスポンスを含めネゴシエーションを受けさせる事ができる。
HTTP で可能な内容ネゴシエーションには二種類ある。 サーバ駆動型ネゴシエーションとエージェント駆動型ネゴシエーションである。 これら二つのネゴシエーションは直交{orthogonal} し、故に別々にあるいは組み合わせて使う事ができる。 一つの組み合わせ方として、透過的ネゴシエーションと呼ばれる方法は、キャッシュが以降のリクエストに対してサーバ駆動型ネゴシエーションを提供するためにオリジンサーバによって供給されるエージェント駆動型ネゴシエーション情報を使用する時に発生する。
レスポンスとしての最適な表現の選択がサーバに設けられたアルゴリズムによって行われた場合、これはサーバ駆動型ネゴシエーションと呼ばれる。 選択は、利用可能なレスポンスの表現 (それが変化できる次元、例えば言語や内容コーディング等) や、リクエストメッセージ内の特定のヘッダフィールドの内容、あるいはそのリクエストに関するその他の情報 (例えばクライアントのネットワークアドレス) に基づく。
サーバ駆動型ネゴシエーションは、利用可能な表現の中から選択するためのアルゴリズムがユーザエージェントに説明するのが難しい時や、サーバが最初のレスポンスと一緒にクライアントに自身の "最適な推測" を送る事を望む (もしその "最適な推測" がユーザにとって十分なものであれば、以降のリクエストの往復時間遅れ{round-trip delay} を避けられる) 時に有益である。 サーバの推測を改善するため、ユーザエージェントはそのようなレスポンスのための自身の優先度を表すリクエストヘッダフィールド (Accept, Accept-Language, Accept-Encoding 等) を含む事ができる。
サーバ駆動型ネゴシエーションは以下の不都合を持つ:
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 を、それぞれ参照の事。
エージェント駆動型ネゴシエーションの場合、レスポンスとしての最適な表現の選択は、オリジンサーバからの最初のレスポンスを受けとった後にユーザエージェントによって実行される。 選択は、最初のレスポンスのヘッダフィールドやエンティティボディに含まれる利用可能なレスポンスの表現のリストに基づき、それぞれの表現毎に自身の URI によって識別される。 表現内からの選択は、 (ユーザエージェントがそうする能力があれば) 自動的に、あるいは生成された (おそらくハイパーテキストの) メニューからのユーザの選択によって手動的に行われるだろう。
エージェント駆動型ネゴシエーションは、レスポンスが一般的に使われる次元 (例えばタイプ、言語、エンコーディングのような) と異なる時、オリジンサーバがリクエストの評価からはユーザエージェントの能力を決定できない時、そして一般的に共有キャッシュがサーバの負荷を分散し、ネットワークの使用を減らすために使用される時に有益である。
エージェント駆動型ネゴシエーションは、最適な入れ替わるべき表現を得るために次のリクエストが必要となるという不都合がある。 次のリクエストはキャッシングが使用されている時にのみ効率的である。 さらに、この仕様書では自動選択をサポートするどんなメカニズムも拡張として改良したり、HTTP/1.1 内で使用したりする事を禁止しないが、そのいかなるメカニズムも定義しない。
HTTP/1.1 は、サーバがサーバ駆動型ネゴシエーションで使って異なるレスポンスを供給しようとしない、あるいはできない時にエージェント駆動型ネゴシエーションを可能にするため、300 (Multiple Choices) と 406 (Not Acceptable) ステータスコードを定義する。
透過的ネゴシエーションは、サーバ駆動型ネゴシエーションとエージェント駆動型ネゴシエーションの両方の組み合わせである。 キャッシュが (エージェント駆動型ネゴシエーションの中で) レスポンスとして利用可能な表現のリストのフォームを供給され、その違いの次元をキャッシュが完全に理解できた時、キャッシュはそのリソースへの以降のリクエストのためにオリジンサーバに代わってサーバ駆動型ネゴシエーションを実行できるようになる。
透過的ネゴシエーションは、他の方法でオリジンサーバに要求されるネゴシエーション作業の分散と、キャッシュが正しいレスポンスを正しく推測する事ができる時にエージェント駆動型ネゴシエーションの次のリクエストによる遅れを無くするという利点を持つ。
この仕様書では、透過的ネゴシエーションのためのどんなメカニズムも拡張として改良したり、HTTP/1.1 内で使用したりする事を禁止しないが、そのいかなるメカニズムも定義しない。
HTTP は基本的に情報配布システムとして使われるが、そのパフォーマンスはレスポンスキャッシュの使用によって改善する事ができる。 HTTP/1.1 プロトコルは、できるだけキャッシング作業を行おうとするためのいくつかの要素を含む。 これらの要素はプロトコルの別の側面からは解決できず、それらが相互に作用するため、メソッド、ヘッダ、レスポンスコードなどの詳細な記述とは別に HTTP の基本的なキャッシングデザインを記述する事は有用である。
もし十分にパフォーマンスを高めなければ、キャッシングは役に立たないであろう。 HTTP/1.1 におけるキャッシングが目指すものは、多くの場合でリクエストを送る必要を無くし、また別の多くの場合において全レスポンスを送る必要を無くす事である。 前者は、多くの操作に対して必要とされるネットワークラウンドトリップ{round-trip} をいくらか減らす。 我々は、この目的のため "期限" メカニズムを使用する (section 13.2 参照)。 後者は、必要なネットワークバンド幅を減らす。 我々は、この目的のため "検証" メカニズムを使用する (section 13.3 参照)。
パフォーマンス、有用性、分離された操作のための要求は、我々に意味的透過性の目標点を緩める{relax} 事ができるように要求する。 HTTP/1.1 プロトコルによって、オリジンサーバ、キャッシュ、クライアントは必要な時に透過性を明白に減らす事ができる。 しかしながら、非透過な操作は専門家以外のユーザを混乱させるかもしれないし、ある (商品の注文用等の) サーバアプリケーションとは互換性が無いかもしれないので、プロトコルは以下の透過性を緩める必要がある。
それ故に、HTTP/1.1 プロトコルは以下の重要な要素を提供する。
基本原理はクライアントが意味的透過性のあらゆる潜在的な緩和も検出可能でなければならないという事である。
注: サーバ、キャッシュもしくはクライアント実装者はこの仕様書において明確に論議されないデザインの決定に直面するだろう。 もし決定が意味的透過性に影響するなら、注意深く完全な分析が透過性の破壊で重要な恩恵を表す以外、実装者は透過性を維持する面からは離れた間違いを犯すはずである。
正当なキャッシュは、以下の状況の一つに合うリクエスト (section 13.2.5, 13.2.6, 13.12 参照) に適した、キャッシュが持っている最新のレスポンスをもってリクエストに答えなければならない。
オリジンサーバがレスポンスの再検証によってオリジンサーバで返されたものとの等価性が確認されている (section 13.3)。
"十分に新鮮" (section 13.2 参照) である。 既定の場合、これはクライアント、オリジンサーバ、キャッシュの最低限の新鮮度要求に合う事を意味する (section 14.9 参照)。 オリジンサーバがそう指定する場合、それはオリジンサーバ単独の新鮮度要求である。
保存されたレスポンスがクライアントとオリジンサーバの両方の最も限定的な新鮮度要求から "十分に新鮮" で無い場合、そのようなレスポンスが禁じられている (例えば "no-store" キャッシュ指示子や、"no-cache" キャッシュリクエスト指示子等;section 14.9 参照) ので無ければ、深く考慮された環境ではキャッシュが適切な Warning ヘッダを伴ってそのレスポンスを返してもよい。
適切な 304 (Not Modified), 305 (Proxy Redirect) かエラー (4xx か 5xx) レスポンスメッセージである。
キャッシュがオリジンサーバと通信できない時、レスポンスがキャッシュから正しく対応させる事ができるならば、正しいキャッシュは上記のものを返すべきであり、そうでなければ通信失敗があった事を示すエラーか警告を返さなければならない。
キャッシュがリクエストしているクライアントに普通に転送するレスポンス (レスポンス全体か、304 (Not Modified) レスポンス) を受け取り、その受け取ったレスポンスが既に新鮮で無い場合、キャッシュはそれに新しい Warning を追加する事無く (しかし存在するどんな Warning ヘッダも削除する事も無く) リクエストしているクライアントに転送すべきである。 レスポンスは転送において新鮮で無くなったのかもしれないので、キャッシュは簡単にそのレスポンスの再検証を試すべきではない。 それによって無限ループを引き起こすかもしれない。 Warning を伴わない新鮮で無いレスポンスを受け取ったユーザエージェントは、ユーザに示すための警告を表示する事ができる。
キャッシュがファーストハンドでも無く、 (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 のこのバージョンではどの警告を表示するか、あるいはその優先順序を決定するための厳密な優先規定を記述しないが、いくつかの発見的教授方法を提案する。
HTTP/1.1 における基本的なキャッシュメカニズム (サーバに指定された期限時刻とバリディタ) はキャッシュにとっての暗黙的命令である。 いくつかの場合で、サーバやクライアントは HTTP キャッシュに明示的指示を提供する必要があるかもしれない。 我々はこの目的のため Cache-Control ヘッダを使用する。
Cache-Control ヘッダによって、クライアントやサーバはリクエストやレスポンスにおける様々な指示が伝えられるようになる。 これらの指示子は、典型的に既定のキャッシングアルゴリズムを無効にする。 一般的な規定として、もしヘッダ値の間に明らかな矛盾が存在するなら、最も限定的な解釈が適用される (これは、意味論等価性を維持するために最適なものである)。 しかしながら、いくつかの場合では、Cache-Control 指示子は意味論等価性の概略を弱めるように明示的に詳述される (例えば "max-stale" や "public")。
Cache-Control 指示子は section 14.9 において詳細に記述されている。
多くのユーザエージェントでは、ユーザが基本的なキャッシングメカニズムとは別の物を使えるようにさせている。 例えば、ユーザエージェントはユーザに (明らかに古くなっているものでさえ) キャッシュされたエンティティは決して検証されないという事を指定できるようにするだろう。 あるいは、ユーザエージェントはリクエスト毎に "Cache-Control: max-stale=3600" を習慣的に追加するかもしれない。 ユーザエージェントは透過的で無い振る舞いや、異常に効果の無いキャッシングを引き起こす振る舞いを既定とすべきではない が、ユーザの明示的な動作によってはそうするように形成する事ができる。
もしユーザが基本的なキャッシングメカニズムとは別の物を使うならば、ユーザエージェントは、それがサーバの透過的要求に合っていないという情報の表示という結果になる時はいつでも (特に、表示されたエンティティが古くなっていると分かっている場合は) ユーザに明示的に示すべきである。 プロトコルは、通常ユーザエージェントにレスポンスが古くなっているかどうかを決定できるようにさせているので、この指示はそれが実際に起こった時にのみ表示される必要がある。この指示はダイアログボックスである必要は無く、アイコン (例えば、腐った魚の絵) や別の表示機であってもよい。
もしユーザがキャッシュの有効性を異常に減少するであろう方法でキャッシングメカニズムを上書きしているなら、ユーザが不注意に余分なリソースを消費したり過度の待ち時間に苦しまないようにユーザエージェントは続けて現在の状態をユーザに (例えば、炎の中の通貨の絵を示す事で) 表示すべきである。
いくつかの場合、キャッシュのオペレータはクライアントによって要求されない時に古くなったレスポンスを返すような設定を選ぶ事ができる。 この決定は気軽に行われるべきではないが、有用性やパフォーマンス上の理由、特にキャッシュがオリジンサーバとの接続が不十分である時に必要であろう。 キャッシュが古くなったレスポンスを返す時はいつでも、クライアントソフトウェアがユーザに潜在的な問題があるかもしれないという事を警告できるようにするために (Warning ヘッダを使って) そのように印付けておかなければならない。
ユーザエージェントがファーストハンドあるいは新鮮なレスポンスを得るという処置を行う事もできる。 この理由により、クライアントが明示的にファーストハンドあるいは新鮮なレスポンスを要求している場合、技術的もしくはポリシー上の理由のために応ずる事ができないというので無ければ、キャッシュは古くなったレスポンスを返すべきではない。
オリジンサーバ (とレスポンスの経過時間へ寄与するより小さな範囲の中間キャッシュ) が期限切れについての情報のプライマリリソースである間、いくつかの場合クライアントはキャッシュされたレスポンスを再検証する事無く返すかどうかについてのキャッシュの決定を制御する必要があるかもしれない。 クライアントは、いくつかの Cache-Control ヘッダの指示子を使ってこれを行う。
クライアントのリクエストは、正当性が検証されていないレスポンスの受け取りを意図して最大経過時間を指定する事ができる。 ゼロの値の記述すれば、強制的にキャッシュにすべてのレスポンスの正当性を再検証させる。 また、クライアントはレスポンスが期限切れになる前に残される最小時間を指定する事もできる。 これらオプションは両方とも、キャッシュの振る舞いの制約を増やすもので、キャッシュの意味的透過性の概略をそれ以上緩める事はできない。
クライアントは古くなったレスポンスを受け入れる意図で、ある古さまでの最大量を指定する事もできる。 これはキャッシュの制約を緩め、オリジンサーバに記述された意味的透過性の制約に違反する事になるかもしれないが、非接続時の操作や貧弱な接続に直面した時の高い有用性をサポートするために必要かもしれない。
HTTP キャッシングは、キャッシュがオリジンサーバにリクエストを送るという事を完全に避ける事ができる時に最善に動作する。 リクエストを避けるための第一のメカニズムは、レスポンスが以降のリクエストを満足させるために使用する事ができるという事を含め、オリジンサーバが将来において明確な期限切れになる時間を提供する事である。 言い換えれば、キャッシュはサーバに先に接続する前に新鮮なレスポンスを返す事ができる。
我々が期待する事は、有効期限が切れる前にエンティティは意味的に重要な方法では変更無いであろう、という確信を持って、サーバがレスポンスに将来の明確な有効期限を割り当てているだろう事である。 これは普通、サーバが期限を注意深く選んでいる間は、意味的な透過性を維持する。
期限メカニズムは、キャッシュから取得したレスポンスのみに適用され、リクエストしているクライアントに直ちに転送されたファーストハンドのレスポンスには適用されない。
オリジンサーバがすべてのリクエストで強制的に意味的に透過なキャッシュの検証を望む場合、過去における明示的有効期限を割り当てる事ができる。 これは、そのレスポンスは既に古いので、キャッシュは以降のリクエストでそれを使用する前にその正当性を検証すべきであるという事を意味する。 強制的な再検証のためのより限定的な方法については section 14.9.5 参照。
もしオリジンサーバがすべての HTTP/1.1 キャッシュを、それがどのように設定されているかに関わらず、すべてのリクエストで強制的に検証させたい場合、"must-revalidate" cache-control 指示子 (section 14.9 参照) を使うべきである。
サーバは、Expires ヘッダか Cache-Control ヘッダの max-age 指示子のどちらかを使って明示的有効期限を指定する。
有効期限は、表示の更新や、リソースのリロードをユーザエージェントに強制するために使う事はできない。 その意味論はキャッシングメカニズムにのみ適用され、そのようなメカニズムはそのリソースへの新しいリクエストが始められた時にそのリソースの期限ステータスのみをチェックする必要がある。 キャッシュと履歴メカニズムの違いについての説明は section 13.13 参照。
オリジンサーバは明示的有効期限を常に提供するわけではないので、HTTP キャッシュは典型的に、本当の有効期限を見積もるために (Last-Modified の時間のような) 別のヘッダ値を使うようなアルゴリズムを使って、帰納的有効期限を割り当てる。 HTTP/1.1 仕様書では詳細なアルゴリズムを提供しないが、その結果への最悪の場合の制約を課す。 帰納的有効期限は意味的な透過性を損なうかもしれないので、それらは慎重に使用されるべきであり、我々はオリジンサーバが可能な限り明確な有効期限を提供するという事を推奨する。
キャッシュエントリが新鮮かどうかを知るために、キャッシュは経過時間がその有効期間を超えているかどうかを知る必要がある。 我々は、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 ヘッダの値を示すために使用する。
レスポンスの経過時間は二つの完全に独立した方法で計算する事ができる。
レスポンスを受け取った時にその経過時間を計算するために二つの独立した方法を与える事で、我々はそれらを以下のように組み合わせる事ができる。
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 ヘッダフィールドを実装していないので)。
レスポンスが新鮮かどうかを決定するために、その有効期間と経過時間とを比較する必要がある。 経過時間は、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)
期限値が楽天的に割り当てられるために、二つのキャッシュが同じリソースに対して異なる新鮮度値を含む事が可能である。
もし回収を実行しているクライアントが自身のキャッシュにおいて既に新鮮であるリクエストに対してファーストハンドで無いレスポンスを受け取り、存在するキャッシュエントリの Date ヘッダが新しいレスポンスの Date ヘッダよりも新しければ、クライアントはそのレスポンスを無視する事ができる。 その場合、オリジンサーバに強制的にチェックするため、"Cache-Control: max-age=0" 指示子 (section 14.9 参照) を持ったリクエストを再試行できる。
もしキャッシュが同じ表現だが異なるバリディタを持つ二つの新鮮なレスポンスを持つなら、Date ヘッダが新しい方を使わなければならない。 この状況は、キャッシュが別のキャッシュからのレスポンスを共有するため、あるいはクライアントが明らかに新鮮なキャッシュエントリの再ロードや再検証を要求したために生じるかもしれない。
クライアントは複数の経路からレスポンスを受け取る事ができるので、あるレスポンスがあるキャッシュのセットを通って流れ、別のレスポンスが別のキャッシュのセットを通って流れる場合、クライアントはオリジンサーバがレスポンスを送った時とは違う順番でレスポンスを受け取るかもしれない。 もし古いレスポンスがまだ明らかに新鮮であっても、クライアントは最も新しく生成されたレスポンスを使うした方が良い。
後のレスポンスはより早い有効期限を故意に指定する事ができるので、エンティティタグや期限値でレスポンスに順序付けを課す事はできない。 Date 値に秒の粒状性{granularity} を定めた。
クライアントがキャッシュエントリの再検証を試行し、受信したレスポンスが既存のエントリの Date ヘッダよりも古い Date ヘッダを含んでいる時、クライアントはそのリクエストを無条件に繰り返すべきであり、そこに
Cache-Control: max-age=0
を、あらゆる中間キャッシュにオリジンサーバへそれらのコピーの検証を強制的に行わせるために含むか、あるいは
Cache-Control: no-cache
を、あらゆる中間キャッシュにオリジンサーバからの新しいコピーを強制的に取得させるために含むべきである。
Date 値が等しい場合、クライアントはどちらのレスポンスでも使う事ができる (あるいは極端に慎重になるでのあれば、新しいレスポンスを要求してもよい)。 もし同じ秒の間に生成されたレスポンスの有効期限が重複していたら、サーバはその選択の決定についてそれができるクライアントを当てにしてはならない。
キャッシュがクライアントのリクエストへのレスポンスとして使いたいような新鮮で無いエントリを持っている時、そのキャッシュされたエントリがまだ使用可能かどうかを確かめるために最初にオリジンサーバ (かあるいは新鮮なレスポンスを持っている中間キャッシュ) へチェックしなければならない。 我々はこれをキャッシュエントリの "検証{validating}" と呼ぶ。 もしキャッシュされたエントリで良ければ我々は完全なレスポンスの再転送によるオーバーヘッドを望まないし、キャッシュされたエンティティが適切で無ければ余分なラウンドトリップによるオーバーヘッドを望まないので、HTTP/1.1 プロトコルは条件付きメソッドの使用をサポートしている。
条件付きメソッドをサポートするための重要なプロトコルの機能は、"キャッシュバリディタ" に関するものである。 オリジンサーバが全体のレスポンスを生成する時、それにある種のバリディタを付けられ、キャッシュエントリと共に保存される。 クライアント (ユーザエージェントやプロクシキャッシュ) がキャッシュエントリに持つリソースに条件付きリクエストを作る時、リクエストに関するバリディタを追加する。
この時サーバはそのバリディタと現在のエンティティのバリディタを調べ、もしそれらが一致すれば (section 13.3.3 参照) 、エンティティボディを含まない特別なレスポンスコード (通常は 304 (Not Modified)) を返す。 そうで無ければ、完全なレスポンス (エンティティボディを含む) を返す。 従って、もしバリディタが一致すれば完全なレスポンスを転送する事は避けられるし、一致しなければ余分なラウンドトリップを避けられる。
HTTP/1.1 において、条件付きリクエストは、暗にそのメソッド (通常 GET) を条件付きにする (バリディタを含んだ) 特別なヘッダを含む事を除けば、同じリソースに対する通常のリクエストと全く同じに見える。
プロトコルは、キャッシュの検証条件の肯定的と否定的の両方の意図を持っている。 つまり、バリディタが一致した時のみ、あるいはバリディタが一致しなかった時のみ、のどちらかでメソッドが実行されるという事を要求する事ができる。
注: バリディタの無いレスポンスは、もしそれが Cache-Control 指示子によって明示的に禁止されていなければ、その期限が切れるまでキャッシュされ、また使用されるであろう。 しかし、もしキャッシュがそのエンティティのバリディタを持っていなければ条件付き回収を行う事ができない。 これはその期限が切れた後も再び新しくする事はできないだろうという事を意味する。
Last-Modified エンティティヘッダフィールド値はしばしばキャッシュバリディタとして使われる。 簡単な条件としては、もしエンティティが Last-Modified 値から更新されていなければキャッシュエントリは有効であるとみなせる。
ETag レスポンスヘッダフィールド値、すなわちエンティティタグは、"それ自体は読んでも意味のわからない{opaque}" キャッシュバリディタを提供する。 これによって、更新時刻を保存する事が不都合な状況、HTTP 日付値の秒単位の解析が十分でない状況、オリジンサーバが更新時刻の使用から起こるであろうある種の矛盾を避ける事を望む状況でより信頼できる検証ができるようになるだろう。
エンティティタグは section 3.11 にて記述される。 エンティティタグと共に使われるヘッダは section 14.19, 14.24, 14.26, 14.44 にてそれぞれ記述される。
オリジンサーバやキャッシュの両方でそれが同じエンティティを表すかどうかを決定するために二つのバリディタを比較するため、通常はエンティティ(エンティティボディかエンティティヘッダ) が何らかの理由で変わっていたら、それに関するバリディタも同様に変更しているだろうという事を期待できる。 これが真である場合、我々はこのバリディタを "強いバリディタ" と呼ぶ。
しかしながら、サーバがエンティティの意味的に重要な変更時にのみバリディタを変更し、重要でない側面にはバリディタを変更したがらない場合があるかもしれない。 リソースの変更時に常に変更されないバリディタは "弱いバリディタ" である。
エンティティタグは通常 "強いバリディタ" であるが、このプロトコルでは "弱い" エンティティタグを付けるためのメカニズムを提供している。 強いバリディタはエンティティが少しでも変更した時に変更されるもので、弱いバリディタはエンティティの意味が変更した時に変更される、と考える事ができる。 または、強いバリディタは特定のエンティティの識別子{identifier} の一部であり、弱いバリディタは意味的に等しいエンティティのセットの識別子の一部である、と考える事もできる。
注: 強いバリディタの一例に、安定した記憶装置においてエンティティが変更される毎に増加される整数がある。
エンティティの更新時間は、リソースを1秒以内に2度更新する事は可能なので、もしそれが秒解像度に相当するなら弱いバリディタである。
弱いバリディタのサポートはオプションである。 しかしながら、弱いバリディタによって同等のオブジェクトのより効率的なキャッシングができるようになる。 例えば、あるサイトのヒットカウンタが数日や数週毎に更新されるのであればおそらくそれで十分に良く、その期間内のあらゆる値は多分 "十分に良く{good enough}" 等しい。
バリディタの "使用" は、クライアントがリクエストを生成し検証用ヘッダフィールドにバリディタを含む時、あるいはサーバが二つのバリディタを比較する時のどちらかである。
強いバリディタはいかなる状況にも使う事ができる。 弱いバリディタはエンティティの正確な等価性に頼らない状況においてのみ使う事ができる。 例えば、完全なエンティティの条件付き GET のためにどちらかの種類を使う事ができる。 しかし、別の方法ではクライアントが内部的に一致しないエンティティとなってしまうかもしれないので、サブレンジ回収のためには強いバリディタのみを使う事ができる。
クライアントは、単純な (非サブレンジ) GET リクエストの発行には弱いバリディタも強いバリディタも使う事ができる。 その他のリクエストの形式には弱いバリディタを使ってはならない。
HTTP/1.1 プロトコルがバリディタに定義している機能は比較のみである。 二つのバリディタ比較機能があり、これは比較状況が弱いバリディタの使用を許すかどうかに依存する。
明確に弱いと印されていなければエンティティタグは強い。 section 3.11 ではエンティティタグのための構文を与えている。
Last-Modified 時間がリクエストにおいてバリディタとして使用された時、以下の規定を使ってそれが強いと推定できなければ暗黙的に弱い。
あるいは
あるいは
この方法は、二つの異なるレスポンスが同じ秒にオリジンサーバから送られたが、両方とも同じ Last-Modified 時刻を持っていた場合に、それらのレスポンスの少なくとも一つはその Last-Modified 時刻と同じ Date 値を持っているであろうという事実を当てにしている。 独断的な 60 秒制限は Date と Last-Modified 値が別の時計から、あるいはレスポンスの準備の間のわずかに異なる時間に生成されるという可能性について警戒する。 もし実装が 60 秒はあまりに短いと思うのであれば、60 秒より大きな値を使用してもよい。
もしクライアントが Last-Modified 時刻のみを持ち、それ自体は読んでも意味のわからない{opaque} バリディタを持たない値のサブレンジ回収を行いたければ、Last-Modified 時刻がここで記述された意図において強い場合のみこれを行う事ができる。
完全なボディの GET リクエスト以外の、条件付きリクエストを受信するキャッシュやオリジンサーバは、条件を評価するために強い比較機能を使わなければならない。
これらの規定によって、HTTP/1.1 キャッシュやクライアントは HTTP/1.0 サーバから得られた値のサブレンジ回収を安全に実行できるようになる。
我々は様々なバリディタタイプがいつ、何の目的で使用されるべきかに関するオリジンサーバ、クライアント、キャッシュのための規定と推薦のセットを採用する。
HTTP/1.1 オリジンサーバについて
言い換えれば、HTTP/1.1 オリジンサーバにとってより望まれる動作とは強いエンティティタグと Last-Modified 値の両方を送る事である。
規格上適正であるため、強いエンティティタグは関連するエンティティ値にどんな点においての変化があっても変わらなければならない。 弱いエンティティタグは関連するエンティティタグが意味上で重要な点において変わる時に変わるべきである。
注: 意味的に透過なキャッシングを提供するため、オリジンサーバは二つの異なるエンティティに対しての特定の強いエンティティタグ値の再使用、あるいは二つの意味的に異なるエンティティに対しての特定の弱いエンティティタグ値の再使用を避けなければならない。 キャッシュエントリは有効期限に関係なく、任意に長期間持続するかもしれないので、キャッシュが過去のある点で得られたバリディタを使ってエントリの検証を再び試みる事は無いだろうと期待する事は不適当であろう。
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 オリジンサーバはこれを提供すべきではない。
エンティティタグの背景にある原理は、サービスの著者のみが適切なキャッシュバリディタメカニズムを選択するのに十分なリソースの意味論を知る事で、バイト等価性よりも複雑なあらゆるバリディタ比較機能についての仕様書は虫の缶{can of worms} を開ける事になるだろう。 従って、その他のヘッダの比較は (HTTP/1.0 互換性のための Last-Modified を除いて) キャッシュエントリの検証の目的では決して使用されない。
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)。
HTTP キャッシュの目的は、将来のリクエストへの応答での使用するためにリクエストへのレスポンスで受信した情報を保存する事である。 多くの場合、キャッシュはリクエスト者へ単純にレスポンスの適切な部分を返す。 しかしながら、もしキャッシュが以前のレスポンスに基づくキャッシュエントリを持っていたら、新しいレスポンスの部分とキャッシュエントリとして持っているものとを結び付ける事ができる。
キャッシュや非キャッシュプロクシの振る舞いを定義する目的のために、我々は HTTP ヘッダを二つのカテゴリに分ける。
以下の HTTP/1.1 ヘッダはホップバイホップヘッダである。
(※訳注) "Trailer" (section 14.40) の Typo と思われる。
HTTP/1.1 で定義されている他のすべてのヘッダはエンドトゥエンドヘッダである。
HTTP/1.1 (あるいはそれ以降) に導入されるその他のホップバイホップヘッダは、Connection ヘッダにおいて列挙されなければならない (section 14.10)。
Digest 認証のような、HTTP/1.1 プロトコルのいくつかの機能では、特定のエンドトゥエンドヘッダの値に依存する。 透過的プロクシは、そのヘッダの定義がそれを要求していたり、あるいはそれが特に許されている場合以外は、エンドトゥエンドヘッダを修正すべきではない。
透過的プロクシはリクエストやレスポンス中の以下のフィールドのどれも修正してはならないし、それが存在していなければそれらを追加してはならない。
透過的プロクシはレスポンス中の以下のフィールドについては修正してはならない。
しかし、それが存在していなければそれらを追加する事ができる。 Expires ヘッダが追加された場合、その field-value にはそのレスポンス中の Date ヘッダと同じ値が与えられなければならない。
プロクシは、no-transform cache-control 指示子を含んでいるメッセージ、あるいはあらゆるリクエストにおいて、以下のフィールドのどれも修正したり追加してはならない。
非透過的プロクシは 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) は維持しなければならない。
キャッシュがサーバに検証リクエストを送り、サーバが 304 (Not Modified) か 206 (Partial Content) レスポンスを返した場合、キャッシュはリクエストしたクライアントに返すレスポンスを構築する。
ステータスコードが 304 (Not Modified) の場合、キャッシュは出力するレスポンスのエンティティボディとしてキャッシュエントリに保存されたエンティティボディを使う。 ステータスコードが 206 (Partial Content) で ETag か Last-Modified 各ヘッダが正確に一致した場合、キャッシュはキャッシュエントリに保存された内容とレスポンスとして新たに受信した内容を連結でき、出力するレスポンスのエンティティボディとしてそれを使う事ができる (section 13.5.4 参照)。
キャッシュエントリに保存されたエンドトゥエンドヘッダは、以下を除いて構築されたレスポンスのために使われる。
キャッシュがそのキャッシュエントリの削除を決めた場合以外は、すぐ上で示したように Warning ヘッダを除いて、キャッシュエントリと共に保存されたエンドトゥエンドヘッダを入ってきたレスポンス中に含まれる対応するヘッダと置き換えなければならない。 もし入ってきたレスポンス中のヘッダフィールド名がキャッシュエントリ中の二つ以上のヘッダに一致したら、そのようなすべての古いヘッダは置きかえられなければならない。
言い換えれば、入ってきたレスポンスで受信したエンドトゥエンドヘッダのセットはキャッシュエントリと共に保存されているすべての対応するエンドトゥエンドヘッダを上書きする (warn-code 1xx と共に保存される Warning ヘッダを除く、これは例え上書きされなくても削除される)。
注: この規則によってオリジンサーバは 304 (Not Modified) や 206 (Partial Content) 各レスポンスを同じエンティティやその一部分に対する以前のレスポンスに関連するあらゆるヘッダを更新するために使えるようになるが、それが常に意味を持ったり常にそうするのが正しいわけではない。 この規則ではオリジンサーバが 304 (Not Modified)や 206 (Partial Content) 各レスポンスを以前のレスポンスにて提供されたヘッダを完全に削除する事はできない。
リクエストが一つ以上の Range 詳述を含んでいたり、接続が早まって切断されたりするので、レスポンスはエンティティボディのバイトのサブレンジのみを転送できる。 そのようないくつかの転送の後、キャッシュは同じエンティティボディのいくつかの範囲を受信する事ができる。
もしキャッシュがエンティティに対するサブレンジの保存された空でないセットを持っており、入ってきたレスポンスが別のサブレンジを転送するような時に、以下の両方の条件を満たすのであれば、キャッシュは新しいサブレンジを既存のセットと連結できる。
この要求のどちらかを満たせない場合、キャッシュは最新の部分的なレスポンス (レスポンス毎に転送された Date 値に基づき、またそれらの値が等しいか欠けているのであれば入ってきたレスポンス) のみを使用しなければならない し、他の部分的な情報は破棄しなければならない。
レスポンス中の 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 が既存のエントリの物より新しいような成功レスポンスを受信した場合、既存のエントリは将来のリクエストへのレスポンスとして返されるべきではなく、それをキャッシュから削除すべきである。
セキュリティやプライバシー上の理由により、"共有{shared}" キャッシュと "非共有{non-shared}" キャッシュとの間に区別を付ける必要がある。 非共有キャッシュは単一のユーザのみがアクセス可能なものである。この場合のアクセス可能性とは、適切なセキュリティメカニズムによって施行されるべきである。 他のキャッシュはすべて "共有" されたとみなされる。 この仕様書の別の章ではプライバシーの損失やアクセス制御の失敗を防止するために共有されたキャッシュの操作へのある制約をかけている。
不完全なレスポンス (例えば、Content-Length ヘッダで記述されたものより少ないデータのバイトを伴うもの) を受信するキャッシュはレスポンスを保存する事ができる。 しかし、キャッシュは部分的なレスポンスとしてこれを扱わなければならない。 部分的なレスポンスは section 13.5.4 にて定義されているように結合する事ができるが、その結果は完全なレスポンスかもしれないし、まだ部分的であるかもしれない。 キャッシュは 206 (Partial Content) ステータスコードを使ってそれを明示的にそれを示さなければ、クライアントに部分的なレスポンスを返してはならない。 キャッシュは 200 (OK) ステータスコードを使って 部分的なレスポンスを返してはならない。
もしキャッシュがエントリの正当性再検証を試みる一方で 5xx レスポンスを受信したら、リクエストしているクライアントにこのレスポンスを転送するか、あるいはまるでサーバが応答に失敗したかのように動作するかどちらかを行う事ができる。 後者の場合、キャッシュされたエントリが "must-revalidate" cache-control 指示子 (section 14.9 参照) を含んでいなければ、以前に受信したレスポンスを返す事ができる。
オリジンサーバがそれらのレスポンスのキャッシングを明示的に禁止していない場合に、あらゆるリソースへ GET や HEAD メソッドを適用する事によってそれらのレスポンスがキャッシュから取り出されたならば、誤った動作を導くような副作用を抱えるべきではない。 それらは副作用を抱えるかもしれないが、キャッシュはそのキャッシング決定においてそのような副作用を考慮必要は無い。 キャッシュは常にキャッシングにおいてオリジンサーバの明示的な制限を観察する事が期待される。
この規則の一つの例外について記す。アプリケーションの中には伝統的に重要な副作用を抱えた操作を実行するためにクエリ URL (それらは rel_path 部分に "?" を含んでいる) を伴う GET や HEAD を使用しているものがあるので、キャッシュはサーバが明示的有効期限を与えていなければそのようなURI へのレスポンスを新鮮であるように扱ってはならない。 これは、そのような URI に対する HTTP/1.0 サーバからのレスポンスはキャッシュから取り出されるべきではない という事を特に意味している。 関連する情報については section 9.1.1 参照。
オリジンサーバ上のリソースに行われるあるメソッドの影響によって一つ以上の既存のキャッシュエントリが非透過で無効なものになってしまうかもしれない。 つまり、それらは "新鮮" であり続けるかもしれないが、それらはオリジンサーバがそのリソースへの新しいリクエストに対して返すであろうものを正確に反映していないという事である。
HTTP プロトコルでは、そのようなキャッシュエントリすべてが無効であると示す事を保証するための方法は無い。 例えば、オリジンサーバ上で変更を引き起こすリクエストはキャッシュエントリが保存されているプロクシを通り抜けていないかもしれない。 しかし、いくつかの規定は間違った振る舞いの可能性を減らす助けとなる。
この章では、"エンティティを無効にする" というフレーズは、キャッシュはその保存媒体からそのエンティティのすべてのインスタンスを削除する、あるいはそれらが以降のリクエストへのレスポンスとして返される前にそれらを "不正" と印し強制的に再検証を行う必要があるであろうという意味である。
HTTP メソッドによってはキャッシュがエンティティを無効にしなければならないものがある。 これは Request-URI によって参照されるエンティティ、あるいは (それが存在するならば) Location や Content-Location レスポンスフィールドによって参照されるエンティティのどちらかである。 そのメソッドは以下のものである。
サービス不能攻撃を防ぐために、Location や Content-Location ヘッダ中の URI に基づく無効化はそのホスト部分が Request-URI のものと同じ場合にのみ実行されなければならない。
自身が理解できないメソッドを使ったリクエストを通すキャッシュは、その Request-URI によって参照されるあらゆるエンティティを無効化すべきである。
オリジンサーバのリソースに修正をさせる事が期待されるすべてのメソッドは、オリジンサーバへと通されて書かれる{write through} ものでなければならない。 これは現在 GET と HEAD 以外のすべてのメソッドが含まれる。 キャッシュはインバウンドサーバへとリクエストを転送し、インバウンドサーバからそれに対応するレスポンスを受け取る前には、そのようなクライアントからのリクエストに応答してはならない。 これは、キャッシュがインバウンドサーバが最後の応答を送信する前にプロクシキャッシュが 100 (Continue) レスポンスを送る事は妨げない。
一貫した更新を提供する事が難しい事、また write-back より前のサーバ、キャッシュ、ネットワークの失敗から生じる問題のために、("write-back" や "copy-back" キャッシングとして知られる) 代替案は HTTP/1.1 において認められていない。
もしあるリソースについてのレスポンスが既にキャッシュされている時に、同じリソースから新しくキャッシュ可能な (section 14.9.2, 13.2.5, 13.2.6, 13.8 参照) レスポンスが受信された場合、キャッシュは現在のリクエストへの応答には新しいレスポンスを使用すべきである。 キャッシュはそれをキャッシュ保存媒体に書き込む事ができ、もし他のすべての要求を満たすのであれば、以前には古いレスポンスが返されるであろう将来のリクエストへ応答するためにそれを使用する事ができる。 キャッシュ保存媒体に新しいレスポンスを書き込む時は、section 13.5.3 の規則が適用される。
注: 既存のキャッシュされたレスポンスより古い Date ヘッダ値を持つ新しいレスポンスはキャッシュ可能ではない。
ユーザエージェントはしばしば、"戻る" ボタンと履歴リストのような履歴メカニズムを持っていて、セッションにおいて以前に回収したエンティティを再表示するために使う事ができる。
履歴メカニズムとキャッシュは異なる。特に履歴メカニズムはリソースの現在の状態の意味的に透過なビューを表示しようとはすべきではない。 むしろ、履歴メカニズムはリソースが回収された時刻を正確に表示するという意味を持つ。
既定では、有効期限は履歴メカニズムには適用されない。 もしそのエンティティがまだ保存していて、ユーザが特にエージェントを期限切れの履歴文書をリフレッシュするように設定していなければ、履歴メカニズムは例えエンティティの期限が切れていてもそれを表示すべきである。
これは、履歴システムがユーザにビューが古くなっているかもしれないという事を知らせる事を禁止すると解釈されるものではない。
注: もし履歴表メカニズムがユーザが古くなったリソースを見る事を不必要に妨げるのであれば、サービスの著者が別の方法を望む場合に、HTTP の期限制御とキャッシュ制御を強制的に使わせないようにする傾向があるだろう。 サービスの著者は、ユーザが前もって回収したリソースを見るために (「戻る」のような) ナビゲーション制御を使う時にユーザがエラーメッセージや警告メッセージが見えない事を重要だと考えるかもしれない。 例え、時にそのようなリソースはキャッシュされるべきではなく、すぐに期限が切れるべきだとしても、不適当に機能している履歴メカニズムの影響のよって苦しまないためにユーザインターフェースはサービスの著者にキャッシングさせないようにするための別の方法 (例: "一度きりの" URL) に強制的に訴える事ができるように考慮されている。
この章では、すべての標準 HTTP/1.1 ヘッダフィールドの構文と意味論を定義する。 エンティティヘッダフィールドに対して、送信者と受信者の両方は、クライアントかサーバのどちらかを参照するが、それはエンティティを誰が送信し誰が受信するかに依存する。
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, */*
この優先順位は以下の様になる。
あるメディアタイプに関連付けられる品質係数は、そのメディアタイプにマッチする最も高い優先度を持つメディアレンジを発見する事によって決定される。 例を見よ。
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
注: ユーザエージェントは、あるメディアレンジに対して既定の品質値を供給するかもしれない。 しかし、ユーザエージェントが他のレンダリングエージェントと相互作用できないクローズドなシステムで無いのであれば、この既定値はユーザが設定できるようにすべきである。
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) エラーレスポンスを返すべきである。
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 フィールドに従って、以下の規定を使い内容コーディングが受け入れ可能かどうかを試す。
リクエストに 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 については作動しないし許可しない事を意味する。
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" を加える事を提案できる。
Accept-Ranges レスポンスヘッダフィールドは、サーバにリソースへの範囲リクエストの受け入れを示させる。
Accept-Ranges = "Accept-Ranges" ":" acceptable-ranges acceptable-ranges = 1#range-unit | "none"
バイトレンジリクエストを受け入れるオリジンサーバは、以下のものを送る事ができる。
Accept-Ranges: bytes
しかし、これは必ずとも必要ではない。 クライアントは、必要とするリソースに関してこのヘッダを受けなくても、バイトレンジリクエストを生成する事ができる。 レンジ単位は、section 3.12 にて定義されている。
リソースへのいかなる範囲リクエストも受け入れないサーバは、以下のものを送る事ができる。
Accept-Ranges: none
これは、クライアントに範囲リクエストをしないように忠告する。
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 の範囲はある計算型を使うべきである。
Allow エンティティヘッダフィールドは、Request-URI によって識別されるリソースがサポートするメソッドの一覧を示す。 このフィールドは、リソースに関する有効なメソッドを受信者に厳密に知らせる事を目的にする。 Allow ヘッダフィールドは、405 (Method Not Allowed) レスポンス中に存在しなければならない。
Allow = "Allow" ":" #Method
使用例を見よ。
Allow: GET, HEAD, PUT
このフィールドを使っても、クライアントが他のメソッドを試す事を妨げる事はできない。 しかし、クライアントは Allow ヘッダフィールドにて示された値には従うべきである。 実際に許可されるメソッドのセットは、各々のリクエストの度にオリジンサーバによって定義される。
PUT リクエスト時に、Allow ヘッダフィールドを使って、新規、あるいは更新されるリソースによってサポートされる事が推奨されるメソッドを提供する事ができる。 サーバはこれらのメソッドをサポートする事は要求されないが、レスポンスには実際にサポートされるメソッドを与えた Allow ヘッダを含めるべきである。
プロクシは、例えそこに書かれたすべてのメソッドが理解できなくても、ユーザエージェントがオリジンサーバと通信するための別の意味を持っているかもしれないので、Allow ヘッダフィールドを書き換えてはならない。
サーバに認証を受けようとするユーザエージェントは、必ずというわけではないが、通常は 401 レスポンスの後、リクエストに Authorization リクエストヘッダフィールドを含める。 Authorization フィールド値は、リクエストされたリソースのある領域へのユーザエージェントの認証情報を含む credentials からなる。
Authorization = "Authorization" ":" credentials
HTTP アクセス認証については、"HTTP Authentication: Basic and Digest Access Authentication" [43] にて記述されている。 もしリクエスト認証され、領域が指定されれば、その領域内への他のすべてのリクエストへも同じ credentials は有効であるべきである (認証スキーム自身は、例えば challenge 値や使用中の同期した時計によって変更した credentials のように、他の場合を要求しない事を仮定する)。
共有キャッシュ (section 13.7 参照) が Authorization フィールドを含むリクエストを受けた時、以下の例外のどれにも当てはまらなければ、他のどんなリクエストへの応答としても対応するレスポンスを返してはならない。
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 指示子は、これらの一般的なカテゴリの中に分類する事ができる。
リクエストメソッド、リクエストヘッダフィールド、レスポンスステータスがキャッシュ可能である事を要求している場合、既定ではレスポンスはキャッシュ可能である。 section 13.4 では、キャッシュ可能性のためのこれらの既定を要約している。 以下の Cache-Control レスポンス指示子を使うと、オリジンサーバはレスポンスの既定のキャッシュ可能性を上書きする事ができる。
たとえそれが通常はキャッシュ可能でなかったり、非共有キャッシュ内でのみキャッシュ可能であったとしても、レスポンスがすべてのキャッシュによってキャッシュ可能にできる事を示す。 (追加される詳細のため、section 14.8 の Authorization も見よ。)
レスポンスメッセージのすべてもしくは一部は、単一のユーザのために用意された物であり、共有キャッシュによってキャッシュされてはならない事を示す。 これによって、オリジンサーバは、そのレスポンスの指定された部分ががあるユーザにのみ向けられたもので、別のユーザによるリクエストにとっては正当なレスポンスではない事を述べる事ができるようにする。 プライベート (非共有) キャッシュは、そのレスポンスをキャッシュできる。
注: この private と言う指示子の使用は、レスポンスがキャッシュできるところのみを制御するもので、メッセージ内容のプライバシーは保証できない。
もし no-cache 指示子がフィールド名を指定していなければ、オリジンサーバへの再検証が成功するまで、以降のリクエストを満足させるためにそのレスポンスを使ってはならない。 これによって、オリジンサーバはリクエストするクライアント古くなったレスポンスを返すよう設定されているキャッシュによるキャッシングさえ行えなくする事ができる。
もし no-cache 指示子が一つ以上のフィールド名を指定していたら、キャ ッシュはキャッシングにおける他の制約の元で、以降のリクエストを満足 するためにそのレスポンスを使う事ができる。しかし、指定されたフ ィールド名はオリジンサーバへの再検証が成功するまで、以降のリクエス トを満足させるためにそのレスポンスを使ってはならない。これによ って、オリジンサーバはレスポンスの残りをキャッシングできる間、レス ポンス中のあるヘッダフィールドの再使用を行えなくする事ができる。
注: 多くの HTTP/1.0 キャッシュは、この指示子を理解できず、従う事はないだろう。
no-store 指示子の目的は、取り扱いが慎重な (例えばバックアップテープ上の) 情報の不注意な漏洩や保留を防ぐ事である。 no-store 指示子はメッセージ全体に適用され、レスポンスかリクエストのどちらかで送る事ができる。 リクエストで送られる場合、キャッシュはそのリクエストやそれへのいかなるレスポンスの一部分を保存してはならない。 レスポンスで送られる場合、キャッシュはそのレスポンスやそれを引き起こしたリクエストの一部分を保存してはならない。 この指示は、非共有・共有キャッシュのどちらにも当てはまる。 この状況下での "保存してはならない" は、キャッシュを一時的なものではない保存場所{non-volatile storage} にその情報を故意に保存してはならないし、一時的な保存場所{volatile storage} であってもそれを転送した後にできるだけ早くそこから情報の削除するために最善を尽くさなければならない、という事を意味する。
その指示がレスポンスに関連している時でも、ユーザはキャッシングシステムの外側にそのようなレスポンスを明白に (例えば、"Save As" ダイアログを伴って) 保存できる。 履歴バッファは、これらの通常操作の一部としてこのようなレスポンスを保存する事ができる。
この指示の目的は、キャッシュデータ構造への予期しないアクセスを経て情報の偶発的な漏洩を心配するユーザやサービス著者達が前もって示した必要条件に見合うようにするためである。 この指示子を使う事でいくつかの場合でプライバシーを改善できるであろうが、これはプライバシーを保証するための信頼できる、もしくは十分なメカニズムのどのような方法におけるものでは無い事を警告しておく。 特に、悪意のあるキャッシュや一部の機能のみが実装された{compromised} キャッシュはこの命令を認識しなかったり従わなかったりするかもしれないし、あるいは通信ネットワーク自体が盗聴に対して無防備であるかもしれない。
エンティティの有効期限は、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 指示子を含んでいる場合、共有キャッシュについて (非共有キャッシュについてではない) 、この指示子で指定された最大使用期限は 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-stale 指示子が含まれていなければ、クライアントは古くなったレスポンスを受け入れようとはしていない。
クライアントは、それが新鮮であるような残り時間がここで指定した秒時間に現在の経過時間を足した物より小さくなるようなレスポンスを受け入れる意図を持つ事を表す。 これは、クライアントが少なくとも指定した秒数の間はまだ新鮮であるようなレスポンスを望んでいるという事である。
クライアントは、期限を超えたようなレスポンスを受け入れる意図を持つ事を表す。 max-stale に値を割り当てられている場合、クライアントは指定した秒数だけ有効期限を過ぎてしまったようなレスポンスを受け入れようとしている。 max-stale に値が割り当てられていない場合は、クライアントはどれだけ時間が経過しような新鮮で無いレスポンスも受け入れようとしている。
リクエスト中の max-stale 指示子、あるいはキャッシュがレスポンスの有効期限を上書きするように形成されているかのどちらかの理由で、キャッシュが新鮮でないレスポンスを返す場合、キャッシュは Warning 110 (Response is stale) を使って、新鮮ではないレスポンスに Warning ヘッダを追加しなければならない。
キャッシュは、キャッシュの再検証に関しての "MUST" レベルの必要条件 (例えば "must-revalidate" cache-control 指示子) とは矛盾を起こさないようにする場合のみ、再検証せずに新鮮で無いレスポンスを返すように構成する事ができる。
もし新しいリクエストとキャッシュされたエントリの両方に "max-age" 指示子が含まれていたら、そのリクエストのためのキャッシュされるエントリの残り時間の決定には、二つの値の小さい方が使われる。
時々ユーザエージェントは、キャッシュがオリジンサーバ (オリジンサーバへの経路上の次のキャッシュではなく) にキャッシュエントリの再検証を行う事を要求したり、オリジンサーバからそのキャッシュエントリをリロードする事を望みあるいは必要とするかもしれない。エンドトゥエンド{end-to-end} 再検証は、キャッシュかオリジンサーバのどちらかがキャッシュされたレスポンスの有効期限を過大評価している場合に必要とあろう。 エンドトゥエンド・リロードは、キャッシュエントリがある理由のため古く使えなくなった場合に必要とあろう。
エンドトゥエンドの再検証は、クライアントが自身のローカルにキャッシュされたコピーを持っていないような、我々が "未指定性エンドトゥエンド再検証{Unspecified end-to-end revalidation}" と呼ぶような場合か、クライアントがローカルにキャッシュされたコピーを持っているような、我々が"指定性エンドトゥエンド再検証{Specific end-to-end revalidation}" と呼ぶような場合の、どちらかの場合で要求されるであろう。
クライアントは、Cache-Control リクエスト指示子を使って以下の三種類の動作を指定する事ができる。
中間キャッシュが max-age=0 によって、そのキャッシュエントリの再確認を強制され、クライアントがそのリクエスト中に自身のバリディタを供給するような場合、供給されたバリディタは現在キャッシュエントリに保存されているバリディタとは異なるかもしれない。 この場合、キャッシュは意味的透過性の影響を考える事無くそれ自身のリクエストを作成する際にはどちらのバリディタでも使う事ができる。
しかし、バリディタの選択によってパフォーマンスに影響が出るかもしれない。 中間キャッシュがリクエストを作成する際の最良のアプローチは、自身の確証子を使う事である。サーバが 304 (Not Modified) を返した場合は、キャッシュはクライアントに 200 (OK) レスポンスと現在の検証されたコピーを返す事ができる。 しかし、もしサーバが新しいエンティティとキャッシュバリディタを返したら、中間キャッシュは返されたバリディタとクライアントのリクエストから与えられたものとを強い比較機能を使用して比較する事ができる。 クライアントのバリディタがオリジンサーバのものと等しければ、中間キャッシュは単純に 304 (Not Modified) を返す。 そうでなければ、200 (OK) レスポンスと新しいエンティティを返す。
リクエストが no-cache 指示子を含む場合は、min-fresh, max-stale, max-age を含むべきではない。
例えばネットワーク接続が極めて貧弱である等、いくつかの場合では、クライアントはキャッシュが現在保存しているレスポンスのみを返し、オリジンサーバにリロードや再検証を行わないように望むだろう。 これを行うため、クライアントはリクエスト中に only-if-cached 指示子を含む事ができる。 この指示子を受け取った場合、キャッシュはそのリクエストの別の条件を満たすようなキャッシュエントリを使って返すか、504 (Gateway Timeout) ステータスを返すか、どちらかを行うべきである。 しかし、もしあるキャッシュのグループが内部の接続性が良い統合システムとして運用されているなら、そのようなリクエストはそのようなキャッシュのグループ内に転送してもよい。
キャッシュはサーバの指定する有効期限を無視するように形成する事ができ、またクライアントのリクエストでは 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 指示子は、非共有ユーザエージェントキャッシュには適用されない事を除けば、must-revalidate 指示子と同じ意味を持つ。 これは、多くのユーザにサービスしているプロクシは毎回再検証する事を必要とする (それぞれのユーザが認証されている事を保証するため) 一方で、ユーザのキャッシュにそれを再検証する必要が無いレスポンス (ユーザによって既に一度認証されているので) を保存し、後に返すような事を許すような認証リクエストへのレスポンスとして使用できる。
そのような認証されたレスポンスも、それらがすべてキャッシュされるようにするためには public キャッシュコントロール指示子を必要とする事に注意せよ。
中間キャッシュ (プロクシ) の実装者は、あるエンティティボディのメディアタイプを変換する事が有用である事を知っている。 例えば、透過的プロクシはキャッシュスペースを節約したり、遅い通信路上のトラフィックの量を減らすために画像フォーマットの変換を行う事ができる。
しかし、これらの変換がある種のアプリケーションのために作られたエンティティボディに適用される時に、深刻な操作上の問題が起こる事がある。 例えば、医療用の映像処理、科学的なデータ分析、およびエンドトゥエンド認証を使うようなアプリケーションは、すべて元々のエンティティボディと bit 単位で同一のエンティティボディを受け取る事を前提にしている。
それ故に、もしメッセージが no-transform 指示子を含んでいたら、中間キャッシュやプロクシは no-transform 指示に従うものとして section 13.5.2 で列挙されているようなヘッダを変更してはならない。 これは、キャッシュやプロクシがこれらのヘッダによって指定されたエンティティボディの、エンティティボディ自身の値を含め、いかなる部分も変更してはならない 事を意味する。
Cache-Control ヘッダフィールドは、それぞれにオプション的に割り当てられる値を伴う、一つ以上の cache-extension トークンを使う事によって拡張可能である。 情報的拡張 (キャッシュの振る舞いにおける変更を必要としないもの) は、他の指示子の意味論を変更せずに追加できる。 振る舞いの拡張は、既存のキャッシュ指示子のベースへの修飾子として動作する事により機能するために設計されている。 新しい指示子と標準の指示子が与えられる場合、新しい指示子を理解しないアプリケーションは標準の指示子によって指定される振る舞いを既定とし、新しい指示子を理解するようなアプリケーションは標準命令に関連する要求点を修正するようにそれを認識する。 このようにして、Cache-Control 指示子はその基底のプロトコルを変更する必要なく拡張する事ができる。
この拡張メカニズムは、それに元々の HTTP バージョンによって定義されるすべての cache-control 指示子に従い、ある特定の拡張にも従い、理解できない指示子はすべて無視するような HTTP キャッシュに依存する。
例えば、ここで private 指示子の修飾子として動作する "community" と呼ばれる新しいレスポンス指示子を仮定する。 この新しい指示子を、あらゆる非共有キャッシュに加えて、この値で名前付けされたコミュニティのメンバによってのみ共有されるあらゆるキャッシュはそのレスポンスをキャッシュできる、と定義する。 UCI というコミュニティに元々プライベートレスポンスであるものを共有キャッシュとして使わせようとするオリジンサーバは、以下のものを含む事でそうする事ができる。
Cache-Control: private, community="UCI"
このヘッダフィールドを認識するキャッシュは、例え community というキャッシュ拡張を理解しなくても、private 指示子を見つけ理解する事で、安全な振る舞いを既定とするので正しく動作するだろう。
認識できないキャッシュ指示子は、無視されなければならない。 つまり、HTTP/1.1 キャッシュには理解されないであろうあらゆるキャッシュ指示子は例えキャッシュが拡張を理解できないとしてもキャッシュの振る舞いが最小限正しいものであるように、標準の指示子 (やレスポンスの既定のキャッシュ能力) と結合され送られるという事が仮定される。
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 参照。
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) のステータスコードを持つレスポンスを返すべきである。
エンティティに複数のエンコーディングが適用されている場合は、それが適用された順に列挙されなければならない。 エンコーディングパラメータについての追加情報は、この仕様書では定義されない他のエンティティヘッダフィールドによって与える事ができる。
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 は、テキスト文書だけでなく、あらゆるメディアタイプに適用する事ができる。
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 にある規則で禁じられていなければ、メッセージを転送する前にその長さを決定できる時は常にそれを送るべきである。
Content-Location エンティティヘッダフィールドは、エンティティがリクエストされたリソースの URI とは別の場所から取得可能である時に、そのメッセージに含まれるエンティティに対するリソースの場所を与える時に使う事ができる。 サーバは、そのレスポンスエンティティに対応する別種のもの{variant} のための Content-Location を提供すべきである; 特に、それに関連するリソースが複数あり、それらのエンティティが実際に個別にアクセスされ得る別の位置{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 の意味は定義されていないので、この場合サーバはそれを無視してもかまわない。
Content-MD5 エンティティヘッダフィールドは、RFC 1864 [23] にて定義されるように、エンティティボディのメッセージ状態チェック{message integrity check} (MIC) をエンティトゥエンドで提供するという目的を持つエンティティボディの MD5 ダイジェストである。 (注: MIC は転送時における偶発的変化を発見するには有効であるが、故意的攻撃においては十分に対抗はできない。)
Content-MD5 = "Content-MD5" ":" md5-digest md5-digest = <RFC 1864 に従った 128 bit MD5 ダイジェストの base64>
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 以外の改行規定を持つテキストタイプの伝送を許している。
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 バイト持っていると仮定する。
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) レスポンスを送るであろうという事を当てにはできない。
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 にて更に詳しく記述されている。
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 ヘッダフィールドを含めなければならない。
Date ヘッダフィールドを持たないメッセージが、メッセージが受信者によってキャッシュされたり、Date ヘッダが要求されるプロトコルによって経由されていれば、受信者がそれを割り当てなければならない。 時計を持たない HTTP 実装は、使うたびにその有効性を再検証しない限りはレスポンスをキャッシュしてはならない。 HTTP キャッシュ、特に共有キャッシュは、NTP [28] のような、信頼できる外部の標準の時計と同期するためのメカニズムを使うべきである。
クライアントは、PUT リクエストや POST リクエストのように、エンティティボディを含むようなメッセージにのみ Date ヘッダフィールドを送るべきであるが、省略してもよい。 時計を持たないクライアントは、リクエストに Date ヘッダフィールドを送ってはならない。
Date ヘッダ中に送られる HTTP-date は、メッセージ生成後の日付・時刻を表すべきではない。 もし、実装がかなり正確な日付・時刻を生成できるのでなければ、メッセージの生成時刻として最も利用可能な近似値を表すべきである。 理論上は、日付はエンティティを生成する直前の時刻を表すべきである。 しかし実用上は、メッセージの生成中ならば、その意味上の値に影響を及ぼす事無く、いつでも生成できる。
オリジンサーバ実装の中には、利用可能な時計を持っていないものがあるかもしれない。 時計の無いオリジンサーバは、信頼ある時計を持つシステムやユーザによるリソースに関連付けられた値で無ければ、Expires や Last-Modified 値を割り当ててはならない。 しかし、そのサーバが設置される時刻以前の、それが過去であるとわかっている Expires 値は割り当てる事ができる (これは、各々のリソースの Expires 値を分けて保存する事無く、レスポンスの "pre-expiration" を許す) 。
ETag レスポンスヘッダフィールドは、リクエストされたバリアントのエンティティタグの現在の値を示す。 エンティティタグと共に使われるヘッダは、section 14.24, 14.26, 14.44 にて記されている。 エンティティタグは、同じリソースからの他のエンティティとの比較に使う事ができる (section 13.3.3 参照)。
ETag = "ETag" ":" entity-tag
例を見よ。
ETag: "xyzzy" ETag: W/"xyzzy" ETag: ""
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 参照。
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) にて何らかの指示がなされていなければ、そのレスポンスはキャッシュ可能である。
もし From リクエストヘッダフィールドが与えられていれば、そこにはリクエストしているユーザエージェントを操っている人間のインターネット e-mail アドレスが含められているべきである。 そのアドレスは、RFC 1123 [8] によってアップデートされた RFC 822 [9] の中で定義されているような、マシンが使えるものであるべきである。
From = "From" ":" mailbox
例を見よ。
From: webmaster@w3.org
このヘッダフィールドは、ログを取るという目的や不正なあるいは望まないリクエストの原因を究明するために使う事ができる。 アクセス保護の安全性が確保できない形態では使うべきではない。 このフィールドは、このリクエストがそのメソッドを実行する責任を持つ者に代わって実行された、という事を意味する。 特に、ロボットエージェントは、受信後に問題が起きた場合にロボットを操作している責任者に連絡を取るために、このヘッダを含めるべきである。
このフィールドのインターネット e-mail アドレスは、リクエストを発行するインターネットホストとは異なるものを使う事ができる。 例えば、リクエストがプロクシを通して送られた場合、元々のリクエスト者のアドレスが使われるべきである。
クライアントは、それがユーザのプライバシーへの関心やそのサイトのセキュリティポリシーにそぐわないかもしれないので、From ヘッダフィールドをユーザの承認無しには送るべきではない。 ユーザが、リクエストの前にこのフィールドの値を使用不可にしたり、使用可能にしたり、修正したりできるようする事を強く推奨する。
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") を使用する事を意味する。 例えば、<http://www.w3.org/pub/WWW/> のオリジンサーバへのリクエストは、厳密には以下のものを含んでいるであろう。
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 を見よ。
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 ヘッダフィールドを使用しているようなリクエストについては、この仕様書ではその結果についてを定義しない。
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 ヘッダによって与えられる時刻以降に更新された場合のみ指定したエンティティを転送する事を要求する。 これを決定するためのアルゴリズムには、以下のようなものを含む。
この機能は、通信処理の負荷を最小量にするようにキャッシュされた情報を能率的に更新する事を目的にしている。
注: 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 ヘッダフィールドを使用しているようなリクエストについては、この仕様書ではその結果についてを定義しない。
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 ヘッダフィールドを使用しているようなリクエストについては、この仕様書ではその結果についてを定義しない。
もしクライアントがキャッシュとしてあるエンティティのコピーの一部を保持していて、そのエンティティ全体の最新のコピーが欲しい場合、 (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) レスポンスを使って、そのエンティティ全体を返すべきである。
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 ヘッダフィールドを使用しているようなリクエストについては、この仕様書ではその結果についてを定義しない。
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 を送るべきである。
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 も合わせて見よ。
Max-Forwards リクエストヘッダフィールドは、TRACE (section 9.8) や OPTIONS (section 9.2) の各メソッドに、次のインバウンドサーバにリクエストを転送できるプロクシやゲートウェイの数を制限するというメカニズムを提供する。 これは、クライアントが、その中間で失敗したりループしたりしているリクエスト連鎖を追跡しようとする場合に有用である。
Max-Forwards = "Max-Forwards" ":" 1*DIGIT
Max-Forwards 値は、このリクエストメッセージが残り何回転送できるかという回数を表す 10 進数の整数値である。
Max-Forwards ヘッダフィールドを含む TRACE あるいは OPTIONS リクエストを受けたプロクシやゲートウェイは、リクエストを転送する前にその値を調べ、更新しなければならない。 もし、受けとった Max-Forwards の値が 0 であれば、受信者はそのリクエストを転送してはならない代わりに、最後の受信者として応答しなければならない。 受けとった Max-Forwards の値が 0 以上であれば、転送されるメッセージにはその値から 1 を引いた値に更新した Max-Forwards フィールドを含めなければならない。
Max-Forwards ヘッダフィールドは、その仕様書で定義された他のすべてのメソッドや、そのメソッド定義の部分で明確に述べられていない拡張メソッド中では無視してもよい。
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" の確実な代用とはならない。
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 ヘッダフィールドを転送しているように見える事がある。
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 を取り次ぐ事ができる。
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 と仮定する)。
条件付き、あるいは条件の付かない GET メソッドを使った HTTP 検索リクエストは Range リクエストヘッダを使って、エンティティ全体の代わりに、エンティティの一つ以上の sub-range を要求でき、リクエストの結果として返されるエンティティに当たる。
Range = "Range" ":" ranges-specifier
サーバは、Range ヘッダを無視できる。 しかし、Range をサポートする事で転送に失敗した部分の再取得や、大きなサイズのエンティティの部分的な検索を効果的にサポートするので、HTTP/1.1 のオリジンサーバや中間キャッシュは、可能であればバイトレンジをサポートすべきである。
もし、サーバが Range ヘッダをサポートし、指定される範囲 (群) がそのエンティティに適切であれば、以下の様になる。
場合によっては、Range ヘッダに加えて If-Range ヘッダ (section 14.27 参照) を使う方が適切であるかもしれない。
もし、レンジをサポートするプロクシが Range リクエストを受け、そのリクエストをインバウンドサーバに転送し、その返答としてエンティティ全体を受け取ったとしたら、プロクシはクライアントが要求した範囲のみを返すべきである。 もしそれがキャッシュの割り当て方針にあったものであれば、キャッシュには受け取ったレスポンス全体を保存すべきである。
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 参照。
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 分である。
Server レスポンスヘッダフィールドは、リクエストを処理するオリジンサーバが使っているソフトウェアについての情報を含んでいる。 このフィールドには、複数の製品トークン (section 3.8) や、サーバとその他の重要な付属製品を識別するためのコメントを含める事ができる。 製品トークンは、アプリケーションを識別するために重要な順に列挙される。
Server = "Server" ":" 1*( product | comment )
例を見よ。
Server: CERN/3.0 libwww/2.17
レスポンスがプロクシを通して送られた場合、プロクシアプリケーションは Server レスポンスヘッダを書き換えてはならない。 代わりに、 (section 14.45 に記述されている) Via フィールドを使うべきである。
注: サーバのソフトウェアバージョンを明らかにする事で、セキュリティホールを持っている事がわかっているソフトウェアを使うサーバのマシンは攻撃を受けやすくなるかもしれない。 サーバの開発者は、このフィールドをオプションとして設定を変更できるようにする事が推奨される。
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 フィールドによって与えられた転送コーディングが受け入れ可能かを試すために、以下の規則を使う事ができる。
"chunked" 転送コーディングは常に受け入れ可能である。"trailers" というキーワードが列挙されていれば、クライアントは、自身やダウンストリームのクライアントがチャンク形式のレスポンス中の trailer フィールドを受け入れ可能である、という事を示す。このフィールドが与えられた場合、クライアントは、すべてのダウンストリームクライアントは転送されるレスポンス中の trailer フィールドを受け入れ可能であるか、あるいはダウンストリームの受信者のためにレスポンスをバッファしようとしているか、のどちらかを示している事を意味する。
注: HTTP/1.1 は、クライアントがレスポンス全体のバッファリング を保証できるようなチャンク形式レスポンスのサイズの制限するため の手段を定義しない。
現在試している転送コーディングが TE フィールド内に列挙されている転送コーディングの一つで、その qvalue が 0 でなければ、受け入れ可能である。 (section 3.9 にて定義されるように、qvalue が 0 であるという事は、"受け入れ不可能" を意味する。)
複数の転送コーディングが受け入れ可能である時は、qvalue が 0 以上で最も大きい値を持つ転送コーディングが優先される。"chunked" 転送コーディングの qvalue は常に 1 である。
TE フィールド値が空か、あるいは TE フィールドが与えられていなければ、使用できる転送コーディングは "chunked" のみとなる。 転送コーディングがなされていないメッセージは、常に受け入れ可能である。
Trailer 一般フィールドの値は、その中で与えられたヘッダフィールドのセットがチャンク形式転送コーディングにてエンコードされたメッセージの後につけられるもの{trailer} の中に含まれている事を表す。
Trailer = "Trailer" ":" 1#field-name
HTTP/1.1 のメッセージは、チャンク形式転送コーディングされ空ではない trailer を持っているメッセージ中では Trailer ヘッダフィールドを含むべきである。そうする事で、受信者は trailer の中にどんなヘッダフィ ールドがあるかを知る事ができる。
Trailer ヘッダフィールドがなければ、trailer はいかなるヘッダフィールドも含むべきではない。 "chunked" 転送コーディング中の trailer フィールドの使用の制限については、section 3.6.1 参照。
Trailer ヘッダフィールド中に列挙されるメッセージヘッダフィールドには以下のヘッダフィールドを含めてはならない。
Tranfer-Encoding 一般ヘッダフィールドは、 (もし変形がなされていれば)送信者と受信者の間でメッセージボディを安全に転送するために、適用されている変形の形を示す。 転送コーディングというのは、メッセージの特性であり、エンティティの特性では無い、という点で内容コーディングとは異なる。
Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer-coding
転送コーディングは section 3.6 にて定義される。例を見よ。
Transfer-Encoding: chunked
もしエンティティに複数のエンコーディングが適用されていたら、適用されている順番に列挙しなければならない。 エンコーディングパラメータについての追加的情報は、この仕様書に定義されていない他のエンティティヘッダフィールドによって与える事ができる。
多くの古い HTTP/1.0 アプリケーションは、Transfer-Encoding ヘッダを理解しない。
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" というプロトコル名のみを定義する。 プロトコル名としてはあらゆるトークンが使用できるが、クライアントとサーバの両方がその名前で同じプロトコルを関連付けている場合のみそれが有効となるであろう。
User-Agent リクエストヘッダフィールドは、リクエストを生成したユーザエージェントについての情報を含む。 これは、統計目的、プロトコル違反の追跡、特定のユーザエージェントの制限を回避するようなレスポンスを作成するためのユーザエージェントの自動認識のために使う。 ユーザエージェントは、リクエストの際にこのヘッダを含むべきである。 このフィールドには、複数の製品トークン (section 3.8) や、エージェントやユーザエージェントの重要な付属製品を識別するためのコメントを含める事ができる。 慣習によれば、製品トークンはアプリケーションを識別するために重要な順に列挙される。
User-Agent = "User-Agent" ":" 1*( product | comment )
例を見よ。
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
Vary フィールド値は、そのレスポンスが新鮮である{fresh} 間、キャッシュが再検証無しにそれに続くリクエストに対するレスポンスとして使ってよいかどうかを、完全に決定するためのリクエストヘッダフィールドのセットを示す。 キャッシュできない、あるいは新鮮でなくなった{stale} レスポンスの場合、Vary フィールド値はユーザエージェントにその表現を選択するために使われた基準{criteria} について通知するために使われる。 "*" という Vary フィールド値は、キャッシュはこのレスポンスが適切な表現であるかどうかをそれに続くリクエストのリクエストヘッダからは決定できない、という事を意味する。 キャッシュにおける Vary ヘッダフィールドの使い方については section 13.6 参照。
Vary = "Vary" ":" ( "*" | 1#field-name )
HTTP/1.1 サーバは、サーバ駆動型ネゴシエーションを受けるあらゆるキャッシュ可能なレスポンスに Vary ヘッダフィールド値を含むべきである。 そうする事で、キャッシュはそのリソースへの将来のリクエストを適切に解釈する事ができ、ユーザエージェントにそのリソースへのネゴシエーションの存在について知らせる事ができる。 サーバは、サーバ駆動型ネゴシエーションを受けるキャッシュ不可能なレスポンスにも、ユーザエージェントにそのレスポンス時には変化してしまうレスポンスのについての有益な情報を提供するであろうから、Vary ヘッダフィールド値を含む事ができる。
Vary フィールド値は、最もふさわしい表現を選択するために列挙されたリクエストヘッダフィールド値のみを考慮する選択アルゴリズムに従ってレスポンスとして選択された表現を知らせる field-name の列挙から成る。 キャッシュは、そのレスポンスが新鮮である間は、列挙されるフィールド名に同じフィールド値を取るような将来のリクエストでも同じ選択がなされるであろう、と仮定する事ができる。
与えられる field-name は、この仕様書にて定義されている標準のリクエストヘッダフィールドに制限されない。 フィールド名は、大文字・小文字を区別しない。
"*" という Vary フィールド値は、指定されていないパラメータはリクエストヘッダに制限されないという事を示し (例えば、クライアントのネットワークアドレス) 、レスポンスの表現の選択において役割を果たす。 プロクシサーバは、"*" という値を生成してはならない。 それは生成できるのはオリジンサーバのみである。
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 値を持つエントリを連結してはならない。
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 を尊重するキャッシュの振る舞いの必要条件は、section 13.1.2 にて述べられている。
以下は、現在定義されている warn-code の一覧と、それぞれに英語での推奨される warn-text をつけて、その意味について記述したものである。
もし実装が HTTP/1.0 以下のバージョンの一つ以上の Warning ヘッダを持ったメッセージを送ったならば、送信者はそれぞれの warning-value にレスポンスの時刻に一致する warn-date を含まなければならない。
もし実装が warn-date 付きの warning-value を持つメッセージを受け取り、その warn-date がレスポンス中の Date 値と異なっていたとしたら、それを保存、転送、使用する前にメッセージからその warning-value を消去しなければならない。 (これは、無用心なキャッシュが Warning ヘッダフィールドを処理した時に好ましくない結果を引き起こす事を防止する。) この理由によりすべての warning-value が消去されたならば、同様にして Waning ヘッダも消去されなければならない。
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 フィールド値を解析するのには特別な注意を払うべきである。
この章はアプリケーション開発者、情報提供者、そしてユーザにこの文書で記述されているような HTTP/1.1 のセキュリティ限界を知らせるという意図を持つ。 このディスカッションでは明示される問題の決定的な解決方法を含んでいないが、セキュリティリスクを減らすためのいくつかの提案を行っている。
HTTP クライアントはしばしば多くの量の個人情報 (例えばユーザの名前、場所、メールアドレス、パスワード、暗号キー、等々) を管理しているので、この情報を HTTP プロトコル経由で他のリソースへと知らないうちに漏洩していないように特に気をつけるべきである。 我々は、ユーザがそのような情報の公開についてを制御するための便利なインタフェースが提供される事と、設計者や実装者はこの部分を特に注意する事を特に強く推奨する。 歴史的に、この部分のエラーがしばしば深刻なセキュリティやプライバシー問題を引き起こし、その結果実装者の会社に対して不利な評判を高めている。
サーバは、読み込みの傾向や興味の対象で識別されるであろうユーザのリクエストについての個人情報を保存する立場にある。 この情報は本質的に明らかに秘密であり、その扱いは国によっては法によって統制されているであろう。 データを供給するために HTTP プロトコルを使用している人々は、そのようなデータは発行された結果、身元がわかってしまうその個人の許可無しには配布されないという事を保証しなければならない。
一般的なデータ転送プロトコルと同様に、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 ではそれ以上の仕組みを持たない他の貴重な目的にもしばしば使われる。
リンクのソースがプライベートな情報、あるいは他のプライベートな情報のソースを明らかにしてしまうかもしれないので、ユーザが Referer フィールドを送信するかどうかを選択出来るようにする事を強く推奨する。 例えば、ブラウザクライアントは公然に/匿名にブラウジングするためのトグルスイッチを持ち、Referer や From の各情報の送信をそれぞれ有効/無効とできる。
クライアントは、参照されるページがセキュアプロトコルで転送された場合は、(セキュアで無い) HTTP リクエストに Referer ヘッダフィールドを含むべきではない。
HTTP プロトコルを使うサービスの作者は、その Request-URI にエンコードされたデータが現れるので、機密性の高いデータの提出に GET を使ったフォームを使うべきではない。 多くの現存のサーバやプロクシ、ユーザエージェントは、第三者が見るかもしれない場所にその Request-URI を記録するだろう。 サーバは、代わりに POST を使ったフォームを使うべきである。
Accept リクエストヘッダは、アクセスされたすべてのサーバにユーザに関する情報を表す事ができる。 特に Accept-Language ヘッダは、特定の言語を理解するという事がしばしば特定の民族グループの一員である事と強く関連付けられているため、個人的な性質であるとみなすであろう情報を表す。 リクエスト毎に送られる Accept-Language ヘッダの内容を設定するためのオプションを提供するユーザエージェントは、設定のプロセス中にそれがユーザのプライバシーの損失になるという事に気づかせるようなメッセージを含むようにする事が強く推奨される。
プライバシーの損失をより制限するためには、ユーザエージェントが既定では Accept-Language ヘッダを送信しないようにし、サーバによって生成された Vary レスポンスヘッダフィールドを見つけ、その送信によってサービスの品質を向上できるとわかった場合に、サーバに Accept-Language ヘッダを送る事を開始するどうかをユーザに尋ねるようにする。
ユーザによって設定された詳細な Accept ヘッダフィールドがリクエストごとに送られ、特にそれらが品質値を含んでいたら、比較的信頼でき長い間住んでいる{long-lived} ユーザを識別するものとしてサーバによって使われうる。 そのようなユーザを識別するものは、内容供給者がクリックの追跡{click-trail tracking} をできるようにし、共同で作業する内容供給者が個々のユーザのサーバ越しのクリックの追跡{cross-server click-trail} やフォーム提出と一致できるようにする。 プロクシの内側でない多くのユーザにとって、ユーザエージェントが実行されているホストのネットワークアドレスも長く住んでいる{long-lived} ユーザを識別するものとして役に立つという事に注意せよ。 プロクシがプライバシーを高めるために使用されている環境においては、ユーザエージェントはエンドユーザに accept ヘッダコンフィギュレーションオプションを提供する事には保守的であるべきである。 極端なプライバシー手段として、プロクシは中継されたリクエストにおける accept ヘッダをフィルタできる。 高いヘッダ設定機能を供給する一般的な目的のユーザエージェントは、伴う可能性のあるプライバシーの損失に関してユーザに警告すべきである。
HTTP オリジンサーバの実装は、HTTP リクエストによって返される文書はサーバ管理者によって意図されたものだけに制限するように注意すべきである。 HTTP サーバがファイルシステムコールを含む HTTP URI を直接解釈する場合、サーバは HTTP クライアントへの配信を意図しないファイルを送信しないように特に注意を払わなければならない。 例えば、UNIX や Microsoft Windows や他のオペレーティングシステムはカレントディレクトリの上の階層のディレクトリを表すパス要素として ".." を使う。 そのようなシステムにおいては、HTTP サーバ経由でアクセス可能である事が意図されている外部リソースへのアクセスが別の方法で許されている場合、HTTP サーバは Request-URI 中にそのような構造のものを許してはならない。 同様に、サーバ内部でのみでの参照が意図されたファイル (アクセス制御ファイル、設定ファイル、スクリプトコード等) は、機密性の高い情報を含んでいるので、不適当な検索から保護されなければならない。 経験的に、そのような HTTP サーバ実装の小さなバグがセキュリティリスクになっている。
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} 動作を改善し、この作戦を使うサイトをアクセスした場合にユーザが直面する失敗の可能性を減らす。
もし単一のサーバがお互いを信頼していない複数の組織をサポートするならば、権限を持っていないところでリソースを無効にしないようにと気をつけるため、示された組織の制御の元で生成されたレスポンスの Location ヘッダと Content-Location ヘッダの値をチェックしなければならない。
RFC 1806 [35] は、HTTP ではしばしば実装されている Content-Disposition ヘッダについてのものだが、これはいくつかの深刻なセキュリティ上の問題を抱えている。 Content-Disposition は HTTP 標準では無いが、広く実装されているので、我々は実装者にその使用法とリスクについて記述している。 詳細については (RFC 1806 を更新した) RFC 2183 [49] を参照。
現存の HTTP クライアントやユーザエージェントは、典型的に認証情報を無期限に保持している。 HTTP/1.1 では、サーバがクライアントこれらのキャッシュされた証明書を破棄させるようにするための方法は提供していない。 これは、HTTP の将来の拡張で要求される重大な欠点である。証明書をキャッシュした状況ではアプリケーションのセキュリティモデルと共にそれに干渉する事ができるが、以下については制限がない。
これは現在切り離され研究されている。 この問題に一部にまつわるものがいくつかあるが、我々はスクリーンセーバへのパスワードプロテクト、アイドル時のタイムアウト、その他この問題が本来持っているセキュリティ問題を軽減するための方法を使用する事を推奨する。 特に、証明書をキャッシュするユーザエージェントにはユーザが簡単にキャッシュされた証明書を破棄を指示できるようなメカニズムを提供する事を推奨する。
その性質から必然的に、HTTP プロクシは人と人の間に入り{men-in-the-middle}、中継者による攻撃{man-in-the-middle attacks} の機会が与えられる。 プロクシが運転されているシステムの妥協{compromise} が深刻なセキュリティとプライバシーの問題を引き起こす。 プロクシはセキュリティに関係した情報、ユーザ個人やその団体についての個別の情報、ユーザやそのプロバイダが所有する所有者情報にアクセスする。 妥協したプロクシや、セキュリティやプライバシーの問題に無関心に実装、形成されたプロクシは、様々な可能性を持つ攻撃に使われる。
プロクシのオペレータは、機密性の高い情報を含み、また転送するシステムを守るように、プロクシが運転しているシステムを守るべきである。 特に、プロクシによって集められたログ情報はしばしば特に機密性の高い個人情報や組織情報を含んでいる。 ログ情報は注意深く監視すべきであり、改善や更新のための使用にも適切なガイドラインを設けるべきである。 (section 15.1.1)
キャッシングプロクシは、キャッシュの内容が悪意ある利用には魅力的なターゲットを表しているので、潜在的な弱点が付け加えられる。 キャッシュの内容が HTTP リクエストが完了した後もずっと残っているので、キャッシュへのアタックでユーザがその情報はネットワークからは既に削除されたと信じているずっと後にその情報を見る事ができる。 それ故に、キャッシュの内容は機密性の高い情報として守られるべきである。
プロクシの実装者は、その設計やコーディングの決定、そしてプロクシオペレータへ提供する設定オプション (特に既定の設定) がプライバシーやセキュリティに関わるという事を考慮すべきである。
プロクシのユーザは、プロクシを運転する人間しか信頼する価値のある人はいないという事を知っておく必要がある。 HTTP 自身はこの問題を解決できない。
暗号を適切な時に適切に使う事は、広い範囲のセキュリティや個人への攻撃に対しての防御に十分なものとなろう。 このような暗号については HTTP/1.1 の仕様書の範囲を超える。
この攻撃は存在する。この攻撃を防御する事は難しい。調査を続けよ。用心せよ。
この仕様書では、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 以前のものを実装した。 我々はそれによってこの文書が正そうとしていた多くの問題を発見する事ができたという事を彼らに感謝したい。
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
HTTP/1.1 プロトコルの定義に追加して、この文書ではインターネットメディアタイプ "message/http" と "application/http" についての仕様を示す。 message/http タイプは単一の HTTP リクエストやレスポンスメッセージを含むために使う事ができ、行長さやエンコーディングに関する全ての "message" タイプが受ける MIME 制限 に従う。 application/http タイプは一つ以上の HTTP リクエストやレスポンスメッセージ (混合されてはいないもの) のパイプラインを含むために使う事ができる。 以下のものが IANA にて登録されている。
メディアタイプ名 | message |
メディアサブタイプ名 | http |
必要なパラメータ | なし |
省略可能なパラメータ | version, msgtype
|
エンコーディングについて | "7bit", "8bit", "バイナリ" のみが許される。 |
セキュリティについて | なし |
メディアタイプ名 | application |
メディアサブタイプ名 | http |
必要なパラメータ | なし |
省略可能なパラメータ |
version, msgtype
|
エンコーディングについて | このタイプに含まれる HTTP メッセージは "バイナリ" フォーマットである; すなわち、 E-mail 経由で転送される時は、適切な Content-Transfer-Encoding の使用が必要である。 |
セキュリティについて | なし |
HTTP 206 (Partial Content) レスポンスメッセージが複数の範囲の内容 (複数の重ならない範囲のリクエストへのレスポンス) を含む時、これらはマルチパートメッセージボディとして転送される。 この目的のためのメディアタイプは "multipart/byteranges" と呼ばれる。
multipart/byteranges メディアタイプは二つ以上の部分を含み、それぞれに自身の Content-Type と Content-Range フィールドを持つ。 要求される境界パラメータはそれぞれのボディ部分を分けるために使われる境界文字列を指定する。
メディアタイプ名 | multipart |
メディアサブタイプ名 | byteranges |
必要なパラメータ | boundary |
省略可能なパラメータ | なし |
エンコーディングについて | "7bit", "8bit", "バイナリ" のみが許される。 |
セキュリティについて | なし |
例を見よ。
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--
注意
この文書は 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 は、エンティティが公開されている様々な表現や拡張可能なメカニズムによって転送できるようにするためにインターネットメール (RFC 822 [9]) や Multipurpose Internet Mail Extensions (MIME [7]) のために定義されている多くの構造を使用する。 しかし、RFC 2045 ではメールについて議論し、HTTP は RFC 2045 中に表されているものとは違ういくつかの特徴を持っている。 これらの違いはバイナリ接続以上にパフォーマンスを最適化するために、新しいメディアタイプをより自由に使用できるために、日付の比較を容易にするために、そしていくつかの初期の HTTP サーバやクライアントの実行を認めるために注意深く選ばれた。
この付録では HTTP が RFC 2045 と異なる具体的な部分を表す。厳密な MIME 環境へのプロクシやゲートウェイはこの違いを知るべきであり必要な部分での適切な変換を提供すべきである。 また MIME 環境から HTTP へのプロクシやゲートウェイもいくつか変換が必要であるのでこの違いを知る必要がある。
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 の仕様ではない。
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 中にてチェックサムを使うあらゆる内容に対して推奨される。
HTTP/1.1 は日付比較の処理を簡単にするために制限された日付フォーマット (section 3.3.1) のセットを使用する。 他のプロトコルからのプロクシやゲートウェイは、確実にメッセージ中に与えられるあらゆる Date ヘッダも HTTP/1.1 フォーマットの一つに従い必要であれば日付を書き換えるべきである。
RFC 2045 は HTTP/1.1 の Content-Encoding ヘッダフィールドに相当するどんな概念も含んでいない。 これはメディアタイプを修正子のように動作するので、HTTP から MIME 準拠のプロトコルへのプロクシやゲートウェイは Content-Type ヘッダフィールドの値を変更するか、あるいはメッセージを転送する前にエンティティボディをデコードするかしなければならない。 (インターネットメールについての Content-Type のいくつかの実験的なアプリケーションは既に Content-Encoding と等価な機能を行う ";conversions=<content-coding>" のメディアタイプパラメータを使用している。 しかし、このパラメータは RFC 2045 の一部ではない。)
HTTP は RFC 2045 の Content-Transfer-Encoding (CTE) フィールドを使用していない。 MIME 準拠のプロトコルから HTTP へのプロクシやゲートウェイは HTTP クライアントへとレスポンスメッセージを配信する前にあらゆる identify で無い CTE ("quoted-printable" や "base64") エンコーディングを取り除かなければならない。
HTTP から MIME 準拠のプロトコルへのプロクシやゲートウェイはメッセージがそのプロトコル上で安全に転送されるための正しいフォーマットとエンコーディングがなされる事を保証する責任を持つが、ここでの "安全な転送" とは使用されているプロトコルの制限によって定義される。 そのようなプロクシやゲートウェイは、もしそうする事が目的のプロトコル上での安全な転送の可能性を高めるのであれば、適切な Content-Transfer-Encoding を持ったデータをラベル付けすべきである。
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
MHTML [45] 実装に伴うコードを共有する HTTP 実装は、MIME 行末制限に気をつける必要がある。 HTTP にはそのような制限は無いので、HTTP は長い行を折り返さない。HTTP によって転送されている MHTML メッセージは、HTTP はすべてのメッセージボディを付加物{payload} として転送し、その中に含まれるであろう内容や MIME ヘッダラインを解釈しないので、行末制限、折り返し、公式化などを含んだ、すべての MHTML の慣習に従う。
RFC 1945 や RFC 2068 ではいくつかの既存の HTTP 実装によって使われているプロトコル要素について記述したが、これらは多くのHTTP/1.1 アプリケーションを通じて一貫していなく、また正確ではない。 実装者はこれらの機能を知っておいたほうがよいが、他の HTTP/1.1 アプリケーションにおいてそれらの存在や通信協力{interoperability} を当てにはできない。 これらの内のいくつかは実験的な機能として提案されるものを示し、またいくつかは基本の HTTP/1.1 仕様書中に現在表された欠如を実験的な配置が見つける機能を記述する。
Content-Disposition や Title のような、SMTP や MIME からのいくつかの他のヘッダもまたしばしば実装される (RFC 2076 [37] 参照)。
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 実装に適用されるために信じられる唯一の情報だからである。 ファイル名は端末構成部品としてのみ扱われるべきである。
このヘッダが content-type に application/octet-stream を持つレスポンス中で使われる場合、ユーザエージェントはレスポンスを表示すべきではなく、直接「レスポンスを名前を付けて保存」ダイアログを記入する事が暗黙的に提案される。
Content-Disposition のセキュリティ上の問題については section 15.5 参照。
前のバージョンに従うように指示する事はプロトコル仕様書としての範疇を超える。 しかしながら、HTTP/1.1 は前のバージョンを簡単にサポートさせられるように慎重に設計された。 この仕様書を作った時 (1996) に、我々が HTTP/1.1 サーバに以下を期待していたであろう事に注目する価値はある。
また、我々は HTTP/1.1 クライアントには以下を期待していたであろう事に注目する価値はある。
多くの HTTP/1.0 実装では、それぞれの接続はリクエストの前にクライアントによって確立され、レスポンスを送った後にサーバによって切断される。 実装の中には RFC 2068 [33] の section 19.7.1 中に記される Keep-Alive バージョンの持続的接続を実装しているものがある。
この章では HTTP/1.0 と HTTP/1.1 との間での主な違いを簡単に述べる。
クライアントとサーバは 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.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] 中に記述されている。
この仕様書はキーワードの仕様について正しくまた曖昧で無い様に慎重に検査された。 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)
ここにあるエラーの結果はインターネットに重要な影響を及ぼしうるので、実装者が状況をこれ以上悪くする事を、また実装者が以下の問題を扱う事を避けるためのメッセージ転送の必要条件の書き直し:
この変更により 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, and 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] 参照。
索引についてはこの RFC の PostScript 版を見ていただきたい。
Copyright © The Internet Society (1999). All Rights Reserved.
この文章とその翻訳は、複製し他人に配布する事ができ、またその実装についてのコメント、その他の方法を用いた説明、その補助となるような派生的作業はそれらの中に上の著作権表示とこの段落を含む事によって、その全て又は一部を、いかなる制約も受けずに、作成、複製、発表、及び配布する事ができる。 しかしながら、インターネット標準化プロセスにて定義されている著作権のための手続きに従わなければならないような場合の中でインターネット標準を開発するという目的に必要である、あるいは英語以外の言語に翻訳する必要があるという場合を除いて、この文章自体を、その著作権表示や、インターネット学会あるいは他のインターネット団体への参照を削除するような、いかなる変更もできない。
上で認めた制限された許諾は永続的なものであり、インターネット学会及びその継承者や譲渡者によって取り消される事は無い。
この文書とここに含まれた情報は、"そのまま {AS IS}" である事を基に提供され、インターネット学会、及び IETF は、この中の情報の使用が、商用利用及び特定用途においていかなる権利もいかなる暗黙的保障も侵害していないという保障への制限を含め、明示的に又は暗黙的に、全ての保障を放棄する。
RFC Editer 機構の資金は、現在インターネット学会から提供されている。