|Summary:||Socket timeout handler can delete uploaded files PUT upload|
|Product:||Apache httpd-2||Reporter:||Kenkendk <kenneth>|
|Component:||mod_dav||Assignee:||Apache HTTPD Bugs Mailing List <bugs>|
Description Kenkendk 2013-04-03 06:30:50 UTC
When issuing a PUT request for a non-existent resource, the upload will eventually return "201 - Created". However, if this upload is paused, or the cable is "cut", the socket will remain open. Now, if another PUT request is then issued against the same resource, it can upload a new file, but will get a "204 - No Content" response. Issuing a PROPFIND will show the file, and issuing a GET will download the file. All good. But when the original request times out, it will delete the file on the server! This happens in production, because some German DSL subscribers have their lines reset at least every 24-hours. When this happens, every socket is immediately discovered as disconnected by the client, but the server only notices absence of data. When the client retries the upload, it can succeed (with a 204) and later disappear. If the file is large enough, the timeout occurs during the second upload and the server responds "500 - Internal Error" (not as bad, as the client knows it failed). There may be similar side-effects with existing files. The only issue I have found that appear somewhat related is #39815.
Comment 1 sensille 2013-05-02 07:41:41 UTC
This is by design, see dav_fs_close_stream in modules/dav/fs/repos.c. In case of error, the commit parameter is 0, leading to a call to apr_file_remove. What do you propose should happen in case of error instead?
Comment 2 Kenkendk 2013-05-02 09:41:09 UTC
I expect commands to be atomic. That is, until the file is uploaded successfully, it does not exist. Thus a failed upload does not require a delete of the target file (but maybe a temp file). If two connections are uploading the same file, the current approach would mess things up too? If you upload the file to a temporary location, and move into the right spot on completion, you would never have this problem. Two simultaneous uploads would also work with "last to finish completely replaces original". Another approach, which is simpler to implement, is to lock the file while uploading, so you cannot have competing uploads. In this case, the client would at least get an error message while the other upload is "in progress".