From f9b9fbe7b840f09277e0668d63da03df0cae4b0e Mon Sep 17 00:00:00 2001 From: Greg Stein Date: Wed, 7 Feb 2001 12:33:17 +0000 Subject: [PATCH] Revamp the CHECKOUT method handling and various support functions for it. Basically, the original CHECKOUT was based on a really old draft of the DeltaV specification. This brings it up to date. *) get_resource hook now takes an optional label name and/or a flag on whether to use the DAV:checked-in property; if either one is provided, then a version resource is looked up and returned. WARNING: the parameter types are now the same, but have very different semantics. this means you won't get a compile error to figure out that something needs to be changed here. *) mod_dav.c::dav_get_resource no longer cahces the fetched resource in the request userdata. Some requests will call this function multiple times, for different resources -- we don't want to keep returning the same resource (no idea how this ended up working). *) dav_get_resource()'s parameters have been updated. target_allowed is old terminology; it is now label_allowed. The target paramter is obsoleted by the simple use_checked_in flag. *) dav_get_target_selector() is obsolete. XML element processing is done within the CHECKOUT method (i.e. only where it occurs). The other half of the old function was to simply fetch the Label: header. *) DAV_TARGET_SELECTOR_HDR is now DAV_LABEL_HDR *) dav_method_checkout() now processes all the various options for a CHECKOUT method and either modifies the initial resource lookup, or passes the data to the checkout hook function. *) the checkout hook grew a bunch of new parameters *) new utility function: dav_xml_get_cdata() to gather up all the CDATA from an XML element. this is used to extract DAV:href values. (probably move to util_xml.c at some point) git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88007 13f79535-47bb-0310-9956-ffa450edef68 --- modules/dav/fs/repos.c | 4 +- modules/dav/main/mod_dav.c | 177 +++++++++++++++++++++++++------------ modules/dav/main/mod_dav.h | 63 ++++++------- modules/dav/main/util.c | 119 ++++++++++++++----------- 4 files changed, 223 insertions(+), 140 deletions(-) diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c index c5917dccb8..5ee6e40c94 100644 --- a/modules/dav/fs/repos.c +++ b/modules/dav/fs/repos.c @@ -594,8 +594,8 @@ static dav_error *dav_fs_deleteset(apr_pool_t *p, const dav_resource *resource) static dav_error * dav_fs_get_resource( request_rec *r, const char *root_dir, - const char *target, - int is_label, + const char *label, + int use_checked_in, dav_resource **result_resource) { dav_resource_private *ctx; diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index 06dd4bf327..df4b893cc2 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -346,6 +346,8 @@ static const char *dav_cmd_davparam(cmd_parms *cmd, void *config, ** Send a nice response back to the user. In most cases, Apache doesn't ** allow us to provide details in the body about what happened. This ** function allows us to completely specify the response body. +** +** ### this function is not logging any errors! (e.g. the body) */ static int dav_error_response(request_rec *r, int status, const char *body) { @@ -614,35 +616,24 @@ static int dav_get_overwrite(request_rec *r) } /* resolve a request URI to a resource descriptor. - * If target_allowed != 0, then allow the request target to be overridden - * by either a DAV:version or DAV:label-name element (passed as - * the target argument), or any Target-Selector header in the request. + * + * If label_allowed != 0, then allow the request target to be altered by + * a Label: header. + * + * If use_checked_in is true, then the repository provider should return + * the resource identified by the DAV:checked-in property of the resource + * identified by the Request-URI. */ -static dav_error * 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 label_allowed, + int use_checked_in, dav_resource **res_p) { - void *data; dav_dir_conf *conf; - const char *target_selector = NULL; - int is_label = 0; - int result; + const char *label = NULL; dav_error *err; - /* 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 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 dav_new_error(r->pool, result, 0, - "Could not process the method target."); + if (label_allowed) { + label = apr_table_get(r->headers_in, "label"); } conf = ap_get_module_config(r->per_dir_config, &dav_module); @@ -650,7 +641,7 @@ static dav_error * dav_get_resource(request_rec *r, int target_allowed, /* resolve the resource */ err = (*conf->provider->repos->get_resource)(r, conf->dir, - target_selector, is_label, + label, use_checked_in, res_p); if (err != NULL) { err = dav_push_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, @@ -668,9 +659,6 @@ static dav_error * dav_get_resource(request_rec *r, int target_allowed, ap_escape_html(r->pool, r->uri))); } - (void) apr_set_userdata(*res_p, DAV_KEY_RESOURCE, apr_null_cleanup, - r->pool); - /* ### hmm. this doesn't feel like the right place or thing to do */ /* if there were any input headers requiring a Vary header in the response, * add it now */ @@ -736,7 +724,8 @@ static int dav_method_get(request_rec *r) * visible to Apache. We will fetch the resource from the repository, * then create a subrequest for Apache to handle. */ - err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -930,7 +919,8 @@ static int dav_method_post(request_rec *r) dav_error *err; /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -967,7 +957,8 @@ static int dav_method_put(request_rec *r) } /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -1181,7 +1172,8 @@ static int dav_method_delete(request_rec *r) } /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -1538,7 +1530,8 @@ static int dav_method_options(request_rec *r) dav_error *err; /* resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -1890,7 +1883,8 @@ static int dav_method_propfind(request_rec *r) dav_response *multi_status; /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -2154,7 +2148,8 @@ static int dav_method_proppatch(request_rec *r) dav_prop_ctx *ctx; /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -2354,7 +2349,8 @@ static int dav_method_mkcol(request_rec *r) &dav_module); /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -2473,7 +2469,8 @@ static int dav_method_copymove(request_rec *r, int is_move) int resource_state; /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, !is_move /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, !is_move /* label_allowed */, + 0 /* use_checked_in */, &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -2527,7 +2524,8 @@ static int dav_method_copymove(request_rec *r, int is_move) } /* Resolve destination resource */ - err = dav_get_resource(lookup.rnew, 0 /*target_allowed*/, NULL, &resnew); + err = dav_get_resource(lookup.rnew, 0 /* label_allowed */, + 0 /* use_checked_in */, &resnew); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -2856,7 +2854,9 @@ static int dav_method_lock(request_rec *r) * so allow it, and let provider reject the lock attempt * on a version if it wants to. */ - err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource); + /* ### gjs: I'm not sure we want to allow for locking a version... */ + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -3043,7 +3043,9 @@ static int dav_method_unlock(request_rec *r) * so allow it, and let provider reject the unlock attempt * on a version if it wants to. */ - err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource); + /* ### gjs: I'm not sure we want to allow for locking a version... */ + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -3101,7 +3103,8 @@ static int dav_method_vsn_control(request_rec *r) return DECLINED; /* ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -3279,7 +3282,11 @@ static int dav_method_checkout(request_rec *r) dav_error *err; int result; ap_xml_doc *doc; - ap_xml_elem *target = NULL; + int apply_to_vsn = 0; + int is_unreserved = 0; + int is_fork_ok = 0; + int create_activity = 0; + apr_array_header_t *activities = NULL; /* If no versioning provider, decline the request */ if (vsn_hooks == NULL) @@ -3289,6 +3296,8 @@ static int dav_method_checkout(request_rec *r) return result; if (doc != NULL) { + const ap_xml_elem *aset; + if (!dav_validate_root(doc, "checkout")) { /* This supplies additional information for the default msg. */ ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, @@ -3297,12 +3306,57 @@ static int dav_method_checkout(request_rec *r) return HTTP_BAD_REQUEST; } - if ((target = dav_find_child(doc->root, "version")) == NULL) - target = dav_find_child(doc->root, "label-name"); + if (dav_find_child(doc->root, "apply-to-version") != NULL) { + if (apr_table_get(r->headers_in, "label") != NULL) { + /* ### we want generic 403/409 XML reporting here */ + /* ### DAV:must-not-have-label-and-apply-to-version */ + return dav_error_response(r, HTTP_CONFLICT, + "DAV:apply-to-version cannot be " + "used in conjunction with a " + "Label header."); + } + apply_to_vsn = 1; + } + + is_unreserved = dav_find_child(doc->root, "unreserved") != NULL; + is_fork_ok = dav_find_child(doc->root, "fork-ok") != NULL; + + if ((aset = dav_find_child(doc->root, "activity-set")) != NULL) { + if (dav_find_child(aset, "new") != NULL) { + create_activity = 1; + } + else { + const ap_xml_elem *child = aset->first_child; + + for (; child != NULL; child = child->next) { + if (child->ns == AP_XML_NS_DAV_ID + && strcmp(child->name, "href") == 0) { + const char *href; + + href = dav_xml_get_cdata(child, r->pool, + 1 /* strip_white */); + *(const char **)apr_push_array(activities) = href; + } + } + + if (activities->nelts == 0) { + /* no href's is a DTD violation: + + */ + + /* This supplies additional info for the default msg. */ + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, + "Within the DAV:activity-set element, the " + "DAV:new element must be used, or at least " + "one DAV:href must be specified."); + return HTTP_BAD_REQUEST; + } + } + } } /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 1 /*target_allowed*/, target, &resource); + err = dav_get_resource(r, 1 /*label_allowed*/, apply_to_vsn, &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -3331,7 +3385,9 @@ static int dav_method_checkout(request_rec *r) /* ### do lock checks, once behavior is defined */ /* Do the checkout */ - if ((err = (*vsn_hooks->checkout)(resource, &working_resource)) != NULL) { + if ((err = (*vsn_hooks->checkout)(resource, is_unreserved, is_fork_ok, + create_activity, activities, + &working_resource)) != NULL) { err = dav_push_error(r->pool, HTTP_CONFLICT, 0, apr_psprintf(r->pool, "Could not CHECKOUT resource %s.", @@ -3367,7 +3423,8 @@ static int dav_method_uncheckout(request_rec *r) } /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -3430,7 +3487,8 @@ static int dav_method_checkin(request_rec *r) } /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /* target_allowed */, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -3536,7 +3594,8 @@ static int dav_method_set_target(request_rec *r) return DECLINED; /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -3718,7 +3777,8 @@ static int dav_method_label(request_rec *r) return DECLINED; /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 1 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -3829,7 +3889,7 @@ static int dav_method_report(request_rec *r) dav_resource *resource; const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); int result; - int target_allowed; + int label_allowed; ap_xml_doc *doc; ap_text_header hdr = { 0 }; ap_text *t; @@ -3852,8 +3912,9 @@ static int dav_method_report(request_rec *r) * First determine whether a Target-Selector header is allowed * for this report. */ - target_allowed = (*vsn_hooks->report_target_selector_allowed)(doc); - err = dav_get_resource(r, target_allowed, NULL, &resource); + label_allowed = (*vsn_hooks->report_target_selector_allowed)(doc); + err = dav_get_resource(r, label_allowed, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -3900,7 +3961,8 @@ static int dav_method_make_workspace(request_rec *r) return DECLINED; /* ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -3963,7 +4025,8 @@ static int dav_method_make_activity(request_rec *r) return DECLINED; /* ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); @@ -4034,7 +4097,8 @@ static int dav_method_bind(request_rec *r) return DECLINED; /* Ask repository module to resolve the resource */ - err = dav_get_resource(r, 0 /*!target_allowed*/, NULL, &resource); + err = dav_get_resource(r, 0 /* label_allowed */, 0 /* use_checked_in */, + &resource); if (err != NULL) return dav_handle_err(r, err, NULL); if (!resource->exists) { @@ -4081,7 +4145,8 @@ static int dav_method_bind(request_rec *r) } /* resolve binding resource */ - err = dav_get_resource(lookup.rnew, 0 /*!target_allowed*/, NULL, &binding); + err = dav_get_resource(lookup.rnew, 0 /* label_allowed */, + 0 /* use_checked_in */, &binding); if (err != NULL) return dav_handle_err(r, err, NULL); diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index a73f12901a..70e29c2d9f 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -59,11 +59,13 @@ #ifndef _MOD_DAV_H_ #define _MOD_DAV_H_ -#include "httpd.h" -#include "util_xml.h" #include "apr_hooks.h" #include "apr_hash.h" #include "apr_dbm.h" +#include "apr_tables.h" + +#include "httpd.h" +#include "util_xml.h" #include /* for INT_MAX */ @@ -519,6 +521,10 @@ int dav_get_depth(request_rec *r, int def_depth); int dav_validate_root(const ap_xml_doc *doc, const char *tagname); ap_xml_elem *dav_find_child(const ap_xml_elem *elem, const char *tagname); +/* gather up all the CDATA into a single string */ +const char *dav_xml_get_cdata(const ap_xml_elem *elem, apr_pool_t *pool, + int strip_white); + /* -------------------------------------------------------------------- ** @@ -599,9 +605,6 @@ APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, insert_all_liveprops, (request_rec *r, const dav_resource *resource, dav_prop_insert what, ap_text_header *phdr)) -/* ### make this internal to mod_dav.c ? */ -#define DAV_KEY_RESOURCE "dav-resource" - const dav_hooks_locks *dav_get_lock_hooks(request_rec *r); const dav_hooks_propdb *dav_get_propdb_hooks(request_rec *r); const dav_hooks_vsn *dav_get_vsn_hooks(request_rec *r); @@ -1573,11 +1576,17 @@ struct dav_hooks_repository * URI or accessing the resource or whatever, then an error should be * returned. * - * 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. + * root_dir: + * the root of the directory for which this repository is configured. + * + * label: + * if a Label: header is present (and allowed), this is the label + * to use to identify a version resource from the resource's + * corresponding version history. Otherwise, it will be NULL. + * + * use_checked_in: + * use the DAV:checked-in property of the resource identified by the + * Request-URI to identify and return a version resource * * The provider may associate the request storage pool with the resource * (in the resource->pool field), to use in other operations on that @@ -1586,8 +1595,8 @@ struct dav_hooks_repository dav_error * (*get_resource)( request_rec *r, const char *root_dir, - const char *target, - int is_label, + const char *label, + int use_checked_in, dav_resource **resource ); @@ -1786,25 +1795,6 @@ struct dav_hooks_repository */ -/* - * dav_get_target_selector - * - * If a DAV:version or DAV:label-name element is provided, - * then it is assumed to provide the target version. - * If no element is provided (version==NULL), then the - * request headers are examined for a Target-Selector header. - * - * The target version, if any, is then returned. If the version - * was specified by a label, then *is_label is set to 1. - * Otherwise, the target is a version URI. - * - * (used by versioning clients) - */ -int dav_get_target_selector(request_rec *r, - const ap_xml_elem *version, - const char **target, - int *is_label); - /* dav_add_vary_header * * If there were any headers in the request which require a Vary header @@ -1925,8 +1915,19 @@ struct dav_hooks_vsn * resource descriptor will refer to the working resource. * The working_resource argument can be NULL if the caller * is not interested in the working resource. + * + * If the client has specified DAV:unreserved or DAV:fork-ok in the + * checkout request, then the corresponding flags are set. If + * DAV:activity-set has been specified, then create_activity is set + * if DAV:new was specified; otherwise, the DAV:href elements' CDATA + * (the actual href text) is passed in the "activities" array (each + * element of the array is a const char *). activities will be NULL + * no DAV:activity-set was provided or when create_activity is set. */ dav_error * (*checkout)(dav_resource *resource, + int is_unreserved, int is_fork_ok, + int create_activity, + apr_array_header_t *activities, dav_resource **working_resource); /* Uncheckout a resource. If successful, the resource diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c index 51ca37a343..041355c988 100644 --- a/modules/dav/main/util.c +++ b/modules/dav/main/util.c @@ -305,6 +305,61 @@ ap_xml_elem *dav_find_child(const ap_xml_elem *elem, const char *tagname) return NULL; } +/* gather up all the CDATA into a single string */ +const char *dav_xml_get_cdata(const ap_xml_elem *elem, apr_pool_t *pool, + int strip_white) +{ + apr_size_t len = 0; + ap_text *scan; + const ap_xml_elem *child; + char *cdata; + char *s; + apr_size_t tlen; + + for (scan = elem->first_cdata.first; scan != NULL; scan = scan->next) + len += strlen(scan->text); + + for (child = elem->first_child; child != NULL; child = child->next) { + for (scan = child->following_cdata.first; + scan != NULL; + scan = scan->next) + len += strlen(scan->text); + } + + cdata = s = apr_palloc(pool, len + 1); + + for (scan = elem->first_cdata.first; scan != NULL; scan = scan->next) { + tlen = strlen(scan->text); + memcpy(s, scan->text, tlen); + s += tlen; + } + + for (child = elem->first_child; child != NULL; child = child->next) { + for (scan = child->following_cdata.first; + scan != NULL; + scan = scan->next) { + tlen = strlen(scan->text); + memcpy(s, scan->text, tlen); + s += tlen; + } + } + + *s = '\0'; + + if (strip_white && len > 0) { + /* trim leading whitespace */ + while (apr_isspace(*cdata)) /* assume: return false for '\0' */ + ++cdata; + + /* trim trailing whitespace */ + while (len-- > 0 && apr_isspace(cdata[len])) + continue; + cdata[len + 1] = '\0'; + } + + return cdata; +} + /* --------------------------------------------------------------- ** ** Timeout header processing @@ -1492,6 +1547,8 @@ dav_error * dav_get_locktoken_list(request_rec *r, dav_locktoken_list **ltl) return NULL; } +#if 0 /* not needed right now... */ + static const char *strip_white(const char *s, apr_pool_t *pool) { apr_size_t idx; @@ -1513,53 +1570,9 @@ static const char *strip_white(const char *s, apr_pool_t *pool) return s; } +#endif -#define DAV_TARGET_SELECTOR_HDR "Target-Selector" - -/* see mod_dav.h for docco */ -int dav_get_target_selector(request_rec *r, - const ap_xml_elem *version, - const char **target, - int *is_label) -{ - /* Initialize results */ - *target = NULL; - *is_label = 0; - - if (version != NULL) { - /* Expect either URI - * or LABEL */ - if (strcmp(version->name, "version") == 0) { - if ((version = dav_find_child(version, "href")) == NULL) { - ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, - "Missing DAV:href in DAV:version element"); - return HTTP_BAD_REQUEST; - } - - /* return the contents of the DAV:href element */ - /* ### this presumes no child elements */ - *target = strip_white(version->first_cdata.first->text, r->pool); - } - else if (strcmp(version->name, "label-name") == 0) { - /* return contents of the DAV:label-name element */ - *target = strip_white(version->first_cdata.first->text, r->pool); - *is_label = 1; - } - else { - ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, - "Unknown version specifier (not DAV:version or DAV:label-name)"); - return HTTP_BAD_REQUEST; - } - } - else { - /* no element. see if a Target-Selector header was provided - * (which is always interpreted as a label) */ - *target = apr_table_get(r->headers_in, DAV_TARGET_SELECTOR_HDR); - *is_label = 1; - } - - return OK; -} +#define DAV_LABEL_HDR "Label" /* dav_add_vary_header * @@ -1572,18 +1585,22 @@ void dav_add_vary_header(request_rec *in_req, { const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(in_req); + /* ### this is probably all wrong... I think there is a function in + ### the Apache API to add things to the Vary header. need to check */ + /* Only versioning headers require a Vary response header, * so only do this check if there is a versioning provider */ if (vsn_hooks != NULL) { - const char *target = apr_table_get(in_req->headers_in, DAV_TARGET_SELECTOR_HDR); + const char *target = apr_table_get(in_req->headers_in, DAV_LABEL_HDR); const char *vary = apr_table_get(out_req->headers_out, "Vary"); /* If Target-Selector specified, add it to the Vary header */ if (target != NULL) { if (vary == NULL) - vary = DAV_TARGET_SELECTOR_HDR; + vary = DAV_LABEL_HDR; else - vary = apr_pstrcat(out_req->pool, vary, "," DAV_TARGET_SELECTOR_HDR, NULL); + vary = apr_pstrcat(out_req->pool, vary, "," DAV_LABEL_HDR, + NULL); apr_table_setn(out_req->headers_out, "Vary", vary); } @@ -1649,7 +1666,7 @@ dav_error *dav_ensure_resource_writable(request_rec *r, * Note that auto-versioning can only be applied to a version selector, * so no separate working resource will be created. */ - if ((err = (*vsn_hooks->checkout)(parent, NULL)) + if ((err = (*vsn_hooks->checkout)(parent, 0, 0, 0, NULL, NULL)) != NULL) { body = apr_psprintf(r->pool, @@ -1685,7 +1702,7 @@ dav_error *dav_ensure_resource_writable(request_rec *r, if (!parent_only && !resource->working) { /* Auto-versioning can only be applied to version selectors, so * no separate working resource will be created. */ - if ((err = (*vsn_hooks->checkout)(resource, NULL)) + if ((err = (*vsn_hooks->checkout)(resource, 0, 0, 0, NULL, NULL)) != NULL) { body = apr_psprintf(r->pool, -- 2.40.0