8.2 LOCK Method

The LOCK request is used in WebDAV both to get new locks and to refresh existing locks.

8.2.1 Creating a Lock

The server needs a number of pieces of information to create a lock. Listing 8-1 is an example of a LOCK request that locks a single file for exclusive use, followed by a run-through of each piece of information that appears in the request.

Listing 8-1 LOCK request.
 LOCK /hr/ergonomics/posture.doc HTTP/1.1 Host: www.example.com Timeout: Infinite If-Match: * Content-Type: text/xml; charset="utf-8" Content-Length: xxxx graphics/enter.gif <?xml version="1.0" encoding="utf-8" ?> <D:lockinfo xmlns:D='DAV:'>    <D:lockscope><D:exclusive/></D:lockscope>    <D:locktype><D:write/></D:locktype>    <D:owner xmlns:x="http://www.customapp.com/ns/">       <x:lock-user>alice@example.com</x:lock-user>       <x:created-by>Text Editor v1.2.5</x:created-by>    </D:owner> </D:lockinfo> 

Table 8-1 takes each relevant piece of information in the request the request URI, the new header, and the request body to show what each piece means.

Table 8-1. Information Provided in a LOCK Request

Where

Information

Request-URI

The URL of the resource to be locked.

Timeout header (optional)

The desired lifetime of the lock. This header is optional. Values for the header may be either Infinite or an integer specifying a number of seconds. If the value is an integer, it is prefixed with Second-.

 Timeout: Second-360 

Multiple values may be included in a comma-separated list, starting with most preferred:

 Timeout: Infinite, Second-604800 

The server may ignore the suggested timeout completely.

lockscope element in body

Whether the lock is to be exclusive or shared. This element may contain either the exclusive or the shared element only:

 <lockscope><exclusive/><lockscope> 

or:

 <lockscope><shared/><lockscope> 

owner element in body

A client-provided identifier for the lock owner (string or XML). The server must save this identifier and return it in the lockdiscovery property so that other users and other client software can see some information about the lock creator. In Listing 8-1, the client responsibly identified the user as well as the application software that created the lock. See Section 8.2.6 for more considerations relating to this field.

locktype element in body

The type of lock. Even though the only legal value is the write element, this element must appear anyway. Future protocol extensions may identify new types of locks.

 <locktype><write/><locktype> 

Assuming the LOCK request is successful, most of the same information (plus the lock token) is returned in the response, as shown in Listing 8-2. The lock information is also preserved in the lockdiscovery property as long as the lock exists. The format of the response body is the same as the format of the lockdiscovery property, which we cover in more detail in Section 8.5.1. The client should pay particular attention to the lock token and the timeout, in case the server chooses a different timeout value. Since there are no restrictions on how the server chooses a timeout value, the value could be shorter or longer than the timeout requested by the client.

Listing 8-2 Response to LOCK successfully locked the resource.
 HTTP/1.1 200 OK Date: Sun, 29 Jul 2001 15:24:17 GMT Lock-Token:opaquelocktoken:e71d4fae-5dec-22d6-fea5-00a0c91e6 Content-Type: text/xml; charset="utf-8" Content-Length: xxxx graphics/enter.gif <?xml version="1.0" encoding="utf-8" ?> <D:prop xmlns:D="DAV:"> <D:lockdiscovery>    <D:activelock>       <D:locktype><D:write/></D:locktype>       <D:lockscope><D:exclusive/></D:lockscope>       <D:depth>0</D:depth>       <D:owner xmlns:a="http://www.customapp.com/ns/">          <a:lock-user>alice@example.com</a:lock-user>          <a:created-by>Text Editor v1.2.5</a:created-by>       </D:owner>       <D:timeout>Second-604800</D:timeout>       <D:locktoken>          <D:href>opaquelocktoken:e71d4fae-5dec graphics/ap03inl01.gif             -22d6-fea5-00a0c91e6</D:href>       </D:locktoken>    </D:activelock> </D:lockdiscovery> </D:prop> 

graphics/roadt_icon.jpg

