-
Notifications
You must be signed in to change notification settings - Fork 4
/
366.txt
279 lines (214 loc) · 17.1 KB
/
366.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
- [1] 【[[HTTP]] など】[[サーバー]]と[[クライアント]]の間で、クライアントが受け取る[[資源]]の形式 ([[媒体型]], [[言語]]など) を決定すべく交わされるやり取り, あるいはその概念の総称。 Content negotiation。
- [2] 略して [[conneg]] とも。
- [3] [[HTTP]] の内容折衝では、主として [CODE(HTTP)[[[Accept-*:]]]] 欄を使ってクライアントが受け付ける形式を主張する形で[[要求]]します。
- [4] [[電子メイル]]では、送られてきたメッセージに不満があればその旨を [[MDN]] で伝え、サーバーが送り直す形で実現しています。 [[RFC3297]] などで規定されています。
* 仕様書
[REFS[
- [9] [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>
]REFS]
* 分類
[12] [[RFC 7231]] は、[[利用者エージェント]]の希望に基づき[[鯖]]が選択する
[[proactive negotiation]] (旧・[[鯖駆動折衝]]) と[[鯖]]のリストに基づき[[利用者エージェント]]が選択する
[[reactive negotiation]] (旧・[[エージェント駆動折衝]]) に分類しています。更に、その他の[[内容折衝]]の実現例として、
複数の部分を含む[[表現]]から[[利用者エージェント]]が選択する[RUBYB[条件付き内容]@en[conditional content]]、
[[表現]]が[[スクリプト]]を含んでいる[RUBYB[活性内容]@en[active content]]、
[[中間器]]が選択を行う[[透過内容折衝]]を挙げています。 [SRC[>>9]]
* 処理モデル
;; [24] 詳細はそれぞれの[[内容折衝]]の手法の項を参照。
[19] [[内容折衝]]により[[鯖]]側で行う処理にはいくつかの種類があります。
[20] [[対象資源]]から[[応答]]で返す[[表現]]の決定が[[内容折衝]]の主目的です。
この場合は[[認証]]などの処理よりも後、
[[条件付き要求]]や[[範囲要求]]よりは前に[[内容折衝]]の処理が行われます。
[21] エラーを表す[[応答]]や [CODE(HTTP)@en[[[POST]]]] の処理結果を表す[[応答]]など[[対象資源]]自体ではない[[応答]]の[[表現]]の決定にも[[内容折衝]]は用いられます。これは[[認証]]などの処理でのエラーを表すこともあれば、[[条件付き要求]]などの処理のエラーを表すこともあります。またこの場合は[[内容折衝]]の後から[[条件付き要求]]や[[範囲要求]]が適用されることはありません。
[22] [[内容折衝]]の処理自体がエラーとなることもあります。その場合のエラーを表す[[応答]]にも[[内容折衝]]を適用できることもありますが、再帰的にエラーとなっては困りますから、実装時は注意が必要です。
[EG[
[23] 例えば [CODE(HTTP)[[[406]]]] [[応答]]の[[内容折衝]]は、
通常の[[内容折衝]]より簡易的な処理に切り替える必要がある (あるいは無効にする必要がある)
かもしれません。
]EG]
* 内容折衝の問題点
[28] [[内容折衝]]が広く普及しない背景には、実用上の様々な問題があります。
[29] [[内容折衝]]のための[[鯖]]の設定は必ずしも簡単ではありません。
[[Apache]] [[MultiViews]] のように比較的容易な方法で有効にすることができる実装もありますが、
優先度を適切に設定することが難しいなど、活用するのは簡単ではありません。
[30] [[内容折衝]]のために複数の[[ファイル]]を用意する場合、それらの更新時に内容を同期する必要がありますが、
しばしばその作業は煩雑で忘れがちです。正しい状態を維持することは必ずしも簡単ではありません。
[31] [[内容折衝]]を導入することで、色々なシステムに悪影響が出ることがあります。
これは必ずしも関係するシステム上や[[プロトコル]]上の欠陥ではなく、
仕組み上は対応していたとしても運用するのが難しいものも含みます。
例えば次のようなものがあります。
[FIG(list)[
- [32] [[キャッシュ]]の扱いが極めて複雑になります。 [[HTTP]]
自身も[[内容折衝]]のせいで複雑になっています。 [[Webアプリケーション]]内部の[[キャッシュ]]や[[クライアント]]側の[[キャッシュ]]など、
関係するシステムの色々な場面で問題になります。
- [33] [[URL]] と内容を一対一に紐づけている機能やサービスが正しく動作しなくなります。
[[Webブラウザー]]の[[ブックマーク]]や[[ソーシャルブックマークサービス]]、
[[掲示板]]や [[SNS]] の [[URL]] 投稿時のサマリー等の表示など色々なものが暗黙裡にこの仮定を置いています。
- [35] [[素片識別子]]がある場合、返される[[内容]]によってその指すものが変わったり、
なくなったりするかもしれません。
]FIG]
[34] [[内容折衝]]により見る人によって得られる内容が異なるということは、
[[URL]] や[[リンク]]を他の人に提示しても、その人が同じものを見るとは限らないことになります。
これは多くの人が持っている暗黙の前提に反するので、混乱の元になります。
;; [36] [[内容折衝]]は、おおよそどんなものでも [[URL]] で識別できるという
[[Web]] の特徴を崩すものなので、できるだけ避けるべきです。
;; [37] どんなものでも [[URI]] で識別できるという世界観を持つ [[Semantic Web]]
を支持する人達の中には、なぜか [[RDF]] と [[HTML]] を[[内容折衝]]により同じ
[[URL]] で提供することを好む人もいて、不思議です。
;; [38] [[Web開発]]に携わる人達は、 [[URL]] で識別された[[資源]]を取得する処理を実装する時や、
[[デバッグ]]時などに、それを ([[HTML]] でないとしても)
まず [[Webブラウザー]]で開いて確認したりすることがあります。
[[テキスト]]ベースのファイル形式ならそれで十分なことも多く、手軽です。
[[内容折衝]]は、こうした開発を難しくします。
* 歴史
[FIG(quote)[
[FIGCAPTION[
[5] [[HTTP]] ([[RFC2068]] 1.3, [[RFC2616]] 1.3)
]FIGCAPTION]
>
: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 するときに適当な[[表現]]を選択する機構。
任意の応答中の[[実体]]の表現は折衝することができる ([[誤り応答]]を含む)。
]FIG]
[FIG[
[FIGCAPTION[
[10] RFC 2068・2616 (HTTP/1.1) 12 Content Negotiation
]FIGCAPTION]
> 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.
[CODE(ABNF)[[[entity-body]]]] を含んだ任意の実体は、
[[誤り応答]]も含めて、折衝の対象にして'''構いません'''。
HTTP で可能な内容折衝には2種類あります。
この2種類の折衝は直行するものですから、
別々に使っても構いませんし、組合せても構いません。
組合せる方法の一つは、透過折衝と呼ばれるもので、
[[起源サーバー]]が以後の要求についての[[サーバー駆動折衝]]を提供するために提供した[[エージェント駆動折衝]]情報をキャッシュが使用するときに行われます。
*** 12.1 Server-driven Negotiation
→[CODE(WikiPage)[[[サーバー駆動折衝]]]]参照。
*** 12.2 Agent-driven Negotiation
→[CODE(WikiPage)[[[エージェント駆動折衝]]]]参照。
*** 12.3 Transparent Negotiation
→[CODE(WikiPage)[[[透過折衝]]]]参照。
]FIG]
** 電子メールにおける内容折衝
[REFS[
- [27] [CITE@en[draft-ietf-http-negotiate-scenario-02 - Scenarios for the Delivery of Negotiated Content]] ([TIME[2014-10-20 07:23:06 +09:00]] 版) <https://tools.ietf.org/html/draft-ietf-http-negotiate-scenario-02>
- [26] [CITE@en[RFC 2703 - Protocol-independent Content Negotiation Framework]] ([TIME[2014-11-02 14:46:57 +09:00]] 版) <https://tools.ietf.org/html/rfc2703>
- [25] [CITE@en[RFC 3297 - Content Negotiation for Messaging Services based on Email]] ([TIME[2014-09-22 06:00:13 +09:00]] 版) <https://tools.ietf.org/html/rfc3297>
]REFS]
* 実装
[14] [[Apache]] は、 1.3 の頃から[[内容折衝]]に対応しています。
2000年代初め頃には[[拡張子]]のない [[URL]] が流行しましたが、 [[Apache]]
でそれを実現する手法の一つとしてもよく用いられました。
[13] [CODE(HTTP)@en[[[Accept-Language:]]]] を用いた[[言語]]に関する[[内容折衝]]
([[proactive negotiation]]) は、[[多言語]]対応した [[Webアプリケーション]]を中心に、
しばしば使われています。
[15] その他の[[内容折衝]]は、実装されていることも少なくありませんが、
事実上ほとんど使われていません。 [CODE(HTTP)@en[[[Accept-Encoding:]]]]
による[[内容符号化]]に関する[[内容折衝]]は、
ほとんどの[[クライアント]]が標準的な[[内容符号化]]すべてに対応していて、
それ以外の[[内容符号化]]が使われることはほとんどないため、
事実上意味をなしていません。 [CODE(HTTP)@en[[[Accept:]]]]
による[[MIME型]]に関する[[内容折衝]]は、異なる形式の同じ内容のデータを同じ
[[URL]] で提供するのが便利なことがほとんどないため、あまり使われていません。
[16] >>12 の定義によれば [CODE(HTTP)@en[[[User-Agent:]]]] の値に基づく[[応答]]の[[文書]]の使い分けも[[内容折衝]]の一種ということになり、
これは多くの [[Webアプリケーション]]で行われていますが、
技術的には [[HTTP]] の提供する仕組みとの関連性が薄いものです。
[17] [[レンダリング]]される[[装置]]や利用方法による違いは、[[内容折衝]]ではなく、
別の [[URL]] によって提供されるのが一般的です。例えば、通常の [[HTML]]
と印刷用の [[PDF]] を別の [[URL]] で提供したり、通常の [[HTML]]
と[[携帯電話]]向けの [[HTML]] を別の[[ドメイン]]で提供したり、
ダウンロード提供する[[画像]]をサイズにより別の[[ファイル名]]としたりが普通であり、
技術的には[[内容折衝]]を用いていません。
10年代になってからは[[レスポンシブデザイン]]により、単一の [[HTML]]
で[[デスクトップ]]向けと[[スマートフォン]]向けの内容を提供するのが一般的になってきていますが、
やはりこれも [[HTTP]] の[[内容折衝]]とは異なるものです。 (>>12
の分類によれば条件付き内容に当てはまるでしょうが、 [[HTTP]] とは関係ない話です。)
* メモ
[18] [[内容折衝]]によって [[HTTP]] の仕様上の[[資源]]や[[表現]]の定義と概念が複雑になっていますし、
[[キャッシュ]]の実装も複雑化しています。[[内容折衝]]は一見便利な機能ですが、
>>15 の通り現在ではあまり使われなくなっていますし、
本当に必要だったのかは大変怪しいところです。 (今更削除するのも困難ですが...)
[6]
アイデアのメモ。
''問題'': [[日本語]]版と[[英語]]版がある [[Webサイト]]で、
[[リンク]]はすべて折衝が行われる [[URI]]
を使って記述されている。 [CODE(HTTP)@en[[[Accept-Language]]]]
で[[日本語]]を最優先にしていると、通常は[[日本語]]版が
[[Webブラウザ]]に表示されるが、敢えて[[英語]]版が見たく、
[[Web頁]] [VAR@en[A.ja]] 内の[[リンク]]を使って
[VAR@en[A.en]] に移動する。ここで、更に
[VAR@en[A.en]] 内の[[リンク]]から [VAR@en[B]]
に移動すると、[[日本語]]版が表示されてしまうのだが、
[[英語]]版の方が自然ではないか。
(あくまで例であり、言語以外に[[媒体型]]その他でもいい。
[[日本語]]も[[英語]]も [CODE(HTTP)@en[[[Accept-Language]]]]
に入っていない場合というシナリオも興味深い。)
''すぐ思いつく対策'':
[VAR@en[A.en]] 内の[[リンク]]先 [[URI]] は
[VAR@en[B]] ではなく [VAR@en[B.en]] にすればよい。
''すぐ思いつく対策の問題'':
- [VAR@en[A]] の編集時に [VAR@en[B]]
の何語版が存在しているか知っていなければならない。
- [VAR@en[B]] の言語非依存代表 [[URI]]
を使う機会がないのがおもしろくない。
''解'':
[[Webブラウザ]]を修正する。
[CODE(HTML)@en[[[rel]]=[[alternate]]]]
その他代替版への移動であることが明確な方法で頁遷移が行われた後は、
その[[リンク]]の情報 (例: [CODE(HTMLa)@en[[[hreflang]]]])
や[[リンク]]先の[[実体]]に付された情報
(例: [CODE(HTTP)@en[[[Content-Language]]]])
を[[内容折衝]]で優先的に使う
([CODE(HTTP)@en[[[Accept-Language]]]] で最優先にする)。
最優先にする対象範囲は、[[鯖]]全体か、 [[URI]]
[CODE(ABNF)@en[[[path]]]] の階層によって決定する。
''解の既知の問題'':
- 一時的な代替版の選択。例えば印刷版や [[RSS]]
版を選択したとしても、それ以降ずっとその種類の版を選び続けたいとは限らない。
''解の REST consideration'':
[[認証]]と同じように、[[利用者]]には[[セッション]]に見えるかもしれないが実際には[[セッション]]ではない。
''解の security consideration'':
[[利用者]]の操作によって生成された[[内容折衝]]のための情報を[[鯖]]に送信することになるが、
privacy 上問題となるほど繊細なものではないと思われる。
([[名無しさん]])
[7]
[CITE[コンテントネゴシエーション - Apache HTTP サーバ]] <http://httpd.apache.org/docs/2.0/ja/content-negotiation.html>
([[名無しさん]])
[8]
[CITE@en[HTTP Content Negotiation and Mixed-Namespace Documents Requirements]] ([TIME[2005-02-09 22:11:02 +09:00]] 版) <http://damowmow.com/temp/http-conneg-cdi-req.xhtml>
[11] [CITE@en[279729 – Notify user agent of xforms "capabilities"]] ([TIME[2014-06-25 14:36:21 +09:00]] 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=279729>
[407] [CITE@en-GB-x-Hixie[Hixie's Natural Log: Content negotiation in heterogenous XML environments]]
( ([TIME[2014-11-18 00:05:18 +09:00]] 版))
<http://ln.hixie.ch/?start=1036767231&count=1>