内容折衝

内容折衝 (HTTP)

仕様書

分類

[12] RFC 7231 は、利用者エージェント希望に基づきが選択する proactive negotiation (旧・鯖駆動折衝) とのリストに基づき利用者エージェントが選択する reactive negotiation (旧・エージェント駆動折衝) に分類しています。更に、その他の内容折衝の実現例として、 複数の部分を含む表現から利用者エージェントが選択する条件付き内容 (conditional content) 表現スクリプトを含んでいる活性内容 (active content) 中間器が選択を行う透過内容折衝を挙げています。 >>9

プロトコル

処理

[24] 詳細はそれぞれの内容折衝の手法の項を参照。

[19] 内容折衝により側で行う処理にはいくつかの種類があります。

[20] 対象資源から応答で返す表現の決定が内容折衝の主目的です。 この場合は認証などの処理よりも後、 条件付き要求範囲要求よりは前に内容折衝の処理が行われます。

[21] エラーを表す応答POST の処理結果を表す応答など対象資源自体ではない応答表現の決定にも内容折衝は用いられます。これは認証などの処理でのエラーを表すこともあれば、条件付き要求などの処理のエラーを表すこともあります。またこの場合は内容折衝の後から条件付き要求範囲要求が適用されることはありません。

[22] 内容折衝の処理自体がエラーとなることもあります。その場合のエラーを表す応答にも内容折衝を適用できることもありますが、再帰的にエラーとなっては困りますから、実装時は注意が必要です。

[23] 例えば 406 応答内容折衝は、 通常の内容折衝より簡易的な処理に切り替える必要がある (あるいは無効にする必要がある) かもしれません。

内容折衝の問題点

[28] 内容折衝が広く普及しない背景には、実用上の様々な問題があります。

[29] 内容折衝のためのの設定は必ずしも簡単ではありません。 Apache MultiViews のように比較的容易な方法で有効にすることができる実装もありますが、 優先度を適切に設定することが難しいなど、活用するのは簡単ではありません。

[30] 内容折衝のために複数のファイルを用意する場合、それらの更新時に内容を同期する必要がありますが、 しばしばその作業は煩雑で忘れがちです。正しい状態を維持することは必ずしも簡単ではありません。

[31] 内容折衝を導入することで、色々なシステムに悪影響が出ることがあります。 これは必ずしも関係するシステム上やプロトコル上の欠陥ではなく、 仕組み上は対応していたとしても運用するのが難しいものも含みます。 例えば次のようなものがあります。

[34] 内容折衝により見る人によって得られる内容が異なるということは、 URLリンクを他の人に提示しても、その人が同じものを見るとは限らないことになります。 これは多くの人が持っている暗黙の前提に反するので、混乱の元になります。

[36] 内容折衝は、おおよそどんなものでも URL で識別できるという Web の特徴を崩すものなので、できるだけ避けるべきです。
[37] どんなものでも URI で識別できるという世界観を持つ Semantic Web を支持する人達の中には、なぜか RDFHTML内容折衝により同じ URL で提供することを好む人もいて、不思議です。
[38] Web開発に携わる人達は、 URL で識別された資源を取得する処理を実装する時や、 デバッグ時などに、それを (HTML でないとしても) まず Webブラウザーで開いて確認したりすることがあります。 テキストベースのファイル形式ならそれで十分なことも多く、手軽です。 内容折衝は、こうした開発を難しくします。

歴史

[5] HTTP (RFC2068 1.3, RFC2616 1.3)
content negotiation
The mechanism for selecting the appropriate representation when servicing a request, as described in section 12. The representation of entities in any response can be negotiated (including error responses).
内容折衝
要求を service するときに適当な表現を選択する機構。 任意の応答中の実体の表現は折衝することができる (誤り応答を含む)。
[10] RFC 2068・2616 (HTTP/1.1) 12 Content Negotiation

Most HTTP responses include an entity which contains information for interpretation by a human user. Naturally, it is desirable to supply the user with the "best available" entity corresponding to the request. Unfortunately for servers and caches, not all users have the same preferences for what is "best," and not all user agents are equally capable of rendering all entity types. For that reason, HTTP has provisions for several mechanisms for "content negotiation" -- the process of selecting the best representation for a given response when there are multiple representations available.

