Internet Engineering Task Force (IETF) J. Snell
Request for Comments: 7240 2014年6月
カテゴリ: 標準化トラック
ISSN: 2070-1721

HTTP の Prefer ヘッダー


概要

本仕様は、クライアントがリクエストの処理中にサーバーに特定の動作を行うよう要求するために使用できる HTTP ヘッダーフィールドを定義します。

このメモのステータス

これはインターネット標準化トラック文書です。

本書はインターネット技術標準化委員会(IETF)の成果物です。本書は IETF コミュニティの合意を表しており、公開のための公開レビューを受け、IESG によって公開が承認されています。インターネット標準に関する詳細は RFC 5741 のセクション2 を参照してください。

本書の現在のステータス、正誤表、およびフィードバックの提供方法に関する情報は http://www.rfc-editor.org/info/rfc7240 で入手できます。

Copyright Notice

Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

1. Introduction

HTTP リクエストの処理の過程では、サーバーや中継者が適用し得る必須または任意の動作が通常いくつか存在します。これらは応答内でさまざまな微妙な、または明白な形で現れることが多いです。

例えば、Atom Publishing Protocol [RFC5023] で定義されたものと類似して、リソースを変更するために HTTP PUT メソッドを使用する場合、サーバーは変更されたリソースの完全な表現を返すか、操作の成功完了のみを示す最小限の応答を返すかを選択することができます。どの種類の応答をクライアントに返すかの選択は通常リクエストの正常な処理には影響しませんが、たとえばクライアントが応答を受け取った後にどのようなアクションを取る必要があるかに影響する場合があります。つまり、応答内に変更後のリソースの表現を返すことで、クライアントはその後の追加の GET リクエストを送信する必要を回避できます。

同様に、リクエストを処理するサーバーは、技術的には無効または誤りがあるが理解可能なリクエストをどのように扱うかについて判断を迫られることがしばしばあります。サーバーがリクエスト内の技術的エラーを見過ごしてもリクエストを正常に処理できる場合があります。アプリケーションの特定の要件やリクエストの性質に応じて、クライアントはそのような寛容な処理が適切かどうかを判断する場合としない場合があります。

これらの場合にどの動作を適用するかの決定はリクエストを処理するサーバーに委ねられますが、サーバーはオプションの動作についてクライアントに優先を指定させたいと考えるかもしれません。

現状、HTTP には特定のリクエストの処理に関する任意の側面に対するクライアントの好みを明示的に表現する手段が定義されていません。HTTP は Expect ヘッダを提供しており、これはリクエスト処理に対する必須の期待を識別するために使用できますが、オプションのプリファレンスを伝えるためにこのフィールドを使うことには問題があります:

  1. Expect ヘッダの意味は、未認識または未サポートの期待値を記述したリクエストを中継者やサーバーが拒否することを要求するようになっている。
  2. Expect ヘッダはエンドツーエンドのヘッダですが、HTTP 仕様はそのヘッダを hop-by-hop で処理することを要求しています。つまり、クライアントとオリジンサーバーの間でリクエストを扱うすべての中継者が期待を処理し、それを適切に扱えるかどうかを判断する必要があります。

Expect ヘッダの must-understand 的な意味は、任意のプリファレンスを表現するには不向きです。

クライアントが利用できる別の選択肢として、Request URI のクエリ文字列パラメータを用いてプリファレンスを表現する方法があります。しかし URI を変更するような機構は、キャッシュが変更された URI を記録するなど望ましくない副作用を持つ可能性があります。

代替案として、本仕様はクライアントがリクエストの処理中に適用される任意の動作を要求するために使用できる新しい HTTP リクエストヘッダフィールドを定義します。さらに、新しいヘッダで使用するための初期プリファレンストークンをいくつか定義します。

本書中のキーワード "MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"MAY"、および "OPTIONAL" は [RFC2119] に示される通りに解釈されます。

1.1. 構文表記法

