[409] [DFN[[[reactive negotiation]]]] ([DFN[[RUBYB[[[エージェント駆動折衝]]]@en[agent-driven negotiation]]]])
は、[[鯖]]が提供したリストに基づき[[利用者エージェント]]が[[表現]]を選択する[[内容折衝]]です。

* 仕様書

[REFS[
- [407] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-3.4.2>
]REFS]

* 処理モデル

[410] [[reactive negotiation]] では、
[[起源鯖]]が最初の[[応答]]に代替[[表現]]の[[資源]]のリストを含めます。
[[利用者エージェント]]はその[[応答]]に含まれる[[表現]]を用いても構いませんが、
それが最適だと考えない場合は、リストに示されたメタデータによりいずれか1つ以上の代替[[資源]]を選び、
[CODE(HTTP)@en[[[GET]]]] [[要求]]を発行します。 [SRC[>>407]]

;; [419] このために [CODE(HTTP)[[[300]]]] [[状態符号]]が用意されています。
ただし [CODE(HTTP)[[[300]]]] 以外を使っても構わないようです。

[FIG(sequence)[
:C:[[利用者エージェント]]
:S:[[起源鯖]]
:C -> S:[[要求]]
:S -> C:選択肢リスト付き[[応答]]
:#C#:リストから[[資源]]を選択
:C -> S:選択した[[資源]]を[[要求]]
:S -> C:選択された[[資源]]を[[応答]]
]FIG]

[411] この代替[[資源]]の選択は、[[利用者エージェント]]によって自動的に行っても構いませんし、
メニューを生成して[[利用者]]に選ばせても構いません。 [SRC[>>407]]

[412] [[鯖]]は、代替[[資源]]のリストのみを送り、最初の[[表現]]を送らないことにしても構いません
[SRC[>>407]]。

[413] [[reactive negotiation]] は、[[型]]や[[言語]]や[[符号化]]のような共通の次元で異なっている時や、
[[要求]]から[[利用者エージェント]]の能力を判断しかねる時には有用です。 [SRC[>>2]]

[414] [[reactive negotiation]] は、公開[[キャッシュ]]によって[[鯖]]の負荷やネットワークの利用を削減している時にも有用です
[SRC[>>2]]。

[415] [[reactive negotiation]] はリストを送信しないといけないため転送時間が増えることや、
別の[[表現]]を得るために別の[[要求]]を送らないといけないといった欠点があります。 [SRC[>>2]]

[421] 選択後の[[資源]]の取得は新たな [CODE(HTTP)@en[[[GET]]]] [[要求]]として行われるため、
[CODE(HTTP)@en[[[GET]]]] 以外には [[reactive negotiation]] は簡単には使えません。
他の[[要求メソッド]]でも [[reactive negotiation]] を提供したければ、
結果を[[鯖]]側で別の [CODE(HTTP)@en[[[GET]]]] 可能な [[URL]] に保存するなど、
[[proactive negotiation]] よりも複雑な処理が必要になります。

* 歴史

[FIG(quote)[
[FIGCAPTION[
[408] RFC 2068・2616 (HTTP/1.1)  12.2 Agent-driven Negotiation
]FIGCAPTION]

> With agent-driven negotiation, selection of the best representation
for a response is performed by the user agent after receiving an
initial response from the origin server. Selection is based on a list
of the available representations of the response included within the
header fields [DEL[(this specification reserves the field-name Alternates, as described in appendix 19.6.2.1)]]
or entity-body of the initial response, with each representation identified by its own URI.
Selection from among the representations may be performed automatically
(if the user agent is capable of doing so) or manually by the user selecting from a
generated (possibly hypertext) menu.

[DFN[エージェント駆動折衝]]では、[[利用者エージェント]]は[[起源サーバー]]から最初の[[応答]]を受信した後で最善の[[表現]]の選択を行います。
最初の応答の[[頭欄]]又は [CODE(ABNF)[[[entity-body]]]]
の中には、それ自身の [[URI]]
で識別される利用可能な表現の一覧が含まれていて、
これに基づいて選択します。 [DEL[(この仕様書は [CODE(HTTP)[[[Alternate]]]] という欄名を予約しています。)]]
表現の選択は (利用者エージェントにそうする能力があれば) 
自動的に行っても構いませんし、 (おそらく[[ハイパーテキスト]]で)
生成されたメニューから[[利用者]]が手動で選択しても構いません。

> Agent-driven negotiation is advantageous when the response would vary
over commonly-used dimensions (such as type, language, or encoding),
when the origin server is unable to determine a user agent's
capabilities from examining the request, and generally when public
caches are used to distribute server load and reduce network usage.

エージェント駆動折衝は、応答が広く使われている次元
(型、[[言語]]、[[符号化]]など) によって変化する場合や、
起源サーバーが要求を検査しても利用者エージェントの能力を決定できない場合や、
サーバーの負荷を分散させたりネットワークの使用を削減するために公開キャッシュが使われている一般的な場合に有利です。

> Agent-driven negotiation suffers from the disadvantage of needing a
second request to obtain the best alternate representation. This
second request is only efficient when caching is used. In addition,
this specification does not define any mechanism for supporting
automatic selection, though it also does not prevent any such
mechanism from being developed as an extension and used within HTTP/1.1.

エージェント駆動折衝は、最善の代替表現を得るために二番目の要求を必要であるという欠点があります。
この二番目の要求はキャッシュが使われているときだけ有効です。
加えて、この仕様書は自動的選択に対応する機構を定義していません。
但し、そのような機構を拡張として開発して [[HTTP/1.1]] で使うことも妨げてはいません。

> HTTP/1.1 defines the 300 (Multiple Choices) and 406 (Not Acceptable)
status codes for enabling agent-driven negotiation when the server is
unwilling or unable to provide a varying response using server-driven negotiation.

HTTP/1.1 は、[[サーバー駆動折衝]]を使って変化させた応答を提供するつもりがないか、
それができないときにエージェント駆動折衝を有効化する、
[CODE(HTTP)[[[300]]]] (複数選択肢) と [CODE(HTTP)[[[406]]]]
(受け入れ不能) の2つの[[状態符号]]を定義しています。
]FIG]

