]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Don't delete the whole file if a PUT with content-range failed.
authorStefan Fritsch <sf@apache.org>
Mon, 9 Nov 2009 13:50:21 +0000 (13:50 +0000)
committerStefan Fritsch <sf@apache.org>
Mon, 9 Nov 2009 13:50:21 +0000 (13:50 +0000)
PR: 42896

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@834062 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/dav/fs/repos.c

diff --git a/CHANGES b/CHANGES
index f7aaaf7938303b5de47f40332b031601c2050e49..3911238786690a98d9145a78522931db94872f23 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,9 @@ Changes with Apache 2.3.3
      mod_proxy_ftp: NULL pointer dereference on error paths.
      [Stefan Fritsch <sf fritsch.de>, Joe Orton]
 
+  *) mod_dav_fs: Don't delete the whole file if a PUT with content-range failed.
+     PR 42896. [Stefan Fritsch]
+
   *) mod_dav_fs: Make PUT create files atomically and no longer destroy the
      old file if the transfer aborted. PR 39815. [Paul Querna, Stefan Fritsch]
 
index 3e0b5d2b43b7491c52a1664c4fe54a57d553cee8..efb01ac3c687b5b67f51cd1b748b30398d59ff3f 100644 (file)
@@ -198,6 +198,7 @@ struct dav_stream {
     apr_file_t *f;
     const char *pathname;       /* we may need to remove it at close time */
     const char *temppath;
+    int unlink_on_error;
 };
 
 /* returns an appropriate HTTP status code given an APR status code for a
@@ -891,6 +892,7 @@ static dav_error * dav_fs_open_stream(const dav_resource *resource,
     ds->p = p;
     ds->pathname = resource->info->pathname;
     ds->temppath = NULL;
+    ds->unlink_on_error = 0;
 
     if (mode == DAV_MODE_WRITE_TRUNC) {
         ds->temppath = apr_pstrcat(p, ap_make_dirstr_parent(p, ds->pathname),
@@ -899,6 +901,18 @@ static dav_error * dav_fs_open_stream(const dav_resource *resource,
         apr_pool_cleanup_register(p, ds, tmpfile_cleanup,
                                   apr_pool_cleanup_null);
     }
+    else if (mode == DAV_MODE_WRITE_SEEKABLE) {
+        rv = apr_file_open(&ds->f, ds->pathname, flags | APR_FOPEN_EXCL,
+                           APR_OS_DEFAULT, ds->p);
+        if (rv == APR_SUCCESS) {
+            /* we have created a new file */
+            ds->unlink_on_error = 1;
+        }
+        else if (APR_STATUS_IS_EEXIST(rv)) {
+            rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT,
+                               ds->p);
+        }
+    }
     else {
         rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p);
     }
@@ -924,7 +938,7 @@ static dav_error * dav_fs_close_stream(dav_stream *stream, int commit)
         if (stream->temppath) {
             apr_pool_cleanup_run(stream->p, stream, tmpfile_cleanup);
         }
-        else {
+        else if (stream->unlink_on_error) {
             if (apr_file_remove(stream->pathname, stream->p) != APR_SUCCESS) {
                 /* ### use a better description? */
                 return dav_new_error(stream->p, HTTP_INTERNAL_SERVER_ERROR, 0,