The status code for a successful LOCK response on an existing resource must be 200 OK. The body must contain the value of the lockdiscovery property at the point of time right after the lock is created (that means that if multiple shared locks existed, the response would show all of them). As the user requested, an exclusive write lock was granted. The server did not grant an infinite lifetime but instead chose a timeout of one week. The server also realized that since the request was made on a noncollection, the depth must be 0.

Note that the lock token is shown both in the body and in the Lock-Token header. This is required by RFC2518 in response to the creation of a new lock.

Clients should pay attention to the LOCK response return code. The return code is 201 Created, not 200 OK, if a new resource was created. The client may have expected there to be an existing resource to lock, but there's a chance the existing resource was just deleted by another user. Clients should use the If-Match or If-None-Match header on a LOCK request to make sure that the correct resource is being locked. The request in Listing 8-1 shows how to use the If-Match header to assert that the resource must exist; otherwise, the server should fail the request rather than create a new resource.

8.2.2 Locking a Collection

When the Request-URI identifies a collection, the LOCK request may include a Depth header. If the Depth header is omitted, the server must choose a default depth of infinity. The values 0 and infinity are supported when locking collections, but a depth of 1 is never supported with a LOCK request (thus, servers should respond with 400 Bad Request to a LOCK request with a depth of 1).

Depth Infinity

A lock depth infinity on a collection is easy to interpret: Lock the collection and every descendant of the collection, as illustrated in Figure 8-1. No write operation, whether PUT, PROPPATCH, COPY, MOVE, or DELETE, can be applied to the collection or any descendant of the collection without providing the correct lock token. It also means that if this is an exclusive lock, then none of the descendants of the collection can be locked with a different lock until the infinite-depth lock is removed.

Figure 8-1. Depth infinity lock.

graphics/08fig01.jpg

Despite the apparent simplicity, there are some difficult issues to deal with when infinite-depth collection locks are used. These issues are more related to the If header syntax than to the application of the lock itself, so we'll discuss that in a bit (Section 8.4.3). In the meantime, it's enough to point out that some servers (including IIS 5.0) don't support this type of lock, and most clients don't use it.

Authoring applications may never need infinite-depth locks, because typically the user opens files one at a time to edit them, and the application locks each file as it is opened. Multiple resources may be opened for simultaneous editing, but there's no need to lock the parent collection (which would prevent other users from creating new resources).

File management clients may sometimes need to lock collections, but even for these clients, operations on many files at once are rare. When the user does want to operate on entire collections, it's often possible to use a single infinite-depth COPY or MOVE request, in which case a lock may not be required.

Clients do not use collection locks much. Perhaps it's because IIS 5.0 doesn't support collection locks, and it's easier for clients to rely on features that are supported by all popular WebDAV servers. Perhaps clients do not use infinite-depth locks much because the If header is quite complicated to use with multiple resources (see Section 8.4.13).

When a collection descendent is included in the scope of a depth infinity collection lock, even though the descendent is not directly locked, the value of its lockdiscovery property must include all the lock information.

Depth 0

A depth 0 lock on a collection means that the collection's contents and metadata, but not the contents or metadata of its children or other descendents, are protected from changes. The contents of a collection are usually interpreted as the list of children, so if the list changes, that's governed by the lock. Changes that take place that don't affect the list of children are allowed, however. Figure 8-2 shows how the lock encompasses changes to the collection itself, its membership list, and its properties but not the content of its descendents.

Figure 8-2. Depth 0 collection lock.

graphics/08fig02.jpg

Here are a few examples to illustrate this concept. If the collection /hr is locked with a depth 0 lock, some write operations are always affected, and some are affected only under certain circumstances. These requests are affected by a depth 0 lock on /hr:

  • PROPPATCH the locked collection.

  • DELETE a child of the locked collection because that would alter the contents of the collection.

  • MKCOL or PUT when these result in a new child being created in the locked collection.

  • MOVE a child to or from the locked collection.

  • MOVE the locked collection somewhere else, or MOVE to a destination that overwrites the locked collection.

  • COPY to a destination that overwrites the locked collection, or COPY, which creates a new child inside the locked collection.

