diff options
author | Greg Stein <gstein@apache.org> | 2001-02-07 13:33:17 +0100 |
---|---|---|
committer | Greg Stein <gstein@apache.org> | 2001-02-07 13:33:17 +0100 |
commit | f9b9fbe7b840f09277e0668d63da03df0cae4b0e (patch) | |
tree | 46d54493528804575c738aec57f4e4dd70c2e16c /modules/dav/main/util.c | |
parent | $enable_dav can be one of: yes, shared, no. We want to adjust the INCLUDES (diff) | |
download | apache2-f9b9fbe7b840f09277e0668d63da03df0cae4b0e.tar.xz apache2-f9b9fbe7b840f09277e0668d63da03df0cae4b0e.zip |
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
Diffstat (limited to 'modules/dav/main/util.c')
-rw-r--r-- | modules/dav/main/util.c | 119 |
1 files changed, 68 insertions, 51 deletions
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 <DAV:version><DAV:href>URI</DAV:href></DAV:version> - * or <DAV:label-name>LABEL</DAV:label-name> */ - 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, |