Bug 47657 - Make WebDAV MOVE atomic when replacing files on same device
Summary: Make WebDAV MOVE atomic when replacing files on same device
Status: NEW
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_dav (show other bugs)
Version: 2.5-HEAD
Hardware: All All
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-08-06 14:55 UTC by alex
Modified: 2009-11-07 14:22 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description alex 2009-08-06 14:55:34 UTC
When WebDAV MOVE is used to replace an existing file with a new one, mod_dav systematically deletes the destination file before moving the new file to the destination filename. This non-atomicity leads to a race condition whereby GET requests can return 404 Not Found for a short time. When the source and destination are on the same filesystem, it should be possible to use standard OS APIs for file renaming (which generally support atomic file replacement) without deleting the destination file first.

See line 2873 of modules/dav/main/mod_dav.c (http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/dav/main/mod_dav.c?revision=644050):

    /* If destination is being replaced, remove it first
     * (we know Ovewrite must be TRUE). Then try to copy/move the resource.
     */
    if (replace_dest)
        err = (*resnew->hooks->remove_resource)(resnew, &multi_response);

    if (err == NULL) {
        if (is_move)
            err = (*resource->hooks->move_resource)(resource, resnew,
                                                    &multi_response);
        else
            err = (*resource->hooks->copy_resource)(resource, resnew, depth,
                                                    &multi_response);
    }

It may be sufficient to simply suppress the call to remove_resource to fix this bug, although I haven't tried it...

The original WebDAV specification (RFC 2518) clearly says that the replacement should occur atomically:

8.9 MOVE Method

   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 more recent specification (RFC 4918) changes the wording slightly: "all three actions are performed in a single operation". Whether this means "atomic" is debatable. Nevertheless, it is highly useful in practice for the operation to be atomic whenever possible.

Note: To ensure atomic file replacement on Win32, it is apparently necessary to use MoveFileTransacted to ensure atomicity (see http://msdn.microsoft.com/en-us/library/aa365241%28VS.85%29.aspx), although this API is only supported on Vista and later. For other OSes, POSIX rename should do the job.
Comment 1 Stefan Fritsch 2009-11-07 14:22:28 UTC
It is not that easy:

- The current mod_dav API requires that the destination of a move_resource does not exist.
- The move must also work if the destination is a collection (directory).
- The move must also move the properties.

Maybe the API should be changed in a way that move_resource should handle this automatically.