These requests are not affected by the same depth 0 lock:

  • PROPPATCH any resource inside the collection.

  • DELETE or MOVE requests that result in the removal of a resource within the locked collection but not a direct child of the locked collection.

  • PUT, MKCOL, COPY, or MOVE requests that result in the creation of a resource within children of the locked collection (inside subfolders).

There are a couple of interesting use cases for the depth 0 collection lock. The most useful case is simply to change properties. If the repository supports access control, depth 0 collection locks would be quite useful so that the client can get the access control information, modify it, and resubmit the changed access control information to the server.

Another use case is to be able to create a resource without risk of overwriting an existing one (a problem first discussed in Section 5.4.3). When a resource is locked depth 0, only the holder of the lock can create new resources in the collection, but the lock doesn't prevent other users from modifying the body or properties of existing child resources. To ensure that a file creation is not overwriting an existing resource, the client can issue a LOCK (depth 0) on the collection, a PROPFIND on the collection to see if the resource exists, and then the PUT or MKCOL request to create the new resource. Of course, an infinite-depth lock would serve the same purpose, but that would be overkill, unnecessarily preventing other users' actions.

8.2.3 Creating Lock-Null Resources

If a LOCK request is sent to an unmapped URL, rather than return 404 Not Found, the server must create a lock-null resource (and return a status of 201 Created).

graphics/bomb_icon.jpg

Lock-null resources are a special kind of resource invented to prevent the lost update problem for new resources. They are unnecessary, not broadly implemented, and may be obsolete in future drafts of the standard.

Lock-null resources were invented to help prevent two clients sending a PUT request for a new resource at nearly the same time. The client with the second PUT will unintentionally overwrite the content first put there. It's not sufficient to just check to see if the resource already exists, because with the latency of requests over the Internet, there's no guarantee that the resource will be in the same state when the actual PUT request is made.

A lock-null resource behaves in the following manner:

  • It is protected by the lock in the same way it would be if the resource existed the lock token must be in the If header for changes to be allowed.

  • It does not show up in the parent collection as a child member.

  • It does not support methods other than PUT, MKCOL, OPTIONS, PROPFIND, LOCK, and UNLOCK. (Other methods must result in an error.)

  • It supports the lock-related properties, lockdiscovery and supportedlocks, but not the get* properties (e.g., getcreationdate, getcontenttype).

  • It can be converted from a lock-null resource to a collection or a noncollection resource.

  • If the lock is removed before the lock-null resource is converted to a regular resource, the lock-null resource is removed as well.

After the lock-null resource is created, the next step is usually for the client to convert the lock-null resource into a regular resource or collection, using the lock token, of course. Now the resource is no longer a lock-null resource, so it behaves as a regular resource or collection, and property changes can be made. When all the write operations are complete, the client will probably unlock the resource.

Preventing Overwrite on Create with Collection Locks

Clients can also ensure that their new resource won't overwrite another new resource by locking the entire collection. However, users may not have permission to lock the whole collection, and this prevents other users from modifying other resources that aren't even affected by the new resource creation.

The best way to solve this problem is to put a conditional header on the creation request, as described in Section 3.7.6:

 
 If-None-Match: * 


8.2.4 Refreshing a Lock

Another use of the LOCK method is to refresh an existing lock on a resource (see Listing 8-3). An existing lock can be renewed or refreshed any time before it expires.

Listing 8-3 LOCK request to refresh a lock.
 LOCK /hr/ergonomics/posture.doc HTTP/1.1 Host: www.example.com Timeout: Second-300 If: (<opaquelocktoken:e71d4fae-5dec-22d6-fea5-00a0c91e6>) graphics/enter.gif 

The Timeout header is optional on a lock refresh request, but the If header is required. The syntax and meaning of the Timeout header are unchanged. The If header is required in order to supply the correct lock token, because there may be more than one shared lock on a given resource. Although the If header syntax has not been described yet, there will be a lot to say about it shortly (see Section 8.4.2).

8.2.5 Lock Timeout

The server controls lock timeout. It has a great deal of flexibility:

  • It can grant a shorter timeout than the client requested.

  • It can grant a longer timeout than the client requested.

  • It can remove timed-out locks aggressively as soon as the timeout is reached or allow a grace period.

Servers grant shorter lock timeouts than requested to keep unused locks to a minimum in a system where there are many authors collaborating or to reduce the system resources required to track and maintain locks. Many servers refuse to grant infinite length locks, but there's no reason that the client can't request those anyway. Typically, the server responds with the maximum lifetime it allows.

It's a little less obvious why servers grant a longer lock timeout than the client requests, but this practice arises from real implementation experience. The MS Web Folders implementation Office 2000 uses requests lock timeouts as short as two minutes. That requires the client software to refresh the lock at least that often, as long as the user still has the document open for editing. A server receiving lock refresh requests every two minutes from thousands of clients may see a noticeable performance degradation from this practice. Thus, the server grants the client a longer lock timeout. Happily, Web Folders does not refresh every two minutes if the lock lifetime granted by the server is longer.

Grace periods are also found in existing lock timeout implementations because Web Folders doesn't give itself much leeway when refreshing locks. See Section 8.6.2 for client lock refresh guidelines and an explanation of why the Web Folders practice causes many user errors.

Although the server has final power to choose a timeout, the client should try to give an opinion if the client has useful extra information about what the user intends. When a user opens a document in Word and makes changes, Word automatically locks the file for a short time. That's reasonable, because Word will be editing the document only as long as the software is still active and connected to the network.

In contrast, a client application that allows the user to "check out" or synchronize files for editing offline may choose to lock certain files for a longer period, say from 12 to 72 hours. In this case, the client application has some indication that the author wants to reserve the file and prevent changes from other users. The lock will then last even while the author's editing software is inactive or not connected to the network.

8.2.6 Use of the Lock Owner Element

When a user wants to modify a resource but a lock already exists, often the only recourse is to wait until the lock expires or is removed. However, if information about the lock owner is provided, it's possible the user may be able to ask the lock owner to remove the lock. Thus, the owner tag is included in the lockdiscovery property so that one human user can contact another.

The value of the lock owner tag may be XML or a string. The client defines the value when the lock is created. The client should provide useful identification information about the user who created the lock. This could be an email address and a client software identification string, as shown in the examples here. It could also include a full name, a URL to a Web page, a Principal URL as defined by the Access control extensions to WebDAV, or some other construct related to user or client identity. Although it's not specified, the owner tag can contain an href tag if the information identifying the lock creator is formatted as a URI (this is shown by the examples in RFC2518, although it's not required). Clients and servers must be prepared to handle a regular string, one or more href tags, or any other XML construct.

graphics/roadt_icon.jpg

WebDAV interoperability events have supplied a great deal of information about how to use and how not to use the owner element, since it wasn't unambiguously defined in RFC2518 yet it's extremely useful. Some clients (most notably those from Adobe) use the lock-owner field to contain custom machine-parsable information about the lock and the software that created the lock. The information is not intended for the user to view, but instead for communication between client software.

Servers should not enforce any particular syntax in the owner value, or some clients will fail to interoperate. Some clients send nothing in this element. A server could use authentication information to replace a blank or missing owner value with some information identifying the user, but the server should not alter a nonblank owner value, or some clients will fail to interoperate.

8.2.7 Special Status Codes for LOCK

If the resource is already locked with an exclusive lock, the server returns 423 Locked. Moreover, if the resource is already locked with a shared lock and the client requests an exclusive lock, the server responds with a 423 Locked.

Both 200 OK and 201 Created indicate that locks were created. The latter shows that a lock-null resource (or in the case of IIS 5.0, a locked empty resource) was created.

Many server implementations can return a 401 Unauthorized or 403 Forbidden response if the user asking for the lock does not have permission to perform write methods on a resource. Although it might be useful for a client to be able to lock a resource while reading it, to make sure that the resource doesn't change during the read, most clients don't do this.



WebDAV. Next Generation Collaborative Web Authoring
WebDAV. Next Generation Collaborative Web Authoring
ISBN: 130652083
EAN: N/A
Year: 2003
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net