From: Stefan Fritsch Date: Mon, 9 Nov 2009 13:50:21 +0000 (+0000) Subject: Don't delete the whole file if a PUT with content-range failed. X-Git-Tag: 2.3.3~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=539b5f666c7a3f18d3e16fb63743b7779e1a1851;p=thirdparty%2Fapache%2Fhttpd.git Don't delete the whole file if a PUT with content-range failed. PR: 42896 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@834062 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index f7aaaf79383..39112387866 100644 --- 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 , 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] diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c index 3e0b5d2b43b..efb01ac3c68 100644 --- a/modules/dav/fs/repos.c +++ b/modules/dav/fs/repos.c @@ -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,