- From: Julian Reschke <julian.reschke@gmx.de>
- Date: Wed, 15 Mar 2006 16:33:30 +0100
- To: WebDAV <w3c-dist-auth@w3.org>
Below is a summary of problems I found with draft 14. Note that I've marked up everything in <http://greenbytes.de/tech/webdav/draft-reschke-webdav-rfc2518bis-latest.html>, which may be more readable. Also note that this document contains more changes based on issues that have been discussed before on this list; the fact that I may not be repeating them below doesn't indicate that they shouldn't be fixed before IESG submission as well. Also note that the term "Section" should be uppercased everywhere when used to refer to a specific section; otherwise the RFC Editor will have to do that; and we want to save his/her time, right? [Page 8] Properties: The ability to create, remove, and query information about Web pages, such as their authors, creation dates, etc. Also, the ability to link pages of any media type to related pages. -> what is the last sentence about? Namespace Operations: The ability to instruct the server to copy and move Web resources, operations which change the URL. -> Sentence structure? This standard does not specify the versioning operations suggested by [RFC2291]. That work was done in a separate document, "Versioning Extensions to WebDAV" [RFC3253]. -> This document isn't a standard. Just say "this document". The sections below provide a detailed introduction to various WebDAV abstractions: resource properties (Section 4), collections of resources (Section 5), locks (Section 6) in general and write locks (Section 7) specifically. These abstractions are manipulated by the WebDAV-specific HTTP methods (Section 9) and the new HTTP headers (Section 10) used with WebDAV methods. -> No mention of Section 8? [Page 11] Collection - Informally, a resource that also acts as a container of references to child resources. Formally, a resource that contains a set of mappings between path segments and resources and meets the requirements in Section 5. -> "...defined in Section 5". [Page 18] An HTTP URL namespace is said to be consistent if it meets the following conditions: for every URL in the HTTP hierarchy there exists a collection that contains that URL as an internal member. -> "...internal member URL". The root, or top-level collection of the namespace under consideration is exempt from the previous rule. The top-level -> ^^^^^^^^^^^^^, (insert comma) Although implicit in [RFC2616] and [RFC3986], any resource, including collection resources, MAY be identified by more than one URI. For example, a resource could be identified by multiple HTTP URLs. -> Why "Although"? I think this needs to be rephrased. For all WebDAV compliant resources A and B, identified by URLs "U" and "V" respectively, such that "V" is equal to "U/SEGMENT", A MUST be a collection that contains a mapping from "SEGMENT" to B. So, if resource B with URL "http://example.com/bar/blah" is WebDAV compliant and if resource A with URL "http://example.com/bar/" is WebDAV compliant, then resource A must be a collection and must contain at least one mapping from "blah" to B. -> Insert paragraph suggested by Geoff Clemm below: 'Although commonly a mapping consists of a single segment and a resource, in general, a mapping consists of a set of segments and a resource. This allows a server to treat a set of segments as equivalent (i.e. either all of the segments are mapped to the same resource, or none of the segments are mapped to a resource). For example, a server that performs case-folding on segments will treat the segments "ab", "Ab", "aB", and "AB" as equivalent, A client can then use any of these segments to identify the resource. Note that a PROPFIND result will select one of these equivalent segments to identify the mapping, so there will be one PROPFIND response element per mapping, not one per segment in the mapping.' [Page 19] A typical scenario in which mapped URLs do not appear as members of their parent collection is the case where a server allows links or redirects to non-WebDAV resources. For instance, "/col/link" might not appear as a member of "/col/", although the server would respond with a 302 status to a GET request to "/col/link", thus the URL "/col/link" would indeed be mapped. Similarly, a dynamically- generated page might have a URL mapping from "/col/index.html", thus this resource might respond with a 200 OK to a GET request yet not appear as a member of "/col/". -> Please re-insert subsection title in front of this para so that it's easier to see where normative text ends and examples start. [Page 21] This section provides a concise model for how locking behaves. Later sections will provide more detail on some of the concepts and refer back to these model statements. Normative statements related to LOCK and UNLOCK handling can be found in the sections on those methods, whereas normative statements that cover any method are gathered here. -> "...LOCK and UNLOCK method handling..." [Page 22] However, there are times when the goal of a lock is not to exclude others from exercising an access right but rather to provide a mechanism for principals to indicate that they intend to exercise their access rights. Shared locks are provided for this case. A shared lock allows multiple principals to receive a lock. Hence any principal with appropriate access can use the lock. -> Avoid a potential misunderstanding: each principal will need its own shared lock, they will *not* share the same lock. For instance. "However, there are times when the goal of a lock is not to exclude others from exercising an access right but rather to provide a mechanism for principals to indicate that they intend to exercise their access rights. Shared locks are provided for this case, allowing multiple principals to receive a lock." [Page 23] The creator of a lock has special privileges to use the locked resource. When a locked resource is modified, a server MUST check that the authenticated principal matches the lock creator (in addition to checking for valid lock token submission). For multi- user shared lock cases, each authenticated principal MUST obtain its own shared lock. -> Misleading. Lock creator checks only apply (as a MUST level requirement) to lock token submission in the If header; removing the lock using UNLOCK is a separate thing. Furthermore, making a special statement about shared locks IMHO is confusing here. [Page 24] Servers MAY make lock tokens publicly readable (e.g. in the DAV: lockdiscovery property). One use case for making lock tokens readable is so that a long-lived lock can be removed by the resource owner (the client that obtained the lock might have crashed or disconnected before cleaning up the lock). Except for the case of using UNLOCK under user guidance, a client SHOULD NOT use a lock tokens created by another client instance. -> s/tokens/token/ [Page 25] A client MUST NOT assume that just because the time-out has expired the lock has immediately been cleaned up. -> s/cleaned up/removed/ [Page 27] An exclusive write lock will prevent parallel changes to a resource by any principal other than the lock creator and in any case where the lock token is not submitted (e.g. by a client process other than the one holding the lock). -> remove "parallel"; it may lead people to believe that this has something to do with timing -> furthermore, this paragraph just states things repeated in aubsequent paragraphs, so it's best just to remove it While those without a write lock may not alter a property on a resource it is still possible for the values of live properties to change, even while locked, due to the requirements of their schemas. Only dead properties and live properties defined to respect locks are guaranteed not to change while write locked. -> The whole paragraph doesn't seem to make sense anymore, because it seems to say the same thing as the previous section, but uses different terminology. [Page 29] WebDAV provides the ability to lock an unmapped URL in order to reserve the name for use. This is a simple way to avoid the lost- update problem on the creation of a new resource (another way is to use If-None-Match header specified in HTTP 1.1). It has the side benefit of locking the new resource immediately for use of the creator. -> s/HTTP 1.1/Section 14.26 of [RFC2616]/ -> Regarding the remainder of Section 7.3, please see <http://ietf.cse.ucsc.edu:8080/bugzilla/show_bug.cgi?id=202> and <http://lists.w3.org/Archives/Public/w3c-dist-auth/2006JanMar/0734.html>. [Page 31] There are two kinds of collection write locks. A "Depth 0" write lock on a collection protects the collection metadata plus the internal member URLs of that collection, while not protecting the content or metadata of child resources. A "Depth: infinity" write lock on a collection provides the same protection on that collection and also protects every descendent resource as if that resource were itself write locked. -> Again repeats stuff from previous sections, but in this case fails to say that collection content is lockable as well (if present). Why not just refer to "collection state"???? Expressed otherwise, a write lock protects any request that would create a new resource in a write locked collection, any request that would remove an internal member URL of a write locked collection, and any request that would change the binding name of a member URL. -> "binding name"? [Page 32] In order to prevent these collisions a lock token MUST be submitted by an authorized principal for all locked resources that a method may change or the method MUST fail. A lock token is submitted when it appears in an If header. For example, if a resource is to be moved and both the source and destination are locked then two lock tokens must be submitted in the if header, one for the source and the other for the destination. -> s/if/If/ [Page 34] 7.7. Refreshing Write Locks -> IMHO, the whole subsection is both unneeded (there simply isn't anything particular about refreshing *write* locks) and misleading. Please remove it. A client MUST NOT submit the same write lock request twice. Note that a client is always aware it is resubmitting the same lock request because it must include the lock token in the If header in order to make the request for a resource that is already locked. -> Repeating a LOCK request with an existing lock token in the If header is going to fail for an exclusive lock anway. However, a client may submit a LOCK method with an If header but without a body. This form of LOCK MUST only be used to "refresh" a lock. Meaning, at minimum, that any timers associated with the lock MUST be re-set. -> Just point to the paragraph in the LOCK definition here. At a minimum, fix above sentence to say "request" instead of "method". [Page 38] Some of these new methods do not define bodies. Servers MUST examine all requests for a body, even when a body was not expected. In cases where a request body is present but would be ignored by a server, the server MUST reject the request with 415 (Unsupported Media Type). This informs the client (which may have been attempting to use an extension) that the body could not be processed as they intended. -> s/they// HTTP defines many headers that can be used in WebDAV requests and responses. Not all of these are appropriate in all situations and some interactions may be undefined. Note that HTTP 1.1 requires the Date header in all responses if possible (see section 14.18, [RFC2616]). -> Not true, for instance for 100 Continue. [Page 39] Because clients may be forced to prompt users or throw away changed content if the ETag changes, a WebDAV server SHOULD NOT change the ETag (or the Last-Modified time) for a resource that has an unchanged body and location. The ETag represents the state of the body or contents of the resource. There is no similar way to tell if properties have changed. -> Language: "body or contents"? HTTP and WebDAV did not use the bodies of most error responses for machine-parsable information until DeltaV introduced a mechanism to include more specific information in the body of an error response (section 1.6 of [RFC3253]). The error body mechanism is appropriate to use with any error response that may take a body but does not already have a body defined. The mechanism is particularly appropriate when a status code can mean many things (for example, 400 Bad Request can mean required headers are missing, headers are incorrectly formatted, or much more). This error body mechanism is covered in Section 16 -> s/Section 16/Section 16./ [Page 41] A client MUST submit a Depth header with a value of "0", "1", or "infinity" with a PROPFIND request. Servers MUST support "0" and "1" depth requests on WebDAV-compliant resources and SHOULD support "infinity" requests. In practice, support for depth infinity requests MAY be disabled, due to the performance and security concerns associated with this behavior. Since clients weren't required to include the Depth header in [RFC2518], servers SHOULD treat such a request as if a "Depth: infinity" header was included. -> IMHO doesn't make sense. If servers SHOULD accept requests without depth header, there's no point in having a MUST-level requirement for clients to send it. Please keep changes compared to RFC2518 at a minimum. o Request particular property values, by naming the properties desired within the 'prop' element (the ordering of properties in here MAY be ignored by server), -> That implies that ordering could be relevant somehow, which it isn't. [Page 42] If there is an error retrieving a property then a proper error result MUST be included in the response. A request to retrieve the value of a property which does not exist is an error and MUST be noted, if the response uses a 'multistatus' XML element, with a 'response' XML element which contains a 404 (Not Found) status value. -> Is there a case where the response isn't a multistatus element??? Consequently, the 'multistatus' XML element for a collection resource with member URLs MUST include a 'response' XML element for each member URL of the collection, to whatever depth was requested. It SHOULD NOT include any 'response' elements for resources that are not WebDAV-compliant. Each 'response' element MUST contain an 'href' element that contains the URL of the resource on which the properties in the prop XML element are defined. Results for a PROPFIND on a collection resource with internal member URLs are returned as a flat list whose order of entries is not significant. Note that a resource may have only one value for a property of a given name, so the property may only show up once in PROPFIND responses. -> In this paragraph, please remove "with member URLs" and "with internal member URLs". The semantics of PROPFIND is indepedant of whether the collection has members or not. 403 Forbidden - A server MAY reject PROPFIND requests on collections with depth header of "Infinity", in which case it SHOULD use this error with the precondition code 'propfind-finite-depth' inside the error body. -> s/on collections// (it's irrelevant whether it's a collection or not) [Page 43] 9.1.2. Status codes for use with 207 (Multi-Status) The following are examples of response codes one would expect to be used in a 207 (Multi-Status) response for this method. Note, however, that unless explicitly prohibited any 2/3/4/5xx series response code may be used in a 207 (Multi-Status) response. -> Replace by: 9.1.2. Status Codes for use in 'propstat' Element In PROPFIND responses, information about individual properties is returned inside 'propstat' elements (see Section 14.22), each containing an individual 'status' element containing information about the properties appearing in it. The list below summarizes the most common status codes used inside 'propstat', however clients should be prepared to handle other 2/3/4/5xx series status codes as well. (see <http://ietf.cse.ucsc.edu:8080/bugzilla/show_bug.cgi?id=177>). [Page 45] 9.1.4. Example - Retrieving Named and Dead Properties -> Remove whole subsection and replace with correct one (see <http://ietf.cse.ucsc.edu:8080/bugzilla/show_bug.cgi?id=188>): 9.1.4 Example - Retrieving (almost) all properties plus selected live properties >>Request PROPFIND /mycol/changes HTTP/1.1 Host: www.example.com Depth: 0 Content-Type: application/xml; charset="utf-8" Content-Length: xxxx <?xml version="1.0" encoding="utf-8" ?> <D:propfind xmlns:D="DAV:"> <D:allprop/> <D:include> <D:checked-in/> <D:checked-out/> </D:include> </D:propfind> In this example, PROPFIND is executed on the resource http://www.example.com/mycol/changes. The client requests the values of all properties defined in this specification, plus the two live properties DAV:checked-in and DAV:checked-out defined in [RFC3253]. [Page 49] The last four properties are WebDAV-specific, defined in Section 15. Since GET is not supported on this resource, the get* properties (e.g., DAV:getcontentlength) are not defined on this resource. The -> Strike the 2nd "on this resource". [Page 50] 9.2. PROPPATCH Method The request message body of a PROPPATCH method MUST contain the propertyupdate XML element. Clients SHOULD NOT alter the same property more than once in a single PROPPATCH request. -> Huh? Why not? -> Also I note that we never normatively define the response body for PROPPATCH, will make proposal in a separate mail. 9.2.1. Status Codes for use in 207 (Multi-Status) The following are examples of response codes one would expect to be used in a 207 (Multi-Status) response for this method. Note, however, that unless explicitly prohibited any 2/3/4/5xx series response code may be used in a 207 (Multi-Status) response. -> Replace by (see <http://ietf.cse.ucsc.edu:8080/bugzilla/show_bug.cgi?id=177>: 9.2.1. Status Codes for use in 'propstat' Element In PROPPATCH responses, information about individual properties is returned inside 'propstat' elements (see Section 14.22), each containing an individual 'status' element containing information about the properties appearing in it. The list below summarizes the most common status codes used inside 'propstat', however clients should be prepared to handle other 2/3/4/5xx series status codes as well. 403 (Forbidden): The client has attempted to set a read-only property, such as DAV:getetag. If returning this error, the server SHOULD use the precondition code 'cannot-modify-protected-property' inside the response body. -> Replace by: "403 (Forbidden) (with the condition code 'cannot-modify-protected-property' defined in Section 16) - The client has attempted to set a protected property, such as DAV:getetag." [Page 52] The MKCOL method is used to create a new collection. All WebDAV compliant resources MUST support the MKCOL method. -> Nit: So does an unmapped URI (the thing you address the MKCOL to) identify a WebDAV compliant resource? Otherwise this requirement isn't really helpful... [Page 53] 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 URL namespace, or 2) the parent collection of the Request-URI exists but cannot accept members. -> Language? I think it can indicate lots of other things. [Page 54] Since by definition the actual function performed by POST is determined by the server and often depends on the particular resource, the behavior of POST when applied to collections cannot be meaningfully modified because it is largely undefined. Thus the semantics of POST are unmodified when applied to a collection. -> Nit: the fact that it's undefined in RF2616 really wouldn't stop us to define it, I think. A server processing a successful DELETE request: MUST destroy locks rooted on the deleted resource MUST remove the mapping from the Request-URI to any resource. -> Nit: list style? [Page 56] A PUT request is the only way a client has to indicate to the server what Content-Type a resource should have, and whether it should change if the resource is overwritten. Thus, a client SHOULD provide a Content-Type for a new resource if any is known. If the client does not provide a Content-Type for a new resource, the server MAY create a resource with no Content-Type assigned, or it MAY attempt to assign a reasonable and legal Content-Type. -> (1) So then why do we also say that DAV:getcontenttype will be writeable unless "prefers to assign content types on its own"? (2) Please rephrase or remove "reasonable and legal". "reasonable" doesn't have any place in normative text, and "legal" doesn't make sense either. [Page 58] After a successful COPY invocation, all dead properties on the source resource MUST be duplicated on the destination resource, along with all properties as appropriate. Live properties described in this -> MUST seems to be too strong, as the ability to PROPPATCH dead properties is only a SHOULD-level requirement. A COPY operation creates a new resource, much like a PUT operation does. Live properties which are related to resource creation (such as DAV:creationdate) should have their values set accordingly. -> "A COPY operation applied to an unmapped URL creates a new resource..." [Page 62] >>Response HTTP/1.1 207 Multi-Status Content-Type: application/xml; charset="utf-8" Content-Length: xxxx <?xml version="1.0" encoding="utf-8" ?> <d:multistatus xmlns:d="DAV:"> <d:response> <d:href>http://www.example.com/othercontainer/R2/</d:href> <d:status>HTTP/1.1 423 Locked</d:status> </d:response> </d:multistatus> -> d:error missing in example The MOVE operation on a non-collection resource is the logical equivalent of a copy (COPY), followed by consistency maintenance processing, followed by a delete of the source, where all three actions are performed atomically. The consistency maintenance step -> Replace "atomically" by "in a single operation" (to prevent confusion about the best-effort semantics). [Page 63] MOVE is frequently used by clients to rename a file without changing its parent collection, so it's not appropriate to reset all live properties which are set at resource creation. For example, the DAV: creationdate property value SHOULD remain the same after a MOVE. -> well, unless it needs to be modified. See Section 8.8. Dead properties MUST be moved along with the resource. -> Again, hard to defend because there's only a SHOULD level req to support them in PROPPATCH. [Page 65] 412 (Precondition Failed) - A condition header failed. Specific to MOVE, this could mean that the Overwrite header is "F" and the state of the destination URL is already mapped to a resource. -> s/the state of// [Page 66] >>Response HTTP/1.1 207 Multi-Status Content-Type: application/xml; charset="utf-8" Content-Length: xxxx <?xml version="1.0" encoding="utf-8" ?> <d:multistatus xmlns:d='DAV:'> <d:response> <d:href>http://www.example.com/othercontainer/C2/</d:href> <d:status>HTTP/1.1 423 Locked</d:status> </d:response> </d:multistatus> -> d:error missing [Page 67] A LOCK request to an existing resource will create a lock on the resource identified by the Request-URI, provided the resource is not already locked with a conflicting lock. The resource identified in the Request-URI becomes the root of the lock. Lock method requests -> No, the URL is the root. to create a new lock MUST have a XML request body. The server MUST preserve the information provided by the client in the 'owner' field in the request body when the lock information is requested. The LOCK -> "when the lock information is requested"??? 9.10.2. Refreshing Locks -> Issue: Lock refresh now is incompatible with RFC2518, causing required changes both in servers and clients for little gain; I don't think anybody wants to implement this. See <http://ietf.cse.ucsc.edu:8080/bugzilla/show_bug.cgi?id=143>. [Page 68] If the Depth header is set to infinity then the resource specified in the Request-URI along with all its internal members, all the way down the hierarchy, are to be locked. A successful result MUST return a single lock token which represents all the resources that have been locked. -> No, it doesn't represent the resources. If represents the lock. If an UNLOCK is successfully executed on this token, all associated resources are unlocked. -> The preceding sentence seems to be misplaced; probably it needs to be moved at the end of the paragraph. Hence, partial success is not an option. Either the entire hierarchy is locked or no resources are locked. A successful LOCK method MUST result in the creation of an empty resource which is locked (and which is not a collection), when a resource did not previously exist at that URL. Later on, the lock may go away but the empty resource remains. Empty resources MUST then appear in PROPFIND responses including that URL in the response scope. A server MUST respond successfully to a GET request to an empty resource, either by using a 204 No Content response, or by using 200 OK with a Content-Length header indicating zero length -> This repeats stuff from Section 7, but in an inconsistent way. According to this version, LNRs are not compliant; and it also applies to any kind of lock while Section 7 specifically talks about write locks. [Page 75] In this example, the lock identified by the lock token "urn:uuid:a515cfa4-5da4-22e1-f5b5-00a0451e6bf7" is successfully removed from the resource http://example.com/workspace/webdav/info.doc. If this lock included more than just one resource, the lock is removed from all resources included in the lock. The 204 (No Content) status code is used instead of 200 (OK) because there is no response entity body. -> Preceding sentence just duplicates text from above.
Received on Wednesday, 15 March 2006 15:41:55 UTC