Prefer

Prefer: ヘッダー (HTTP)

[49] Prefer: ヘッダーは、要求の処理方法に関するクライアントの好みを示すものです >>7

仕様書

意味

[15] Prefer: ヘッダーは、 クライアントの特定の動作を好んでいる (prefer) こと、 しかしそれは要求の成功には必須ではないことを示すために使います >>7

[8] PUT により資源を編集した後に、 変更後の完全な表現応答として得たいこともあれば、 操作が成功したことのみの最低限の応答を得たいこともあります >>7

[9] は、技術的に非妥当だったり誤っていたりするものの理解はできる要求をどう処理するか決めなければならないことがあります。 は誤りがあっても要求を処理できるかもしれませんが、 アプリケーションの要件と要求の性質によってはそれが好ましかったり、 好ましくなかったりするかもしれません。 >>7

[42] Prefer:内容折衝の仕組みとして使うべきではありません >>7

構文

[16] Prefer: ヘッダーの値は、1つ以上の「好み」 のリスト (#) です >>7

  1. 好み
  2. *
    1. OWS
    2. ,
    3. OWS
    4. 好み

[19] 好みは、好み字句に、省略可能な値と、0個以上の引数を続けたものです。 値を指定する場合は、 =字句と値の間に置きます。 また各引数の前には ; を置きます。 >>7

[29] 好み字句は、字句です。大文字・小文字不区別です。 >>7

  1. 字句
  2. ?
    1. =
    2. |
      1. 字句
      2. 引用文字列
  3. *
    1. OWS
    2. ;
    3. ?
      1. OWS
      2. 引数

[35] 同名の好み字句を複数回指定するべきではありません >>7

[36] なぜ MUST でないのか謎です。

[37] 別名の好み字句の順序は意味を持ちません >>7

[24] 引数は、名前か、名前と値を = で連結したものです >>7

[26] 引数の名前は、字句です。大文字・小文字不区別です。 >>7

  1. 字句
  2. ?
    1. =
    2. |
      1. 字句
      2. 引用文字列

[20] ただし引数のかわりに空文字列とすることができます >>7

[30] 引数の意味は好み字句に依存します。引数の順序は意味を持ちません。 >>7

[38] 同名の引数の処理には RFC は言及していないようです。

[21] ; の前後には OWS を挿入できます。また = の前後には BWS があります。 >>7

[22] 値は字句または引用文字列です。

[23] RFC 7240RFC 7230word を参照していますが、そのような定義は RFC 7230 にはありません。文脈から >>22 のように推測されます。

[46] 字句引用文字列のどちらの構文を使っても構わず、 どちらも同じ意味と思われますが、明記はされていません。また好み字句それぞれの構文の定義で値が字句または引用文字列のどちらかの構文だけが示されていることがありますが、 HTTP の仕様では歴史的にどちらでも構わないものと (行間から) 解釈されています。

[47] 2014年にもなって未だに行間を読まないといけない仕様書が新たに出版されるとは驚きですが...

[27] 好み字句についても引数についても、値がないものと、 空文字列の値は同じです >>7

[28] 次の3つのヘッダーは同じ意味です >>7

Prefer: foo; bar
Prefer: foo; bar=""
Prefer: foo=""; bar
[55] これが正しく実装されているかどうかは怪しいところです。要求ヘッダーの場合、 解釈するのはWAF などのライブラリー、個々の Webアプリケーションのいずれにせよ多数あり、相互運用性が高い状態を維持するのは困難そうです。 Prefer: safe を理解できるWebサービスPrefer: safe="" も理解できるかは大変怪しいと思われます。 (なぜ敢えて相互運用性が低くなる危険を犯してまでこんな複雑な構文と意味を規定したのでしょうか...)

文脈

[17] このヘッダー要求で使います。

[18] このヘッダーは複数指定できます。

処理

[25] は、好み字句を認識できない場合や従えない場合には、誤りを通知するのではなく、 当該字句を無視して処理を継続しなければなりません >>7

[34] Expect: の場合は未対応なら 417 を返すことになっていますが、 Prefer: ではそのような処理は認められていません。

[39] は同名の好み字句が複数回指定されていれば、誤り通知その他の通常と異なる処理をすることなく、最初のもの以外は無視するべきです >>7

[40] なぜか MUST ではないようです。

[31] は、 Connection: で明示されない限り、 Prefer:転送しなければなりません >>7

[32] 起源鯖とは別に Prefer: を受けて処理しても構いません >>7

例えば respond-async を参照。
[33] しかしその場合に Prefer: を削除しても良いとはされていないようです。

[41] 応答キャッシュに影響を及ぼす形で Prefer: を使わないよう注意することがすすめられています (urged) >>7Prefer: の指定 (またはその欠如) が応答キャッシュに影響を及ぼすなら、 Vary: Prefer または Prefer: * を指定しなければなりません >>7

[60] 実際 Upgrade-Insecure-Requests: は当初 Prefer: を使うことを計画していましたが、 撤回されました (Upgrade-Insecure-Requests: 参照)。 しかしそんな具合では、HTTPキャッシュが使われ得る場面で Prefer: ヘッダーはほとんど使いものにならないということになりますね。

好み字句

[44] Prefer: ヘッダーで指定するリスト項目それぞれの字句好み字句 (preference token) >>7 と呼ばれています。またそれぞれの項目 (あるいは好み字句によって表される概念) のことは好み (preference) >>7 と呼ばれています。

[48] 好み字句としては次のようなものが定義されています。

[54] 現時点で広く実装されているのは Prefer: safe のみです。

[45] 好み字句には IANA登録簿があります >>7, >>50

[43] RFC 7240 には priority という架空の好み字句の例 >>7 も示されています。

[58] >>57JSON 形式の好み字句一覧があります。

[51] 引数については各好み字句の項を参照。

歴史

[62] RFC 723x と同時に出版された RFC 7240 により導入されました。

[52] ODataPrefer:プロトコルに組み込んでいます。

[53] ただし OData が独自に追加した好みは現時点で IANA に登録されていません。

[4] LDPPrefer: を採用していますが、やはり独自に拡張しています。

実装

[61] Prefer:SafeWebブラウザーWebアプリケーションで多数の実装例があります。 その他の機能が実装されているのかは不明です。

関連

[10] Expect: ヘッダーの元々の定義も似たようなものでしたが、 Expect: の場合すべての中間器起源鯖がすべての「期待」 に対応していなければ拒絶しなければならないことになっており、 対応していてもいなくても良いクライアントの「好み」には相応しくないとして Prefer: が別途追加されました >>7Prefer: で指定された「好み」を無視することができます >>7

[14] Opt: ヘッダーも似たような要件で追加されたようですが、 名前空間により間接的に要望を記述するものとなっていますので、 直接指定する Prefer: とは異なっています。

Opt:名前空間と複数のヘッダーを使って記述していたものを Prefer: は単一のヘッダーで記述する形に改めたとも解釈できます。

[11] 要求URLquery に「好み」を指定することもできますが、 URL を変更するとキャッシュに悪影響があるなど相応しくないとして、 Prefer: が別途追加されました >>7

[12] Prefer: で指定する値として規定・提案されているもののうちのいくつかは、 URLqueryPOST 時の application/x-www-form-urlencodedmultipart/form-dataapplication/json などの payload body に (アプリケーション依存の方法で) 指定するので十分な気がしますが・・・。

[13] あるいは Prefer: ヘッダーにまとめずとも、 用途ごとにそれぞれ個別のヘッダーとした方が処理もしやすそうなものがいくつかありますが・・・。

[56] JSON Home Document では、 accept-prefer によりが対応できる好み字句を表明できます。

[418] Create Table ( ( 版)) <http://msdn.microsoft.com/ja-jp/library/azure/dd135729.aspx>

[59] Upgrade Insecure Requests ( 版) <https://w3c.github.io/webappsec-upgrade-insecure-requests/#feature-detect>

Note: Though the Upgrade-Insecure-Requests header expresses a preference, sending it via the existing Prefer header is problematic, as we expect the response from the server to use it as part of the cache key. Vary: Prefer is too broad, as discussed in w3/webappsec#216.

[63] Web Annotation Protocol () <https://w3c.github.io/web-annotation/protocol/wd/#h-annotation-pages>

The client should not send the Prefer header when requesting the Page, as it has already been taken into account when requesting the Collection.