You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by gs...@apache.org on 2001/01/26 12:44:55 UTC
cvs commit: httpd-2.0/modules/dav/main mod_dav.c mod_dav.h util.c util_lock.c
gstein 01/01/26 03:44:55
Modified: modules/dav/fs repos.c
modules/dav/main mod_dav.c mod_dav.h util.c util_lock.c
Log:
Provide a way to allow get_resource and get_parent_resource to return errors
that might occur during the parsing of the URI and/or the lookup of the
resource in the repository.
Specifically: return a dav_error* and move the returned dav_resource* to an
"out" parameter of the hook function.
Revision Changes Path
1.46 +16 -7 httpd-2.0/modules/dav/fs/repos.c
Index: repos.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/dav/fs/repos.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -u -r1.45 -r1.46
--- repos.c 2001/01/23 04:14:21 1.45
+++ repos.c 2001/01/26 11:44:46 1.46
@@ -591,11 +591,12 @@
** REPOSITORY HOOK FUNCTIONS
*/
-static dav_resource * dav_fs_get_resource(
+static dav_error * dav_fs_get_resource(
request_rec *r,
const char *root_dir,
const char *target,
- int is_label)
+ int is_label,
+ dav_resource **result_resource)
{
dav_resource_private *ctx;
dav_resource *resource;
@@ -679,7 +680,10 @@
** be in path_info. The resource is simply an error: it
** can't be a null or a locknull resource.
*/
- return NULL; /* becomes HTTP_NOT_FOUND */
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST, 0,
+ "The URL contains extraneous path "
+ "components. The resource could not "
+ "be identified.");
}
/* retain proper integrity across the structures */
@@ -689,10 +693,12 @@
}
}
- return resource;
+ *result_resource = resource;
+ return NULL;
}
-static dav_resource * dav_fs_get_parent_resource(const dav_resource *resource)
+static dav_error * dav_fs_get_parent_resource(const dav_resource *resource,
+ dav_resource **result_parent)
{
dav_resource_private *ctx = resource->info;
dav_resource_private *parent_ctx;
@@ -706,8 +712,10 @@
#else
strcmp(ctx->pathname, "/") == 0
#endif
- )
+ ) {
+ *result_parent = NULL;
return NULL;
+ }
/* ### optimize this into a single allocation! */
@@ -740,7 +748,8 @@
parent_resource->exists = 1;
}
- return parent_resource;
+ *result_parent = parent_resource;
+ return NULL;
}
static int dav_fs_is_same_resource(
1.41 +93 -80 httpd-2.0/modules/dav/main/mod_dav.c
Index: mod_dav.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/dav/main/mod_dav.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -u -r1.40 -r1.41
--- mod_dav.c 2001/01/26 02:24:16 1.40
+++ mod_dav.c 2001/01/26 11:44:49 1.41
@@ -618,39 +618,54 @@
* by either a DAV:version or DAV:label-name element (passed as
* the target argument), or any Target-Selector header in the request.
*/
-static int dav_get_resource(request_rec *r, int target_allowed,
- ap_xml_elem *target, dav_resource **res_p)
+static dav_error * dav_get_resource(request_rec *r, int target_allowed,
+ ap_xml_elem *target, dav_resource **res_p)
{
void *data;
dav_dir_conf *conf;
const char *target_selector = NULL;
int is_label = 0;
int result;
+ dav_error *err;
- /* go look for the resource if it isn't already present */
+ /* only look for the resource if it isn't already present */
(void) apr_get_userdata(&data, DAV_KEY_RESOURCE, r->pool);
if (data != NULL) {
*res_p = data;
- return OK;
+ return NULL;
}
/* if the request target can be overridden, get any target selector */
if (target_allowed) {
+ /* ### this should return a dav_error* */
if ((result = dav_get_target_selector(r, target,
&target_selector,
&is_label)) != OK)
- return result;
+ return dav_new_error(r->pool, result, 0,
+ "Could not process the method target.");
}
conf = ap_get_module_config(r->per_dir_config, &dav_module);
/* assert: conf->provider != NULL */
/* resolve the resource */
- *res_p = (*conf->provider->repos->get_resource)(r, conf->dir,
- target_selector, is_label);
+ err = (*conf->provider->repos->get_resource)(r, conf->dir,
+ target_selector, is_label,
+ res_p);
+ if (err != NULL) {
+ err = dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+ "Could not fetch resource information.", err);
+ return err;
+ }
+
+ /* Note: this shouldn't happen, but just be sure... */
if (*res_p == NULL) {
- /* Apache will supply a default error for this. */
- return HTTP_NOT_FOUND;
+ /* ### maybe use HTTP_INTERNAL_SERVER_ERROR */
+ return dav_new_error(r->pool, HTTP_NOT_FOUND, 0,
+ apr_psprintf(r->pool,
+ "The provider did not define a "
+ "resource for %s.",
+ ap_escape_html(r->pool, r->uri)));
}
(void) apr_set_userdata(*res_p, DAV_KEY_RESOURCE, apr_null_cleanup,
@@ -661,7 +676,7 @@
* add it now */
dav_add_vary_header(r, r, *res_p);
- return OK;
+ return NULL;
}
static dav_error * dav_open_lockdb(request_rec *r, int ro, dav_lockdb **lockdb)
@@ -715,14 +730,15 @@
{
dav_resource *resource;
int result;
+ dav_error *err;
/* This method should only be called when the resource is not
* visible to Apache. We will fetch the resource from the repository,
* then create a subrequest for Apache to handle.
*/
- result = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -912,13 +928,11 @@
{
dav_resource *resource;
dav_error *err;
- int result;
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK) {
- return result;
- }
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
/* Note: depth == 0. Implies no need for a multistatus response. */
if ((err = dav_validate_request(r, resource, 0, NULL, NULL,
@@ -953,10 +967,9 @@
}
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK) {
- return result;
- }
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
/* If not a file or collection resource, PUT not allowed */
if (resource->type != DAV_RESOURCE_TYPE_REGULAR) {
@@ -1168,9 +1181,9 @@
}
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -1522,11 +1535,12 @@
apr_array_header_t *uri_ary;
ap_xml_doc *doc;
const ap_xml_elem *elem;
+ dav_error *err;
/* resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
/* parse any request body */
if ((result = ap_xml_parse_input(r, &doc)) != OK) {
@@ -1872,9 +1886,9 @@
dav_response *multi_status;
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (dav_get_resource_state(r, resource) == DAV_RESOURCE_NULL) {
/* Apache will supply a default error for this. */
@@ -2136,9 +2150,9 @@
dav_prop_ctx *ctx;
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -2336,9 +2350,9 @@
&dav_module);
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (resource->exists) {
/* oops. something was already there! */
@@ -2455,9 +2469,9 @@
int resource_state;
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, !is_move /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, !is_move /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -2509,9 +2523,9 @@
}
/* Resolve destination resource */
- result = dav_get_resource(lookup.rnew, 0 /*target_allowed*/, NULL, &resnew);
- if (result != OK)
- return result;
+ err = dav_get_resource(lookup.rnew, 0 /*target_allowed*/, NULL, &resnew);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
/* are the two resources handled by the same repository? */
if (resource->hooks != resnew->hooks) {
@@ -2838,9 +2852,9 @@
* so allow it, and let provider reject the lock attempt
* on a version if it wants to.
*/
- result = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
/*
** Open writable. Unless an error occurs, we'll be
@@ -3025,9 +3039,9 @@
* so allow it, and let provider reject the unlock attempt
* on a version if it wants to.
*/
- result = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
resource_state = dav_get_resource_state(r, resource);
@@ -3083,9 +3097,9 @@
return DECLINED;
/* ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
/* remember the pre-creation resource state */
resource_state = dav_get_resource_state(r, resource);
@@ -3284,9 +3298,9 @@
}
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 1 /*target_allowed*/, target, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 1 /*target_allowed*/, target, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -3349,9 +3363,9 @@
}
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -3412,9 +3426,9 @@
}
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /* target_allowed */, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /* target_allowed */, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -3518,9 +3532,9 @@
return DECLINED;
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -3700,9 +3714,9 @@
return DECLINED;
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -3835,9 +3849,9 @@
* for this report.
*/
target_allowed = (*vsn_hooks->report_target_selector_allowed)(doc);
- result = dav_get_resource(r, target_allowed, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, target_allowed, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -3882,9 +3896,9 @@
return DECLINED;
/* ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
/* parse the request body (must be a mkworkspace element) */
if ((result = ap_xml_parse_input(r, &doc)) != OK) {
@@ -3961,16 +3975,15 @@
dav_response *multi_response = NULL;
dav_lookup_result lookup;
int overwrite;
- int result;
/* If no bindings provider, decline the request */
if (binding_hooks == NULL)
return DECLINED;
/* Ask repository module to resolve the resource */
- result = dav_get_resource(r, 0 /*!target_allowed*/, NULL, &resource);
- if (result != OK)
- return result;
+ err = dav_get_resource(r, 0 /*!target_allowed*/, NULL, &resource);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
if (!resource->exists) {
/* Apache will supply a default error for this. */
return HTTP_NOT_FOUND;
@@ -4015,9 +4028,9 @@
}
/* resolve binding resource */
- result = dav_get_resource(lookup.rnew, 0 /*!target_allowed*/, NULL, &binding);
- if (result != OK)
- return result;
+ err = dav_get_resource(lookup.rnew, 0 /*!target_allowed*/, NULL, &binding);
+ if (err != NULL)
+ return dav_handle_err(r, err, NULL);
/* are the two resources handled by the same repository? */
if (resource->hooks != binding->hooks) {
1.39 +23 -14 httpd-2.0/modules/dav/main/mod_dav.h
Index: mod_dav.h
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/dav/main/mod_dav.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -u -r1.38 -r1.39
--- mod_dav.h 2001/01/20 11:29:34 1.38
+++ mod_dav.h 2001/01/26 11:44:49 1.39
@@ -1566,32 +1566,41 @@
*/
int handle_get;
- /* Get a resource descriptor for the URI in a request.
- * A descriptor is returned even if the resource does not exist.
- * The return value should only be NULL for some kind of fatal error.
+ /* Get a resource descriptor for the URI in a request. A descriptor
+ * should always be returned even if the resource does not exist. This
+ * repository has been identified as handling the resource given by
+ * the URI, so an answer must be given. If there is a problem with the
+ * URI or accessing the resource or whatever, then an error should be
+ * returned.
*
- * The root_dir is the root of the directory for which this repository
- * is configured.
- * The target is either a label, or a version URI, or NULL. If there
- * is a target, then is_label specifies whether the target is a label
- * or a URI.
+ * root_dir: the root of the directory for which this repository is
+ * configured.
+ * target: is either a label, or a version URI, or NULL. If there is
+ * a target, then is_label specifies whether the target is a
+ * label or a URI.
*
- * The provider may associate the request storage pool with the resource,
- * to use in other operations on that resource.
+ * The provider may associate the request storage pool with the resource
+ * (in the resource->pool field), to use in other operations on that
+ * resource.
*/
- dav_resource * (*get_resource)(
+ dav_error * (*get_resource)(
request_rec *r,
const char *root_dir,
const char *target,
- int is_label
+ int is_label,
+ dav_resource **resource
);
/* Get a resource descriptor for the parent of the given resource.
* The resources need not exist. NULL is returned if the resource
* is the root collection.
+ *
+ * An error should be returned only if there is a fatal error in
+ * fetching information about the parent resource.
*/
- dav_resource * (*get_parent_resource)(
- const dav_resource *resource
+ dav_error * (*get_parent_resource)(
+ const dav_resource *resource,
+ dav_resource **parent_resource
);
/* Determine whether two resource descriptors refer to the same resource.
1.17 +11 -4 httpd-2.0/modules/dav/main/util.c
Index: util.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/dav/main/util.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -u -r1.16 -r1.17
--- util.c 2000/12/14 18:47:25 1.16
+++ util.c 2001/01/26 11:44:50 1.17
@@ -1345,13 +1345,15 @@
/* (2) Validate the parent resource if requested */
if (err == NULL && (flags & DAV_VALIDATE_PARENT)) {
- dav_resource *parent_resource = (*repos_hooks->get_parent_resource)(resource);
+ dav_resource *parent_resource;
- if (parent_resource == NULL) {
+ err = (*repos_hooks->get_parent_resource)(resource, &parent_resource);
+
+ if (err == NULL && parent_resource == NULL) {
err = dav_new_error(r->pool, HTTP_FORBIDDEN, 0,
"Cannot access parent of repository root.");
}
- else {
+ else if (err == NULL) {
err = dav_validate_resource_state(r->pool, parent_resource, lockdb,
if_header,
flags | DAV_VALIDATE_IS_PARENT,
@@ -1603,7 +1605,12 @@
/* check parent resource if requested or if resource must be created */
if (!resource->exists || parent_only) {
- dav_resource *parent = (*resource->hooks->get_parent_resource)(resource);
+ dav_resource *parent;
+
+ if ((err = (*resource->hooks->get_parent_resource)(resource,
+ &parent)) != NULL)
+ return err;
+
if (parent == NULL || !parent->exists) {
body = apr_psprintf(r->pool,
"Missing one or more intermediate collections. "
1.13 +15 -3 httpd-2.0/modules/dav/main/util_lock.c
Index: util_lock.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/dav/main/util_lock.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -u -r1.12 -r1.13
--- util_lock.c 2000/11/26 04:47:40 1.12
+++ util_lock.c 2001/01/26 11:44:51 1.13
@@ -460,6 +460,7 @@
while (resource != NULL) {
dav_error *err;
dav_lock *lock;
+ dav_resource *parent;
/*
** Find the lock specified by <locktoken> on <resource>. If it is
@@ -488,7 +489,12 @@
}
/* the lock was indirect. move up a level in the URL namespace */
- resource = (*resource->hooks->get_parent_resource)(resource);
+ if ((err = (*resource->hooks->get_parent_resource)(resource,
+ &parent)) != NULL) {
+ /* ### add a higher-level desc? */
+ return err;
+ }
+ resource = parent;
}
return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
@@ -625,14 +631,20 @@
dav_response *multi_status;
if (use_parent) {
- which_resource = (*repos_hooks->get_parent_resource)(resource);
- if (which_resource == NULL) {
+ dav_resource *parent;
+ if ((err = (*repos_hooks->get_parent_resource)(resource,
+ &parent)) != NULL) {
+ /* ### add a higher-level desc? */
+ return err;
+ }
+ if (parent == NULL) {
/* ### map result to something nice; log an error */
return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
"Could not fetch parent resource. Unable to "
"inherit locks from the parent and apply "
"them to this resource.");
}
+ which_resource = parent;
}
else {
which_resource = resource;