本仕様は拡張バッカス・ノール形式(ABNF)を使用します([RFC5234])。さらに、[RFC7230] の Sections 3.2.1 および 3.2.4 で定義される "token"、"word"、"OWS"、"BWS" ルールおよび #rule 拡張、並びに [RFC7231] の Section 8.1.3 で定義される "delta-seconds" ルールを参照によって含めます。

2. Prefer リクエストヘッダーフィールド

Prefer リクエストヘッダーフィールドは、特定のサーバー動作がクライアントによって好まれているが、リクエストの正常な完了に必須ではないことを示すために使用されます。Prefer は [RFC7231] の Section 6.1.2 で定義された Expect ヘッダーフィールドに性質が類似していますが、サーバーが指定されたプリファレンスを無視してよい点が異なります。

ABNF:

  Prefer     = "Prefer" ":" 1#preference
  preference = token [ BWS "=" BWS word ] 
               *( OWS ";" [ OWS parameter ] )
  parameter  = token [ BWS "=" BWS word ]
      

このヘッダーフィールドは拡張可能な構文で定義されており、Registry of Preferences(Section 5.1)に含まれる将来の値を許容します。リクエストの Prefer ヘッダーフィールド内の特定のプリファレンストークンをサーバーが認識しない、あるいは順守できない場合、そのトークンを無視して処理を継続し、エラーを返してはなりません。

プリファレンストークンとパラメータの両方において、空または長さゼロの値は指定されていないのと同等です。したがって、次の三つは "foo" プリファレンスに単一の "bar" パラメータを付与した等価な例です。

  Prefer: foo; bar
  Prefer: foo; bar=""
  Prefer: foo=""; bar
      

任意のプリファレンストークンに対して一連のパラメータを指定することができます。これらのパラメータの意味と適用は各プリファレンストークンの定義およびサーバーの実装に依存します。特定のプリファレンスにおけるパラメータの並び順に意味はありません。

プリファレンストークン名およびパラメータ名については比較は大文字小文字を区別しませんが、値は token 形式であれ quoted-string 形式であれ大文字小文字を区別します。

Prefer ヘッダーフィールドはエンドツーエンドであり、リクエストが転送される場合は、Prefer が Connection ヘッダで明示的に hop-by-hop と識別されない限り、プロキシはそれを転送しなければなりません([RFC7230] Section 6.1 を参照)。

さまざまな状況において、プロキシはオリジンサーバーとは独立にプリファレンスを尊重できると判断する場合があります。例えば、介在するプロキシがオリジンサーバーに関係なく 202 (Accepted) を用いた非同期処理を提供できる場合があります。そのようなプロキシは、オリジンが可能か否かにかかわらず独自に "respond-async" プリファレンスを尊重する選択をできます。

個々のプリファレンストークンは、中継者がオリジンサーバーとは独立してプリファレンスを適用できるかどうか、またどのように適用できるかについて独自の要件や制限を定義してよいものとします。

クライアントは単一メッセージ内で Prefer ヘッダーフィールドを複数使用しても、あるいは複数のカンマ区切りプリファレンストークンを含む単一の Prefer ヘッダーフィールドを使用してもよいです。複数の Prefer ヘッダーフィールドが使用された場合、それはすべてのトークンをカンマで連結した単一の Prefer ヘッダーフィールドと同等です。例えば、次のように同等です:

三つの異なるプリファレンストークンを定義する複数の Prefer ヘッダーフィールドの例:

POST /foo HTTP/1.1
Host: example.org
Prefer: respond-async, wait=100
Prefer: handling=lenient
Date: Tue, 20 Dec 2011 12:34:56 GMT

同じ三つのプリファレンストークンを定義する単一の Prefer ヘッダーフィールドの例:

POST /foo HTTP/1.1
Host: example.org
Prefer: handling=lenient, wait=100, respond-async
Date: Tue, 20 Dec 2011 12:34:56 GMT

