3
3
## All lines beginning with `## DP:' are a description of the patch.
4
4
## DP: Various bug fixes for mod_dav/mod_dav_fs
5
## DP: upstream svn revs 834018:835092 in modules/dav
7
# *) mod_dav: Include uri when logging a PUT error due to connection abort.
8
# PR 38149. [Stefan Fritsch]
10
# *) mod_dav: Return 409 instead of 500 for a LOCK request if the parent
11
# resource does not exist or is not a collection. PR 43465. [Stefan Fritsch]
13
# *) mod_dav_fs: Return 409 instead of 500 for Litmus test case copy_nodestcoll
14
# (a COPY request where the parent of the destination resource does not
15
# exist). PR 39299. [Stefan Fritsch]
17
# *) mod_dav_fs: Don't delete the whole file if a PUT with content-range failed.
18
# PR 42896. [Stefan Fritsch]
20
# *) mod_dav_fs: Make PUT create files atomically and no longer destroy the
21
# old file if the transfer aborted. PR 39815. [Paul Querna, Stefan Fritsch]
23
# *) mod_dav_fs: Remove inode keyed locking as this conflicts with atomically
24
# creating files. On systems with inode numbers, this is a format change of
25
# the DavLockDB. The old DavLockDB must be deleted on upgrade.
5
## DP: upstream svn revs 834018:835092 and 928403 in modules/dav
7
## DP: *) mod_dav: Include uri when logging a PUT error due to connection abort.
8
## DP: PR 38149. [Stefan Fritsch]
10
## DP: *) mod_dav: Return 409 instead of 500 for a LOCK request if the parent
11
## DP: resource does not exist or is not a collection. PR 43465. [Stefan Fritsch]
13
## DP: *) mod_dav_fs: Return 409 instead of 500 for Litmus test case copy_nodestcoll
14
## DP: (a COPY request where the parent of the destination resource does not
15
## DP: exist). PR 39299. [Stefan Fritsch]
17
## DP: *) mod_dav_fs: Don't delete the whole file if a PUT with content-range failed.
18
## DP: PR 42896. [Stefan Fritsch]
20
## DP: *) mod_dav_fs: Make PUT create files atomically and no longer destroy the
21
## DP: old file if the transfer aborted. PR 39815. [Paul Querna, Stefan Fritsch]
23
## DP: *) mod_dav_fs: Remove inode keyed locking as this conflicts with atomically
24
## DP: creating files. On systems with inode numbers, this is a format change of
25
## DP: the DavLockDB. The old DavLockDB must be deleted on upgrade.
26
## DP: [Stefan Fritsch]
28
Index: a/modules/dav/main/mod_dav.c
29
===================================================================
30
--- a/modules/dav/main/mod_dav.c (Revision 834018)
31
+++ a/modules/dav/main/mod_dav.c (Revision 835089)
34
if (rc != APR_SUCCESS) {
35
err = dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
36
- "Could not get next bucket brigade");
37
+ apr_psprintf(r->pool,
38
+ "Could not get next bucket "
39
+ "brigade (URI: %s)",
40
+ ap_escape_html(r->pool, r->uri)));
44
@@ -1005,8 +1008,10 @@
45
rc = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
46
if (rc != APR_SUCCESS) {
47
err = dav_new_error(r->pool, HTTP_BAD_REQUEST, 0,
48
- "An error occurred while reading "
49
- "the request body.");
50
+ apr_psprintf(r->pool,
51
+ "An error occurred while reading"
52
+ " the request body (URI: %s)",
53
+ ap_escape_html(r->pool, r->uri)));
60
dav_resource *resource;
61
+ dav_resource *parent;
62
const dav_hooks_locks *locks_hooks;
65
@@ -3026,6 +3032,20 @@
67
return dav_handle_err(r, err, NULL);
69
+ /* Check if parent collection exists */
70
+ if ((err = resource->hooks->get_parent_resource(resource, &parent)) != NULL) {
71
+ /* ### add a higher-level description? */
72
+ return dav_handle_err(r, err, NULL);
74
+ if (parent && (!parent->exists || parent->collection != 1)) {
75
+ err = dav_new_error(r->pool, HTTP_CONFLICT, 0,
76
+ apr_psprintf(r->pool,
77
+ "The parent resource of %s does not "
78
+ "exist or is not a collection.",
79
+ ap_escape_html(r->pool, r->uri)));
80
+ return dav_handle_err(r, err, NULL);
84
* Open writable. Unless an error occurs, we'll be
85
* writing into the database.
86
Index: a/modules/dav/fs/lock.c
87
===================================================================
88
--- a/modules/dav/fs/lock.c (Revision 834018)
89
+++ a/modules/dav/fs/lock.c (Revision 835089)
28
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' trunk~/modules/dav/fs/lock.c trunk/modules/dav/fs/lock.c
29
--- trunk~/modules/dav/fs/lock.c 2010-03-29 21:46:51.000000000 +0200
30
+++ trunk/modules/dav/fs/lock.c 2010-03-29 21:49:00.970983302 +0200
231
Index: a/modules/dav/fs/repos.c
232
===================================================================
233
--- a/modules/dav/fs/repos.c (Revision 834018)
234
+++ a/modules/dav/fs/repos.c (Revision 835089)
172
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' trunk~/modules/dav/fs/repos.c trunk/modules/dav/fs/repos.c
173
--- trunk~/modules/dav/fs/repos.c 2010-03-29 21:46:51.000000000 +0200
174
+++ trunk/modules/dav/fs/repos.c 2010-03-29 21:49:08.031078314 +0200
176
#include <stdio.h> /* for sprintf() */
179
+#if APR_HAVE_UNISTD_H
180
+#include <unistd.h> /* for getpid() */
184
#include "http_log.h"
185
#include "http_protocol.h" /* for ap_set_* (in dav_fs_set_headers) */
237
188
#define DAV_PROPID_FS_executable 1
240
191
+ * prefix for temporary files
242
+#define DAV_FS_TMP_PREFIX ".davfs."
193
+#define DAV_FS_TMP_PREFIX ".davfs.tmp"
244
195
static const dav_liveprop_spec dav_fs_props[] =
246
197
/* standard DAV properties */
247
@@ -192,11 +197,14 @@
198
@@ -191,11 +200,14 @@
250
201
const char *pathname; /* we may need to remove it at close time */
315
266
+ return APR_SUCCESS;
269
+/* custom mktemp that creates the file with APR_OS_DEFAULT permissions */
270
+static apr_status_t dav_fs_mktemp(apr_file_t **fp, char *templ, apr_pool_t *p)
273
+ int num = ((getpid() << 7) + (int)templ % (1 << 16) ) % ( 1 << 23 ) ;
274
+ char *numstr = templ + strlen(templ) - 6;
276
+ ap_assert(numstr >= templ);
279
+ num = (num + 1) % ( 1 << 23 );
280
+ snprintf(numstr, 7, "%06x", num);
281
+ rv = apr_file_open(fp, templ,
282
+ APR_WRITE | APR_CREATE | APR_BINARY | APR_EXCL,
283
+ APR_OS_DEFAULT, p);
284
+ } while (APR_STATUS_IS_EEXIST(rv));
318
289
static dav_error * dav_fs_open_stream(const dav_resource *resource,
319
290
dav_stream_mode mode,
320
291
dav_stream **stream)
324
295
ds->pathname = resource->info->pathname;
464
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' trunk~/modules/dav/main/mod_dav.c trunk/modules/dav/main/mod_dav.c
465
--- trunk~/modules/dav/main/mod_dav.c 2010-03-29 21:46:51.000000000 +0200
466
+++ trunk/modules/dav/main/mod_dav.c 2010-03-29 21:49:00.966964568 +0200
469
if (rc != APR_SUCCESS) {
470
err = dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
471
- "Could not get next bucket brigade");
472
+ apr_psprintf(r->pool,
473
+ "Could not get next bucket "
474
+ "brigade (URI: %s)",
475
+ ap_escape_html(r->pool, r->uri)));
479
@@ -1009,8 +1012,10 @@
480
rc = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
481
if (rc != APR_SUCCESS) {
482
err = dav_new_error(r->pool, HTTP_BAD_REQUEST, 0,
483
- "An error occurred while reading "
484
- "the request body.");
485
+ apr_psprintf(r->pool,
486
+ "An error occurred while reading"
487
+ " the request body (URI: %s)",
488
+ ap_escape_html(r->pool, r->uri)));
492
@@ -2966,6 +2971,7 @@
495
dav_resource *resource;
496
+ dav_resource *parent;
497
const dav_hooks_locks *locks_hooks;
500
@@ -2997,6 +3003,20 @@
502
return dav_handle_err(r, err, NULL);
504
+ /* Check if parent collection exists */
505
+ if ((err = resource->hooks->get_parent_resource(resource, &parent)) != NULL) {
506
+ /* ### add a higher-level description? */
507
+ return dav_handle_err(r, err, NULL);
509
+ if (parent && (!parent->exists || parent->collection != 1)) {
510
+ err = dav_new_error(r->pool, HTTP_CONFLICT, 0,
511
+ apr_psprintf(r->pool,
512
+ "The parent resource of %s does not "
513
+ "exist or is not a collection.",
514
+ ap_escape_html(r->pool, r->uri)));
515
+ return dav_handle_err(r, err, NULL);
519
* Open writable. Unless an error occurs, we'll be
520
* writing into the database.