ほとんどの HTTP 応答は、人間利用者が解釈する情報を含んだ実体を含んでいます。 当然、要求に対応する「利用可能な最善」の実体を利用者に供給するのが望ましいといえます。 サーバーキャッシュには嬉しくないことですが、 何が「最善」であるかに全ての利用者が同じものを好むわけではありませんし。 全ての利用者エージェントが全ての実体型をレンダリングする能力を等しく有しているわけでもありません。 こうした理由から、 HTTP は「内容折衝」という、 当該応答の複数の表現が利用可能なときに最善の表現を選択する処理のための機構を幾つか用意しています。

Note: This is not called "format negotiation" because the alternate representations may be of the same media type, but use different capabilities of that type, be in different languages, etc.

注意 : 代替表現は同じ媒体型で、その型の異なる能力を使っていたり、 異なる言語で書かれていたりのような場合もあるので、「書式折衝」 とは呼びません。

Any response containing an entity-body MAY be subject to negotiation, including error responses. There are two kinds of content negotiation which are possible in HTTP: server-driven and agent-driven negotiation. These two kinds of negotiation are orthogonal and thus may be used separately or in combination. One method of combination, referred to as transparent negotiation, occurs when a cache uses the agent-driven negotiation information provided by the origin server in order to provide server-driven negotiation for subsequent requests.

entity-body を含んだ任意の実体は、 誤り応答も含めて、折衝の対象にして構いません。 HTTP で可能な内容折衝には2種類あります。 この2種類の折衝は直行するものですから、 別々に使っても構いませんし、組合せても構いません。 組合せる方法の一つは、透過折衝と呼ばれるもので、 起源サーバーが以後の要求についてのサーバー駆動折衝を提供するために提供したエージェント駆動折衝情報をキャッシュが使用するときに行われます。

12.1 Server-driven Negotiation

サーバー駆動折衝参照。

12.2 Agent-driven Negotiation

エージェント駆動折衝参照。

12.3 Transparent Negotiation

透過折衝参照。

電子メールにおける内容折衝

実装

[14] Apache は、 1.3 の頃から内容折衝に対応しています。 2000年代初め頃には拡張子のない URL が流行しましたが、 Apache でそれを実現する手法の一つとしてもよく用いられました。

[13] Accept-Language: を用いた言語に関する内容折衝 (proactive negotiation) は、多言語対応した Webアプリケーションを中心に、 しばしば使われています。

[15] その他の内容折衝は、実装されていることも少なくありませんが、 事実上ほとんど使われていません。 Accept-Encoding: による内容符号化に関する内容折衝は、 ほとんどのクライアントが標準的な内容符号化すべてに対応していて、 それ以外の内容符号化が使われることはほとんどないため、 事実上意味をなしていません。 Accept: によるMIME型に関する内容折衝は、異なる形式の同じ内容のデータを同じ URL で提供するのが便利なことがほとんどないため、あまり使われていません。

[16] >>12 の定義によれば User-Agent: の値に基づく応答文書の使い分けも内容折衝の一種ということになり、 これは多くの Webアプリケーションで行われていますが、 技術的には HTTP の提供する仕組みとの関連性が薄いものです。

[17] レンダリングされる装置や利用方法による違いは、内容折衝ではなく、 別の URL によって提供されるのが一般的です。例えば、通常の HTML と印刷用の PDF を別の URL で提供したり、通常の HTML携帯電話向けの HTML を別のドメインで提供したり、 ダウンロード提供する画像をサイズにより別のファイル名としたりが普通であり、 技術的には内容折衝を用いていません。 10年代になってからはレスポンシブデザインにより、単一の HTMLデスクトップ向けとスマートフォン向けの内容を提供するのが一般的になってきていますが、 やはりこれも HTTP内容折衝とは異なるものです。 (>>12 の分類によれば条件付き内容に当てはまるでしょうが、 HTTP とは関係ない話です。)

メモ