あらゆる曖昧さを避けるため、個々のプリファレンストークンは単一リクエスト内で複数回出現してはなりません。もしプリファレンスが複数回指定されている場合、最初の出現のみが考慮されるべきです。以降の出現はエラーを示すことなく無視されるべきです。これがリクエスト内でプリファレンスの順序が重要と見なされる唯一のケースです。

サーバー駆動のコンテンツネゴシエーション、効果的なキャッシング、および任意プリファレンスの適用を適切に実装するには固有の複雑さがあるため、実装者は応答のキャッシュに影響を与える方法でプリファレンスを使用する際には注意を払うべきです。Prefer ヘッダメカニズムはコンテンツネゴシエーションには使用すべきではありません。サーバーがキャッシュの応答エンティティの扱いに差異をもたらし得るプリファレンスの任意適用をサポートする場合、クライアントが実際に Prefer を使用したかどうかにかかわらず、レスポンスには Prefer ヘッダーフィールドを列挙する Vary ヘッダフィールドが含まれていなければなりません(代替として、サーバーは [RFC7231] Section 8.2.1 で定義される特殊値 "*" を持つ Vary ヘッダを含めることができます)。ただし "Vary: *" を使用するとプロキシが応答をキャッシュできなくなることに注意してください。

プリファレンストークンは構造として HTTP Expect トークンに類似していますが、Prefer と Expect ヘッダーフィールドは目的が明確に異なり、プリファレンスは期待(expectations)として使用できません。

2.1. 

以下の例は、本仕様で定義されたさまざまなプリファレンスの使用法と、説明目的での未定義拡張の例を示します:

1. もしリクエストの処理に 10 秒を超える時間がかかる場合、非同期処理のために 202 (Accepted) 応答を返す。未定義の "priority" プリファレンスも指定されています:

POST /some-resource HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: respond-async, wait=10
Prefer: priority=5

{...}

2. 寛容(lenient)処理を使用する例:

POST /some-resource HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: Lenient

{...}

3. return=minimal プリファレンスに未定義の任意パラメータを付与する例:

POST /some-resource HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: return=minimal; foo="some parameter"

{...}

3. Preference-Applied 応答ヘッダーフィールド

Preference-Applied 応答ヘッダーフィールドは、レスポンスメッセージ内に含めることで、サーバーがどの Prefer トークンを尊重してリクエストの処理に適用したかを示す手段となります(任意)。

ABNF:

  Preference-Applied = "Preference-Applied" ":" 1#applied-pref
  applied-pref = token [ BWS "=" BWS word ]
      

Preference-Applied ヘッダの構文は Prefer ヘッダと異なり、パラメータは含まれません。

Preference-Applied ヘッダの使用は、サーバーが特定のプリファレンスを適用したかどうかが明白でなく、その曖昧さがクライアントの応答処理に影響を及ぼす場合にのみ必要です。例えば "return=representation" や "return=minimal" プリファレンスを使用する場合、クライアントは応答のペイロードを見ただけではプリファレンスが適用されたかを確実に判断できないことがあります。そのような場合に Preference-Applied ヘッダを用いることができます。

リクエスト:

PATCH /my-document HTTP/1.1
Host: example.org
Content-Type: application/example-patch
Prefer: return=representation

[{"op": "add", "path": "/a", "value": 1}]

レスポンス:

HTTP/1.1 200 OK
Content-Type: application/json
Preference-Applied: return=representation
Content-Location: /my-document

{"a": 1}

4. プリファレンス定義

以下の小節では初期セットのプリファレンスを定義します。追加のプリファレンスは利便性や他のアプリケーションによる再利用を促進するために登録できます。本仕様は IANA によるプリファレンスのレジストリを確立します(Section 5.1 を参照)。

4.1. "respond-async" プリファレンス

"respond-async" プリファレンスはクライアントがサーバーに対して非同期に応答することを好むことを示します。例えば、応答の生成にサーバー側で任意のしきい値を超える時間がかかる場合、サーバーは "respond-async" を尊重して 202 (Accepted) 応答を返すことができます。

ABNF:

  respond-async = "respond-async"
      

