From: Graham Leggett Date: Sat, 19 Sep 2009 11:20:24 +0000 (+0000) Subject: mod_dav: Allow other modules to become providers and add resource types X-Git-Tag: 2.3.3~277 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2ee2cd5689036fa99ee958aff606e25ba5f5ab8c;p=apache mod_dav: Allow other modules to become providers and add resource types to the DAV response. Submitted by: Jari Urpalainen , Brian France git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@816893 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 8e7e229fd3..5debcbc0c8 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,10 @@ Changes with Apache 2.3.3 mod_proxy_ftp: NULL pointer dereference on error paths. [Stefan Fritsch , Joe Orton] + *) mod_dav: Allow other modules to become providers and add resource types + to the DAV response. [Jari Urpalainen , + Brian France ] + *) mod_dav: Allow other modules to add things to the DAV or Allow headers of an OPTIONS request. [Jari Urpalainen , Brian France ] diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index 6218266b52..ac04cda419 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -15,7 +15,7 @@ */ /** - * @file mod_dav.h + * @file mod_dav.h * @brief DAV extension module for Apache 2.0.* * * @defgroup MOD_DAV mod_dav @@ -78,7 +78,7 @@ extern "C" { #define DAV_INFINITY INT_MAX /* for the Depth: header */ -/* Create a set of DAV_DECLARE(type), DAV_DECLARE_NONSTD(type) and +/* Create a set of DAV_DECLARE(type), DAV_DECLARE_NONSTD(type) and * DAV_DECLARE_DATA with appropriate export and import tags for the platform */ #if !defined(WIN32) @@ -136,7 +136,7 @@ typedef struct dav_error { ** Create a new error structure. save_errno will be filled with the current ** errno value. */ -DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status, +DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status, int error_id, const char *desc); @@ -145,7 +145,7 @@ DAV_DECLARE(dav_error*) dav_new_error(apr_pool_t *p, int status, ** namespace may be NULL, which means "DAV:". save_errno will be ** filled with the current errno value. */ -DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status, +DAV_DECLARE(dav_error*) dav_new_error_tag(apr_pool_t *p, int status, int error_id, const char *desc, const char *namespace, const char *tagname); @@ -411,28 +411,28 @@ typedef struct #define DAV_BUFFER_PAD 64 /* amount of pad when growing */ /* set the cur_len to the given size and ensure space is available */ -DAV_DECLARE(void) dav_set_bufsize(apr_pool_t *p, dav_buffer *pbuf, +DAV_DECLARE(void) dav_set_bufsize(apr_pool_t *p, dav_buffer *pbuf, apr_size_t size); /* initialize a buffer and copy the specified (null-term'd) string into it */ -DAV_DECLARE(void) dav_buffer_init(apr_pool_t *p, dav_buffer *pbuf, +DAV_DECLARE(void) dav_buffer_init(apr_pool_t *p, dav_buffer *pbuf, const char *str); /* check that the buffer can accomodate more bytes */ -DAV_DECLARE(void) dav_check_bufsize(apr_pool_t *p, dav_buffer *pbuf, +DAV_DECLARE(void) dav_check_bufsize(apr_pool_t *p, dav_buffer *pbuf, apr_size_t extra_needed); /* append a string to the end of the buffer, adjust length */ -DAV_DECLARE(void) dav_buffer_append(apr_pool_t *p, dav_buffer *pbuf, +DAV_DECLARE(void) dav_buffer_append(apr_pool_t *p, dav_buffer *pbuf, const char *str); /* place a string on the end of the buffer, do NOT adjust length */ -DAV_DECLARE(void) dav_buffer_place(apr_pool_t *p, dav_buffer *pbuf, +DAV_DECLARE(void) dav_buffer_place(apr_pool_t *p, dav_buffer *pbuf, const char *str); /* place some memory on the end of a buffer; do NOT adjust length */ -DAV_DECLARE(void) dav_buffer_place_mem(apr_pool_t *p, dav_buffer *pbuf, - const void *mem, apr_size_t amt, +DAV_DECLARE(void) dav_buffer_place_mem(apr_pool_t *p, dav_buffer *pbuf, + const void *mem, apr_size_t amt, apr_size_t pad); @@ -604,7 +604,7 @@ typedef struct { ** ** (of course, use your own domain to ensure a unique value) */ -APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, gather_propsets, +APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, gather_propsets, (apr_array_header_t *uris)) /* @@ -634,7 +634,7 @@ APR_DECLARE_EXTERNAL_HOOK(dav, DAV, int, find_liveprop, ** properties on the specified resource. If a particular liveprop is ** not defined for this resource, then it should not be inserted. */ -APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, insert_all_liveprops, +APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, insert_all_liveprops, (request_rec *r, const dav_resource *resource, dav_prop_insert what, apr_text_header *phdr)) @@ -687,7 +687,7 @@ typedef enum { dav_if_etag, dav_if_opaquelock, - dav_if_unknown /* the "unknown" state type; always matches false. */ + dav_if_unknown /* the "unknown" state type; always matches false. */ } dav_if_state_type; typedef struct dav_if_state_list @@ -714,7 +714,7 @@ typedef struct dav_if_header int dummy_header; /* used internally by the lock/etag validation */ } dav_if_header; -typedef struct dav_locktoken_list +typedef struct dav_locktoken_list { dav_locktoken *locktoken; struct dav_locktoken_list *next; @@ -746,7 +746,7 @@ struct dav_hooks_liveprop ** if the property is defined on the resource, then ** a DAV:supported-live-property element, as defined ** by the DeltaV extensions to RFC2518. - ** + ** ** Providers should return DAV_PROP_INSERT_NOTDEF if the property is ** known and not defined for this resource, so should be handled as a ** dead property. If a provider recognizes, but does not support, a @@ -887,7 +887,7 @@ DAV_DECLARE(long) dav_get_liveprop_info(int propid, const dav_liveprop_spec **info); /* ### docco */ -DAV_DECLARE(void) dav_register_liveprop_group(apr_pool_t *pool, +DAV_DECLARE(void) dav_register_liveprop_group(apr_pool_t *pool, const dav_liveprop_group *group); /* ### docco */ @@ -1083,7 +1083,7 @@ struct dav_hooks_propdb dav_error * (*map_namespaces)(dav_db *db, const apr_array_header_t *namespaces, dav_namespace_map **mapping); - + /* ** Store a property value for a given name. The value->combined field ** MUST be set for this call. @@ -1258,7 +1258,7 @@ DAV_DECLARE(dav_error *) dav_notify_created(request_rec *r, int resource_state, int depth); -DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb, +DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb, const dav_resource *resource, dav_lock **locks); @@ -1654,7 +1654,7 @@ typedef struct dav_walker_ctx /* ### client data... phasing out this big glom */ - /* this brigade buffers data being sent to r->output_filters */ + /* this brigade buffers data being sent to r->output_filters */ apr_bucket_brigade *bb; /* a scratch pool, used to stream responses and iteratively cleared. */ @@ -1748,7 +1748,7 @@ struct dav_hooks_repository * * The provider may associate the request storage pool with the resource * (in the resource->pool field), to use in other operations on that - * resource. + * resource. */ dav_error * (*get_resource)( request_rec *r, @@ -1759,7 +1759,7 @@ struct dav_hooks_repository ); /* Get a resource descriptor for the parent of the given resource. - * The resources need not exist. NULL is returned if the 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 @@ -2417,7 +2417,7 @@ DAV_DECLARE(apr_size_t) dav_get_limit_xml_body(const request_rec *r); typedef struct { int propid; /* live property ID */ const dav_hooks_liveprop *provider; /* the provider defining this prop */ -} dav_elem_private; +} dav_elem_private; /* -------------------------------------------------------------------- ** @@ -2430,19 +2430,39 @@ typedef struct dav_options_provider dav_error* (*dav_header)(request_rec *r, const dav_resource *resource, apr_text_header *phdr); - + dav_error* (*dav_method)(request_rec *r, const dav_resource *resource, apr_text_header *phdr); - - void *ctx; + + void *ctx; } dav_options_provider; extern DAV_DECLARE(const dav_options_provider *) dav_get_options_providers(const char *name); -extern DAV_DECLARE(void) dav_options_provider_register(apr_pool_t *p, - const char *name, - const dav_options_provider *provider); +extern DAV_DECLARE(void) dav_options_provider_register(apr_pool_t *p, + const char *name, + const dav_options_provider *provider); + +/* -------------------------------------------------------------------- +** +** DAV RESOURCE TYPE HOOKS +*/ + +typedef struct dav_resource_type_provider +{ + int (*get_resource_type)(const dav_resource *resource, + const char **name, + const char **uri); +} dav_resource_type_provider; + +#define DAV_RESOURCE_TYPE_GROUP "dav_resource_type" + +DAV_DECLARE(void) dav_resource_type_provider_register(apr_pool_t *p, + const char *name, + const dav_resource_type_provider *provider); + +DAV_DECLARE(const dav_resource_type_provider *) dav_get_resource_type_providers(const char *name); #ifdef __cplusplus } diff --git a/modules/dav/main/providers.c b/modules/dav/main/providers.c index 96a8fc5e93..44870fd01b 100644 --- a/modules/dav/main/providers.c +++ b/modules/dav/main/providers.c @@ -32,9 +32,9 @@ DAV_DECLARE(const dav_provider *) dav_lookup_provider(const char *name) return ap_lookup_provider(DAV_PROVIDER_GROUP, name, "0"); } -DAV_DECLARE(void) dav_options_provider_register(apr_pool_t *p, - const char *name, - const dav_options_provider *provider) +DAV_DECLARE(void) dav_options_provider_register(apr_pool_t *p, + const char *name, + const dav_options_provider *provider) { ap_register_provider(p, DAV_OPTIONS_EXTENSION_GROUP, name, "0", provider); } @@ -44,3 +44,15 @@ DAV_DECLARE(const dav_options_provider *) dav_get_options_providers(const char * return ap_lookup_provider(DAV_OPTIONS_EXTENSION_GROUP, name, "0"); } + +DAV_DECLARE(void) dav_resource_type_provider_register(apr_pool_t *p, + const char *name, + const dav_resource_type_provider *provider) +{ + ap_register_provider(p, DAV_RESOURCE_TYPE_GROUP, name, "0", provider); +} + +DAV_DECLARE(const dav_resource_type_provider *) dav_get_resource_type_providers(const char *name) +{ + return ap_lookup_provider(DAV_RESOURCE_TYPE_GROUP, name, "0"); +} diff --git a/modules/dav/main/std_liveprop.c b/modules/dav/main/std_liveprop.c index 297b04bdbf..1f79dc7128 100644 --- a/modules/dav/main/std_liveprop.c +++ b/modules/dav/main/std_liveprop.c @@ -17,6 +17,7 @@ #include "httpd.h" #include "util_xml.h" #include "apr_strings.h" +#include "ap_provider.h" #include "mod_dav.h" @@ -59,7 +60,7 @@ static dav_prop_insert dav_core_insert_prop(const dav_resource *resource, int propid, dav_prop_insert what, apr_text_header *phdr) { - const char *value; + const char *value = NULL; const char *s; apr_pool_t *p = resource->pool; const dav_liveprop_spec *info; @@ -68,32 +69,63 @@ static dav_prop_insert dav_core_insert_prop(const dav_resource *resource, switch (propid) { case DAV_PROPID_resourcetype: + { /* additional type info provided by external modules ? */ + int i; + + apr_array_header_t *extensions = + ap_list_provider_names(p, DAV_RESOURCE_TYPE_GROUP, "0"); + ap_list_provider_names_t *entry = + (ap_list_provider_names_t *)extensions->elts; + + for (i = 0; i < extensions->nelts; i++, entry++) { + const dav_resource_type_provider *res_hooks = + dav_get_resource_type_providers(entry->provider_name); + const char *name = NULL, *uri = NULL; + + if (!res_hooks || !res_hooks->get_resource_type) + continue; + + if (!res_hooks->get_resource_type(resource, &name, &uri) && + name) { + + if (!uri || !strcasecmp(uri, "DAV:")) + value = apr_pstrcat(p, value ? value : "", + "", NULL); + else + value = apr_pstrcat(p, value ? value : "", + "", NULL); + } + } + } switch (resource->type) { case DAV_RESOURCE_TYPE_VERSION: if (resource->baselined) { - value = ""; + value = apr_pstrcat(p, value ? value : "", "", NULL); break; } /* fall through */ case DAV_RESOURCE_TYPE_REGULAR: case DAV_RESOURCE_TYPE_WORKING: if (resource->collection) { - value = ""; + value = apr_pstrcat(p, value ? value : "", "", NULL); } else { /* ### should we denote lock-null resources? */ - + if (value == NULL) { value = ""; /* becomes: */ } + } break; case DAV_RESOURCE_TYPE_HISTORY: - value = ""; + value = apr_pstrcat(p, value ? value : "", "", NULL); break; case DAV_RESOURCE_TYPE_WORKSPACE: - value = ""; + value = apr_pstrcat(p, value ? value : "", "", NULL); break; case DAV_RESOURCE_TYPE_ACTIVITY: - value = ""; + value = apr_pstrcat(p, value ? value : "", "", NULL); break; default: