The MOVE method is a way to rename resources within the parent collection, as well as move them from one collection to another, along with all dead properties. The client must specify the target location and name using a Destination header with a fully qualified URL that must include the host name (see Listing 6-2). Listing 6-2 MOVE request and response for a regular resource.Request: MOVE /hr/drafts/application.doc HTTP/1.1 Host: www.example.com Destination: http://www.example.com/hr/recruiting/application.doc Response: HTTP/1.1 201 Created Date: Sun, 29 Jul 2001 15:24:17 GMT This operation moves the resource application.doc to the destination directory without changing its base name (the last segment of the URL). After this operation, a request to the original URL in the drafts/ collection will return 404 Not Found, whereas a request to the new URL in the recruiting/ collection will return the resource. 6.3.1 Destination HeaderThe Destination header always specifies a single URL, which is the full destination URL, not just the destination parent URL. The URL must be a full legal URL (any illegal characters must be escaped). The Destination header shown in Listing 6-2 shows how to move a resource to a new location without changing its name. Since the Destination header includes the full URL for the new resource including the base name, it's possible to rename the resource at the same time. If the request in Listing 6-2 contained this header instead, then the resource's base name would change as well as its parent collection. Destination: http://www.example.com/hr/recruiting/job-app.doc 6.3.2 Depth HeaderWe introduced the semantics of applying operations over an entire tree, or to a specified depth, in Chapter 3, HTTP Mechanics (Section 3.3). MOVE is the first method to be introduced that allows the Depth header, although it doesn't require it because it's always possible to apply a reasonable default value. The defined values for the Depth header are 0, 1, and infinity. Note that the server should ignore case when parsing the value of the Depth header, but the client should use the exact case shown in the standard. The default value for the Depth header is infinity. The example of moving a file application.doc didn't need the Depth header because the resource being moved is not a collection. Thus, the only conceivable value for the depth is 0. The server automatically handled the request as if a Depth 0 header was present. Since the MOVE method is legal on a collection, we must also consider what happens when the client sends the MOVE request to a collection. Can you move a collection without moving all of its descendants? What would happen to any members of the collection that can't be moved where would they exist? Most file systems don't allow this to happen. Although it may be conceivable to apply a MOVE request with a depth of 0 or 1 to a collection, it's hard to define a consistent and interoperable behavior that could be supported on all server implementations. Thus, WebDAV doesn't allow a MOVE of a collection unless the collection and all its descendants are moved. Since WebDAV only allows a value of infinity for the Depth header when moving a collection, the Depth header is not actually required when moving collections, either. The collection must always be moved along with all of its descendants. However, the client can still include the Depth header (see Listing 6-3). Listing 6-3 MOVE request and response for a collection.Request: MOVE /hr/resumes/ HTTP/1.1 Host: www.example.com Depth: infinity Destination: http://www.example.com/hr/recruiting/resumes/ Response: HTTP/1.1 201 Created Date: Sun, 29 Jul 2001 15:24:17 GMT If the client includes a Depth header with an illegal value, the server should return 400 Bad Request. 6.3.3 Depth noroot ExtensionMicrosoft has extended the Depth header syntax in several of its products in a way that isn't legal and may cause interoperability problems. The client sends a header with multiple comma-separated values: Depth: infinity,noroot Depth: 1,noroot The meaning of the noroot value is to exclude the target URL itself (the root) from the operation. It's useful in a number of situations that would otherwise require multiple requests:
This was first seen in Hotmail traffic from Outlook Express. Exchange Server 2000 is known to support the extensions. Support on other servers has not been verified. This practice is not legal, because the Depth header isn't defined to have multiple values. Worse, it is bad for interoperability. Sending this header value to a server that is not known to support the feature would most likely result in an 400 Bad Request, but it could also result in the server interpreting the depth incorrectly and performing the wrong operation. 6.3.4 The Overwrite HeaderThe MOVE method can also contain the Overwrite header. WebDAV defines the Overwrite header so that the client can specify what should happen if a resource already exists at the Destination URI. This header has two legal values, either T or F (true or false). Any other value should result in a 400 Bad Request response from the server. A value of "T" on the Overwrite header indicates that the destination resource should be replaced if it existed at the time of the MOVE request. A value of F means that the client prefers the request to fail if the destination resource already exists. The Overwrite header is considered to be a "precondition" header. Thus, any time the Overwrite header has a value of F and the destination already exists, the request should fail with a response of 412 Precondition Failed (see Listing 6-4). Listing 6-4 MOVE request and response with Overwrite header.Request: MOVE /hr/drafts/candidate-application.doc HTTP/1.1 Host: www.example.com Destination: http://www.example.com/hr/recruiting/candidate- application.doc Overwrite: F Response: HTTP/1.0 412 Precondition Failed Date: Sun, 29 Jul 2001 15:24:17 GMT
The Overwrite header is only defined for COPY and MOVE requests. Although it might be nice to be able to use it for PUT, MKCOL, or other write operations, it is not defined for those methods. Here's why:
6.3.5 Status Codes for MOVEThe MOVE response should never use 200 OK unless it has a body, which it normally will not. The 201 Created status code must be used if the destination resource did not previously exist and was created as a result of this operation. The 204 No Content status code must be used if the destination resource already exists. This allows the client to distinguish between the two cases. It's important for the client to be able to distinguish between an overwrite and the creation of a new resource, because when resources are freshly created, the client may want to initialize some metadata. For example, the client might create a Title property or initialize access control settings on every resource when it is first created. The server might also initialize some property values that the client could be interested in seeing. Some other special failure status codes for MOVE:
6.3.6 102 Processing ResponseWhen the MOVE method is used with a collection, the server may take a long time to process the request. Clients must be prepared to wait a little while the response is generated before timing out and dropping the TCP connection. Clients can also give the user the choice of when to give up. WebDAV introduces the 102 Processing response for servers to let the client know that the request will take a while. The server can send one of these responses immediately or after processing a while, or it can send multiple 102 Processing responses at intervals. The client must wait until the final response (see Listing 6-5). Servers do not frequently use this response.
Listing 6-5 102 Continue example over single TCP connection.Request: MOVE /hr/resumes/ HTTP/1.1 Host: www.example.com Depth: infinity Destination: http://www.example.com/hr/recruiting/resumes Response: HTTP/1.1 102 Processing Date: Sun, 29 Jul 2001 15:24:17 GMT [time passes] HTTP/1.1 102 Processing Date: Sun, 29 Jul 2001 15:27:17 GMT [time passes] HTTP/1.1 201 Created Date: Sun, 29 Jul 2001 15:29:02 GMT The 102 Processing response interacts somewhat poorly with pipelining. Because there's no way to correlate pipelined requests with pipelined responses except by sequence, the 102 Processing response must be entirely completed before being able to respond to the next pipelined request. 6.3.7 The Multi-Status ResponseThe MOVE operation can act on several resources. Therefore, MOVE responses sometimes need to have more information than can be presented using a single status code. As with DELETE on multiple resources (Section 5.5.1), multiple errors are marshaled using the 207 Multi-Status response. Within the 207 Multi-Status message, each resource can be listed with the status code indicating why it couldn't be moved. As with DELETE, the MOVE method is not atomic, which means that some resources may be moved and some remain. Success status codes do not appear in the response. Resources that could not be moved do appear with a status code. Figure 6-1 shows a scenario in which a MOVE operation fails. The client asked to rename a collection from /hr/recruiting/positions/ to /hr/recruiting/openings/, but the source collection contains one resource locked by somebody else. Figure 6-1. Directory to be renamed (moved) has a locked resource.The client was unaware of this locked child and sent the MOVE request. The server began to handle the operation, creating the destination collection and moving some children. Then the server discovered the locked resource and stopped, failing to complete the operation. At this point, the server must respond with a 207 Multi-Status response (see Listing 6-6). Listing 6-6 Partially failed MOVE request requiring Multi-Status response.Request: MOVE /hr/recruiting/positions/ HTTP/1.1 Host: www.example.com Depth: infinity Destination: http://www.example.com/hr/recruiting/openings/ Response: HTTP/1.1 207 Multi-Status Content-Type: text/xml Content-Length: xxx Date: Sun, 29 Jul 2001 15:24:17 GMT <?xml version="1.0" encoding="utf-8" ?> <d:multistatus xmlns:d="DAV:"> <d:response> <d:href>http://www.example.com/hr/recruiting/positions/ java-eng.doc</d:href> <d:status>HTTP/1.1 423 Locked</d:status> </d:response> </d:multistatus> The response shows that java-eng.doc could not be moved and thus remained where it originally was. In fact, although it's not listed in the response, the /hr/recruiting/positions/ directory must still exist in its original location: If its child couldn't be moved, the parent must remain to contain the child. Figure 6-2 shows the result of the partially successful MOVE operation. Figure 6-2. Results of partial MOVE operation: old directory still exists.A server can handle a failed MOVE operation in several ways. It could fail the entire operation and not change any resources. A server could do "best effort" and move as many resources as possible, or it could quit as soon as it encounters an error.
6.3.8 Specifying Property Value BehaviorThe WebDAV designers thought that clients needed a way to tell the server when property values and behavior are important to preserve during a MOVE operation. In theory, the client may prefer not to do the MOVE at all, unless the server can guarantee that property values and important semantics can be preserved. For example, it does the client little good to have the value of a live property such as quota preserved after a MOVE if the server then fails to enforce the quota as it did in the original location.
To attempt to specify property value preservation in a MOVE operation, the client adds a body to the MOVE request (see Listing 6-7). Listing 6-7 MOVE request specifying property value behavior.MOVE /hr/drafts/chairs.doc HTTP/1.1 Host: www.example.com Destination: http://www.example.com/hr/ergonomics/chairs.doc Overwrite: F Content-Type: text/xml Content-Length: xxx <?xml version="1.0" encoding="utf-8" ?> <d:propertybehavior xmlns:d='DAV:'> <d:keepalive>*</d:keepalive> </d:propertybehavior> In this example, the asterisk (*) in the keepalive field indicates that all live properties must be maintained for all resources being copied. If the server cannot guarantee the desired live property behavior, it must fail. The asterisk can theoretically be replaced by a list of property names in href elements; however, this feature is not implemented at all. The WebDAV specification does not provide enough detail to reliably put property names in href elements, because it does not specify how a namespace and name of a property combine to form a legal URI. The only other legal value for the propertybehavior element is: <d:propertybehavior xmlns:d='DAV:'> <d:omit/> </d:propertybehavior> The omit body simply means that the server should attempt to copy properties and keep the live properties live, but it must not fail the overall request even if it has difficulty copying properties. It is the same as a request without the propertybehavior body. The WebDAV Working Group plans to simplify or even deprecate the property keepalive feature if the WebDAV specification is reissued as a Draft Standard. No significant client/server interoperability has been demonstrated with the keepalive feature containing property names. The IETF process requires that each specification feature must either be proven interoperable or removed in order to publish a Draft Standard, and this feature is definitely a candidate for removal. However, the server has to implement the logic to move and copy live properties one way or another, and WebDAV doesn't provide much guidance in defining desired behavior for the MOVE and COPY methods overall. A better approach is to define behavior individually for each property, since each property has different semantics. The DeltaV specification started this new practice, requiring certain properties to be moved or copied live. |