From: Greg Stein Date: Thu, 23 Nov 2000 12:50:31 +0000 (+0000) Subject: shift some processing of "core" WebDAV properties out of the generic X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=81019eac54eb884f04e08bf1c8f8ffec003a6952;p=apache shift some processing of "core" WebDAV properties out of the generic property handling code, and into a new, core liveprop handler. *) add std_liveprop.c to deal with the core DAV properties *) move DAV:resourcetype, DAV:supported-method-set, DAV:supported-live-property-set, and DAV:supported-report-set over to the new handler *) props.c::dav_get_allprops() should not look in the deadprop database for the DAV:resourcetype -- it is readonly, so should never be in there. *) strip vsn_hooks from the propdb; only the core liveprops need it now *) mod_dav.c: register the core liveprop hooks and URIs *) fs/repos.c: stripped DAV:displayname and DAV:source, in favor of letting the core handler deal with them. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@87075 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c index c168d2a9f2..9118fc6b7a 100644 --- a/modules/dav/fs/repos.c +++ b/modules/dav/fs/repos.c @@ -186,20 +186,6 @@ static const dav_liveprop_spec dav_fs_props[] = DAV_PROPID_FS_executable, 0 /* handled special in dav_fs_is_writeable */ }, - - /* ### these aren't FS specific */ - { - DAV_FS_URI_DAV, - "displayname", - DAV_PROPID_displayname, - 1, - }, - { - DAV_FS_URI_DAV, - "source", - DAV_PROPID_source, - 1, - }, { 0 } /* sentinel */ }; @@ -1743,10 +1729,6 @@ static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource, ** None of FS provider properties are defined if the resource does not ** exist. Just bail for this case. ** - ** Note that DAV:displayname and DAV:source will be stored as dead - ** properties; the NOTDEF return code indicates that dav_props.c should - ** look there for the value. - ** ** Even though we state that the FS properties are not defined, the ** client cannot store dead values -- we deny that thru the is_writeable ** hook function. @@ -1804,13 +1786,8 @@ static dav_prop_insert dav_fs_insert_prop(const dav_resource *resource, break; #endif /* WIN32 */ - case DAV_PROPID_displayname: - case DAV_PROPID_source: default: - /* - ** This property is not defined. However, it may be a dead - ** property. - */ + /* ### what the heck was this property? */ return DAV_PROP_INSERT_NOTDEF; } diff --git a/modules/dav/main/config.m4 b/modules/dav/main/config.m4 index 2948261b08..5059556635 100644 --- a/modules/dav/main/config.m4 +++ b/modules/dav/main/config.m4 @@ -2,7 +2,7 @@ dnl modules enabled in this directory by default APACHE_MODPATH_INIT(dav/main) -dav_objects="mod_dav.lo props.lo util.lo util_lock.lo liveprop.lo providers.lo" +dav_objects="mod_dav.lo props.lo util.lo util_lock.lo liveprop.lo providers.lo std_liveprop.lo" APACHE_MODULE(dav, WebDAV protocol handling, $dav_objects, , no) diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index df7c683087..cfc8bcc979 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -4006,6 +4006,13 @@ static void register_hooks(void) { ap_hook_post_config(dav_init_handler, NULL, NULL, AP_HOOK_MIDDLE); ap_hook_type_checker(dav_type_checker, NULL, NULL, AP_HOOK_FIRST); + + ap_hook_find_liveprop(dav_core_find_liveprop, NULL, NULL, AP_HOOK_LAST); + ap_hook_insert_all_liveprops(dav_core_insert_all_liveprops, + NULL, NULL, AP_HOOK_MIDDLE); + + /* ### damn. need a pool. */ + dav_core_register_uris(NULL); } /*--------------------------------------------------------------------------- diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index 7f876d5fe0..808b555dab 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -825,6 +825,19 @@ int dav_get_liveprop_ns_count(void); /* ### docco */ void dav_add_all_liveprop_xmlns(apr_pool_t *p, ap_text_header *phdr); +/* +** The following three functions are part of mod_dav's internal handling +** for the core WebDAV properties. They are not part of mod_dav's API. +*/ +int dav_core_find_liveprop(request_rec *r, const char *ns_uri, + const char *name, + const dav_hooks_liveprop **hooks); +void dav_core_insert_all_liveprops(request_rec *r, + const dav_resource *resource, + int insvalue, ap_text_header *phdr); +void dav_core_register_uris(apr_pool_t *p); + + /* ** Standard WebDAV Property Identifiers ** diff --git a/modules/dav/main/props.c b/modules/dav/main/props.c index 987b503ed9..8e9c6fd4c6 100644 --- a/modules/dav/main/props.c +++ b/modules/dav/main/props.c @@ -267,7 +267,6 @@ struct dav_propdb { /* hooks we should use for processing (based on the target resource) */ const dav_hooks_db *db_hooks; - const dav_hooks_vsn *vsn_hooks; }; @@ -278,11 +277,7 @@ static const char * const dav_core_props[] = "getcontenttype", "getcontentlanguage", "lockdiscovery", - "resourcetype", "supportedlock", - "supported-method-set", - "supported-live-property-set", - "supported-report-set", NULL /* sentinel */ }; @@ -290,11 +285,7 @@ enum { DAV_PROPID_CORE_getcontenttype = DAV_PROPID_CORE, DAV_PROPID_CORE_getcontentlanguage, DAV_PROPID_CORE_lockdiscovery, - DAV_PROPID_CORE_resourcetype, DAV_PROPID_CORE_supportedlock, - DAV_PROPID_CORE_supported_method_set, - DAV_PROPID_CORE_supported_live_property_set, - DAV_PROPID_CORE_supported_report_set, DAV_PROPID_CORE_UNKNOWN }; @@ -382,15 +373,12 @@ static int dav_rw_liveprop(dav_propdb *propdb, dav_elem_private *priv) /* these are defined as read-only */ if (propid == DAV_PROPID_CORE_lockdiscovery - || propid == DAV_PROPID_CORE_resourcetype #if DAV_DISABLE_WRITEABLE_PROPS || propid == DAV_PROPID_CORE_getcontenttype || propid == DAV_PROPID_CORE_getcontentlanguage #endif || propid == DAV_PROPID_CORE_supportedlock - || propid == DAV_PROPID_CORE_supported_method_set - || propid == DAV_PROPID_CORE_supported_live_property_set - || propid == DAV_PROPID_CORE_supported_report_set) { + ) { return 0; } @@ -435,41 +423,6 @@ static dav_error * dav_insert_coreprop(dav_propdb *propdb, switch (propid) { - case DAV_PROPID_CORE_resourcetype: - switch (propdb->resource->type) { - case DAV_RESOURCE_TYPE_VERSION: - if (propdb->resource->baselined) { - value = ""; - break; - } - /* fall through */ - case DAV_RESOURCE_TYPE_REGULAR: - case DAV_RESOURCE_TYPE_WORKING: - if (propdb->resource->collection) { - value = ""; - } - else { - /* ### should we denote lock-null resources? */ - - value = ""; /* becomes: */ - } - break; - case DAV_RESOURCE_TYPE_HISTORY: - value = ""; - break; - case DAV_RESOURCE_TYPE_WORKSPACE: - value = ""; - break; - case DAV_RESOURCE_TYPE_ACTIVITY: - value = ""; - break; - - default: - /* ### bad juju */ - break; - } - break; - case DAV_PROPID_CORE_lockdiscovery: if (propdb->lockdb != NULL) { dav_lock *locks; @@ -507,43 +460,6 @@ static dav_error * dav_insert_coreprop(dav_propdb *propdb, } break; - case DAV_PROPID_CORE_supported_method_set: - /* ### leverage code from dav_method_options ### */ - break; - - case DAV_PROPID_CORE_supported_live_property_set: - /* ### insert all live property names ### */ - break; - - case DAV_PROPID_CORE_supported_report_set: - if (propdb->vsn_hooks != NULL) { - const dav_report_elem *reports; - - if ((err = (*propdb->vsn_hooks->avail_reports)(propdb->resource, &reports)) != NULL) { - return dav_push_error(propdb->r->pool, err->status, 0, - "DAV:supported-report-set could not be determined " - "due to a problem fetching the available reports " - "for this resource.", - err); - } - - if (reports == NULL) - break; - - value = ""; - - for (; reports->nmspace != NULL; ++reports) { - /* Note: we presume reports->namespace is properly XML/URL quoted */ - char *v = apr_psprintf(propdb->p, "<%s xmlns=\"%s\"/>" DEBUG_CR, - reports->name, reports->nmspace); - /* This isn't very memory-efficient, but there should only be a small - * number of reports - */ - value = apr_pstrcat(propdb->p, value, v, NULL); - } - } - break; - case DAV_PROPID_CORE_getcontenttype: if (propdb->subreq == NULL) { dav_do_prop_subreq(propdb); @@ -1005,7 +921,6 @@ dav_error *dav_open_propdb(request_rec *r, dav_lockdb *lockdb, propdb->ns_xlate = ns_xlate; propdb->db_hooks = DAV_GET_HOOKS_PROPDB(r); - propdb->vsn_hooks = DAV_GET_HOOKS_VSN(r); propdb->lockdb = lockdb; @@ -1059,7 +974,6 @@ dav_get_props_result dav_get_allprops(dav_propdb *propdb, int getvals) ap_text_header hdr = { 0 }; ap_text_header hdr_ns = { 0 }; dav_get_props_result result = { 0 }; - int found_resourcetype = 0; int found_contenttype = 0; int found_contentlang = 0; int unused_inserted; @@ -1087,10 +1001,6 @@ dav_get_props_result dav_get_allprops(dav_propdb *propdb, int getvals) goto next_key; /* - ** See if this is the property. We need to - ** know whether it was found (and therefore, whether to supply - ** a default later). - ** ** We also look for and ** . If they are not stored as dead ** properties, then we need to perform a subrequest to get @@ -1110,12 +1020,7 @@ dav_get_props_result dav_get_allprops(dav_propdb *propdb, int getvals) colon = strchr(key.dptr + 2, ':'); } - if (colon[1] == 'r' - && strcmp(colon + 1, "resourcetype") == 0) { - - found_resourcetype = 1; - } - else if (colon[1] == 'g') { + if (colon[1] == 'g') { if (strcmp(colon + 1, "getcontenttype") == 0) { found_contenttype = 1; } @@ -1166,23 +1071,6 @@ dav_get_props_result dav_get_allprops(dav_propdb *propdb, int getvals) (void)dav_insert_coreprop(propdb, DAV_PROPID_CORE_lockdiscovery, "lockdiscovery", getvals, &hdr, &unused_inserted); - (void)dav_insert_coreprop(propdb, - DAV_PROPID_CORE_supported_method_set, "supported-method-set", - getvals, &hdr, &unused_inserted); - (void)dav_insert_coreprop(propdb, - DAV_PROPID_CORE_supported_live_property_set, "supported-live-property-set", - getvals, &hdr, &unused_inserted); - (void)dav_insert_coreprop(propdb, - DAV_PROPID_CORE_supported_report_set, "supported-report-set", - getvals, &hdr, &unused_inserted); - - /* if the resourcetype wasn't stored, then prepare one */ - if (!found_resourcetype) { - /* ### should be handling the return error here */ - (void)dav_insert_coreprop(propdb, - DAV_PROPID_CORE_resourcetype, "resourcetype", - getvals, &hdr, &unused_inserted); - } /* if we didn't find these, then do the whole subreq thing. */ if (!found_contenttype) { diff --git a/modules/dav/main/std_liveprop.c b/modules/dav/main/std_liveprop.c new file mode 100644 index 0000000000..a7acd24c29 --- /dev/null +++ b/modules/dav/main/std_liveprop.c @@ -0,0 +1,289 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +#include "httpd.h" +#include "util_xml.h" +#include "apr_strings.h" + +#include "mod_dav.h" + +/* forward-declare */ +static const dav_hooks_liveprop dav_core_hooks_liveprop; + +/* +** The namespace URIs that we use. There will only ever be "DAV:". +*/ +static const char * const dav_core_namespace_uris[] = +{ + "DAV:", + NULL /* sentinel */ +}; + +/* +** Define each of the core properties that this provider will handle. +** Note that all of them are in the DAV: namespace, which has a +** provider-local index of 0. +*/ +static const dav_liveprop_spec dav_core_props[] = +{ + { 0, "comment", DAV_PROPID_comment, 1 }, + { 0, "creator-displayname", DAV_PROPID_creator_displayname, 1 }, + { 0, "displayname", DAV_PROPID_displayname, 1 }, + { 0, "resourcetype", DAV_PROPID_resourcetype, 0 }, + { 0, "source", DAV_PROPID_source, 1 }, + { 0, "supported-live-property-set", + DAV_PROPID_supported_live_property_set, 0 }, + { 0, "supported-method-set", DAV_PROPID_supported_method_set, 0 }, + { 0, "supported-report-set", DAV_PROPID_supported_report_set, 0 }, + + { 0 } /* sentinel */ +}; + +static const dav_liveprop_group dav_core_liveprop_group = +{ + dav_core_props, + dav_core_namespace_uris, + &dav_core_hooks_liveprop +}; + +static dav_prop_insert dav_core_insert_prop(const dav_resource *resource, + int propid, int insvalue, + ap_text_header *phdr) +{ + const char *value; + const char *s; + dav_prop_insert which; + apr_pool_t *p = resource->pool; + const dav_liveprop_spec *info; + int global_ns; + + switch (propid) + { + case DAV_PROPID_resourcetype: + switch (resource->type) { + case DAV_RESOURCE_TYPE_VERSION: + if (resource->baselined) { + value = ""; + break; + } + /* fall through */ + case DAV_RESOURCE_TYPE_REGULAR: + case DAV_RESOURCE_TYPE_WORKING: + if (resource->collection) { + value = ""; + } + else { + /* ### should we denote lock-null resources? */ + + value = ""; /* becomes: */ + } + break; + case DAV_RESOURCE_TYPE_HISTORY: + value = ""; + break; + case DAV_RESOURCE_TYPE_WORKSPACE: + value = ""; + break; + case DAV_RESOURCE_TYPE_ACTIVITY: + value = ""; + break; + + default: + /* ### bad juju */ + return DAV_PROP_INSERT_NOTDEF; + } + break; + + case DAV_PROPID_supported_live_property_set: + /* ### insert all live property names ### */ + break; + + case DAV_PROPID_supported_method_set: + /* ### leverage code from dav_method_options ### */ + break; + + case DAV_PROPID_supported_report_set: +#if 0 + { + /* ### where to get "r" ??? */ + const dav_hooks_vsn *vsn_hooks = dav_get_vsn_hooks(r); + + if (vsn_hooks != NULL) { + const dav_report_elem *reports; + dav_error *err; + + if ((err = (*vsn_hooks->avail_reports)(resource, + &reports)) != NULL) { + err = dav_push_error(p, err->status, 0, + "DAV:supported-report-set could not " + "be determined due to a problem " + "fetching the available reports " + "for this resource.", + err); + /* ### can't return err... sigh. punt for now. */ + return DAV_PROP_INSERT_NOTDEF; + } + + value = ""; + + if (reports == NULL) { + /* no reports are defined. break with value="" */ + break; + } + + for (; reports->nmspace != NULL; ++reports) { + /* Note: presume reports->namespace is XML/URL quoted */ + const char *v = apr_psprintf(p, "<%s xmlns=\"%s\"/>" DEBUG_CR, + reports->name, reports->nmspace); + + /* This isn't very memory-efficient, but there should only + be a small number of reports */ + value = apr_pstrcat(p, value, v, NULL); + } + } + break; + } +#endif + /* above code disabled. FALLTHROUGH */ + + case DAV_PROPID_comment: + case DAV_PROPID_creator_displayname: + case DAV_PROPID_displayname: + case DAV_PROPID_source: + default: + /* + ** This property is known, but not defined as a liveprop. However, + ** it may be a dead property. + */ + return DAV_PROP_INSERT_NOTDEF; + } + + /* assert: value != NULL */ + + /* get the information and global NS index for the property */ + global_ns = dav_get_liveprop_info(propid, &dav_core_liveprop_group, &info); + + /* assert: info != NULL && info->name != NULL */ + + if (insvalue) { + s = apr_psprintf(p, "%s" DEBUG_CR, + global_ns, info->name, value, global_ns, info->name); + which = DAV_PROP_INSERT_VALUE; + } + else { + s = apr_psprintf(p, "" DEBUG_CR, global_ns, info->name); + which = DAV_PROP_INSERT_NAME; + } + ap_text_append(p, phdr, s); + + /* we inserted a name or value (this prop is done) */ + return which; +} + +static int dav_core_is_writable(const dav_resource *resource, int propid) +{ + const dav_liveprop_spec *info; + + (void) dav_get_liveprop_info(propid, &dav_core_liveprop_group, &info); + return info->is_writable; +} + +static dav_error * dav_core_patch_validate(const dav_resource *resource, + const ap_xml_elem *elem, + int operation, void **context, + int *defer_to_dead) +{ + /* all of our writeable props go in the dead prop database */ + *defer_to_dead = 1; + + return NULL; +} + +static const dav_hooks_liveprop dav_core_hooks_liveprop = { + dav_core_insert_prop, + dav_core_is_writable, + dav_core_namespace_uris, + dav_core_patch_validate, + NULL, /* patch_exec */ + NULL, /* patch_commit */ + NULL, /* patch_rollback */ +}; + +int dav_core_find_liveprop(request_rec *r, const char *ns_uri, + const char *name, + const dav_hooks_liveprop **hooks) +{ + return dav_do_find_liveprop(ns_uri, name, &dav_core_liveprop_group, hooks); +} + +void dav_core_insert_all_liveprops(request_rec *r, + const dav_resource *resource, + int insvalue, ap_text_header *phdr) +{ + (void) dav_core_insert_prop(resource, DAV_PROPID_resourcetype, + insvalue, phdr); + (void) dav_core_insert_prop(resource, + DAV_PROPID_supported_live_property_set, + insvalue, phdr); + (void) dav_core_insert_prop(resource, DAV_PROPID_supported_method_set, + insvalue, phdr); + (void) dav_core_insert_prop(resource, DAV_PROPID_supported_report_set, + insvalue, phdr); +} + +void dav_core_register_uris(apr_pool_t *p) +{ + /* register the namespace URIs */ + dav_register_liveprop_group(p, &dav_core_liveprop_group); +}