[FIG(quote)[
[FIGCAPTION[
[420] RFC 2068・2616 (HTTP/1.1) 12.3 Transparent Negotiation
]FIGCAPTION]

> Transparent negotiation is a combination of both server-driven and
agent-driven negotiation. When a cache is supplied with a form of the
list of available representations of the response (as in agent-driven
negotiation) and the dimensions of variance are completely understood
by the cache, then the cache becomes capable of performing server-driven negotiation on behalf of the origin server for subsequent
requests on that resource.

[DFN[透過折衝]]は、[[サーバー駆動折衝]]と[[エージェント駆動折衝]]の2つの組合せです。
[[キャッシュ]]が (エージェント駆動折衝として)
応答の利用可能な表現の一覧の形で供給された時は、
キャッシュはその資源についてサーバー駆動折衝応答ができるようになります。

> Transparent negotiation has the advantage of distributing the
negotiation work that would otherwise be required of the origin
server and also removing the second request delay of agent-driven
negotiation when the cache is able to correctly guess the right response.

透過折衝には、本来起源サーバーが必要であった折衝を分散させることができ、
キャッシュが正しい応答を正しく推測できるならエージェント折衝の二番目の要求の[RUBY[間] [ま]]をなくすこともできるという利点があります。

> This specification does not define any mechanism for transparent
negotiation, though it also does not prevent any such mechanism from
being developed as an extension [DEL[and]] [INS[that could be]] used within HTTP/1.1. [DEL[An HTTP/1.1 cache performing transparent negotiation MUST include a Vary header field in the response (defining the dimensions of its variance) if it is cachable to ensure correct interoperation with all HTTP/1.1 clients. The agent-driven negotiation information supplied by the origin server SHOULD be included with the transparently negotiated response.]]

この仕様書は、透過折衝の機構を定義していません。
しかし、そのような機構を HTTP/1.1 で使うことのできる拡張として開発することを妨げてもいません。 [DEL[透過折衝を行う HTTP/1.1 キャッシュは、応答がキャッシュ可能であるなら、全ての HTTP/1.1 クライアントに正しく解釈されるようにするため、その応答中に (変化の次元を定義する) [CODE(HTTP)[Vary]] 頭欄を含めなければ'''なりません'''。起源サーバーにより供給されるエージェント折衝情報は透過折衝した応答に含める'''べきです'''。]]
]FIG]

* 実装

[416] [[reactive negotiation]] は [[HTTP]] 仕様書上の概念としては定義されているものの、
実際には[[利用者エージェント]]が自動的に選択できるリストの仕組みが
[[HTTP]] 本体仕様書で定義されていないこともあり、現実にはほとんど用いられていません。

[417] [CODE(HTTP)@en[[[Alternates:]]]] [[ヘッダー]]のようにリストを記述する仕組みが提案されてはいますが、
広く普及するには至っていません。

[418] [CODE(HTTP)[[[300]]]] や [CODE(HTTP)[[[406]]]] の[[応答]]により、
あるいは場合によっては [CODE(HTTP)[[[200]]]] [[応答]]により、
[[利用者]]が選択できるメニューを含む [[HTML文書]]などが提供されることは、
しばしばあります。これも仕様上の [[reactive negotiation]] と言えなくはありません。
(>>411 の通り、手動による選択は明示的に認められています。)
しかし、それは [[Web]] 上にありふれたただの[[ハイパーリンク]]と技術的に何ら変わりありませんから、
敢えて[[内容折衝]]という概念で説明する必要もないでしょう。

[422] [[HTTP]] の原理主義的な人々の間では[[内容折衝]]は人気の機能であり、
未だに [[HTTP]] の仕様書には記述が残っていますが、今後も [[reactive negotiation]] 
が普及しそうな気配はありません。そもそも [[reactive negotiation]]
がなければ実現できないことが存在していないので、
実装しようとする動きも利用しようとする動きも出てこないのでしょう。

* 関連

[423] [[利用者エージェント]]が[[利用者エージェント]]側の機能や環境などの条件によって処理を分けるという点では、
[[Media Queries]] が似た技術とも言えます。 [[HTML]] や [[CSS]]
などでは [[Media Queries]] を使って環境ごとに異なる[[レンダリング]]や異なる[[スクリプト]]の処理を実行できます。 [[reactive negotiation]] とは違って1回のアクセスに複数の[[要求]]と[[応答]]の往復が必要にはなりませんし、
[[窓]]の大きさの変更などの環境の動的な変化にも対応できます。

* メモ

[1]
[Q[[ABBR[UA][利用者エージェント]]駆動折衝]]と訳した方が良いのかも・・・とか思いつつ。