If a client PUTs a file, and its Timeout is shorter than the server's Timeout, and the client then PUTs the file again, the first request will fail and the call to close_stream will delete the file even though the second PUT is currently writing to it. So the second PUT thinks the file is all there even though it isn't. I'm not sure if this is a bug per se, but it is something that I encountered and fixed myself, and I feel it could go into the mod_dav.c code. Also, I strongly recommend adding code that explicitly checks to see if the file really does exist at the end of the PUT and also checks the filesize to see if it matches the number of bytes written. A simple call to "stat" would be sufficient. We experience hundreds of thousands of PUTs a night, and a few files generally just disappear without any errors in the error_log.
I do agree that the delete-on-failed-PUT behaviour is a bug, at least in the case of modifying an existing file. Perhaps it is useful for the case where the resource did not exist before. To completely avoid concurrency problems like this mod_dav_fs would also have to lock the file. That should be relatively simple to do but needs further analysis. w.r.t. doing a the stat()-after-PUT; that would not eliminate the race; another process could still modify the file after the stat() and the returned status code would be "wrong" again
Since the fix for PR 39815 in trunk, a PUT request without range header goes to a temporary file first. This means that a failed PUT will only unlink its temporary file and not the real target file. I belive this is a sufficient fix for this issue.
fixed in 2.4.1