"respond-async" の主な動機は、クライアントが非同期応答を処理する能力およびその好みをサーバーに伝えることで、非同期処理の運用を容易にすることです。

"respond-async" プリファレンスを指定するリクエストの例:

POST /collection HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: respond-async

{Data}

202 (Accepted) を使用した非同期応答の例:

HTTP/1.1 202 Accepted
Location: http://example.org/collection/123

202 (Accepted) レスポンスは [RFC7231] によって定義されていますが、いつどのようにこの応答コードを使うか、また処理の最終結果を決定する手続きについてはほとんど指針がありません。したがって、サーバーが非同期応答をサポートするか否か、およびその方法は実装依存であり本仕様の範囲外と見なされます。

4.2. "return=representation" および "return=minimal" プリファレンス

"return=representation" プリファレンスは、クライアントが成功したリクエストへの応答にリソースの現在の状態を表すエンティティを含めることをサーバーに望むことを示します。

一方 "return=minimal" プリファレンスは、クライアントが成功したリクエストに対してサーバーに最小限の応答のみを返すことを望むことを示します。通常、そのような応答は 204 (No Content) ステータスを利用しますが、0 長のレスポンスエンティティを伴う 200 (OK) のような他のコードも適切に使用され得ます。どの応答が適切な最小応答であるかの判断は完全にサーバーの裁量です。

ABNF:

  return = "return" BWS "=" BWS ("representation" / "minimal")
      

"return=representation" を尊重する場合、返される表現はリクエストの効果的な要求 URI の表現ではない可能性があります。そのような場合、返された表現の URI を特定するために Content-Location ヘッダを使用できます。

"return=representation" プリファレンスは、クライアントとサーバー間の通信を最適化し、変更後のリソースの現在の表現を取得するための追加の GET リクエストの必要性を排除する手段を提供することを意図しています。

POST や PUT のような変更リクエストを正常に処理した後、サーバーは操作の状態を記述するエンティティ、または変更されたリソース自体の表現のいずれかを返すことを選択できます。返すエンティティの種類の選択はサーバーの裁量ですが、"return=representation" および下で定義する "return=minimal" は、応答を構築する際にクライアントの好みを考慮に入れることを可能にします。

"return=representation" を指定するリクエストの例:

PATCH /item/123 HTTP/1.1
Host: example.org
Content-Type: application/example-patch
Prefer: return=representation

1c1
< ABCDEFGHIJKLMNOPQRSTUVWXYZ
---
> BCDFGHJKLMNPQRSTVWXYZ

リソース表現を含む応答の例:

HTTP/1.1 200 OK
Content-Location: http://example.org/item/123
Content-Type: text/plain
ETag: "d3b07384d113edec49eaa6238ad5ff00"

BCDFGHJKLMNPQRSTVWXYZ

対照的に "return=minimal" は、リクエスト後にサーバーがクライアントに返すデータ量を削減できます。これは、帯域が限られたモバイル端末との通信や、クライアントが処理結果について成功したかどうか以上の情報を不要とする場合に有用です。

"return=minimal" を指定するリクエストの例:

POST /collection HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: return=minimal

{Data}

最小限の応答の例:

HTTP/1.1 201 Created
Location: http://example.org/collection/123

"return=minimal" と "return=representation" は相互に排他的な指示です。単一のリクエストで両方を含めることが意味をなす状況は想定されません。そのようなリクエストはおそらくクライアントのコーディングエラーの結果です。そのため、両方を含むリクエストはいずれも指定されていないかのように扱うことができます。

4.3. "wait" プリファレンス

"wait" プリファレンスは、クライアントがサーバーがリクエストを受け取ってから応答を生成するのにかかると予想する最大時間(秒)を設定するために使用できます。応答の生成が指定時間を超える場合、サーバーやプロキシは非同期処理モデルを選択し、例えば 202 (Accepted) を返すことができます。

ABNF:

  wait = "wait" BWS "=" BWS delta-seconds
      