[18] 内容折衝によって HTTP の仕様上の資源表現の定義と概念が複雑になっていますし、 キャッシュの実装も複雑化しています。内容折衝は一見便利な機能ですが、 >>15 の通り現在ではあまり使われなくなっていますし、 本当に必要だったのかは大変怪しいところです。 (今更削除するのも困難ですが...)

[6] アイデアのメモ。

問題: 日本語版と英語版がある Webサイトで、 リンクはすべて折衝が行われる URI を使って記述されている。 Accept-Language日本語を最優先にしていると、通常は日本語版が Webブラウザに表示されるが、敢えて英語版が見たく、 Web頁 A.ja 内のリンクを使って A.en に移動する。ここで、更に A.en 内のリンクから B に移動すると、日本語版が表示されてしまうのだが、 英語版の方が自然ではないか。

(あくまで例であり、言語以外に媒体型その他でもいい。 日本語英語Accept-Language に入っていない場合というシナリオも興味深い。)

すぐ思いつく対策: A.en 内のリンクURIB ではなく B.en にすればよい。

すぐ思いつく対策の問題:

: Webブラウザを修正する。 rel=alternate その他代替版への移動であることが明確な方法で頁遷移が行われた後は、 そのリンクの情報 (例: hreflang) やリンク先の実体に付された情報 (例: Content-Language) を内容折衝で優先的に使う (Accept-Language で最優先にする)。 最優先にする対象範囲は、全体か、 URI path の階層によって決定する。

解の既知の問題:

解の REST consideration: 認証と同じように、利用者にはセッションに見えるかもしれないが実際にはセッションではない。

解の security consideration: 利用者の操作によって生成された内容折衝のための情報をに送信することになるが、 privacy 上問題となるほど繊細なものではないと思われる。

(名無しさん)

[7] コンテントネゴシエーション - Apache HTTP サーバ <http://httpd.apache.org/docs/2.0/ja/content-negotiation.html> (名無しさん)

[8] HTTP Content Negotiation and Mixed-Namespace Documents Requirements ( 版) <http://damowmow.com/temp/http-conneg-cdi-req.xhtml>

[11] 279729 – Notify user agent of xforms "capabilities" ( 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=279729>

[407] Hixie's Natural Log: Content negotiation in heterogenous XML environments ( ( 版)) <http://ln.hixie.ch/?start=1036767231&count=1>

[39] Why not conneg - WHATWG Wiki ( 版) <https://wiki.whatwg.org/wiki/Why_not_conneg>

[40] ietf-http-negotiation-scenarios-00.txt ( 版) <http://ietfreport.isoc.org/idref/draft-ietf-http-negotiation-scenarios/>

[41] Data on the Web Best Practices () <https://www.w3.org/TR/2017/REC-dwbp-20170131/#Conneg>

It is possible to serve data in an HTML page mixed with human-readable and machine-readable data, using RDFa for example. However, as the Architecture of the Web [WEBARCH] and DCAT [VOCAB-DCAT] make clear, a resource, such as a dataset, can have many representations. The same data might be available as JSON, XML, RDF, CSV and HTML. These multiple representations can be made available via an API, but should be made available from the same URL using content negotiation to return the appropriate representation (what DCAT calls a distribution).

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

Servers should support a Turtle representation, and may support other formats. If more than one representation of the Annotation is available, then the server should support content negotiation. Content negotiation for different serializations is performed by including the desired media type in the HTTP Accept header of the request, however clients cannot assume that the server will honor their preferences [rfc7231].

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

For HEAD and GET requests, if the server supports content negotiation by format or JSON-LD profile, the response must have a Vary header with Accept in the value [rfc7231].

[44] draft-ietf-http-negotiate-scenario-02 - Scenarios for the Delivery of Negotiated Content () <https://tools.ietf.org/html/draft-ietf-http-negotiate-scenario-02>

[45] Minutes for W3C Printing workshop () <https://www.w3.org/Printing/minutes960425.html>

Content negotiation was explained, HTTP 1.2 will support content negotiation.

[46] WebSub () <https://w3c.github.io/websub/#content-negotiation>

For practical purposes, it is important that the rel=self URL only offers a single representation.