eZ component: Webdav, RFC overview, 1.0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :Author: Kore Nordmann, Tobias Schlitt :Revision: $Rev$ :Date: $Date$ :Status: Draft .. contents:: Scope ~~~~~ This document tries to summarize the major points of `RFC 2518`_, which seem important for the realization of the Webdav component of eZ Components in version 1.0. This document does not contain any design decisions, but only rephrased contents of the original RFC document. For the design document please refer to design.txt. .. _`RFC 2518`: http://www.ietf.org/rfc/rfc2518.txt General ~~~~~~~ This section contains information that is generally valid for any or, at least, a certain set of opertaions. Operation specific information can be found in the next section. ========== Properties ========== Properties are meta-data for a resource. Each property consists of a name (the tag name actually) and a value (the contents of the tag). In requests and responses, they are defined using the tag, which can contain any number of properties. Live properties =============== Live properties must be supported by every DAV resource and the server is responsible for validating their values. Beside that, a server must support "dead properties", which it simply needs to store, but it does not need to take care about validation. The creattion date of the resource. The #PCDATA in this tag must accord to ISO 8601 Date and Time Profile. Example: :: 2007-08-29T11:35:01Z A name for the resource that is suitable to be displayed to the user (e.g. the filename). Example: :: test.gif Contains language information as provided by the HTTP Content-Language header. Example: :: de, en Contains information about the content size as provided by the HTTP Content-Length header. Example: :: 123456 Contains information about the content type as provided by the HTTP Content-Type header. Example: :: text/html; charset=ISO-8859-4 Contains the etag (indicator of change) for the resource as provided by the HTTP ETag header. Example: :: ... Contains the last modification date of the resource as provided by the Last-Modified header. Example: :: Sun, 06 Nov 1994 08:49:37 GMT Returns a list of lock information for the resource, including information on who has a lock, the type of the lock, expiration time and type of the timeout as well as the associated lock token. Example: :: 0 Jane Smith Infinite opaquelocktoken:f81de2ad-7f3d-a1b2-4f3c-00a0c91a9d76 Defines the type of the resource. Not further speicified how this must look like. Default is empty, but the tag must be present. Example: :: Specifies resources where the source files of a processed resource can be found. This is used, if a desired resource is processed by the server in some way, before being delivered. Using this property, the client can get hold of the un-processed sources of the resource. Example: :: http://foo.bar/program http://foo.bar/src/main.c http://foo.bar/program http://foo.bar/src/main.lib http://foo.bar/program http://foo.bar/src/makefile Returns a list of supported lock types and scopes of a resource. Example: :: ======= Headers ======= Some headers (either for request or response purpose) are used in general by WebDav communication, which are described here. If -- The "If" header is used (similarly to "If-Match" in pure HTTP) to indicate a certain state of the desired resource. The content provided by the header is a list of state tokens. If a resource, affected by the given resource, does not match any of the state tokens, the request must fail with code 412 (Precondition Failed). The only place where the "If" header is used in WebDav is for opaquelocktokens. The exact BNF definition of this header can be seen in the RFC in section 9.4. Status-URI ---------- This header can be used for a process that takes longer than the request-response communication can be kept up. In this case, the client can repeatedly request the given URI to check the status of the process. This header is used in combination with the 102 (Processing) e.g. as an answer to a MOVE operation. Operations ~~~~~~~~~~ This section contains operation specific information. === PUT === Replaces the content which will be returned by GET. Live properties may be recalculated - for example the content type may be set from the corresponding header passed to the server.a Header ====== None special. Response ======== Codes ----- Example response codes to be returned by this request. 201 (Created) The resource was created in its entity. 409 (Conflict) If parent node does not exists, or is no collection. ======== PROPFIND ======== Retrieves information on the properties of the resource identified by the Request-URI. Three different ways of finding properties are possible: - Retrieve a list of certain property names and the correcsponding values. - Retrieve a list of all available property names for a resource, without their corresponding values. - Retrieve a single property name and the correcsponding value. PROPFIND can work recursively on the given resource, if this is a collection. The "Depth" header determines, what level of recursion is desired. Header ====== Depth ----- Defines the search-depth of the resources to search properties for. The Depth header can have the values "0", "1" or "infinity". If the header is not provided, "inifinity" is asumed, which means that the operation is performed recursively down to the leave nodes. A depth of "0" means, that only the resource itself and none of its children is taken into accound and "1" means that only first level descendants are taken into account. XML === Base tag for the PROPFIND request. Only possible XML base tag. Optional for the PROPFIND request. If not given, the request is handled as if "allprop" was set. If this tag is available, a list of all available properties without their corresponding values is desired. The propname XML element specifies that only a list of property names on the resource is to be returned. The -XML-element is a generic container for property information. In case of a PROPFIND request, it contains an empty property tag for each property that should be returned. Example ======= Regular PROPFIND request ------------------------ The following request submits 4 property names to the server, for which the values should be returned. 2 properties are returned successfully in this example, while access to the other 2 requested properties is forbidden. :: >>Request PROPFIND /file HTTP/1.1 Host: www.foo.bar Content-type: text/xml; charset="utf-8" Content-Length: xxxx >>Response HTTP/1.1 207 Multi-Status Content-Type: text/xml; charset="utf-8" Content-Length: xxxx http://www.foo.bar/file Box type A J.J. Johnson HTTP/1.1 200 OK HTTP/1.1 403 Forbidden The user does not have access to the DingALing property. There has been an access violation error. -PROPFIND request ---------------------------- In the following example, a request for all available properties and their values is issued and the proper response is returned. :: >>Request PROPFIND /container/ HTTP/1.1 Host: www.foo.bar Depth: 1 Content-Type: text/xml; charset="utf-8" Content-Length: xxxx >>Response HTTP/1.1 207 Multi-Status Content-Type: text/xml; charset="utf-8" Content-Length: xxxx http://www.foo.bar/container/ Box type A Hadrian 1997-12-01T17:42:21-08:00 Example collection HTTP/1.1 200 OK http://www.foo.bar/container/front.html Box type B 1997-12-01T18:27:21-08:00 Example HTML resource 4525 text/html zzyzx Monday, 12-Jan-98 09:25:56 GMT HTTP/1.1 200 OK -PROPFIND request ----------------------------- The last PROPFIND example issues a tag is send to request the names of all supported properties. :: >>Request PROPFIND /container/ HTTP/1.1 Host: www.foo.bar Content-Type: text/xml; charset="utf-8" Content-Length: xxxx >>Response HTTP/1.1 207 Multi-Status Content-Type: text/xml; charset="utf-8" Content-Length: xxxx http://www.foo.bar/container/ HTTP/1.1 200 OK http://www.foo.bar/container/front.html HTTP/1.1 200 OK ========= PROPPATCH ========= Allows the setting, updating and removing of 1 or more properties. 1 request represents a transaction and can contain multiple manipulations of different kinds on one resource. If one operation fails, all other operations need to be reverted. .. Danger:: The RFC seems not to state anything about PROPPATCH on collection resources. We decided internally to perform the PROPPATCH with a Depth of 0 on collections. Header ====== - XML === Main element for the PROPPATCH request. Contains a set of property manipulations to perform. Indicates that the property given inside should be removed from the resource. The property element cointained in must be empty. Indicates that the given property inside the element should be set to the given value. Response ======== Codes ----- Example response codes to be returned by this request. 200 (OK) The command succeeded. As there can be a mixture of sets and removes in a body, a 201 (Created) seems inappropriate. 403 (Forbidden) The client, for reasons the server chooses not to specify, cannot alter one of the properties. 409 (Conflict) The client has provided a value whose semantics are not appropriate for the property. This includes trying to set read- only properties. 423 (Locked) The specified resource is locked and the client either is not a lock owner or the lock type requires a lock token to be submitted and the client did not submit it. 424 (Failed Dependency) Shown in the example below. Probably used, when one transaction element failed, and all others operations had to be reverted. 507 (Insufficient Storage) The server did not have sufficient space to record the property. Example ======= The PROPPATCH request only has 1 valid format. :: >>Request PROPPATCH /bar.html HTTP/1.1 Host: www.foo.com Content-Type: text/xml; charset="utf-8" Content-Length: xxxx Jim Whitehead Roy Fielding >>Response HTTP/1.1 207 Multi-Status Content-Type: text/xml; charset="utf-8" Content-Length: xxxx http://www.foo.com/bar.html HTTP/1.1 424 Failed Dependency HTTP/1.1 409 Conflict Copyright Owner can not be deleted or altered. ===== MKCOL ===== The MKCOL request is used to create a new collection resource. Collections cannot be created using PUT or any other request, but only by MKCOL. The MKCOL may contain a request body, which is not specified in the RFC. The request body may define the creation of subsequent collections or ressources and their properties. The RFC 2518 itself does not define, or make any examples, how this may look like, but references later RFCs. .. Note:: As we only want to support RFC 2518 for now, we always send a 415 (Unsupported Media Type) response, if a request body is present. Header ====== - XML === - Example ======= The MKCOL request is quite easy. >>Request MKCOL /webdisc/xfiles/ HTTP/1.1 Host: www.server.org >>Response HTTP/1.1 201 Created Response ======== Codes ----- Example response codes to be returned by this request. 201 (Created) The collection or structured resource was created in its entirety. 403 (Forbidden) This indicates at least one of two conditions: 1) the server does not allow the creation of collections at the given location in its namespace, or 2) the parent collection of the Request-URI exists but cannot accept members. 405 (Method Not Allowed) MKCOL can only be executed on a deleted/non-existent resource. 409 (Conflict) A collection cannot be made at the Request-URI until one or more intermediate collections have been created. 415 (Unsupported Media Type) The server does not support the request type of the body. 507 (Insufficient Storage) The resource does not have sufficient space to record the state of the resource after the execution of this method. ====== DELETE ====== Requests to delete a certain resource. May be used on non-collection and collection resources. If used on collection resources, this request works like "Depth: Infinity" header is set and deletes all descendants. Header ====== - XML === - Example ======= The following example shows a case were a descendant resource is locked and therefore the delete failed. >>Request DELETE /container/ HTTP/1.1 Host: www.foo.bar >>Response HTTP/1.1 207 Multi-Status Content-Type: text/xml; charset="utf-8" Content-Length: xxxx http://www.foo.bar/container/resource3 HTTP/1.1 423 Locked ==== COPY ==== Creates a duplicate of the requested resource at the destination defined by the "Destination" header. The state of the duplicate result must match the origin state as good as possible, regarding content and properties. The depth of the duplication is defined by the "Depth" header, while the default is 0 here. The XML element can be used to define the handling of properties while copying the resource. Header ====== Overwrite --------- Value: T The destination is to be DELTED before COPY starts. Value: F If the destination exists, the COPY must fail. If a child COPY fails, the rest of the COPY must be performed. (No transactional behaviour!). Destination ----------- Defines the destination resource to create a duplicate of the requested resource at. Depth ----- Defined like the "Depth" header for the PROPFIND request. The default value here is 0, which means to only copy the resource itself and not descendants. XML === This XML element may be used to influence the way in which a server handles properties during copy. The element may contain 1 or more URIs (inside a each), to define, that the given list must be copied completly "live". Alternatively, a * can be given instead of a list of elements, to indicate, that all properties must be copied live. Using this element, instead of , a client indicates to the server that it should put "best efforts" into copying properties, but that it must not fail, if a property copy fails. Response ======== Codes ----- 201 (Created) The source resource was successfully copied. The copy operation resulted in the creation of a new resource. 204 (No Content) The source resource was successfully copied to a pre-existing destination resource. 403 (Forbidden) The source and destination URIs are the same. 409 (Conflict) A resource cannot be created at the destination until one or more intermediate collections have been created. 412 (Precondition Failed) The server was unable to maintain the liveness of the properties listed in the propertybehavior XML element or the Overwrite header is "F" and the state of the destination resource is non-null. 423 (Locked) The destination resource was locked. 502 (Bad Gateway) This may occur when the destination is on another server and the destination server refuses to accept the resource. 507 (Insufficient Storage) The destination resource does not have sufficient space to record the state of the resource after the execution of this method. Examples ======== Overwriting COPY ---------------- The following example indicates a successful COPY request that has overwritten the already existing destination resource (note: 204 indicates the overwrite!). :: >>Request COPY /~fielding/index.html HTTP/1.1 Host: www.ics.uci.edu Destination: http://www.ics.uci.edu/users/f/fielding/index.html >>Response HTTP/1.1 204 No Content Non-overwriting COPY -------------------- In this example, the "Overwrite" header changed the overwriting behaviour. Because the destination resource exists and cannot be overwritten, COPY fails. :: >>Request COPY /~fielding/index.html HTTP/1.1 Host: www.ics.uci.edu Destination: http://www.ics.uci.edu/users/f/fielding/index.html Overwrite: F >>Response HTTP/1.1 412 Precondition Failed Collection COPY --------------- The following example shows the COPY of a collection resource. The "Depth" header is just set to the default and could therefore be ignored. The COPY operation suceeds almost on all resources, except for R2, which has most-propably a problem with property copying. :: >>Request COPY /container/ HTTP/1.1 Host: www.foo.bar Destination: http://www.foo.bar/othercontainer/ Depth: infinity Content-Type: text/xml; charset="utf-8" Content-Length: xxxx * >>Response HTTP/1.1 207 Multi-Status Content-Type: text/xml; charset="utf-8" Content-Length: xxxx http://www.foo.bar/othercontainer/R2/ HTTP/1.1 412 Precondition Failed ==== MOVE ==== The MOVE operation behaves similar to the COPY operation, followed by a DELETE of the original resource. All in all, the MOVE request is handled very similar to the COPY operation. .. Danger:: Like for COPY, the RFC says, that the server should try to copy as much as possible in case an error occurs for some subtree for a collection MOVE with depth infinity. We decide to omit the deletion of the source collection, if an error occured during the copy operation, even this is not defined by the RFC. Header ====== "Overwrite" as described with COPY. "Depth" must not be sent by the client. XML === - Response ======== Codes ----- 201 (Created) The source resource was successfully moved, and a new resource was created at the destination. 204 (No Content) The source resource was successfully moved to a pre-existing destination resource. 403 (Forbidden) The source and destination URIs are the same. 409 (Conflict) A resource cannot be created at the destination until one or more intermediate collections have been created. 412 (Precondition Failed) The server was unable to maintain the liveness of the properties listed in the propertybehavior XML element or the Overwrite header is "F" and the state of the destination resource is non-null. 423 (Locked) The source or the destination resource was locked. 502 (Bad Gateway) This may occur when the destination is on another server and the destination server refuses to accept the resource. Examples ======== MOVE non-collection ------------------- The following example shows a successful MOVE operation of a non-collection resource. :: >>Request MOVE /~fielding/index.html HTTP/1.1 Host: www.ics.uci.edu Destination: http://www.ics.uci.edu/users/f/fielding/index.html >>Response HTTP/1.1 201 Created Location: http://www.ics.uci.edu/users/f/fielding/index.html MOVE collection --------------- In the following example, a collection-resource is MOVED, while a single child-resource failed. :: >>Request MOVE /container/ HTTP/1.1 Host: www.foo.bar Destination: http://www.foo.bar/othercontainer/ Overwrite: F If: () () Content-Type: text/xml; charset="utf-8" Content-Length: xxxx * >>Response HTTP/1.1 207 Multi-Status Content-Type: text/xml; charset="utf-8" Content-Length: xxxx http://www.foo.bar/othercontainer/C2/ HTTP/1.1 423 Locked ==== LOCK ==== Creates the LOCK descibed by the XML element. Can be used to create a new lock or to refresh an exisiting one. Timeouts can be defined using the "Timeout" header. The response must contain the created lock information in a lockdiscovery property. For a new lock, the lock token must be returned in the "Lock-Token" header. A lock affects a complete resource, including its properties and (for collection-resources) adding and removal of collection members. The depth of a collection lock can be determined by the "Depth" header. Headers ======= Timeout Allows the client to define a timeout value for the lock. This timeout is not mandatory for the server, since locks can also disappear by a system crash or administartor intervention. In a normal case, the server should stick to the timeout. A timeout may be defined for new locks as well as for refresh requests. Multiple timeout alternatives can be defined comma-seperated. Depth Determines the depth of locking for a collection resource. Valid values are here only "0" (for only the collection itself) and "infinity". The default value is "infinity". If The If-Header, which is commonly used to indicate to a server that oneself is the valid owner of a lock, might be present in case of lock refresh requests and gives the lock token it requests an update to. Authorization While this header is not directly used by the WebDAV RFC it is commonly used to submit various authorization informations, especially in cases of the LOCK examples. XML === This element is used as a possible body of the lock request. It is used to specify information about the lock to be created using , and optionally XML elements. This element must always be present in the element and its possible (constant) values describe the type of lock. So far the specification only describes 1 possible settings element here, which is write. => Only write-locks are possible. The optional owner element may contain anything as a description for the owner of the lock. Possible would be e.g. a user ID or the URL of the users website (see example). .. Note:: We asume here 1 of 2 alternatives for the element: - A element with a URL - A #PCDATA node Both will simply be stored as a string and need to be re-serialized correctly, if a URI is returned. Example ------- :: http://www.ics.uci.edu/~ejw/contact.html Response ======== Codes ----- 200 (OK) The lock request succeeded and the value of the lockdiscovery property is included in the body. 412 (Precondition Failed) The included lock token was not enforceable on this resource or the server could not satisfy the request in the lockinfo XML element. 423 (Locked) The resource is locked, so the method has been rejected. Examples ======== Simple LOCK request ------------------- The following example shows a simple LOCK request for a non-collection resource. The request asks for an exclusive write lock, which is successfully granted. The returnes opaquelocktoken can be used to identify the lock globally. :: >>Request LOCK /workspace/webdav/proposal.doc HTTP/1.1 Host: webdav.sb.aol.com Timeout: Infinite, Second-4100000000 Content-Type: text/xml; charset="utf-8" Content-Length: xxxx Authorization: Digest username="ejw", realm="ejw@webdav.sb.aol.com", nonce="...", uri="/workspace/webdav/proposal.doc", response="...", opaque="..." http://www.ics.uci.edu/~ejw/contact.html >>Response HTTP/1.1 200 OK Content-Type: text/xml; charset="utf-8" Content-Length: xxxx Infinity http://www.ics.uci.edu/~ejw/contact.html Second-604800 opaquelocktoken:e71d4fae-5dec-22d6-fea5-00a0c91e6be4 Refreshing a write lock ----------------------- The second example shows a LOCk request that attempts to refresh an existing lock. The opaqualocktoken submitted identifies the affected lock. In this example, the server ignores the timeout values suggested by the client and uses its default value. :: >>Request LOCK /workspace/webdav/proposal.doc HTTP/1.1 Host: webdav.sb.aol.com Timeout: Infinite, Second-4100000000 If: () Authorization: Digest username="ejw", realm="ejw@webdav.sb.aol.com", nonce="...", uri="/workspace/webdav/proposal.doc", response="...", opaque="..." >>Response HTTP/1.1 200 OK Content-Type: text/xml; charset="utf-8" Content-Length: xxxx Infinity http://www.ics.uci.edu/~ejw/contact.html Second-604800 opaquelocktoken:e71d4fae-5dec-22d6-fea5-00a0c91e6be4 Multi resource lock request --------------------------- The following LOCK request desires a lock on a collection resource with infinite depth. The request fails, because an anchestor resource cannot be locked. Since no lock is established, because of this failure, the element is empty in the response. :: >>Request LOCK /webdav/ HTTP/1.1 Host: webdav.sb.aol.com Timeout: Infinite, Second-4100000000 Depth: infinity Content-Type: text/xml; charset="utf-8" Content-Length: xxxx Authorization: Digest username="ejw", realm="ejw@webdav.sb.aol.com", nonce="...", uri="/workspace/webdav/proposal.doc", response="...", opaque="..." http://www.ics.uci.edu/~ejw/contact.html >>Response HTTP/1.1 207 Multi-Status Content-Type: text/xml; charset="utf-8" Content-Length: xxxx http://webdav.sb.aol.com/webdav/secret HTTP/1.1 403 Forbidden http://webdav.sb.aol.com/webdav/ HTTP/1.1 424 Failed Dependency ====== UNLOCK ====== The UNLOCK operation lifts a lock from a desired resource. While a resource is identified by the request as usual, the lock (identified by the "Lock-Token" header) is removed from all affected reources. Headers ======= Lock-Token Uses the lock ID returned by a LOCK operation to UNLOCK the resources locked by this token. XML === Reponse ======= Examples ======== Simple lock removal ------------------- This example shows a simple, successful, removal of a lock. :: >>Request UNLOCK /workspace/webdav/info.doc HTTP/1.1 Host: webdav.sb.aol.com Lock-Token: Authorization: Digest username="ejw", realm="ejw@webdav.sb.aol.com", nonce="...", uri="/workspace/webdav/proposal.doc", response="...", opaque="..." >>Response HTTP/1.1 204 No Content ======= OPTIONS ======= The OPTIONS operation is a standard HTTP/1.1 operation, which is extended by the "DAV" header for WebDav. Headers ======= DAV Defined the level of DAV support provided by the server for a given URI (e.g. 1, 1#extend or 2). .. Local Variables: mode: rst fill-column: 79 End: vim: et syn=rst tw=79