HTTP メッセージはネットワークを横断し中継者によって処理される時間があることに注意することが重要です。これによりクライアントが応答を待つ合計時間は、サーバーが処理に要する時間に加えて増加します。厳密なタイミング要件を持つクライアントはこれらの要素を見積もり、wait 値を適切に調整できます。

他のプリファレンスと同様に "wait" プリファレンスは無視される可能性があります。クライアントは自分が待てる時間を超えたリクエストを放棄することができます。

例えば、次のリクエストを受け取ったサーバーは、処理に 10 秒以上かかる場合は非同期的に応答することを選ぶかもしれません:

POST /collection HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: respond-async, wait=10

{Data}

4.4. 処理プリファレンス "handling=strict" および "handling=lenient"

"handling=strict" と "handling=lenient" のプリファレンスは、リクエスト処理中に発生し得るエラー条件をサーバーがどのように扱うべきかについて、クライアントが希望する方針を(サーバーの裁量で)示します。例えば、リクエストのペイロードにいくつかの小さな構文的または意味的エラーが含まれるが、サーバーがそれを理解して正常に処理できる場合、リクエストを拒否して適切な 4xx エラーで応答するか、処理を進めるかの判断が必要になります。"handling=strict" は、個々のエラーが回復可能であってもクライアントがリクエストを拒否して欲しいことを示すために使用できます。一方 "handling=lenient" は、クライアントがサーバーにリクエストの処理を試みて欲しいことを示します。

ABNF:

  handling = "handling" BWS "=" BWS ("strict" / "lenient")
    

"strict" プリファレンスを指定するリクエストの例:

POST /collection HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: handling=strict

"handling=strict" と "handling=lenient" は相互に排他的な指示です。単一リクエストに両方を含める状況は想定されません。そのようなリクエストはクライアント実装の誤りの結果である可能性が高く、そのため両方を含むリクエストはどちらも指定されていないかのように扱うことができます。

5. IANA に関する考慮事項

