-
Notifications
You must be signed in to change notification settings - Fork 4
/
336.txt
302 lines (227 loc) · 20.2 KB
/
336.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
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
[524] [DFN[[CODE(HTTP)@en[[[PUT]]]]]] は、[[要求URL]]の[[資源]]を指定したデータで置き換え (または新規作成)
することを[[要求]]するものです。
[525] [CODE(HTTP)@en[[[PUT]]]] は最初期から [[HTTP]] 仕様に含まれていた[[要求メソッド]]ですが、
何度も標準化や実装によって普及が試みられたにも関わらず、広く採用されるに至っていません。
最近では [[HTML5]] によって[[フォーム]]の[[提出]]の方法に追加採用されましたが、
利用・実装されなかったため、削除されました。
* 仕様書
[REFS[
- [507] '''[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-4.3.4>'''
- [502] [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-4.2.2>
- [3] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-08-07 05:54:02 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#page-79>
- [8] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-08-07 05:54:02 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#appendix-B>
- [11] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-7>
- [14] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-9.7>
- [23] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-12>
- [25] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#appendix-D>
]REFS]
* 意味
[508] [CODE(HTTP)@en[[[PUT]]]] [[メソッド]]は、[[要求メッセージ]]の [[payload]]
に含まれる[[表現]]によって決まる状態により[[対象資源]]の状態を作成または置換することを要求するものです
[SRC[>>507]]。
[509] [CODE(HTTP)@en[[[PUT]]]] が成功すれば、同じ[[対象資源]]を [CODE(HTTP)@en[[[GET]]]]
したら[[要求]]に含まれていたのと等価な[[表現]]が [CODE(HTTP)[[[200]]]]
[[応答]]に含まれることが想定されていますが、実際にはそのような [CODE(HTTP)@en[[[GET]]]]
より前に他者により変更されたり、[[起源鯖]]側で動的な処理が行われたりする可能性を排除できませんから、
必ずしもそれが観察できるわけではありません。 [CODE(HTTP)@en[[[PUT]]]]
が成功しても、[[起源鯖]]がそれを処理した時点で[[利用者エージェント]]の意図が達成されたことだけを表しています。 [SRC[>>507]]
[503] [CODE(HTTP)@en[[[PUT]]]] は、[[冪等なメソッド]]です [SRC[>>502]]。
[12] [[書き込みロック]]が適用されます [SRC[>>11]]。
* 構文
[19] [[WebDAV]] [[クライアント]]は、新しい[[資源]]の [CODE(HTTP)@en[[[Content-Type:]]]]
が分かっていれば、これを指定する[['''べきです''']] [SRC[>>14]]。
;; [21] しかし[[鯖]]が [CODE(HTTP)@en[[[Content-Type:]]]] を含む[[要求]]の[[ヘッダー]]の情報を使うとは限りませんから、
常に [CODE(HTTP)@en[[[Content-Type:]]]] が反映されると想定することはできません [SRC[>>14]]。
* 処理
[2] [[起源鯖]]は、[[要求メッセージ]]の [[payload body]] や、
[[payload]] に含まれるとみなされる[[ヘッダー]]を保存することが期待されています。
[512] [[起源鯖]]は、 [CODE(HTTP)@en[[[PUT]]]] [[要求]]の認識できない[[ヘッダー]]を
([[資源]]の一部として保存するのではなく) 無視する[['''べきです''']] [SRC[>>507]]。
[6] [[要求メッセージ]]の [CODE(HTTP)@en[[[Content-Location:]]]]
[[ヘッダー]]は、そのまま保存するべきではありません ([[[CODE(HTTP)@en[Content-Location:]]]>>325])。
[4] それ以外にどの[[ヘッダー]]が保存されるべきかは明記されていません。
[5] [[RFC 7231]] は、[[ヘッダー]]の仕様書に対し、 [CODE(HTTP)@en[[[PUT]]]]
で指定された[[ヘッダー]]を保存するべきか明記することを検討するよう求めています [SRC[>>3]]。
ただし [[RFC 723x]] の[[ヘッダー]]についてはそのような記述はありません。
;; [7] [[RFC 2616]] はすべての [CODE(HTTP)@en[[[Content-*:]]]] [[ヘッダー]]に対応することを求めていましたが、
これは [[RFC 723x]] で削除されています [SRC[>>8]]。
[20] [[WebDAV]] に従う[[コレクション]]以外の[[資源]]に [CODE(HTTP)@en[[[PUT]]]]
が送信された場合で、[[要求]]に [CODE(HTTP)@en[[[Content-Type:]]]]
が含まれない場合、 [CODE(HTTP)@en[[[Content-Type:]]]] なしの[[資源]]を作っても構いませんし、
[CODE(HTTP)@en[[[Content-Type:]]]] を割り当てようと試みても構いません [SRC[>>14]]。
[513] [[起源鯖]]は、 [CODE(HTTP)@en[[[PUT]]]] の[[表現]]が当該[[対象資源]]に関する変更できない[[鯖]]の制約を
(あれば) 満たしているか検証する[['''べきです''']]。満たしていない時には、
満たすように変形を加えるか、適切な説明とともにエラーを返す[['''べきです''']]。
[[状態符号]]としては、 [CODE(HTTP)[[[409]]]] を使うことができます。
[CODE(HTTP)@en[[[Content-Type:]]]] に関する制約の時は、
[CODE(HTTP)[[[415]]]] を使うことができます。 [SRC[>>507]]
[514] [[起源鯖]]が実際にどのように状態を保存するかは、実装に依存します。
[[HTTP]] としてはその方法を規定しません [SRC[>>507]]。
[519] [CODE(HTTP)@en[[[PUT]]]] の処理は[[副作用]]を持っても構いません [SRC[>>507]]。
[EG[
[520] 例えば最新版の記事と履歴がある場合、最新版の [[URL]] に [CODE(HTTP)[[[PUT]]]]
した時、最新版が更新されるだけでなく、履歴版の[[資源]]が作成されても構いません。 [SRC[>>507]]
]EG]
[15] [[WebDAV]] に従う[[資源]]で[[コレクション]]以外の場合には、
[CODE(HTTP)@en[[[PUT]]]] は [CODE(HTTP)@en[[[GET]]]] で返される[[表現]]を置き換えます。
この時[[特性]]は再計算されるものもありますが、それ以外は影響を受けません [SRC[>>14]]。
[EG[
[16] [[WebDAV]] [[鯖]]は [CODE(HTTP)@en[[[PUT]]]] [[要求]]の [[payload body]]
の [[MIME型]]に対応していれば、そこから情報を抜き出して[[特性]]とすることができます [SRC[>>14]]。
]EG]
[22] [[WebDAV]] [[コレクション]]に対する [CODE(HTTP)@en[[[PUT]]]]
の動作は定義されていません [SRC[>>14]]。 [CODE(HTTP)[[[405]]]]
[[応答]]を返しても構いません [SRC[>>14]]。
[26] [[LNR]] の場合、 [CODE(HTTP)@en[[[PUT]]]] により通常の[[資源]]に変換されます [SRC[>>25]]。
[510] [[起源鯖]]は、[[対象資源]]が現在[[表現]]を持っておらず、 [CODE(HTTP)[[[PUT]]]]
によってその作成に成功した場合には、 [CODE(HTTP)[[[201]]]]
を送信しなければ[['''なりません''']] [SRC[>>507]]。
[24] [[WebDAV]] に従う[[資源]]は、この場合 [CODE(HTTP)[[[3xx]]]] を返しては[['''なりません''']] [SRC[>>23]]。
[511] [[起源鯖]]は、[[対象資源]]が現在[[表現]]を持っており、 [CODE(HTTP)@en[[[PUT]]]]
によりその編集に成功した場合には、 [CODE(HTTP)[[[200]]]] か [CODE(HTTP)[[[204]]]]
を送信しなければ[['''なりません''']] [SRC[>>507]]。
[17] [[WebDAV]] に従う[[鯖]]は、[[コレクション]]以外の[[資源]]への
[CODE(HTTP)@en[[[PUT]]]] で適切な親となる[[コレクション]]無しで[[資源]]を作ってしまうことになる場合には、
[CODE(HTTP)[[[409]]]] [[応答]]を返さなければ[['''なりません''']] [SRC[>>14]]。
;; [18] 親ディレクトリーが存在しない場合を指すと思われます。
[10] 成功した場合の[[応答]]の [[payload]] には、成功した旨の報告を含めることもできますし、
作成・変更した後の[[資源]]の[[表現]]を含めることもできます。
[[クライアント]]は、どちらを希望するかを [CODE(HTTP)@en[[[Prefer:]] [[return]]]]
により指定できます (が[[鯖]]がそれに従う義務はありません)。
[517] [[起源鯖]]は、[[対象資源]]の状態を変更せず、他の[[資源]]に適用したい場合は、
適切な [CODE(HTTP)[[[3xx]]]] [[応答]]を送信し[['''なければなりません''']]。
その場合[[利用者エージェント]]は[[リダイレクト]]に従うか選ぶことができます。 [SRC[>>507]]
[521] [[起源鯖]]は、[[対象資源]]に [CODE(HTTP)@en[[[PUT]]]] を認めている場合で、
[[要求]]に [CODE(HTTP)@en[[[Content-Range:]]]] [[ヘッダー]]が含まれる場合、
[[payload]] が一部分しか含まれないのに誤って [CODE(HTTP)@en[[[PUT]]]]
を使っている可能性があるため、 [CODE(HTTP)[[[400]]]] [[応答]]を送信しなければ[['''なりません''']]
[SRC[>>507]]。
;; [29] 古い仕様書には [CODE(HTTP)@en[[[Content-Range:]]]] が適用されることをほのめかす記述があり [SRC[>>27]]、
[[対象資源]]の一部分を更新できる実装もあった [SRC[>>28]] ようですが、
広く受け入れられた解釈ではなく、 [[RFC 723x]] で禁止されたようです。
[REFS[
- [27] [CITE@en[RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1]] ([TIME[2014-09-07 13:14:53 +09:00]] 版) <http://tools.ietf.org/html/rfc2616#section-9.6>
- [28] [CITE[RFC Errata Report]] ([TIME[2014-12-03 22:55:49 +09:00]] 版) <http://www.rfc-editor.org/errata_search.php?rfc=5789>
]REFS]
[515] [[起源鯖]]は、[[要求]]の[[表現]]が変形なしに保存され、 [[validator header]]
の値が新しい[[表現]]にそのまま適用される場合を除き、
[CODE(HTTP)@en[[[PUT]]]] への[[応答]]で [[validator header]] を送信しては[['''なりません''']]
[SRC[>>507]]。
;; [13] [[実体タグ]]、[CODE(HTTP)@en[[[Last-Modified:]]]] も参照。
[522] [CODE(HTTP)@en[[[PUT]]]] への[[応答]]は[[キャッシュ可能]]ではありません [SRC[>>507]]。
;; [523] 同じ[[実効要求URL]]の[[キャッシュ]]が存在する状態で [CODE(HTTP)@en[[[PUT]]]]
が成功した場合、[[キャッシュ]]は[[非妥当]]となります [SRC[>>507]]。
* 歴史
[FIG(quote)[
[FIGCAPTION[
[506] RFC 1945 (HTTP/1.0) D.1.1; RFC 2068・2616 (HTTP/1.1) 9.6 PUT
]FIGCAPTION]
> The PUT method requests that the enclosed entity be stored under the
supplied Request-URI. If the Request-URI refers to an already
existing resource, the enclosed entity [DEL[should]] [INS[SHOULD]] be considered as a
modified version of the one residing on the origin server. If the
Request-URI does not point to an existing resource, and that URI is
capable of being defined as a new resource by the requesting user
agent, the origin server can create the resource with that URI. [INS[If a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request. If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be given that reflects the nature of the problem. The recipient of the entity MUST NOT ignore any Content-* (e.g. Content-Range) headers that it does not understand or implement and MUST return a 501 (Not Implemented) response in such cases.]]
[CODE(HTTP)[PUT]] 方式は、囲まれた[[実体]]を供給した
[CODE(HTTP)[[[Request-URI]]]] の元で蓄積することを要求します。
[CODE(HTTP)[[[Request-URI]]]] が既に存在する[[資源]]を指している時は、
囲まれた実体は[[起源サーバー]]にあるものの修正版と考えられる'''べきです'''。
[CODE(ABNF)[Request-URI]] が既存の資源を指しておらず、
その URI に要求している利用者エージェントによって新しい資源を定義する能力があるなら、
起源サーバーはその URI に資源を作ることが出来ます。 [INS[新しい資源が作られたら、起源サーバーは [CODE(HTTP)[[[301]]]] (作成せし) 応答で利用者エージェントに知らせなければ'''なりません'''。既存の資源が修正されたなら、 [CODE(HTTP)[[[200]]]] (了解) または [CODE(HTTP)[[[204]]]] (無内容) の応答符号を送って要求の成功裏完了を示す'''べきです'''。その [CODE(ABNF)[Request-URI]] で資源を作るか修正するかできなかったときは、問題の性質を反映して適切な誤り応答を与える'''べきです'''。実体の受信者は、その理解・実装しない [CODE(HTTP)[Content-[VAR[*]]]] 頭 (例えば [CODE(HTTP)[[[Content-Range]]]]) を無視しては'''なりません'''で、そのような場合には [CODE(HTTP)[[[501]]]] (未実装) 応答を返さなければ'''なりません'''。]]
[INS[
> If the request passes through a cache and the Request-URI identifies
one or more currently cached entities, those entries [DEL[should]] [INS[SHOULD]] be
treated as stale. Responses to this method are not cach[INS[e]]able.
要求が[[キャッシュ]]を通して渡され、 [CODE(ABNF)[Request-URI]]
が一つか複数個の現在キャッシュされている実体を識別する時は、
それらの項目は[[腐敗]]しているものとして扱う'''べきです'''。
この方式への応答は[[キャッシュ可能]]ではありません。
]INS]
> The fundamental difference between the POST and PUT requests is
reflected in the different meaning of the Request-URI. The URI in a
POST request identifies the resource that will handle the enclosed
entity [DEL[[INS[{1945}]] as data to be processed]].
That resource [DEL[[INS[{1945,2068}]] may]] [INS[[INS[{2616}]] might]] be a data-accepting process, a gateway to
some other protocol, or a separate entity that accepts annotations.
In contrast, the URI in a PUT request identifies the entity enclosed
with the request -- the user agent knows what URI is intended and the
server [DEL[[INS[{1945}]] should not]] [INS[MUST NOT attempt to]]
apply the request to some other resource. [INS[If the server desires that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request.]]
[CODE(HTTP)[[[POST]]]] 要求と [CODE(HTTP)[PUT]] 要求の本質的な違いは、
[CODE(ABNF)[Request-URI]] の違った意味を反映しています。
[CODE(HTTP)[POST]] 要求の URI は囲まれた実体を[DEL[処理されるデータとして]]取扱う[[資源]]を識別します。
その資源はデータ受入れ過程かもしれませんし、他のプロトコルとの[[関門]]かもしれませんし、
[[注釈]]を受け入れる別の実体かもしれません。
かわって、 [CODE(HTTP)[PUT]] 要求の URI は要求に囲まれた実体のを識別します。
利用者エージェントはどの URI が意図されているかを知っており、
サーバーはその要求を他の資源に適用しようと試みては'''なりません'''。[INS[サーバーが要求を異なる URI に適用することを望む時は、 [CODE(HTTP)[[[301]]]] (永続的移動) 応答を送らなければ'''なりません'''。利用者エージェントは要求を[[再指向]]するかどうかについて自身の決定を下して'''構いません'''。]]
[INS[
> A single resource MAY be identified by many different URIs. For
example, an article [DEL[may]] [INS[might]] have a URI for identifying "the current
version" which is separate from the URI identifying each particular
version. In this case, a PUT request on a general URI [DEL[may]] [INS[might]] result in
several other URIs being defined by the origin server.
一つの資源は多くの違った URI で識別して'''構いません'''。
例えば、ある記事は特定の版を識別する URI とは別に「現行版」
を識別する URI を持つかもしれません。
この場合、一般 URI への [CODE(HTTP)[PUT]] 要求は、結果その起源サーバーが定義する幾つかの他の URI
となるかもしれません。
> HTTP/1.1 does not define how a PUT method affects the state of an origin server.
HTTP/1.1 は起源サーバーの状態に [CODE(HTTP)[PUT]] 方式がどう影響するかを定義しません。
> PUT requests [DEL[must]] [INS[MUST]] obey the message transmission requirements set out in section 8.2.
[CODE(HTTP)[PUT]] 要求は8.2節のメッセージ転送要件に従わなければ'''なりません'''。
[INS[
> Unless otherwise specified for a particular entity-header, the
entity-headers in the PUT request SHOULD be applied to the resource
created or modified by the PUT.
特定の実体頭で特に指定されていない限り、
[CODE(HTTP)[PUT]] 要求の実体頭は [CODE(HTTP)[PUT]]
で作成または修正された資源に適用する'''べきです'''。
]INS]
]INS]
]FIG]
* 関連
[516] [CODE(HTTP)@en[[[PUT]]]] と [CODE(HTTP)@en[[[POST]]]] は似ていますが、
[CODE(HTTP)@en[[[POST]]]] は[[対象資源]]の意味に基づき処理されるのに対し、
[CODE(HTTP)@en[[[PUT]]]] は[[対象資源]]の状態を置き換えるものである点が根本的に異なります
[SRC[>>507]]。
[518] [[クライアント]]ではなく[[鯖]]側が更新する適切な [[URL]] を選ぶ場合には、
[CODE(HTTP)@en[[[PUT]]]] ではなく [CODE(HTTP)@en[[[POST]]]] を使う[['''べきです''']] [SRC[>>507]]。
* メモ
[1]
Editing the Web - Detecting the Lost Update Problem Using Unreserved Checkout <http://www.w3.org/1999/04/Editing/>
[504] [CITE@en[RFC 7252 - The Constrained Application Protocol (CoAP)]]
( ([TIME[2014-06-27 00:59:37 +09:00]] 版))
<http://tools.ietf.org/html/rfc7252#section-5.8.3>
[505] [CITE[tus resumable upload protocol]]
( ([TIME[2013-04-18 12:55:13 +09:00]] 版))
<http://www.tus.io/protocols/resumable-upload.html>
[9] 理論上は [CODE(HTTP)@en[[[PUT]]]] で任意の[[資源]]を共通のプロトコルで編集できて便利なのでしょうけど、実際上は
[[URL]] の構造や [CODE(HTTP)@en[[[PUT]]]] できる書式、アクセス権限など諸々の事前情報を[[鯖]]と[[クライアント]]の間で何らかの方法で共有し実装しなければいけないので、
[CODE(HTTP)@en[[[POST]]]] に対する優位性は特に無いのですよね...
[FIG(quote)[
[FIGCAPTION[
[30] [CITE@en[REST API for MongoLab | MongoLab Documentation & Support]]
([TIME[2015-03-10 19:57:26 +09:00]] 版)
<http://docs.mongolab.com/restapi/>
]FIGCAPTION]
> Example setting "y" to 5 in the matching document without affecting other fields (using jQuery):
> $.ajax( { url: "https://api.mongolab.com/api/1/databases/my-db/collections/my-coll/4e7315a65e4ce91f885b7dde?apiKey=myAPIKey",
> data: JSON.stringify( { "$set" : { "y" : 5 } } ),
> type: "PUT",
> contentType: "application/json" } );
]FIG]
[31] [CITE@en[RFC 8144 - Use of the Prefer Header Field in Web Distributed Authoring and Versioning (WebDAV)]]
([TIME[2017-04-19 23:22:44 +09:00]])
<https://tools.ietf.org/html/rfc8144#section-3.1>
[32] [CITE@en[RFC 3253 - Versioning Extensions to WebDAV (Web Distributed Authoring and Versioning)]]
([TIME[2017-09-17 18:19:04 +09:00]])
<https://tools.ietf.org/html/rfc3253#section-3.10>
[33] [CITE@en[RFC 4791 - Calendaring Extensions to WebDAV (CalDAV)]]
([TIME[2017-09-24 16:22:36 +09:00]])
<https://tools.ietf.org/html/rfc4791#section-5.3.2.1>
[34] [CITE@en[10671 – consider adding support for PUT and DELETE as form methods]]
([TIME[2018-03-25 11:44:22 +09:00]])
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=10671>