diff options
Diffstat (limited to 'modules/dav/fs/repos.c')
-rw-r--r-- | modules/dav/fs/repos.c | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c index 6a5ff76..64bc894 100644 --- a/modules/dav/fs/repos.c +++ b/modules/dav/fs/repos.c @@ -35,6 +35,7 @@ #include "mod_dav.h" #include "repos.h" +APLOG_USE_MODULE(dav_fs); /* to assist in debugging mod_dav's GET handling */ #define DEBUG_GET_HANDLER 0 @@ -948,15 +949,29 @@ static dav_error * dav_fs_open_stream(const dav_resource *resource, else if (APR_STATUS_IS_EEXIST(rv)) { rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p); + if (rv != APR_SUCCESS) { + return dav_new_error(p, MAP_IO2HTTP(rv), 0, rv, + apr_psprintf(p, "Could not open an existing " + "resource for writing: %s.", + ds->pathname)); + } } } else { rv = apr_file_open(&ds->f, ds->pathname, flags, APR_OS_DEFAULT, ds->p); + if (rv != APR_SUCCESS) { + return dav_new_error(p, MAP_IO2HTTP(rv), 0, rv, + apr_psprintf(p, "Could not open an existing " + "resource for reading: %s.", + ds->pathname)); + } } if (rv != APR_SUCCESS) { return dav_new_error(p, MAP_IO2HTTP(rv), 0, rv, - "An error occurred while opening a resource."); + apr_psprintf(p, "An error occurred while opening " + "a resource for writing: %s.", + ds->pathname)); } /* (APR registers cleanups for the fd with the pool) */ @@ -1572,6 +1587,19 @@ static dav_error * dav_fs_walker(dav_fs_walker_context *fsctx, int depth) status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf, DAV_FINFO_MASK, pool); if (status != APR_SUCCESS && status != APR_INCOMPLETE) { + dav_resource_private *ctx = params->root->info; + + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, ctx->r, + APLOGNO(10472) "could not access file (%s) during directory walk", + fsctx->path1.buf); + + /* If being tolerant, ignore failure due to losing a race + * with some other process deleting files out from under + * the directory walk. */ + if ((params->walk_type & DAV_WALKTYPE_TOLERANT) + && APR_STATUS_IS_ENOENT(status)) { + continue; + } /* woah! where'd it go? */ /* ### should have a better error here */ err = dav_new_error(pool, HTTP_NOT_FOUND, 0, status, NULL); @@ -1663,7 +1691,7 @@ static dav_error * dav_fs_walker(dav_fs_walker_context *fsctx, int depth) /* put a slash back on the end of the directory */ fsctx->path1.buf[fsctx->path1.cur_len - 1] = '/'; - /* these are all non-existant (files) */ + /* these are all non-existent (files) */ fsctx->res1.exists = 0; fsctx->res1.collection = 0; memset(&fsctx->info1.finfo, 0, sizeof(fsctx->info1.finfo)); @@ -1853,27 +1881,26 @@ static dav_error * dav_fs_walk(const dav_walk_params *params, int depth, return dav_fs_internal_walk(params, depth, 0, NULL, response); } -/* dav_fs_etag: Stolen from ap_make_etag. Creates a strong etag - * for file path. - * ### do we need to return weak tags sometimes? +/* dav_fs_etag: Creates an etag for the file path. */ static const char *dav_fs_getetag(const dav_resource *resource) { - dav_resource_private *ctx = resource->info; - /* XXX: This should really honor the FileETag setting */ + etag_rec er; - if (!resource->exists) - return apr_pstrdup(ctx->pool, ""); + dav_resource_private *ctx = resource->info; - if (ctx->finfo.filetype != APR_NOFILE) { - return apr_psprintf(ctx->pool, "\"%" APR_UINT64_T_HEX_FMT "-%" - APR_UINT64_T_HEX_FMT "\"", - (apr_uint64_t) ctx->finfo.size, - (apr_uint64_t) ctx->finfo.mtime); + if (!resource->exists || !ctx->r) { + return ""; } - return apr_psprintf(ctx->pool, "\"%" APR_UINT64_T_HEX_FMT "\"", - (apr_uint64_t) ctx->finfo.mtime); + er.vlist_validator = NULL; + er.request_time = ctx->r->request_time; + er.finfo = &ctx->finfo; + er.pathname = ctx->pathname; + er.fd = NULL; + er.force_weak = 0; + + return ap_make_etag_ex(ctx->r, &er); } static const dav_hooks_repository dav_hooks_repository_fs = @@ -1913,7 +1940,7 @@ static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource, const char *s; apr_pool_t *p = resource->info->pool; const dav_liveprop_spec *info; - int global_ns; + long global_ns; /* an HTTP-date can be 29 chars plus a null term */ /* a 64-bit size can be 20 chars plus a null term */ @@ -1994,18 +2021,20 @@ static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource, /* DBG3("FS: inserting lp%d:%s (local %d)", ns, scan->name, scan->ns); */ if (what == DAV_PROP_INSERT_VALUE) { - s = apr_psprintf(p, "<lp%d:%s>%s</lp%d:%s>" DEBUG_CR, + s = apr_psprintf(p, "<lp%ld:%s>%s</lp%ld:%s>" DEBUG_CR, global_ns, info->name, value, global_ns, info->name); } else if (what == DAV_PROP_INSERT_NAME) { - s = apr_psprintf(p, "<lp%d:%s/>" DEBUG_CR, global_ns, info->name); + s = apr_psprintf(p, "<lp%ld:%s/>" DEBUG_CR, global_ns, info->name); } else { /* assert: what == DAV_PROP_INSERT_SUPPORTED */ - s = apr_psprintf(p, - "<D:supported-live-property D:name=\"%s\" " - "D:namespace=\"%s\"/>" DEBUG_CR, - info->name, dav_fs_namespace_uris[info->ns]); + s = apr_pstrcat(p, + "<D:supported-live-property D:name=\"", + info->name, + "\" D:namespace=\"", + dav_fs_namespace_uris[info->ns], + "\"/>" DEBUG_CR, NULL); } apr_text_append(p, phdr, s); |