'Prefer' および 'Preference-Applied' ヘッダーフィールドは、[RFC3864] で定義された "Permanent Message Header Field Names" レジストリ(http://www.iana.org/assignments/message-headers)に追加されました。

  • Header field name: Prefer
  • Applicable Protocol: HTTP
  • Status: Standard
  • Author: James M Snell <jasnell@gmail.com>
  • Change controller: IETF
  • Specification document: this specification, Section 2
  • Header field name: Preference-Applied
  • Applicable Protocol: HTTP
  • Status: Standard
  • Author: James M Snell <jasnell@gmail.com>
  • Change controller: IETF
  • Specification document: this specification, Section 3

5.1. プリファレンスのレジストリ

IANA は "HTTP Preferences" という新しいレジストリを "Hypertext Transfer Protocol (HTTP) Parameters" レジストリの下に作成しました。新規登録は Specification Required ポリシーを使用します([RFC5226])。登録されたプリファレンスの要件は Section 4 に記載されています。

登録要求は通常、必要な仕様内で公開された完成したテンプレートを含みますが、公開前に値を割り当てるために、指定専門家が仕様が公開されることに満足すれば個別に提出されたテンプレートに基づいて登録を承認することができます。指定専門家は、未登録のプリファレンスが広く展開されており迅速に登録される見込みがないと判断した場合、第三者による登録を承認することができます。

登録テンプレートは次のとおりです:

  • Preference: (Section 2 の構文規則に従う Prefer リクエストヘッダーフィールドの値)
  • Value: (プリファレンストークンの可能な値の列挙または説明)
  • Optional Parameters: (プリファレンストークンに関連する任意パラメータとその値の列挙)
  • Description:
  • Reference:
  • Notes: [optional]

"Value" および "Optional Parameters" フィールドは、特定のプリファレンストークン定義がそれらを定めていない場合、省略してよいです。

登録要求は <ietf-http-wg@w3.org> メーリングリストに送られるべきで、件名には明確に識別子を付けること(例:"NEW PREFERENCE - example")。要求後最大 14 日以内に指定専門家は承認または却下を決定し、その決定をレビューリストと IANA に通知します。却下には説明と、可能ならば要求を成功させるための提案を含めるべきです。

専門家レビュー担当者は次を確保するものとします:

  • 要求されたプリファレンス名が Section 2 の token ルールに従っており、他の登録済みプリファレンス名と同一でないこと。
  • 関連する値、パラメータ名、および値が Section 2 の ABNF 構文に従っていること。
  • 名前がプリファレンスの特異性に適切であること。すなわち、意味が特定アプリケーションに非常に特化している場合は名前もそれを反映すべきで、より一般的な名前はより一般的な用途のために利用可能にしておくこと。
  • 要求されたプリファレンスがサーバー、クライアント、または中継者を正常な処理に必要な挙動に制約しないこと。
  • プリファレンスを定義する仕様文書が、プリファレンスの使用に関する適切かつ完全なセキュリティ考慮の議論を含んでいること。

5.2. 初期レジストリ内容

"HTTP Preferences" レジストリの初期内容は次のとおりです:

  • Preference: respond-async
  • Description: クライアントがリクエストに対してサーバーが非同期に応答することを好むことを示す。
  • Reference: [this specification], Section 4.1
  • Preference: return
  • Value: "minimal" または "representation" のいずれか
  • Description: 値が "minimal" の場合、サーバーがリクエストに対して最小限の応答を返すことをクライアントが好むことを示す。値が "representation" の場合、サーバーがリクエストに対してリソースの現在状態の表現を含めることをクライアントが好むことを示す。
  • Reference: [this specification], Section 4.2
  • Preference: wait
  • Description: クライアントが、サーバーがリクエストを受け取ってから処理するのにかかると予想する時間の上限を示す。
  • Reference: [this specification], Section 4.3
  • Preference: handling
  • Value: "strict" または "lenient" のいずれか
  • Description: 値が "strict" の場合、クライアントはサーバーが厳格な検証とエラー処理を適用することを望む。値が "lenient" の場合、クライアントはサーバーが寛容な検証とエラー処理を適用することを望む。
  • Reference: [this specification], Section 4.4

6. セキュリティに関する考慮事項

クライアントが要求する特定のプリファレンスは、HTTP/1.1(および関連する仕様)で議論されているものを超えるセキュリティ上の考慮事項や懸念を導入する可能性があります。実装者は各プリファレンスの仕様と説明を参照して、関連するセキュリティ考慮事項を判断する必要があります。

サーバーが特定のプリファレンスの遵守を試みることでより大きなコストを負う可能性があります(例えば、通常は含まない表現を応答に含めるコストや、非同期応答のための状態追跡に必要なリソースの確保)。サーバーが無条件にプリファレンスに従うと、プリファレンスを悪用したサービス拒否が可能になる場合があります。サーバーはリソースの消費を避けるために、表明されたプリファレンスを無視することができます。

7. 参考文献

7.1. 規範的参考文献

[RFC2119]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997, <http://www.rfc-editor.org/info/rfc2119>.
[RFC3864]
Klyne, G., Nottingham, M., and J. Mogul, “Registration Procedures for Message Header Fields”, BCP 90, RFC 3864, September 2004, <http://www.rfc-editor.org/info/bcp90>.
[RFC5226]
Narten, T. and H. Alvestrand, “Guidelines for Writing an IANA Considerations Section in RFCs”, RFC 5226, May 2008, <https://www.rfc-editor.org/info/rfc5226>.
[RFC5234]
Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, January 2008, <https://www.rfc-editor.org/info/rfc5234>.
[RFC7230]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing”, RFC 7230, June 2014.
[RFC7231]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content”, RFC 7231, June 2014.

7.2. 参考情報

[RFC5023]
Gregorio, J., Ed. and B. de hOra, Ed., “The Atom Publishing Protocol”, RFC 5023, October 2007, <https://www.rfc-editor.org/info/rfc5023>.

Author's Address

James M Snell
Email: jasnell@gmail.com