wakatonoの戯れメモ

はてなダイアリーから引っ越してきました。

WebDAVにおける「既存コレクションに対するPUT」をどう実装するか

基本的には409で返すのがリーズナブルかなーとか思います。
理由は、RFC2518における記述がすべてなんですが。ちなみにRFC2518における非コレクション/コレクションそれぞれに対するPUTは以下のように定められてます。


8.7.1 PUT for Non-Collection Resources

A PUT performed on an existing resource replaces the GET response
entity of the resource. Properties defined on the resource may be
recomputed during PUT processing but are not otherwise affected. For
example, if a server recognizes the content type of the request body,
it may be able to automatically extract information that could be
profitably exposed as properties.

A PUT that would result in the creation of a resource without an
appropriately scoped parent collection MUST fail with a 409
(Conflict).

8.7.2 PUT for Collections

As defined in the HTTP/1.1 specification [RFC2068], the "PUT method
requests that the enclosed entity be stored under the supplied
Request-URI." Since submission of an entity representing a
collection would implicitly encode creation and deletion of
resources, this specification intentionally does not define a
transmission format for creating a collection using PUT. Instead,
the MKCOL method is defined to create collections.

When the PUT operation creates a new non-collection resource all
ancestors MUST already exist. If all ancestors do not exist, the
method MUST fail with a 409 (Conflict) status code. For example, if
resource /a/b/c/d.html is to be created and /a/b/c/ does not exist,
then the request must fail.

ところが、PUTについては「ヘッダ」「エンティティ」どちらにも「これはコレクションである」「これはリソースである」という識別をできるような要素はありません。
ところが

  • クライアントは「どんな種類のリソース(コレクションとかリソースとか)に対するリクエストであるか」をリクエストを構成する要素に入れられない。
  • サーバは「リクエストがあったURI」に対するものが何かを知っている。
  • そこで、「コレクションに対するPUT」なのか「非コレクションに対するPUT」なのかを判定する。
  • メンバが存在する場合は、そのメンバを消してしまう結果になりかねないが、このような場合は409を返却する。mod_davはこちらの実装
  • Zopeの場合、MKCOLというように解釈して、「リクエスURIに、すでにコレクションが存在する場合」に405 Method Not Allow を返却するので、こちらを返却するようになっていたりする。

というような感じになるのかなー、と。